001package org.hl7.fhir.dstu3.utils;
002
003/*
004  Copyright (c) 2011+, HL7, Inc.
005  All rights reserved.
006  
007  Redistribution and use in source and binary forms, with or without modification, 
008  are permitted provided that the following conditions are met:
009    
010   * Redistributions of source code must retain the above copyright notice, this 
011     list of conditions and the following disclaimer.
012   * Redistributions in binary form must reproduce the above copyright notice, 
013     this list of conditions and the following disclaimer in the documentation 
014     and/or other materials provided with the distribution.
015   * Neither the name of HL7 nor the names of its contributors may be used to 
016     endorse or promote products derived from this software without specific 
017     prior written permission.
018  
019  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
020  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
021  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
022  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
023  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
024  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
025  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
026  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
027  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
028  POSSIBILITY OF SUCH DAMAGE.
029  
030 */
031
032
033
034/*
035Copyright (c) 2011+, HL7, Inc
036All rights reserved.
037
038Redistribution and use in source and binary forms, with or without modification, 
039are permitted provided that the following conditions are met:
040
041 * Redistributions of source code must retain the above copyright notice, this 
042   list of conditions and the following disclaimer.
043 * Redistributions in binary form must reproduce the above copyright notice, 
044   this list of conditions and the following disclaimer in the documentation 
045   and/or other materials provided with the distribution.
046 * Neither the name of HL7 nor the names of its contributors may be used to 
047   endorse or promote products derived from this software without specific 
048   prior written permission.
049
050THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
051ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
052WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
053IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
054INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
055NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
056PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
057WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
058ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
059POSSIBILITY OF SUCH DAMAGE.
060
061 */
062
063import java.util.ArrayList;
064import java.util.Iterator;
065import java.util.List;
066
067import org.apache.commons.lang3.StringUtils;
068import org.hl7.fhir.dstu3.model.BooleanType;
069import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
070import org.hl7.fhir.dstu3.model.CodeType;
071import org.hl7.fhir.dstu3.model.CodeableConcept;
072import org.hl7.fhir.dstu3.model.Coding;
073import org.hl7.fhir.dstu3.model.DataElement;
074import org.hl7.fhir.dstu3.model.DomainResource;
075import org.hl7.fhir.dstu3.model.Element;
076import org.hl7.fhir.dstu3.model.ElementDefinition;
077import org.hl7.fhir.dstu3.model.Extension;
078import org.hl7.fhir.dstu3.model.ExtensionHelper;
079import org.hl7.fhir.dstu3.model.Factory;
080import org.hl7.fhir.dstu3.model.Identifier;
081import org.hl7.fhir.dstu3.model.IntegerType;
082import org.hl7.fhir.dstu3.model.MarkdownType;
083import org.hl7.fhir.dstu3.model.PrimitiveType;
084import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemComponent;
085import org.hl7.fhir.dstu3.model.Questionnaire.QuestionnaireItemType;
086import org.hl7.fhir.dstu3.model.StringType;
087import org.hl7.fhir.dstu3.model.Type;
088import org.hl7.fhir.dstu3.model.UriType;
089import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent;
090import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
091import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
092
093
094public class ToolingExtensions {
095
096  // validated
097  public static final String EXT_SUBSUMES = "http://hl7.org/fhir/StructureDefinition/codesystem-subsumes"; 
098//  private static final String EXT_OID = "http://hl7.org/fhir/StructureDefinition/valueset-oid";
099//  public static final String EXT_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/codesystem-deprecated";
100  public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-definition";
101  public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-comments";
102  public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-comments";
103  private static final String EXT_IDENTIFIER = "http://hl7.org/fhir/StructureDefinition/identifier";
104  public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation";
105  public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source";
106  public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint"; 
107  public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/valueset-replacedby";
108  public static final String EXT_JSON_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type"; 
109  public static final String EXT_RDF_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type"; 
110  public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; 
111  public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/structuredefinition-regex"; 
112  public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"; 
113  public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs"; 
114  public static final String EXT_MAXOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs";
115  public static final String EXT_ALLOWEDRESOURCE = "http://hl7.org/fhir/StructureDefinition/questionnaire-allowedResource";
116  public static final String EXT_REFERENCEFILTER = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter";
117  public static final String EXT_CODE_GENERATION_PARENT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super";
118
119  // unregistered?
120  public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix";
121  public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix";
122
123//  public static final String EXT_FLYOVER = "http://hl7.org/fhir/Profile/questionnaire-extensions#flyover";
124  public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType";
125//  private static final String EXT_QREF = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference";
126//  private static final String EXTENSION_FILTER_ONLY = "http://www.healthintersections.com.au/fhir/Profile/metadata#expandNeedsFilter";
127//  private static final String EXT_TYPE = "http://www.healthintersections.com.au/fhir/Profile/metadata#type";
128//  private static final String EXT_REFERENCE = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference";
129  private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType";
130  private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits";
131  public static final String EXT_CIMI_REFERENCE = "http://hl7.org/fhir/StructureDefinition/cimi-reference";
132  public static final String EXT_UNCLOSED = "http://hl7.org/fhir/StructureDefinition/valueset-unclosed";
133  public static final String EXT_FMM_LEVEL = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm";
134  public static final String EXT_RESOURCE_CATEGORY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-category";
135  public static final String EXT_TABLE_NAME = "http://hl7.org/fhir/StructureDefinition/structuredefinition-table-name";
136  public static final String EXT_OO_FILE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-file";
137  public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg";
138  public static final String EXT_BALLOT_STATUS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-ballot-status";
139
140
141  // specific extension helpers
142
143  public static Extension makeIssueSource(Source source) {
144    Extension ex = new Extension();
145    // todo: write this up and get it published with the pack (and handle the redirect?)
146    ex.setUrl(ToolingExtensions.EXT_ISSUE_SOURCE);
147    CodeType c = new CodeType();
148    c.setValue(source.toString());
149    ex.setValue(c);
150    return ex;
151  }
152
153  public static boolean hasExtension(DomainResource de, String url) {
154    return getExtension(de, url) != null;
155  }
156
157  public static boolean hasExtension(Element e, String url) {
158    return getExtension(e, url) != null;
159  }
160
161//  public static void addStringExtension(DomainResource dr, String url, String content) {
162//    if (!StringUtils.isBlank(content)) {
163//      Extension ex = getExtension(dr, url);
164//      if (ex != null)
165//        ex.setValue(new StringType(content));
166//      else
167//        dr.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
168//    }
169//  }
170
171  public static void addMarkdownExtension(DomainResource dr, String url, String content) {
172    if (!StringUtils.isBlank(content)) {
173      Extension ex = getExtension(dr, url);
174      if (ex != null)
175        ex.setValue(new StringType(content));
176      else
177        dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true));   
178    }
179  }
180
181  public static void addStringExtension(Element e, String url, String content) {
182    if (!StringUtils.isBlank(content)) {
183      Extension ex = getExtension(e, url);
184      if (ex != null)
185        ex.setValue(new StringType(content));
186      else
187        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
188    }
189  }
190
191  public static void addStringExtension(DomainResource e, String url, String content) {
192    if (!StringUtils.isBlank(content)) {
193      Extension ex = getExtension(e, url);
194      if (ex != null)
195        ex.setValue(new StringType(content));
196      else
197        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
198    }
199  }
200
201  public static void addIntegerExtension(DomainResource dr, String url, int value) {
202    Extension ex = getExtension(dr, url);
203    if (ex != null)
204      ex.setValue(new IntegerType(value));
205    else
206      dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true));   
207  }
208
209  public static void addVSComment(ConceptSetComponent nc, String comment) {
210    if (!StringUtils.isBlank(comment))
211      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
212  }
213  public static void addVSComment(ConceptReferenceComponent nc, String comment) {
214    if (!StringUtils.isBlank(comment))
215      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
216  }
217
218  public static void addCSComment(ConceptDefinitionComponent nc, String comment) {
219    if (!StringUtils.isBlank(comment))
220      nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true));   
221  }
222
223//  public static void markDeprecated(Element nc) {
224//    setDeprecated(nc);   
225//  }
226//
227  public static void addSubsumes(ConceptDefinitionComponent nc, String code) {
228    nc.getModifierExtension().add(Factory.newExtension(EXT_SUBSUMES, Factory.newCode(code), true));   
229  }
230
231  public static void addDefinition(Element nc, String definition) {
232    if (!StringUtils.isBlank(definition))
233      nc.getExtension().add(Factory.newExtension(EXT_DEFINITION, Factory.newString_(definition), true));   
234  }
235
236  public static void addDisplayHint(Element def, String hint) {
237    if (!StringUtils.isBlank(hint))
238      def.getExtension().add(Factory.newExtension(EXT_DISPLAY_HINT, Factory.newString_(hint), true));   
239  }
240
241  public static String getDisplayHint(Element def) {
242    return readStringExtension(def, EXT_DISPLAY_HINT);    
243  }
244
245  public static String readStringExtension(Element c, String uri) {
246    Extension ex = ExtensionHelper.getExtension(c, uri);
247    if (ex == null)
248      return null;
249    if (ex.getValue() instanceof UriType)
250      return ((UriType) ex.getValue()).getValue();
251    if (ex.getValue() instanceof CodeType)
252      return ((CodeType) ex.getValue()).getValue();
253    if (ex.getValue() instanceof IntegerType)
254      return ((IntegerType) ex.getValue()).asStringValue();
255    if ((ex.getValue() instanceof MarkdownType))
256      return ((MarkdownType) ex.getValue()).getValue();
257    if (!(ex.getValue() instanceof StringType))
258      return null;
259    return ((StringType) ex.getValue()).getValue();
260  }
261
262  public static String readStringExtension(DomainResource c, String uri) {
263    Extension ex = getExtension(c, uri);
264    if (ex == null)
265      return null;
266    if ((ex.getValue() instanceof StringType))
267      return ((StringType) ex.getValue()).getValue();
268    if ((ex.getValue() instanceof UriType))
269      return ((UriType) ex.getValue()).getValue();
270    if (ex.getValue() instanceof CodeType)
271      return ((CodeType) ex.getValue()).getValue();
272    if (ex.getValue() instanceof IntegerType)
273      return ((IntegerType) ex.getValue()).asStringValue();
274    if ((ex.getValue() instanceof MarkdownType))
275      return ((MarkdownType) ex.getValue()).getValue();
276    return null;
277  }
278
279  @SuppressWarnings("unchecked")
280  public static PrimitiveType<Type> readPrimitiveExtension(DomainResource c, String uri) {
281    Extension ex = getExtension(c, uri);
282    if (ex == null)
283      return null;
284    return (PrimitiveType<Type>) ex.getValue();
285  }
286
287  public static boolean findStringExtension(Element c, String uri) {
288    Extension ex = ExtensionHelper.getExtension(c, uri);
289    if (ex == null)
290      return false;
291    if (!(ex.getValue() instanceof StringType))
292      return false;
293    return !StringUtils.isBlank(((StringType) ex.getValue()).getValue());
294  }
295
296  public static Boolean readBooleanExtension(Element c, String uri) {
297    Extension ex = ExtensionHelper.getExtension(c, uri);
298    if (ex == null)
299      return null;
300    if (!(ex.getValue() instanceof BooleanType))
301      return null;
302    return ((BooleanType) ex.getValue()).getValue();
303  }
304
305  public static boolean findBooleanExtension(Element c, String uri) {
306    Extension ex = ExtensionHelper.getExtension(c, uri);
307    if (ex == null)
308      return false;
309    if (!(ex.getValue() instanceof BooleanType))
310      return false;
311    return true;
312  }
313
314  public static String getCSComment(ConceptDefinitionComponent c) {
315    return readStringExtension(c, EXT_CS_COMMENT);    
316  }
317//
318//  public static Boolean getDeprecated(Element c) {
319//    return readBooleanExtension(c, EXT_DEPRECATED);    
320//  }
321
322  public static boolean hasCSComment(ConceptDefinitionComponent c) {
323    return findStringExtension(c, EXT_CS_COMMENT);    
324  }
325
326//  public static boolean hasDeprecated(Element c) {
327//    return findBooleanExtension(c, EXT_DEPRECATED);    
328//  }
329
330  public static List<CodeType> getSubsumes(ConceptDefinitionComponent c) {
331    List<CodeType> res = new ArrayList<CodeType>();
332
333    for (Extension e : c.getExtension()) {
334      if (EXT_SUBSUMES.equals(e.getUrl()))
335        res.add((CodeType) e.getValue());
336    }
337    return res;
338  }
339
340  public static void addFlyOver(QuestionnaireItemComponent item, String text){
341    if (!StringUtils.isBlank(text)) {
342        QuestionnaireItemComponent display = item.addItem();
343        display.setType(QuestionnaireItemType.DISPLAY);
344        display.setText(text);
345        display.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true));
346    }
347  }
348
349  public static void addMin(QuestionnaireItemComponent item, int min) {
350    item.getExtension().add(Factory.newExtension(EXT_MINOCCURS, Factory.newInteger(min), true));
351  }
352  
353  public static void addMax(QuestionnaireItemComponent item, int max) {
354    item.getExtension().add(Factory.newExtension(EXT_MAXOCCURS, Factory.newInteger(max), true));
355  }
356  
357  public static void addFhirType(QuestionnaireItemComponent group, String value) {
358    group.getExtension().add(Factory.newExtension(EXT_FHIRTYPE, Factory.newString_(value), true));       
359  }
360
361  public static void addControl(QuestionnaireItemComponent group, String value) {
362    group.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true));
363  }
364
365  public static void addAllowedResource(QuestionnaireItemComponent group, String value) {
366    group.getExtension().add(Factory.newExtension(EXT_ALLOWEDRESOURCE, Factory.newCode(value), true));       
367  }
368
369  public static void addReferenceFilter(QuestionnaireItemComponent group, String value) {
370    group.getExtension().add(Factory.newExtension(EXT_REFERENCEFILTER, Factory.newString_(value), true));       
371  }
372
373  public static void addIdentifier(Element element, Identifier value) {
374    element.getExtension().add(Factory.newExtension(EXT_IDENTIFIER, value, true));       
375  }
376
377  /**
378   * @param name the identity of the extension of interest
379   * @return The extension, if on this element, else null
380   */
381  public static Extension getExtension(DomainResource resource, String name) {
382    if (name == null)
383      return null;
384    if (!resource.hasExtension())
385      return null;
386    for (Extension e : resource.getExtension()) {
387      if (name.equals(e.getUrl()))
388        return e;
389    }
390    return null;
391  }
392
393  public static Extension getExtension(Element el, String name) {
394    if (name == null)
395      return null;
396    if (!el.hasExtension())
397      return null;
398    for (Extension e : el.getExtension()) {
399      if (name.equals(e.getUrl()))
400        return e;
401    }
402    return null;
403  }
404
405  public static void setStringExtension(DomainResource resource, String uri, String value) {
406    Extension ext = getExtension(resource, uri);
407    if (ext != null)
408      ext.setValue(new StringType(value));
409    else
410      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new StringType(value)));
411  }
412
413  public static void setStringExtension(Element element, String uri, String value) {
414    Extension ext = getExtension(element, uri);
415    if (ext != null)
416      ext.setValue(new StringType(value));
417    else
418      element.getExtension().add(new Extension(new UriType(uri)).setValue(new StringType(value)));
419  }
420
421  public static void setCodeExtension(DomainResource resource, String uri, String value) {
422    Extension ext = getExtension(resource, uri);
423    if (ext != null)
424      ext.setValue(new CodeType(value));
425    else
426      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new CodeType(value)));
427  }
428
429  public static void setIntegerExtension(DomainResource resource, String uri, int value) {
430    Extension ext = getExtension(resource, uri);
431    if (ext != null)
432      ext.setValue(new IntegerType(value));
433    else
434      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new IntegerType(value)));
435  }
436
437//  public static String getOID(CodeSystem define) {
438//    return readStringExtension(define, EXT_OID);    
439//  }
440//
441//  public static String getOID(ValueSet vs) {
442//    return readStringExtension(vs, EXT_OID);    
443//  }
444//
445//  public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException {
446//    if (!oid.startsWith("urn:oid:"))
447//      throw new FHIRFormatError("Error in OID format");
448//    if (oid.startsWith("urn:oid:urn:oid:"))
449//      throw new FHIRFormatError("Error in OID format");
450//    if (!hasExtension(define, EXT_OID))
451//    define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
452//    else if (!oid.equals(readStringExtension(define, EXT_OID)))
453//      throw new Error("Attempt to assign multiple OIDs to a code system");
454//  }
455//  public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException {
456//    if (!oid.startsWith("urn:oid:"))
457//      throw new FHIRFormatError("Error in OID format");
458//    if (oid.startsWith("urn:oid:urn:oid:"))
459//      throw new FHIRFormatError("Error in OID format");
460//    if (!hasExtension(vs, EXT_OID))
461//    vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
462//    else if (!oid.equals(readStringExtension(vs, EXT_OID)))
463//      throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
464//  }
465
466  public static boolean hasLanguageTranslation(Element element, String lang) {
467    for (Extension e : element.getExtension()) {
468      if (e.getUrl().equals(EXT_TRANSLATION)) {
469        Extension e1 = ExtensionHelper.getExtension(e, "lang");
470
471        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang))
472          return true;
473      }
474    }
475    return false;
476  }
477
478  public static String getLanguageTranslation(Element element, String lang) {
479    for (Extension e : element.getExtension()) {
480      if (e.getUrl().equals(EXT_TRANSLATION)) {
481        Extension e1 = ExtensionHelper.getExtension(e, "lang");
482
483        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang)) {
484          e1 = ExtensionHelper.getExtension(e, "content");
485          return ((StringType) e.getValue()).getValue();
486        }
487      }
488    }
489    return null;
490  }
491
492  public static void addLanguageTranslation(Element element, String lang, String value) {
493    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
494    extension.addExtension().setUrl("lang").setValue(new StringType(lang));
495    extension.addExtension().setUrl("content").setValue(new StringType(value));
496    element.getExtension().add(extension);
497  }
498
499  public static Type getAllowedUnits(ElementDefinition eld) {
500    for (Extension e : eld.getExtension()) 
501      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
502        return e.getValue();
503    return null;
504  }
505
506  public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) {
507    for (Extension e : eld.getExtension()) 
508      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) {
509        e.setValue(cc);
510        return;
511      }
512    eld.getExtension().add(new Extension().setUrl(EXT_ALLOWABLE_UNITS).setValue(cc));
513  }
514
515  public static List<Extension> getExtensions(Element element, String url) {
516    List<Extension> results = new ArrayList<Extension>();
517    for (Extension ex : element.getExtension())
518      if (ex.getUrl().equals(url))
519        results.add(ex);
520    return results;
521  }
522
523  public static List<Extension> getExtensions(DomainResource resource, String url) {
524    List<Extension> results = new ArrayList<Extension>();
525    for (Extension ex : resource.getExtension())
526      if (ex.getUrl().equals(url))
527        results.add(ex);
528    return results;
529  }
530
531  public static void addDEReference(DataElement de, String value) {
532    for (Extension e : de.getExtension()) 
533      if (e.getUrl().equals(EXT_CIMI_REFERENCE)) {
534        e.setValue(new UriType(value));
535        return;
536      }
537    de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value)));
538  }
539
540//  public static void setDeprecated(Element nc) {
541//    for (Extension e : nc.getExtension()) 
542//      if (e.getUrl().equals(EXT_DEPRECATED)) {
543//        e.setValue(new BooleanType(true));
544//        return;
545//      }
546//    nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true)));    
547//  }
548
549  public static void setExtension(Element focus, String url, Coding c) {
550    for (Extension e : focus.getExtension()) 
551      if (e.getUrl().equals(url)) {
552        e.setValue(c);
553        return;
554      }
555    focus.getExtension().add(new Extension().setUrl(url).setValue(c));    
556  }
557
558  public static void removeExtension(DomainResource focus, String url) {
559    Iterator<Extension> i = focus.getExtension().iterator();
560    while (i.hasNext()) {
561      Extension e = i.next(); // must be called before you can call i.remove()
562      if (e.getUrl().equals(url)) {
563        i.remove();
564      }
565    }
566  }
567  
568  public static void removeExtension(Element focus, String url) {
569    Iterator<Extension> i = focus.getExtension().iterator();
570    while (i.hasNext()) {
571      Extension e = i.next(); // must be called before you can call i.remove()
572      if (e.getUrl().equals(url)) {
573        i.remove();
574      }
575    }
576  }
577
578  public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) {
579    Extension ex = ExtensionHelper.getExtension(dr, uri);
580    if (ex == null)
581      return defaultValue;
582    if (ex.getValue() instanceof IntegerType)
583      return ((IntegerType) ex.getValue()).getValue();
584    throw new Error("Unable to read extension "+uri+" as an integer");
585  }
586
587//  public static boolean hasOID(ValueSet vs) {
588//    return hasExtension(vs, EXT_OID);
589//  }
590//  
591//  public static boolean hasOID(CodeSystem cs) {
592//    return hasExtension(cs, EXT_OID);
593//  }
594//  
595  
596}