001package org.hl7.fhir.r5.extensions; 002 003import java.math.BigDecimal; 004import java.util.ArrayList; 005import java.util.List; 006 007import org.hl7.fhir.exceptions.FHIRException; 008import org.hl7.fhir.r5.model.BackboneElement; 009import org.hl7.fhir.r5.model.BackboneType; 010import org.hl7.fhir.r5.model.Base; 011import org.hl7.fhir.r5.model.DataType; 012import org.hl7.fhir.r5.model.DomainResource; 013import org.hl7.fhir.r5.model.Element; 014import org.hl7.fhir.r5.model.Extension; 015import org.hl7.fhir.r5.model.Property; 016import org.hl7.fhir.r5.model.Resource; 017import org.hl7.fhir.utilities.Utilities; 018 019public class ExtensionsUtils { 020 021 private static Extension setExtensionE(Element context, String url, DataType value) { 022 for (Extension ext : context.getExtension()) { 023 if (ext.getUrl().equals(url)) { 024 return ext.setValue(value); 025 } 026 } 027 return context.addExtension().setUrl(url).setValue(value); 028 } 029 030 private static Extension setExtensionBE(BackboneElement context, boolean mod, String url, DataType value) { 031 if (mod) { 032 for (Extension ext : context.getModifierExtension()) { 033 if (ext.getUrl().equals(url)) { 034 return ext.setValue(value); 035 } 036 } 037 return context.addModifierExtension().setUrl(url).setValue(value); 038 } else { 039 return setExtensionE(context, url, value); 040 } 041 } 042 043 private static Extension setExtensionBT(BackboneType context, boolean mod, String url, DataType value) { 044 if (mod) { 045 for (Extension ext : context.getModifierExtension()) { 046 if (ext.getUrl().equals(url)) { 047 return ext.setValue(value); 048 } 049 } 050 return context.addModifierExtension().setUrl(url).setValue(value); 051 } else { 052 return setExtensionE(context, url, value); 053 } 054 } 055 056 private static Extension setExtensionR(DomainResource context, boolean mod, String url, DataType value) { 057 if (mod) { 058 for (Extension ext : context.getModifierExtension()) { 059 if (ext.getUrl().equals(url)) { 060 return ext.setValue(value); 061 } 062 } 063 return context.addModifierExtension().setUrl(url).setValue(value); 064 } else { 065 for (Extension ext : context.getExtension()) { 066 if (ext.getUrl().equals(url)) { 067 return ext.setValue(value); 068 } 069 } 070 return context.addExtension().setUrl(url).setValue(value); 071 } 072 } 073 074 public static Extension setExtension(Base context, String url, DataType value) { 075 boolean mod = ExtensionConstants.isModifier(url); 076 if (context instanceof BackboneElement) { 077 return setExtensionBE((BackboneElement) context, mod, url, value); 078 } else if (mod && context instanceof BackboneType) { 079 return setExtensionBT((BackboneType) context, mod, url, value); 080 } else if (context instanceof Element) { 081 if (mod) { 082 throw new FHIRException("Can't use a modifier extension on "+context.getClass().getName()); 083 } else { 084 return setExtensionE((Element) context, url, value); 085 } 086 } else if (context instanceof DomainResource) { 087 return setExtensionR((DomainResource) context, mod, url, value); 088 } else { 089 throw new FHIRException("Can't use an extension on "+context.getClass().getName()); 090 } 091 } 092 093 094 private static Extension addExtensionE(Element context, String url, DataType value) { 095 return context.addExtension().setValue(value); 096 } 097 098 private static Extension addExtensionBE(BackboneElement context, boolean mod, String url, DataType value) { 099 if (mod) { 100 return context.addModifierExtension().setValue(value); 101 } else { 102 return setExtensionE(context, url, value); 103 } 104 } 105 106 private static Extension addExtensionBT(BackboneType context, boolean mod, String url, DataType value) { 107 if (mod) { 108 return context.addModifierExtension().setUrl(url).setValue(value); 109 } else { 110 return setExtensionE(context, url, value); 111 } 112 } 113 114 private static Extension addExtensionR(DomainResource context, boolean mod, String url, DataType value) { 115 if (mod) { 116 return context.addModifierExtension().setUrl(url).setValue(value); 117 } else { 118 return context.addExtension().setUrl(url).setValue(value); 119 } 120 } 121 122 public static Extension addExtension(Base context, String url, DataType value) { 123 boolean mod = ExtensionConstants.isModifier(url); 124 if (context instanceof BackboneElement) { 125 return addExtensionBE((BackboneElement) context, mod, url, value); 126 } else if (mod && context instanceof BackboneType) { 127 return addExtensionBT((BackboneType) context, mod, url, value); 128 } else if (context instanceof Element) { 129 if (mod) { 130 throw new FHIRException("Can't use a modifier extension on "+context.getClass().getName()); 131 } else { 132 return addExtensionE((Element) context, url, value); 133 } 134 } else if (context instanceof DomainResource) { 135 return addExtensionR((DomainResource) context, mod, url, value); 136 } else { 137 throw new FHIRException("Can't use an extension on "+context.getClass().getName()); 138 } 139 } 140 141 private static List<Extension> getAllExtensions(Base context, String url) { 142 List<Extension> list = new ArrayList<>(); 143 boolean mod = ExtensionConstants.isModifier(url); 144 if (mod) { 145 if (context instanceof BackboneElement) { 146 list.addAll(((BackboneElement) context).getModifierExtension()); 147 } 148 if (context instanceof BackboneType) { 149 list.addAll(((BackboneElement) context).getModifierExtension()); 150 } 151 if (context instanceof DomainResource) { 152 list.addAll(((DomainResource) context).getModifierExtension()); 153 } 154 } else { 155 if (context instanceof Element) { 156 list.addAll(((Element) context).getExtension()); 157 } 158 if (context instanceof DomainResource) { 159 list.addAll(((DomainResource) context).getExtension()); 160 } 161 } 162 return list; 163 } 164 165 public static <T extends DataType> T getExtension(Class<T> class_, Base context, String url) { 166 boolean found = false; 167 T result = null; 168 for (Extension ext : getAllExtensions(context, url)) { 169 if (ext.hasUrl() && ext.getUrl().equals(url)) { 170 if (found) { 171 throw new FHIRException("Multiple Extensions for "+url); 172 } else if (ext.hasValue() && class_.isInstance(ext.getValue())) { 173 found = true; 174 result = (T) ext.getValue(); 175 } 176 } 177 } 178 return result; 179 } 180 181 public static <T extends DataType> List<T> getExtensionList(Class<T> class_, Base context, String url) { 182 List<T> result = new ArrayList<>(); 183 for (Extension ext : getAllExtensions(context, url)) { 184 if (ext.hasUrl() && ext.getUrl().equals(url)) { 185 if (ext.hasValue() && class_.isInstance(ext.getValue())) { 186 result.add((T) ext.getValue()); 187 } 188 } 189 } 190 return result; 191 } 192 193 public static String getExtensionString(Base context, String url) { 194 boolean found = false; 195 String result = null; 196 for (Extension ext : getAllExtensions(context, url)) { 197 if (ext.hasUrl() && ext.getUrl().equals(url)) { 198 if (found) { 199 throw new FHIRException("Multiple Extensions for "+url); 200 } else if (ext.hasValue() && ext.getValue().isPrimitive()) { 201 found = true; 202 result = ext.getValue().primitiveValue(); 203 } 204 } 205 } 206 return result; 207 } 208 209 public static Boolean getExtensionBoolean(Base context, String url) { 210 boolean found = false; 211 Boolean result = null; 212 for (Extension ext : getAllExtensions(context, url)) { 213 if (ext.hasUrl() && ext.getUrl().equals(url)) { 214 if (found) { 215 throw new FHIRException("Multiple Extensions for "+url); 216 } else if (ext.hasValueBooleanType()) { 217 found = true; 218 result = ext.getValueBooleanType().getValue(); 219 } 220 } 221 } 222 return result; 223 } 224 225 public static Integer getExtensionInt(Base context, String url) { 226 boolean found = false; 227 Integer result = null; 228 for (Extension ext : getAllExtensions(context, url)) { 229 if (ext.hasUrl() && ext.getUrl().equals(url)) { 230 if (found) { 231 throw new FHIRException("Multiple Extensions for "+url); 232 } else if (ext.hasValueIntegerType()) { 233 found = true; 234 result = ext.getValueIntegerType().getValue(); 235 } 236 } 237 } 238 return result; 239 } 240 241 public static BigDecimal getExtensionFloat(Base context, String url) { 242 boolean found = false; 243 BigDecimal result = null; 244 for (Extension ext : getAllExtensions(context, url)) { 245 if (ext.hasUrl() && ext.getUrl().equals(url)) { 246 if (found) { 247 throw new FHIRException("Multiple Extensions for "+url); 248 } else if (ext.hasValueIntegerType()) { 249 found = true; 250 result = ext.getValueDecimalType().getValue(); 251 } 252 } 253 } 254 return result; 255 } 256 257 public static List<String> getExtensionStringList(Base context, String url) { 258 List<String> result = new ArrayList<>(); 259 for (Extension ext : getAllExtensions(context, url)) { 260 if (ext.hasUrl() && ext.getUrl().equals(url)) { 261 if (ext.hasValue() && ext.getValue().isPrimitive()) { 262 result.add(ext.getValue().primitiveValue()); 263 } 264 } 265 } 266 return result; 267 } 268 269 public static List<Integer> getExtensionIntList(Base context, String url) { 270 List<Integer> result = new ArrayList<>(); 271 for (Extension ext : getAllExtensions(context, url)) { 272 if (ext.hasUrl() && ext.getUrl().equals(url)) { 273 if (ext.hasValueIntegerType()) { 274 result.add(ext.getValueIntegerType().getValue()); 275 } 276 } 277 } 278 return result; 279 } 280 281 public static boolean stripExtensions(Element element, String... exceptions) { 282 return stripExtensions(element, Utilities.strings(exceptions)); 283 } 284 285 public static boolean stripExtensions(Element element, List<String> exceptions) { 286 boolean res = element.getExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())); 287 if (element instanceof BackboneElement) { 288 res = ((BackboneElement) element).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) || res; 289 } 290 if (element instanceof BackboneElement) { 291 res = ((BackboneElement) element).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) || res; 292 } 293 for (Property p : element.children()) { 294 for (Base v : p.getValues()) { 295 if (v instanceof Element) { 296 res = stripExtensions((Element) v, exceptions) || res; 297 } else if (v instanceof Element) { 298 res = stripExtensions((Resource) v, exceptions) || res; 299 } 300 } 301 } 302 return res; 303 } 304 305 public static boolean stripExtensions(Resource resource, String... exceptions) { 306 return stripExtensions(resource, Utilities.strings(exceptions)); 307 } 308 309 public static boolean stripExtensions(Resource resource, List<String> exceptions) { 310 boolean res = false; 311 if (resource instanceof DomainResource) { 312 res = ((DomainResource) resource).getExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) || 313 ((DomainResource) resource).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())); 314 } 315 for (Property p : resource.children()) { 316 for (Base v : p.getValues()) { 317 if (v instanceof Element) { 318 res = stripExtensions((Element) v, exceptions) || res; 319 } else if (v instanceof Element) { 320 res = stripExtensions((Resource) v, exceptions) || res; 321 } 322 } 323 } 324 return res; 325 } 326 327 public static void copyExtensions(List<Extension> source, List<Extension> dest, String... urls) { 328 if (source != null && dest != null) { 329 for (Extension ex : source) { 330 if (Utilities.existsInList(ex.getUrl(), urls)) { 331 dest.add(ex.copy()); 332 } 333 } 334 } 335 } 336 337 338 339 public static DataType getExtensionValue(List<Extension> extensions, String url) { 340 for (Extension ex : extensions) { 341 if (ex.getUrl().equals(url)) { 342 return ex.getValue(); 343 } 344 } 345 return null; 346 } 347 348 349 public static String getExtensionString(List<Extension> extensions, String url) { 350 for (Extension ex : extensions) { 351 if (ex.getUrl().equals(url)) { 352 return ex.getValue().primitiveValue(); 353 } 354 } 355 return null; 356 } 357 358 359 360 public static Integer getExtensionInteger(List<Extension> extensions, String url) { 361 for (Extension ex : extensions) { 362 if (ex.getUrl().equals(url) && ex.hasValueIntegerType()) { 363 return ex.getValueIntegerType().getValue(); 364 } 365 } 366 return null; 367 } 368 369 public static boolean hasExtension(List<Extension> extensions, String url) { 370 if (extensions == null) { 371 return false; 372 } 373 for (Extension ex : extensions) { 374 if (ex.getUrl().equals(url)) { 375 return true; 376 } 377 } 378 return false; 379 } 380}