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