001package org.hl7.fhir.r5.extensions;
002
003import org.apache.commons.lang3.StringUtils;
004import org.hl7.fhir.exceptions.FHIRException;
005import org.hl7.fhir.r5.model.*;
006
007import org.hl7.fhir.utilities.StandardsStatus;
008import org.hl7.fhir.utilities.Utilities;
009import org.hl7.fhir.utilities.validation.ValidationMessage;
010
011import java.lang.reflect.Field;
012import java.lang.reflect.Modifier;
013import java.math.BigDecimal;
014import java.util.*;
015
016public class ExtensionUtilities {
017
018  // specific extension helpers
019
020  public static Extension makeIssueSource(ValidationMessage.Source source) {
021    Extension ex = new Extension();
022    // todo: write this up and get it published with the pack (and handle the redirect?)
023    ex.setUrl(ExtensionDefinitions.EXT_ISSUE_SOURCE);
024    StringType c = new StringType();
025    c.setValue(source.toString());
026    ex.setValue(c);
027    return ex;
028  }
029
030  public static Extension makeIssueMessageId(String msgId) {
031    Extension ex = new Extension();
032    // todo: write this up and get it published with the pack (and handle the redirect?)
033    ex.setUrl(ExtensionDefinitions.EXT_ISSUE_MSG_ID);
034    CodeType c = new CodeType();
035    c.setValue(msgId);
036    ex.setValue(c);
037    return ex;
038  }
039
040  public static boolean hasExtension(DomainResource de, String url) {
041    return getExtension(de, url) != null;
042  }
043
044  public static boolean hasExtension(Element e, String url) {
045    return getExtension(e, url) != null;
046  }
047
048  //  public static void addStringExtension(DomainResource dr, String url, String content) {
049  //    if (!StringUtils.isBlank(content)) {
050  //      Extension ex = getExtension(dr, url);
051  //      if (ex != null)
052  //        ex.setValue(new StringType(content));
053  //      else
054  //        dr.getExtension().add(Factory.newExtension(url, new StringType(content), true));
055  //    }
056  //  }
057
058  public static void addMarkdownExtension(DomainResource dr, String url, String content) {
059    if (!StringUtils.isBlank(content)) {
060      Extension ex = getExtension(dr, url);
061      if (ex != null)
062        ex.setValue(new StringType(content));
063      else
064        dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true));
065    }
066  }
067
068  public static void addStringExtension(Element e, String url, String content) {
069    if (!StringUtils.isBlank(content)) {
070      Extension ex = getExtension(e, url);
071      if (ex != null)
072        ex.setValue(new StringType(content));
073      else
074        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));
075    }
076  }
077
078  public static void addCodeExtension(Element e, String url, String content) {
079    if (!StringUtils.isBlank(content)) {
080      Extension ex = getExtension(e, url);
081      if (ex != null)
082        ex.setValue(new CodeType(content));
083      else
084        e.getExtension().add(Factory.newExtension(url, new CodeType(content), true));
085    }
086  }
087
088  public static void addStringExtension(DomainResource e, String url, String content) {
089    if (!StringUtils.isBlank(content)) {
090      Extension ex = getExtension(e, url);
091      if (ex != null)
092        ex.setValue(new StringType(content));
093      else
094        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));
095    }
096  }
097
098
099  public static void addBooleanExtension(Element e, String url, boolean content) {
100    Extension ex = getExtension(e, url);
101    if (ex != null)
102      ex.setValue(new BooleanType(content));
103    else
104      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));
105  }
106
107  public static void addBooleanExtension(DomainResource e, String url, boolean content) {
108    Extension ex = getExtension(e, url);
109    if (ex != null)
110      ex.setValue(new BooleanType(content));
111    else
112      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));
113  }
114
115  public static void addIntegerExtension(DomainResource dr, String url, int value) {
116    Extension ex = getExtension(dr, url);
117    if (ex != null)
118      ex.setValue(new IntegerType(value));
119    else
120      dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true));
121  }
122
123  public static void addCodeExtension(DomainResource dr, String url, String value) {
124    Extension ex = getExtension(dr, url);
125    if (ex != null)
126      ex.setValue(new CodeType(value));
127    else
128      dr.getExtension().add(Factory.newExtension(url, new CodeType(value), true));
129  }
130
131  public static void addVSComment(ValueSet.ConceptSetComponent nc, String comment) {
132    if (!StringUtils.isBlank(comment))
133      nc.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_VS_COMMENT, Factory.newString_(comment), true));
134  }
135  public static void addVSComment(ValueSet.ConceptReferenceComponent nc, String comment) {
136    if (!StringUtils.isBlank(comment))
137      nc.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_VS_COMMENT, Factory.newString_(comment), true));
138  }
139
140  //  public static void markDeprecated(Element nc) {
141  //    setDeprecated(nc);
142  //  }
143  //
144
145  public static void addDefinition(Element nc, String definition) {
146    if (!StringUtils.isBlank(definition))
147      nc.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_DEFINITION, Factory.newString_(definition), true));
148  }
149
150  public static void addDisplayHint(Element def, String hint) {
151    if (!StringUtils.isBlank(hint))
152      def.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_DISPLAY_HINT, Factory.newString_(hint), true));
153  }
154
155  public static String getDisplayHint(Element def) {
156    return readStringExtension(def, ExtensionDefinitions.EXT_DISPLAY_HINT);
157  }
158
159  public static String readStringExtension(Element c, String... uris) {
160    for (String uri : uris) {
161      if (hasExtension(c, uri)) {
162        return readStringExtension(c, uri);
163      }
164    }
165    return null;
166  }
167
168  public static String readStringFromExtension(Extension ext) {
169    if (ext.hasValue() && ext.getValue().isPrimitive()) {
170      return ext.getValue().primitiveValue();
171    }
172    return null;
173  }
174
175  public static String readStringExtension(Element c, String uri) {
176    Extension ex = ExtensionHelper.getExtension(c, uri);
177    if (ex == null)
178      return null;
179    if (ex.getValue() instanceof UriType)
180      return ((UriType) ex.getValue()).getValue();
181    if (ex.getValue() instanceof CanonicalType)
182      return ((CanonicalType) ex.getValue()).getValue();
183    if (ex.getValue() instanceof CodeType)
184      return ((CodeType) ex.getValue()).getValue();
185    if (ex.getValue() instanceof IntegerType)
186      return ((IntegerType) ex.getValue()).asStringValue();
187    if (ex.getValue() instanceof Integer64Type)
188      return ((Integer64Type) ex.getValue()).asStringValue();
189    if (ex.getValue() instanceof DecimalType)
190      return ((DecimalType) ex.getValue()).asStringValue();
191    if ((ex.getValue() instanceof MarkdownType))
192      return ((MarkdownType) ex.getValue()).getValue();
193    if ((ex.getValue() instanceof PrimitiveType))
194      return ((PrimitiveType) ex.getValue()).primitiveValue();
195    if (!(ex.getValue() instanceof StringType))
196      return null;
197    return ((StringType) ex.getValue()).getValue();
198  }
199
200  public static List<String> readStringExtensions(Element c, String uri) {
201    List<String> res = new ArrayList<>();
202    List<Extension> list = ExtensionHelper.getExtensionList(c, uri);
203    for (Extension ex : list) {
204      if (ex != null) {
205        if (ex.getValue() instanceof UriType)
206          res.add(((UriType) ex.getValue()).getValue());
207        if (ex.getValue() instanceof CanonicalType)
208          res.add(((CanonicalType) ex.getValue()).getValue());
209        if (ex.getValue() instanceof CodeType)
210          res.add(((CodeType) ex.getValue()).getValue());
211        if (ex.getValue() instanceof IntegerType)
212          res.add(((IntegerType) ex.getValue()).asStringValue());
213        if (ex.getValue() instanceof Integer64Type)
214          res.add(((Integer64Type) ex.getValue()).asStringValue());
215        if (ex.getValue() instanceof DecimalType)
216          res.add(((DecimalType) ex.getValue()).asStringValue());
217        if ((ex.getValue() instanceof MarkdownType))
218          res.add(((MarkdownType) ex.getValue()).getValue());
219        if ((ex.getValue() instanceof PrimitiveType))
220          res.add(((PrimitiveType) ex.getValue()).primitiveValue());
221        if ((ex.getValue() instanceof StringType))
222          res.add(((StringType) ex.getValue()).getValue());
223      }
224    }
225    return res;
226  }
227
228  public static String readStringExtension(DomainResource c, String... uris) {
229    for (String uri : uris) {
230      if (hasExtension(c, uri)) {
231        return readStringExtension(c, uri);
232      }
233    }
234    return null;
235  }
236
237  public static String readStringExtension(DomainResource c, String uri) {
238    Extension ex = getExtension(c, uri);
239    if (ex == null)
240      return null;
241    if ((ex.getValue() instanceof StringType))
242      return ((StringType) ex.getValue()).getValue();
243    if ((ex.getValue() instanceof UriType))
244      return ((UriType) ex.getValue()).getValue();
245    if (ex.getValue() instanceof CodeType)
246      return ((CodeType) ex.getValue()).getValue();
247    if (ex.getValue() instanceof IntegerType)
248      return ((IntegerType) ex.getValue()).asStringValue();
249    if (ex.getValue() instanceof Integer64Type)
250      return ((Integer64Type) ex.getValue()).asStringValue();
251    if (ex.getValue() instanceof DecimalType)
252      return ((DecimalType) ex.getValue()).asStringValue();
253    if ((ex.getValue() instanceof MarkdownType))
254      return ((MarkdownType) ex.getValue()).getValue();
255    return null;
256  }
257
258  public static String readStringSubExtension(DomainResource c, String uri, String name) {
259    Extension ex = getExtension(c, uri);
260    if (ex == null)
261      return null;
262    ex = getExtension(ex, name);
263    if (ex == null)
264      return null;
265    if ((ex.getValue() instanceof StringType))
266      return ((StringType) ex.getValue()).getValue();
267    if ((ex.getValue() instanceof UriType))
268      return ((UriType) ex.getValue()).getValue();
269    if (ex.getValue() instanceof CodeType)
270      return ((CodeType) ex.getValue()).getValue();
271    if (ex.getValue() instanceof IntegerType)
272      return ((IntegerType) ex.getValue()).asStringValue();
273    if (ex.getValue() instanceof Integer64Type)
274      return ((Integer64Type) ex.getValue()).asStringValue();
275    if (ex.getValue() instanceof DecimalType)
276      return ((DecimalType) ex.getValue()).asStringValue();
277    if ((ex.getValue() instanceof MarkdownType))
278      return ((MarkdownType) ex.getValue()).getValue();
279    return null;
280  }
281
282  @SuppressWarnings("unchecked")
283  public static PrimitiveType<DataType> readPrimitiveExtension(DomainResource c, String uri) {
284    Extension ex = getExtension(c, uri);
285    if (ex == null)
286      return null;
287    return (PrimitiveType<DataType>) ex.getValue();
288  }
289
290  public static boolean findStringExtension(Element c, String uri) {
291    Extension ex = ExtensionHelper.getExtension(c, uri);
292    if (ex == null)
293      return false;
294    if (!(ex.getValue() instanceof StringType))
295      return false;
296    return !StringUtils.isBlank(((StringType) ex.getValue()).getValue());
297  }
298
299  public static Boolean readBooleanExtension(Element c, String uri) {
300    Extension ex = ExtensionHelper.getExtension(c, uri);
301    if (ex == null)
302      return null;
303    if (!(ex.getValue() instanceof BooleanType))
304      return null;
305    return ((BooleanType) ex.getValue()).getValue();
306  }
307
308  public static boolean findBooleanExtension(Element c, String uri) {
309    Extension ex = ExtensionHelper.getExtension(c, uri);
310    if (ex == null)
311      return false;
312    if (!(ex.getValue() instanceof BooleanType))
313      return false;
314    return true;
315  }
316
317  public static Boolean readBooleanExtension(DomainResource c, String uri) {
318    Extension ex = ExtensionHelper.getExtension(c, uri);
319    if (ex == null)
320      return null;
321    if (!(ex.getValue() instanceof BooleanType))
322      return null;
323    return ((BooleanType) ex.getValue()).getValue();
324  }
325
326  public static boolean readBoolExtension(DomainResource c, String uri) {
327    Extension ex = ExtensionHelper.getExtension(c, uri);
328    if (ex == null)
329      return false;
330    if (!(ex.getValue() instanceof BooleanType))
331      return false;
332    return ((BooleanType) ex.getValue()).getValue();
333  }
334
335  public static boolean readBoolExtension(DomainResource c, String... uris) {
336    Extension ex = null;
337    for (String uri : uris) {
338      ex = ExtensionHelper.getExtension(c, uri);
339      if (ex != null) {
340        break;
341      }
342    }
343    if (ex == null)
344      return false;
345    if (!(ex.getValue() instanceof BooleanType))
346      return false;
347    return ((BooleanType) ex.getValue()).getValue();
348  }
349
350  public static boolean readBoolExtension(Element e, String uri) {
351    Extension ex = ExtensionHelper.getExtension(e, uri);
352    if (ex == null)
353      return false;
354    if (!(ex.getValue() instanceof BooleanType))
355      return false;
356    if (!(ex.getValue().hasPrimitiveValue()))
357      return false;
358    return ((BooleanType) ex.getValue()).getValue();
359  }
360
361  public static boolean findBooleanExtension(DomainResource c, String uri) {
362    Extension ex = ExtensionHelper.getExtension(c, uri);
363    if (ex == null)
364      return false;
365    if (!(ex.getValue() instanceof BooleanType))
366      return false;
367    return true;
368  }
369
370  //  public static boolean hasDeprecated(Element c) {
371  //    return findBooleanExtension(c, EXT_DEPRECATED);
372  //  }
373
374  public static void addFlyOver(Questionnaire.QuestionnaireItemComponent item, String text, String linkId){
375    if (!StringUtils.isBlank(text)) {
376      Questionnaire.QuestionnaireItemComponent display = item.addItem();
377      display.setType(Questionnaire.QuestionnaireItemType.DISPLAY);
378      display.setText(text);
379      display.setLinkId(linkId);
380      display.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true));
381    }
382  }
383
384  public static void addMin(Questionnaire.QuestionnaireItemComponent item, int min) {
385    item.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_MINOCCURS, Factory.newInteger(min), true));
386  }
387
388  public static void addMax(Questionnaire.QuestionnaireItemComponent item, int max) {
389    item.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_MAXOCCURS, Factory.newInteger(max), true));
390  }
391
392  public static void addFhirType(Questionnaire.QuestionnaireItemComponent group, String value) {
393    group.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_FHIRTYPE, Factory.newString_(value), true));
394  }
395
396  public static void addControl(Questionnaire.QuestionnaireItemComponent group, String value) {
397    group.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true));
398  }
399
400  public static void addAllowedResource(Questionnaire.QuestionnaireItemComponent group, String value) {
401    group.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_ALLOWEDRESOURCE, Factory.newCode(value), true));
402  }
403
404  public static void addReferenceFilter(Questionnaire.QuestionnaireItemComponent group, String value) {
405    group.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_REFERENCEFILTER, Factory.newString_(value), true));
406  }
407
408  //  public static void addIdentifier(Element element, Identifier value) {
409  //    element.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_IDENTIFIER, value, true));
410  //  }
411
412  /**
413   * @param name the identity of the extension of interest
414   * @return The extension, if on this element, else null
415   */
416  public static Extension getExtension(DomainResource resource, String name) {
417    if (resource == null || name == null)
418      return null;
419    if (!resource.hasExtension())
420      return null;
421    for (Extension e : resource.getExtension()) {
422      if (name.equals(e.getUrl()))
423        return e;
424    }
425    return null;
426  }
427
428  public static Extension getExtension(Element el, String name) {
429    if (name == null)
430      return null;
431    if (!el.hasExtension())
432      return null;
433    for (Extension e : el.getExtension()) {
434      if (name.equals(e.getUrl()))
435        return e;
436    }
437    return null;
438  }
439
440  public static void setStringExtension(DomainResource resource, String uri, String value) {
441    if (Utilities.noString(value))
442      return;
443    Extension ext = getExtension(resource, uri);
444    if (ext != null)
445      ext.setValue(new StringType(value));
446    else
447      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
448  }
449
450  public static void setStringExtension(Element resource, String uri, String value) {
451    if (Utilities.noString(value))
452      return;
453    Extension ext = getExtension(resource, uri);
454    if (ext != null)
455      ext.setValue(new StringType(value));
456    else
457      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
458  }
459
460  public static void setUriExtension(DomainResource resource, String uri, String value) {
461    if (Utilities.noString(value))
462      return;
463    Extension ext = getExtension(resource, uri);
464    if (ext != null)
465      ext.setValue(new UriType(value));
466    else
467      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
468  }
469
470  public static void setUriExtension(Element resource, String uri, String value) {
471    if (Utilities.noString(value))
472      return;
473    Extension ext = getExtension(resource, uri);
474    if (ext != null)
475      ext.setValue(new UriType(value));
476    else
477      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
478  }
479
480  public static void setCanonicalExtension(DomainResource resource, String uri, String value) {
481    if (Utilities.noString(value))
482      return;
483    Extension ext = getExtension(resource, uri);
484    if (ext != null)
485      ext.setValue(new UriType(value));
486    else
487      resource.getExtension().add(new Extension(uri).setValue(new CanonicalType(value)));
488  }
489
490  public static void setCanonicalExtension(Element resource, String uri, String value) {
491    if (Utilities.noString(value))
492      return;
493    Extension ext = getExtension(resource, uri);
494    if (ext != null)
495      ext.setValue(new UriType(value));
496    else
497      resource.getExtension().add(new Extension(uri).setValue(new CanonicalType(value)));
498  }
499
500  public static void setUrlExtension(DomainResource resource, String uri, String value) {
501    if (Utilities.noString(value))
502      return;
503    Extension ext = getExtension(resource, uri);
504    if (ext != null)
505      ext.setValue(new UrlType(value));
506    else
507      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
508  }
509
510  public static void setUrlExtension(Element resource, String uri, String value) {
511    if (Utilities.noString(value))
512      return;
513    Extension ext = getExtension(resource, uri);
514    if (ext != null)
515      ext.setValue(new UrlType(value));
516    else
517      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
518  }
519
520  public static void setCodeExtension(DomainResource resource, String uri, String value) {
521    if (Utilities.noString(value))
522      return;
523
524    Extension ext = getExtension(resource, uri);
525    if (ext != null)
526      ext.setValue(new CodeType(value));
527    else
528      resource.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
529  }
530
531  public static void setCodeExtensionMod(DomainResource resource, String uri, String value) {
532    if (Utilities.noString(value))
533      return;
534
535    Extension ext = getExtension(resource, uri);
536    if (ext != null)
537      ext.setValue(new CodeType(value));
538    else
539      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
540  }
541
542  public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) {
543    if (Utilities.noString(value))
544      return;
545
546    Extension ext = getExtension(resource, uri);
547    if (ext != null)
548      ext.setValue(new CodeType(value));
549    else
550      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
551  }
552
553  public static void setCodeExtension(Element element, String uri, String value) {
554    if (Utilities.noString(value))
555      return;
556
557    Extension ext = getExtension(element, uri);
558    if (ext != null)
559      ext.setValue(new CodeType(value));
560    else
561      element.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
562  }
563
564  public static void setMarkdownExtension(DomainResource resource, String uri, String value) {
565    if (Utilities.noString(value))
566      return;
567
568    Extension ext = getExtension(resource, uri);
569    if (ext != null)
570      ext.setValue(new MarkdownType(value));
571    else
572      resource.getExtension().add(new Extension(uri).setValue(new MarkdownType(value)));
573  }
574
575  public static void setIntegerExtension(DomainResource resource, String uri, int value) {
576    Extension ext = getExtension(resource, uri);
577    if (ext != null)
578      ext.setValue(new IntegerType(value));
579    else
580      resource.getExtension().add(new Extension(uri).setValue(new IntegerType(value)));
581  }
582
583  //  public static String getOID(CodeSystem define) {
584  //    return readStringExtension(define, EXT_OID);
585  //  }
586  //
587  //  public static String getOID(ValueSet vs) {
588  //    return readStringExtension(vs, EXT_OID);
589  //  }
590  //
591  //  public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException {
592  //    if (!oid.startsWith("urn:oid:"))
593  //      throw new FHIRFormatError("Error in OID format");
594  //    if (oid.startsWith("urn:oid:urn:oid:"))
595  //      throw new FHIRFormatError("Error in OID format");
596  //    if (!hasExtension(define, EXT_OID))
597  //    define.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_OID, Factory.newUri(oid), false));
598  //    else if (!oid.equals(readStringExtension(define, EXT_OID)))
599  //      throw new Error("Attempt to assign multiple OIDs to a code system");
600  //  }
601  //  public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException {
602  //    if (!oid.startsWith("urn:oid:"))
603  //      throw new FHIRFormatError("Error in OID format");
604  //    if (oid.startsWith("urn:oid:urn:oid:"))
605  //      throw new FHIRFormatError("Error in OID format");
606  //    if (!hasExtension(vs, EXT_OID))
607  //    vs.getExtension().add(Factory.newExtension(ExtensionDefinitions.EXT_OID, Factory.newUri(oid), false));
608  //    else if (!oid.equals(readStringExtension(vs, EXT_OID)))
609  //      throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
610  //  }
611
612  public static boolean hasLanguageTranslations(Element element) {
613    for (Extension e : element.getExtension()) {
614      if (e.getUrl().equals(ExtensionDefinitions.EXT_TRANSLATION)) {
615        return true;
616      }
617    }
618    return false;
619  }
620
621  public static boolean hasLanguageTranslation(Element element, String lang) {
622    for (Extension e : element.getExtension()) {
623      if (e.getUrl().equals(ExtensionDefinitions.EXT_TRANSLATION)) {
624        Extension e1 = ExtensionHelper.getExtension(e, "lang");
625
626        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang))
627          return true;
628      }
629    }
630    return false;
631  }
632
633  public static String getLanguageTranslation(Element element, String lang) {
634    for (Extension e : element.getExtension()) {
635      if (e.getUrl().equals(ExtensionDefinitions.EXT_TRANSLATION)) {
636        Extension e1 = ExtensionHelper.getExtension(e, "lang");
637
638        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
639          e1 = ExtensionHelper.getExtension(e, "content");
640          if (e1 != null && e1.hasValue()) {
641            return e1.getValue().primitiveValue();
642          }
643        }
644      }
645    }
646    return null;
647  }
648
649  public static StringType getLanguageTranslationElement(Element element, String lang) {
650    for (Extension e : element.getExtension()) {
651      if (e.getUrl().equals(ExtensionDefinitions.EXT_TRANSLATION)) {
652        Extension e1 = ExtensionHelper.getExtension(e, "lang");
653
654        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
655          e1 = ExtensionHelper.getExtension(e, "content");
656          return ((StringType) e1.getValue());
657        }
658      }
659    }
660    return null;
661  }
662
663  public static void addLanguageTranslation(Element element, String lang, String value) {
664    if (Utilities.noString(lang) || Utilities.noString(value))
665      return;
666
667    Extension extension = new Extension().setUrl(ExtensionDefinitions.EXT_TRANSLATION);
668    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
669    extension.addExtension().setUrl("content").setValue(new StringType(value));
670    element.getExtension().add(extension);
671  }
672
673  public static void setLanguageTranslation(Element element, String lang, String value) {
674    if (Utilities.noString(lang) || Utilities.noString(value))
675      return;
676
677    for (Extension extension : element.getExtension()) {
678      if (ExtensionDefinitions.EXT_TRANSLATION.equals(extension.getUrl())) {
679        String l = extension.getExtensionString("lang");
680        if (lang.equals(l)) {
681          setStringExtension(extension, "content", value);
682          return;
683        }
684      }
685    }
686
687    Extension extension = new Extension().setUrl(ExtensionDefinitions.EXT_TRANSLATION);
688    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
689    extension.addExtension().setUrl("content").setValue(new StringType(value));
690    element.getExtension().add(extension);
691  }
692
693  public static boolean hasAllowedUnits(ElementDefinition eld) {
694    for (Extension e : eld.getExtension())
695      if (e.getUrl().equals(ExtensionDefinitions.EXT_ALLOWABLE_UNITS))
696        return true;
697    return false;
698  }
699
700  public static DataType getAllowedUnits(ElementDefinition eld) {
701    for (Extension e : eld.getExtension())
702      if (e.getUrl().equals(ExtensionDefinitions.EXT_ALLOWABLE_UNITS))
703        return e.getValue();
704    return null;
705  }
706
707  public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) {
708    for (Extension e : eld.getExtension())
709      if (e.getUrl().equals(ExtensionDefinitions.EXT_ALLOWABLE_UNITS)) {
710        e.setValue(cc);
711        return;
712      }
713    eld.getExtension().add(new Extension().setUrl(ExtensionDefinitions.EXT_ALLOWABLE_UNITS).setValue(cc));
714  }
715
716  public static List<Extension> getExtensions(Element element, String url) {
717    List<Extension> results = new ArrayList<Extension>();
718    for (Extension ex : element.getExtension())
719      if (ex.getUrl().equals(url))
720        results.add(ex);
721    return results;
722  }
723
724  public static List<Extension> getExtensions(DomainResource resource, String url) {
725    List<Extension> results = new ArrayList<Extension>();
726    for (Extension ex : resource.getExtension())
727      if (ex.getUrl().equals(url))
728        results.add(ex);
729    return results;
730  }
731
732  //  public static void addDEReference(DataElement de, String value) {
733  //    for (Extension e : de.getExtension())
734  //      if (e.getUrl().equals(ExtensionDefinitions.EXT_CIMI_REFERENCE)) {
735  //        e.setValue(new UriType(value));
736  //        return;
737  //      }
738  //    de.getExtension().add(new Extension().setUrl(ExtensionDefinitions.EXT_CIMI_REFERENCE).setValue(new UriType(value)));
739  //  }
740
741  //  public static void setDeprecated(Element nc) {
742  //    for (Extension e : nc.getExtension())
743  //      if (e.getUrl().equals(ExtensionDefinitions.EXT_DEPRECATED)) {
744  //        e.setValue(new BooleanType(true));
745  //        return;
746  //      }
747  //    nc.getExtension().add(new Extension().setUrl(ExtensionDefinitions.EXT_DEPRECATED).setValue(new BooleanType(true)));
748  //  }
749
750  public static void setExtension(Element focus, String url, Coding c) {
751    for (Extension e : focus.getExtension())
752      if (e.getUrl().equals(url)) {
753        e.setValue(c);
754        return;
755      }
756    focus.getExtension().add(new Extension().setUrl(url).setValue(c));
757  }
758
759  public static void removeExtension(DomainResource focus, String url) {
760    Iterator<Extension> i = focus.getExtension().iterator();
761    while (i.hasNext()) {
762      Extension e = i.next(); // must be called before you can call i.remove()
763      if (url.equals(e.getUrl())) {
764        i.remove();
765      }
766    }
767  }
768
769  public static void removeExtension(Element focus, String url) {
770    Iterator<Extension> i = focus.getExtension().iterator();
771    while (i.hasNext()) {
772      Extension e = i.next(); // must be called before you can call i.remove()
773      if (e.getUrl().equals(url)) {
774        i.remove();
775      }
776    }
777  }
778
779  public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) {
780    Extension ex = ExtensionHelper.getExtension(dr, uri);
781    if (ex == null)
782      return defaultValue;
783    if (ex.getValue() instanceof IntegerType)
784      return ((IntegerType) ex.getValue()).getValue();
785    throw new Error("Unable to read extension "+uri+" as an integer");
786  }
787
788  public static int readIntegerExtension(Element e, String uri, int defaultValue) {
789    Extension ex = ExtensionHelper.getExtension(e, uri);
790    if (ex == null)
791      return defaultValue;
792    if (ex.getValue() instanceof IntegerType)
793      return ((IntegerType) ex.getValue()).getValue();
794    if (ex.getValue() instanceof DecimalType)
795      return ((DecimalType) ex.getValue()).getValue().intValue();
796    throw new Error("Unable to read extension "+uri+" as an integer");
797  }
798
799  public static Map<String, String> getLanguageTranslations(Element e) {
800    Map<String, String> res = new HashMap<String, String>();
801    for (Extension ext : e.getExtension()) {
802      if (ext.getUrl().equals(ExtensionDefinitions.EXT_TRANSLATION)) {
803        String lang = readStringExtension(ext, "lang");
804        String value = readStringExtension(ext, "content");
805        res.put(lang,  value);
806      }
807    }
808    return res;
809  }
810
811  public static StandardsStatus getStandardsStatus(DomainResource dr) throws FHIRException {
812    return StandardsStatus.fromCode(ExtensionUtilities.readStringExtension(dr, ExtensionDefinitions.EXT_STANDARDS_STATUS));
813  }
814
815  public static StandardsStatus getStandardsStatus(Element e) throws FHIRException {
816    return StandardsStatus.fromCode(ExtensionUtilities.readStringExtension(e, ExtensionDefinitions.EXT_STANDARDS_STATUS));
817  }
818
819  public static void setStandardsStatus(DomainResource dr, StandardsStatus status, String normativeVersion) {
820    if (status == null)
821      ExtensionUtilities.removeExtension(dr, ExtensionDefinitions.EXT_STANDARDS_STATUS);
822    else
823      ExtensionUtilities.setCodeExtension(dr, ExtensionDefinitions.EXT_STANDARDS_STATUS, status.toCode());
824    if (normativeVersion == null)
825      ExtensionUtilities.removeExtension(dr, ExtensionDefinitions.EXT_NORMATIVE_VERSION);
826    else
827      ExtensionUtilities.setCodeExtension(dr, ExtensionDefinitions.EXT_NORMATIVE_VERSION, normativeVersion);
828  }
829
830  public static void setStandardsStatus(Element dr, StandardsStatus status, String normativeVersion) {
831    if (status == null)
832      ExtensionUtilities.removeExtension(dr, ExtensionDefinitions.EXT_STANDARDS_STATUS);
833    else
834      ExtensionUtilities.setCodeExtension(dr, ExtensionDefinitions.EXT_STANDARDS_STATUS, status.toCode());
835    if (normativeVersion == null)
836      ExtensionUtilities.removeExtension(dr, ExtensionDefinitions.EXT_NORMATIVE_VERSION);
837    else
838      ExtensionUtilities.setCodeExtension(dr, ExtensionDefinitions.EXT_NORMATIVE_VERSION, normativeVersion);
839  }
840
841  public static ValidationMessage readValidationMessage(OperationOutcome.OperationOutcomeIssueComponent issue, ValidationMessage.Source source) {
842    ValidationMessage vm = new ValidationMessage();
843    vm.setSource(source);
844    vm.setLevel(mapSeverity(issue.getSeverity()));
845    vm.setType(mapType(issue.getCode()));
846    if (issue.hasExtension(ExtensionDefinitions.EXT_ISSUE_LINE))
847      vm.setLine(ExtensionUtilities.readIntegerExtension(issue, ExtensionDefinitions.EXT_ISSUE_LINE, 0));
848    if (issue.hasExtension(ExtensionDefinitions.EXT_ISSUE_COL))
849      vm.setCol(ExtensionUtilities.readIntegerExtension(issue, ExtensionDefinitions.EXT_ISSUE_COL, 0));
850    if (issue.hasExpression())
851      vm.setLocation(issue.getExpression().get(0).asStringValue());
852    vm.setMessage(issue.getDetails().getText());
853    if (issue.hasExtension("http://hl7.org/fhir/StructureDefinition/rendering-xhtml"))
854      vm.setHtml(ExtensionUtilities.readStringExtension(issue, "http://hl7.org/fhir/StructureDefinition/rendering-xhtml"));
855    return vm;
856  }
857
858  private static ValidationMessage.IssueType mapType(org.hl7.fhir.r5.model.OperationOutcome.IssueType code) {
859    if (code == null) {
860      return null;
861    }
862    switch (code) {
863      case BUSINESSRULE: return ValidationMessage.IssueType.BUSINESSRULE;
864      case CODEINVALID: return ValidationMessage.IssueType.CODEINVALID;
865      case CONFLICT: return ValidationMessage.IssueType.CONFLICT;
866      case DELETED: return ValidationMessage.IssueType.DELETED;
867      case DUPLICATE: return ValidationMessage.IssueType.DUPLICATE;
868      case EXCEPTION: return ValidationMessage.IssueType.EXCEPTION;
869      case EXPIRED: return ValidationMessage.IssueType.EXPIRED;
870      case EXTENSION: return ValidationMessage.IssueType.EXTENSION;
871      case FORBIDDEN: return ValidationMessage.IssueType.FORBIDDEN;
872      case INCOMPLETE: return ValidationMessage.IssueType.INCOMPLETE;
873      case INFORMATIONAL: return ValidationMessage.IssueType.INFORMATIONAL;
874      case INVALID: return ValidationMessage.IssueType.INVALID;
875      case INVARIANT: return ValidationMessage.IssueType.INVARIANT;
876      case LOCKERROR: return ValidationMessage.IssueType.LOCKERROR;
877      case LOGIN: return ValidationMessage.IssueType.LOGIN;
878      case MULTIPLEMATCHES: return ValidationMessage.IssueType.MULTIPLEMATCHES;
879      case NOSTORE: return ValidationMessage.IssueType.NOSTORE;
880      case NOTFOUND: return ValidationMessage.IssueType.NOTFOUND;
881      case NOTSUPPORTED: return ValidationMessage.IssueType.NOTSUPPORTED;
882      case NULL: return ValidationMessage.IssueType.NULL;
883      case PROCESSING: return ValidationMessage.IssueType.PROCESSING;
884      case REQUIRED: return ValidationMessage.IssueType.REQUIRED;
885      case SECURITY: return ValidationMessage.IssueType.SECURITY;
886      case STRUCTURE: return ValidationMessage.IssueType.STRUCTURE;
887      case SUPPRESSED: return ValidationMessage.IssueType.SUPPRESSED;
888      case THROTTLED: return ValidationMessage.IssueType.THROTTLED;
889      case TIMEOUT: return ValidationMessage.IssueType.TIMEOUT;
890      case TOOCOSTLY: return ValidationMessage.IssueType.TOOCOSTLY;
891      case TOOLONG: return ValidationMessage.IssueType.TOOLONG;
892      case TRANSIENT: return ValidationMessage.IssueType.TRANSIENT;
893      case UNKNOWN: return ValidationMessage.IssueType.UNKNOWN;
894      case VALUE: return ValidationMessage.IssueType.VALUE;
895      default: return null;
896    }
897  }
898
899  private static ValidationMessage.IssueSeverity mapSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity severity) {
900    if (severity == null) {
901      return null;
902    }
903    switch (severity) {
904      case ERROR: return ValidationMessage.IssueSeverity.ERROR;
905      case FATAL: return ValidationMessage.IssueSeverity.FATAL;
906      case INFORMATION: return ValidationMessage.IssueSeverity.INFORMATION;
907      case WARNING: return ValidationMessage.IssueSeverity.WARNING;
908      default: return null;
909    }
910  }
911
912  public static String getPresentation(PrimitiveType<?> type) {
913    if (type.hasExtension(ExtensionDefinitions.EXT_RENDERED_VALUE))
914      return readStringExtension(type, ExtensionDefinitions.EXT_RENDERED_VALUE);
915    return type.primitiveValue();
916  }
917
918  public static String getPresentation(Element holder, PrimitiveType<?> type) {
919    if (holder.hasExtension(ExtensionDefinitions.EXT_RENDERED_VALUE))
920      return readStringExtension(holder, ExtensionDefinitions.EXT_RENDERED_VALUE);
921    if (type.hasExtension(ExtensionDefinitions.EXT_RENDERED_VALUE))
922      return readStringExtension(type, ExtensionDefinitions.EXT_RENDERED_VALUE);
923    return type.primitiveValue();
924  }
925
926  //  public static boolean hasOID(ValueSet vs) {
927  //    return hasExtension(vs, EXT_OID);
928  //  }
929  //
930  //  public static boolean hasOID(CodeSystem cs) {
931  //    return hasExtension(cs, EXT_OID);
932  //  }
933  //
934  public static void addUrlExtension(Element e, String url, String value) {
935    if (StringUtils.isBlank(value)) {
936      return;
937    }
938    Extension ex = getExtension(e, url);
939    if (ex != null)
940      ex.setValue(new UrlType(value));
941    else
942      e.getExtension().add(Factory.newExtension(url, new UrlType(value), true));
943  }
944
945  public static void addUrlExtension(DomainResource dr, String url, String value) {
946    if (StringUtils.isBlank(value)) {
947      return;
948    }
949    Extension ex = getExtension(dr, url);
950    if (ex != null)
951      ex.setValue(new UrlType(value));
952    else
953      dr.getExtension().add(Factory.newExtension(url, new UrlType(value), true));
954  }
955
956  public static void addUriExtension(Element e, String url, String value) {
957    if (StringUtils.isBlank(value)) {
958      return;
959    }
960    Extension ex = getExtension(e, url);
961    if (ex != null)
962      ex.setValue(new UriType(value));
963    else
964      e.getExtension().add(Factory.newExtension(url, new UriType(value), true));
965  }
966
967  public static void addUriExtension(DomainResource dr, String url, String value) {
968    if (StringUtils.isBlank(value)) {
969      return;
970    }
971    Extension ex = getExtension(dr, url);
972    if (ex != null)
973      ex.setValue(new UriType(value));
974    else
975      dr.getExtension().add(Factory.newExtension(url, new UriType(value), true));
976  }
977
978  public static void addCanonicalExtension(Element e, String url, String value) {
979    if (StringUtils.isBlank(value)) {
980      return;
981    }
982    Extension ex = getExtension(e, url);
983    if (ex != null)
984      ex.setValue(new CanonicalType(value));
985    else
986      e.getExtension().add(Factory.newExtension(url, new CanonicalType(value), true));
987
988  }
989
990  public static void addCanonicalExtension(DomainResource dr, String url, String value) {
991    if (StringUtils.isBlank(value)) {
992      return;
993    }
994    Extension ex = getExtension(dr, url);
995    if (ex != null)
996      ex.setValue(new CanonicalType(value));
997    else
998      dr.getExtension().add(Factory.newExtension(url, new CanonicalType(value), true));
999  }
1000
1001
1002  public static boolean usesExtension(String url, Base base) {
1003    if ("Extension".equals(base.fhirType())) {
1004      Property p = base.getNamedProperty("url");
1005      for (Base b : p.getValues()) {
1006        if (url.equals(b.primitiveValue())) {
1007          return true;
1008        }
1009      }
1010    }
1011
1012    for (Property p : base.children() ) {
1013      for (Base v : p.getValues()) {
1014        if (usesExtension(url, v)) {
1015          return true;
1016        }
1017      }
1018    }
1019    return false;
1020  }
1021
1022  private static Set<String> cachedConsts;
1023
1024  public static Set<String> allConsts() {
1025    if (cachedConsts == null) {
1026      Set<String> list = new HashSet<>();
1027      for (Field field : ExtensionUtilities.class.getDeclaredFields()) {
1028        int modifiers = field.getModifiers();
1029        if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
1030          try {
1031            list.add(field.get(field.getType()).toString());
1032          } catch (Exception e) {
1033          }
1034        }
1035      }
1036      cachedConsts = list;
1037    }
1038    return cachedConsts;
1039  }
1040
1041  public static boolean hasAnyOfExtensions(Element d, String... urls) {
1042    for (String url : urls) {
1043      if (d.hasExtension(url)) {
1044        return true;
1045      }
1046    }
1047    return false;
1048  }
1049
1050  public static boolean hasAnyOfExtensions(DomainResource dr, String... urls) {
1051    for (String url : urls) {
1052      if (dr.hasExtension(url)) {
1053        return true;
1054      }
1055    }
1056    return false;
1057  }
1058
1059  public static int countExtensions(ElementDefinition d, String... urls) {
1060    int res = 0;
1061    for (String url : urls) {
1062      if (d.hasExtension(url)) {
1063        res++;
1064      }
1065    }
1066    return res;
1067  }
1068
1069  public static boolean hasExtensionValue(StructureDefinition src, String url, String value) {
1070    for (Extension ext : src.getExtension()) {
1071      if (url.equals(ext.getUrl()) && ext.hasValue() && value.equals(ext.getValue().primitiveValue())) {
1072        return true;
1073      }
1074    }
1075    return false;
1076  }
1077
1078
1079  private static Extension setExtensionE(Element context, String url, DataType value) {
1080    for (Extension ext : context.getExtension()) {
1081      if (ext.getUrl().equals(url)) {
1082        return ext.setValue(value);
1083      }
1084    }
1085    return context.addExtension().setUrl(url).setValue(value);
1086  }
1087
1088  private static Extension setExtensionBE(BackboneElement context, boolean mod, String url, DataType value) {
1089    if (mod) {
1090      for (Extension ext : context.getModifierExtension()) {
1091        if (ext.getUrl().equals(url)) {
1092          return ext.setValue(value);
1093        }
1094      }
1095      return context.addModifierExtension().setUrl(url).setValue(value);
1096    } else {
1097      return setExtensionE(context, url, value);
1098    }
1099  }
1100
1101  private static Extension setExtensionBT(BackboneType context, boolean mod, String url, DataType value) {
1102    if (mod) {
1103      for (Extension ext : context.getModifierExtension()) {
1104        if (ext.getUrl().equals(url)) {
1105          return ext.setValue(value);
1106        }
1107      }
1108      return context.addModifierExtension().setUrl(url).setValue(value);
1109    } else {
1110      return setExtensionE(context, url, value);
1111    }
1112  }
1113
1114  private static Extension setExtensionR(DomainResource context, boolean mod, String url, DataType value) {
1115    if (mod) {
1116      for (Extension ext : context.getModifierExtension()) {
1117        if (ext.getUrl().equals(url)) {
1118          return ext.setValue(value);
1119        }
1120      }
1121      return context.addModifierExtension().setUrl(url).setValue(value);
1122    } else {
1123      for (Extension ext : context.getExtension()) {
1124        if (ext.getUrl().equals(url)) {
1125          return ext.setValue(value);
1126        }
1127      }
1128      return context.addExtension().setUrl(url).setValue(value);
1129    }
1130  }
1131
1132  public static Extension setExtension(Base context, String url, DataType value) {
1133    boolean mod = ExtensionUtilities.isModifier(url);
1134    if (context instanceof BackboneElement) {
1135      return setExtensionBE((BackboneElement) context, mod, url, value);
1136    } else if (mod && context instanceof BackboneType) {
1137      return setExtensionBT((BackboneType) context, mod, url, value);
1138    } else if (context instanceof Element) {
1139      if (mod) {
1140        throw new FHIRException("Can't use a modifier extension on "+context.getClass().getName());
1141      } else {
1142        return setExtensionE((Element) context, url, value);
1143      }
1144    } else if (context instanceof DomainResource) {
1145      return setExtensionR((DomainResource) context, mod, url, value);
1146    } else {
1147      throw new FHIRException("Can't use an extension on "+context.getClass().getName());
1148    }
1149  }
1150
1151
1152  private static Extension addExtensionE(Element context, String url, DataType value) {
1153    return context.addExtension().setValue(value);
1154  }
1155
1156  private static Extension addExtensionBE(BackboneElement context, boolean mod, String url, DataType value) {
1157    if (mod) {
1158      return context.addModifierExtension().setValue(value);
1159    } else {
1160      return setExtensionE(context, url, value);
1161    }
1162  }
1163
1164  private static Extension addExtensionBT(BackboneType context, boolean mod, String url, DataType value) {
1165    if (mod) {
1166      return context.addModifierExtension().setUrl(url).setValue(value);
1167    } else {
1168      return setExtensionE(context, url, value);
1169    }
1170  }
1171
1172  private static Extension addExtensionR(DomainResource context, boolean mod, String url, DataType value) {
1173    if (mod) {
1174      return context.addModifierExtension().setUrl(url).setValue(value);
1175    } else {
1176      return context.addExtension().setUrl(url).setValue(value);
1177    }
1178  }
1179
1180  public static Extension addExtension(Base context, String url, DataType value) {
1181    boolean mod = ExtensionUtilities.isModifier(url);
1182    if (context instanceof BackboneElement) {
1183      return addExtensionBE((BackboneElement) context, mod, url, value);
1184    } else if (mod && context instanceof BackboneType) {
1185      return addExtensionBT((BackboneType) context, mod, url, value);
1186    } else if (context instanceof Element) {
1187      if (mod) {
1188        throw new FHIRException("Can't use a modifier extension on "+context.getClass().getName());
1189      } else {
1190        return addExtensionE((Element) context, url, value);
1191      }
1192    } else if (context instanceof DomainResource) {
1193      return addExtensionR((DomainResource) context, mod, url, value);
1194    } else {
1195      throw new FHIRException("Can't use an extension on "+context.getClass().getName());
1196    }
1197  }
1198
1199  private static List<Extension> getAllExtensions(Base context, String url) {
1200    List<Extension> list = new ArrayList<>();
1201    boolean mod = ExtensionUtilities.isModifier(url);
1202    if (mod) {
1203      if (context instanceof BackboneElement) {
1204        list.addAll(((BackboneElement) context).getModifierExtension());
1205      }
1206      if (context instanceof BackboneType) {
1207        list.addAll(((BackboneElement) context).getModifierExtension());
1208      }
1209      if (context instanceof DomainResource) {
1210        list.addAll(((DomainResource) context).getModifierExtension());
1211      }
1212    } else {
1213      if (context instanceof Element) {
1214        list.addAll(((Element) context).getExtension());
1215      }
1216      if (context instanceof DomainResource) {
1217        list.addAll(((DomainResource) context).getExtension());
1218      }
1219    }
1220    return list;
1221  }
1222
1223  public static <T extends DataType> T getExtension(Class<T> class_, Base context, String url) {
1224    boolean found = false;
1225    T result = null;
1226    for (Extension ext : getAllExtensions(context, url)) {
1227      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1228        if (found) {
1229          throw new FHIRException("Multiple Extensions for "+url);
1230        } else if (ext.hasValue() && class_.isInstance(ext.getValue())) {
1231          found = true;
1232          result = (T) ext.getValue();
1233        }
1234      }
1235    }
1236    return result;
1237  }
1238
1239  public static <T extends DataType> List<T> getExtensionList(Class<T> class_, Base context, String url) {
1240    List<T> result = new ArrayList<>();
1241    for (Extension ext : getAllExtensions(context, url)) {
1242      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1243        if (ext.hasValue() && class_.isInstance(ext.getValue())) {
1244          result.add((T) ext.getValue());
1245        }
1246      }
1247    }
1248    return result;
1249  }
1250
1251  public static String getExtensionString(Base context, String url) {
1252    boolean found = false;
1253    String result = null;
1254    for (Extension ext : getAllExtensions(context, url)) {
1255      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1256        if (found) {
1257          throw new FHIRException("Multiple Extensions for "+url);
1258        } else if (ext.hasValue() && ext.getValue().isPrimitive()) {
1259          found = true;
1260          result = ext.getValue().primitiveValue();
1261        }
1262      }
1263    }
1264    return result;
1265  }
1266
1267  public static Boolean getExtensionBoolean(Base context, String url) {
1268    boolean found = false;
1269    Boolean result = null;
1270    for (Extension ext : getAllExtensions(context, url)) {
1271      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1272        if (found) {
1273          throw new FHIRException("Multiple Extensions for "+url);
1274        } else if (ext.hasValueBooleanType()) {
1275          found = true;
1276          result = ext.getValueBooleanType().getValue();
1277        }
1278      }
1279    }
1280    return result;
1281  }
1282
1283  public static Integer getExtensionInt(Base context, String url) {
1284    boolean found = false;
1285    Integer result = null;
1286    for (Extension ext : getAllExtensions(context, url)) {
1287      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1288        if (found) {
1289          throw new FHIRException("Multiple Extensions for "+url);
1290        } else if (ext.hasValueIntegerType()) {
1291          found = true;
1292          result = ext.getValueIntegerType().getValue();
1293        }
1294      }
1295    }
1296    return result;
1297  }
1298
1299  public static BigDecimal getExtensionFloat(Base context, String url) {
1300    boolean found = false;
1301    BigDecimal result = null;
1302    for (Extension ext : getAllExtensions(context, url)) {
1303      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1304        if (found) {
1305          throw new FHIRException("Multiple Extensions for "+url);
1306        } else if (ext.hasValueIntegerType()) {
1307          found = true;
1308          result = ext.getValueDecimalType().getValue();
1309        }
1310      }
1311    }
1312    return result;
1313  }
1314
1315  public static List<String> getExtensionStringList(Base context, String url) {
1316    List<String> result = new ArrayList<>();
1317    for (Extension ext : getAllExtensions(context, url)) {
1318      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1319        if (ext.hasValue() && ext.getValue().isPrimitive()) {
1320          result.add(ext.getValue().primitiveValue());
1321        }
1322      }
1323    }
1324    return result;
1325  }
1326
1327  public static List<Boolean> getExtensionBooleanList(Base context, String url) {
1328    List<Boolean> result = new ArrayList<>();
1329    for (Extension ext : getAllExtensions(context, url)) {
1330      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1331        if (ext.hasValue() && ext.getValue().isPrimitive()) {
1332          result.add(Boolean.valueOf(ext.getValue().primitiveValue()));
1333        }
1334      }
1335    }
1336    return result;
1337  }
1338
1339  public static List<Integer> getExtensionIntList(Base context, String url) {
1340    List<Integer> result = new ArrayList<>();
1341    for (Extension ext : getAllExtensions(context, url)) {
1342      if (ext.hasUrl() && ext.getUrl().equals(url)) {
1343        if (ext.hasValueIntegerType()) {
1344          result.add(ext.getValueIntegerType().getValue());
1345        }
1346      }
1347    }
1348    return result;
1349  }
1350
1351  public static boolean stripExtensions(Element element, String... exceptions) {
1352    return stripExtensions(element, Utilities.strings(exceptions));
1353  }
1354
1355  public static boolean stripExtensions(Element element, List<String> exceptions) {
1356    boolean res = element.getExtension().removeIf(ex -> !exceptions.contains(ex.getUrl()));
1357    if (element instanceof BackboneElement) {
1358      res = ((BackboneElement) element).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) || res;
1359    }
1360    if (element instanceof BackboneElement) {
1361      res = ((BackboneElement) element).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) || res;
1362    }
1363    for (Property p : element.children()) {
1364      for (Base v : p.getValues()) {
1365        if (v instanceof Element) {
1366          res = stripExtensions((Element) v, exceptions) || res;
1367        } else if (v instanceof Element) {
1368          res = stripExtensions((Resource) v, exceptions) || res;
1369        }
1370      }
1371    }
1372    return res;
1373  }
1374
1375  public static boolean stripExtensions(Resource resource, String... exceptions) {
1376    return stripExtensions(resource, Utilities.strings(exceptions));
1377  }
1378
1379  public static boolean stripExtensions(Resource resource, List<String> exceptions) {
1380    boolean res = false;
1381    if (resource instanceof DomainResource) {
1382      res = ((DomainResource) resource).getExtension().removeIf(ex -> !exceptions.contains(ex.getUrl())) ||
1383        ((DomainResource) resource).getModifierExtension().removeIf(ex -> !exceptions.contains(ex.getUrl()));
1384    }
1385    for (Property p : resource.children()) {
1386      for (Base v : p.getValues()) {
1387        if (v instanceof Element) {
1388          res = stripExtensions((Element) v, exceptions) || res;
1389        } else if (v instanceof Element) {
1390          res = stripExtensions((Resource) v, exceptions) || res;
1391        }
1392      }
1393    }
1394    return res;
1395  }
1396
1397  public static void copyExtensions(List<Extension> source, List<Extension> dest, String... urls) {
1398    if (source != null && dest != null) {
1399      for (Extension ex : source) {
1400        if (Utilities.existsInList(ex.getUrl(), urls)) {
1401          dest.add(ex.copy());
1402        }
1403      }
1404    }
1405  }
1406
1407
1408
1409  public static DataType getExtensionValue(List<Extension> extensions, String url) {
1410    for (Extension ex : extensions) {
1411      if (ex.getUrl().equals(url)) {
1412        return ex.getValue();
1413      }
1414    }
1415    return null;
1416  }
1417
1418
1419  public static String getExtensionString(List<Extension> extensions, String url) {
1420    for (Extension ex : extensions) {
1421      if (ex.getUrl().equals(url)) {
1422        return ex.getValue().primitiveValue();
1423      }
1424    }
1425    return null;
1426  }
1427
1428
1429
1430  public static Integer getExtensionInteger(List<Extension> extensions, String url) {
1431    for (Extension ex : extensions) {
1432      if (ex.getUrl().equals(url) && ex.hasValueIntegerType()) {
1433        return ex.getValueIntegerType().getValue();
1434      }
1435    }
1436    return null;
1437  }
1438
1439  public static boolean hasExtension(List<Extension> extensions, String url) {
1440    if (extensions == null) {
1441      return false;
1442    }
1443    for (Extension ex : extensions) {
1444      if (ex.getUrl().equals(url)) {
1445        return true;
1446      }
1447    }
1448    return false;
1449  }
1450
1451
1452  public static boolean isModifier(String url) {
1453    return Utilities.existsInList(url, "http://hl7.org/fhir/StructureDefinition/artifact-status", "http://hl7.org/fhir/StructureDefinition/capabilitystatement-prohibited", "http://hl7.org/fhir/StructureDefinition/request-doNotPerform");
1454  }
1455
1456}