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.dstu3.model.BackboneElement;
092import org.hl7.fhir.utilities.Utilities;
093import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
094
095
096public class ToolingExtensions {
097
098  // validated
099  public static final String EXT_SUBSUMES = "http://hl7.org/fhir/StructureDefinition/codesystem-subsumes"; 
100//  private static final String EXT_OID = "http://hl7.org/fhir/StructureDefinition/valueset-oid";
101//  public static final String EXT_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/codesystem-deprecated";
102  public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-definition";
103  public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-comments";
104  public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-comments";
105  private static final String EXT_IDENTIFIER = "http://hl7.org/fhir/StructureDefinition/identifier";
106  public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation";
107  public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source";
108  public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint"; 
109  public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/valueset-replacedby";
110  public static final String EXT_JSON_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type"; 
111  public static final String EXT_RDF_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type"; 
112  public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; 
113  public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/structuredefinition-regex"; 
114  public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"; 
115  public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs"; 
116  public static final String EXT_MAXOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs";
117  public static final String EXT_ALLOWEDRESOURCE = "http://hl7.org/fhir/StructureDefinition/questionnaire-allowedResource";
118  public static final String EXT_REFERENCEFILTER = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter";
119  public static final String EXT_CODE_GENERATION_PARENT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super";
120
121  // unregistered?
122  public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix";
123  public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix";
124
125//  public static final String EXT_FLYOVER = "http://hl7.org/fhir/Profile/questionnaire-extensions#flyover";
126  public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType";
127//  private static final String EXT_QREF = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference";
128//  private static final String EXTENSION_FILTER_ONLY = "http://www.healthintersections.com.au/fhir/Profile/metadata#expandNeedsFilter";
129//  private static final String EXT_TYPE = "http://www.healthintersections.com.au/fhir/Profile/metadata#type";
130//  private static final String EXT_REFERENCE = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference";
131  private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType";
132  private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits";
133  public static final String EXT_CIMI_REFERENCE = "http://hl7.org/fhir/StructureDefinition/cimi-reference";
134  public static final String EXT_UNCLOSED = "http://hl7.org/fhir/StructureDefinition/valueset-unclosed";
135  public static final String EXT_FMM_LEVEL = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm";
136  public static final String EXT_RESOURCE_CATEGORY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-category";
137  public static final String EXT_TABLE_NAME = "http://hl7.org/fhir/StructureDefinition/structuredefinition-table-name";
138  public static final String EXT_OO_FILE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-file";
139  public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg";
140  public static final String EXT_BALLOT_STATUS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-ballot-status";
141
142
143  // specific extension helpers
144
145  public static Extension makeIssueSource(Source source) {
146    Extension ex = new Extension();
147    // todo: write this up and get it published with the pack (and handle the redirect?)
148    ex.setUrl(ToolingExtensions.EXT_ISSUE_SOURCE);
149    CodeType c = new CodeType();
150    c.setValue(source.toString());
151    ex.setValue(c);
152    return ex;
153  }
154
155  public static boolean hasExtension(DomainResource de, String url) {
156    return getExtension(de, url) != null;
157  }
158
159  public static boolean hasExtension(Element e, String url) {
160    return getExtension(e, url) != null;
161  }
162
163//  public static void addStringExtension(DomainResource dr, String url, String content) {
164//    if (!StringUtils.isBlank(content)) {
165//      Extension ex = getExtension(dr, url);
166//      if (ex != null)
167//        ex.setValue(new StringType(content));
168//      else
169//        dr.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
170//    }
171//  }
172
173  public static void addMarkdownExtension(DomainResource dr, String url, String content) {
174    if (!StringUtils.isBlank(content)) {
175      Extension ex = getExtension(dr, url);
176      if (ex != null)
177        ex.setValue(new StringType(content));
178      else
179        dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true));   
180    }
181  }
182
183  public static void addStringExtension(Element e, String url, String content) {
184    if (!StringUtils.isBlank(content)) {
185      Extension ex = getExtension(e, url);
186      if (ex != null)
187        ex.setValue(new StringType(content));
188      else
189        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
190    }
191  }
192
193  public static void addStringExtension(DomainResource e, String url, String content) {
194    if (!StringUtils.isBlank(content)) {
195      Extension ex = getExtension(e, url);
196      if (ex != null)
197        ex.setValue(new StringType(content));
198      else
199        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
200    }
201  }
202
203  public static void addIntegerExtension(DomainResource dr, String url, int value) {
204    Extension ex = getExtension(dr, url);
205    if (ex != null)
206      ex.setValue(new IntegerType(value));
207    else
208      dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true));   
209  }
210
211  public static void addVSComment(ConceptSetComponent nc, String comment) {
212    if (!StringUtils.isBlank(comment))
213      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
214  }
215  public static void addVSComment(ConceptReferenceComponent nc, String comment) {
216    if (!StringUtils.isBlank(comment))
217      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
218  }
219
220  public static void addCSComment(ConceptDefinitionComponent nc, String comment) {
221    if (!StringUtils.isBlank(comment))
222      nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true));   
223  }
224
225//  public static void markDeprecated(Element nc) {
226//    setDeprecated(nc);   
227//  }
228//
229  public static void addSubsumes(ConceptDefinitionComponent nc, String code) {
230    nc.getModifierExtension().add(Factory.newExtension(EXT_SUBSUMES, Factory.newCode(code), true));   
231  }
232
233  public static void addDefinition(Element nc, String definition) {
234    if (!StringUtils.isBlank(definition))
235      nc.getExtension().add(Factory.newExtension(EXT_DEFINITION, Factory.newString_(definition), true));   
236  }
237
238  public static void addDisplayHint(Element def, String hint) {
239    if (!StringUtils.isBlank(hint))
240      def.getExtension().add(Factory.newExtension(EXT_DISPLAY_HINT, Factory.newString_(hint), true));   
241  }
242
243  public static String getDisplayHint(Element def) {
244    return readStringExtension(def, EXT_DISPLAY_HINT);    
245  }
246
247  public static String readStringExtension(Element c, String uri) {
248    Extension ex = ExtensionHelper.getExtension(c, uri);
249    if (ex == null)
250      return null;
251    if (ex.getValue() instanceof UriType)
252      return ((UriType) ex.getValue()).getValue();
253    if (ex.getValue() instanceof CodeType)
254      return ((CodeType) ex.getValue()).getValue();
255    if (ex.getValue() instanceof IntegerType)
256      return ((IntegerType) ex.getValue()).asStringValue();
257    if ((ex.getValue() instanceof MarkdownType))
258      return ((MarkdownType) ex.getValue()).getValue();
259    if (!(ex.getValue() instanceof StringType))
260      return null;
261    return ((StringType) ex.getValue()).getValue();
262  }
263
264  public static String readStringExtension(DomainResource c, String uri) {
265    Extension ex = getExtension(c, uri);
266    if (ex == null)
267      return null;
268    if ((ex.getValue() instanceof StringType))
269      return ((StringType) ex.getValue()).getValue();
270    if ((ex.getValue() instanceof UriType))
271      return ((UriType) ex.getValue()).getValue();
272    if (ex.getValue() instanceof CodeType)
273      return ((CodeType) ex.getValue()).getValue();
274    if (ex.getValue() instanceof IntegerType)
275      return ((IntegerType) ex.getValue()).asStringValue();
276    if ((ex.getValue() instanceof MarkdownType))
277      return ((MarkdownType) ex.getValue()).getValue();
278    return null;
279  }
280
281  @SuppressWarnings("unchecked")
282  public static PrimitiveType<Type> readPrimitiveExtension(DomainResource c, String uri) {
283    Extension ex = getExtension(c, uri);
284    if (ex == null)
285      return null;
286    return (PrimitiveType<Type>) ex.getValue();
287  }
288
289  public static boolean findStringExtension(Element c, String uri) {
290    Extension ex = ExtensionHelper.getExtension(c, uri);
291    if (ex == null)
292      return false;
293    if (!(ex.getValue() instanceof StringType))
294      return false;
295    return !StringUtils.isBlank(((StringType) ex.getValue()).getValue());
296  }
297
298  public static Boolean readBooleanExtension(Element c, String uri) {
299    Extension ex = ExtensionHelper.getExtension(c, uri);
300    if (ex == null)
301      return null;
302    if (!(ex.getValue() instanceof BooleanType))
303      return null;
304    return ((BooleanType) ex.getValue()).getValue();
305  }
306
307  public static boolean findBooleanExtension(Element c, String uri) {
308    Extension ex = ExtensionHelper.getExtension(c, uri);
309    if (ex == null)
310      return false;
311    if (!(ex.getValue() instanceof BooleanType))
312      return false;
313    return true;
314  }
315
316  public static String getCSComment(ConceptDefinitionComponent c) {
317    return readStringExtension(c, EXT_CS_COMMENT);    
318  }
319//
320//  public static Boolean getDeprecated(Element c) {
321//    return readBooleanExtension(c, EXT_DEPRECATED);    
322//  }
323
324  public static boolean hasCSComment(ConceptDefinitionComponent c) {
325    return findStringExtension(c, EXT_CS_COMMENT);    
326  }
327
328//  public static boolean hasDeprecated(Element c) {
329//    return findBooleanExtension(c, EXT_DEPRECATED);    
330//  }
331
332  public static List<CodeType> getSubsumes(ConceptDefinitionComponent c) {
333    List<CodeType> res = new ArrayList<CodeType>();
334
335    for (Extension e : c.getExtension()) {
336      if (EXT_SUBSUMES.equals(e.getUrl()))
337        res.add((CodeType) e.getValue());
338    }
339    return res;
340  }
341
342  public static void addFlyOver(QuestionnaireItemComponent item, String text){
343    if (!StringUtils.isBlank(text)) {
344        QuestionnaireItemComponent display = item.addItem();
345        display.setType(QuestionnaireItemType.DISPLAY);
346        display.setText(text);
347        display.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true));
348    }
349  }
350
351  public static void addMin(QuestionnaireItemComponent item, int min) {
352    item.getExtension().add(Factory.newExtension(EXT_MINOCCURS, Factory.newInteger(min), true));
353  }
354  
355  public static void addMax(QuestionnaireItemComponent item, int max) {
356    item.getExtension().add(Factory.newExtension(EXT_MAXOCCURS, Factory.newInteger(max), true));
357  }
358  
359  public static void addFhirType(QuestionnaireItemComponent group, String value) {
360    group.getExtension().add(Factory.newExtension(EXT_FHIRTYPE, Factory.newString_(value), true));       
361  }
362
363  public static void addControl(QuestionnaireItemComponent group, String value) {
364    group.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true));
365  }
366
367  public static void addAllowedResource(QuestionnaireItemComponent group, String value) {
368    group.getExtension().add(Factory.newExtension(EXT_ALLOWEDRESOURCE, Factory.newCode(value), true));       
369  }
370
371  public static void addReferenceFilter(QuestionnaireItemComponent group, String value) {
372    group.getExtension().add(Factory.newExtension(EXT_REFERENCEFILTER, Factory.newString_(value), true));       
373  }
374
375  public static void addIdentifier(Element element, Identifier value) {
376    element.getExtension().add(Factory.newExtension(EXT_IDENTIFIER, value, true));       
377  }
378
379  /**
380   * @param name the identity of the extension of interest
381   * @return The extension, if on this element, else null
382   */
383  public static Extension getExtension(DomainResource resource, String name) {
384    if (name == null)
385      return null;
386    if (!resource.hasExtension())
387      return null;
388    for (Extension e : resource.getExtension()) {
389      if (name.equals(e.getUrl()))
390        return e;
391    }
392    return null;
393  }
394
395  public static Extension getExtension(Element el, String name) {
396    if (name == null)
397      return null;
398    if (!el.hasExtension())
399      return null;
400    for (Extension e : el.getExtension()) {
401      if (name.equals(e.getUrl()))
402        return e;
403    }
404    return null;
405  }
406
407  public static void setStringExtension(DomainResource resource, String uri, String value) {
408    Extension ext = getExtension(resource, uri);
409    if (ext != null)
410      ext.setValue(new StringType(value));
411    else
412      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new StringType(value)));
413  }
414
415  public static void setStringExtension(Element element, String uri, String value) {
416    Extension ext = getExtension(element, uri);
417    if (ext != null)
418      ext.setValue(new StringType(value));
419    else
420      element.getExtension().add(new Extension(new UriType(uri)).setValue(new StringType(value)));
421  }
422
423  public static void setCodeExtension(DomainResource resource, String uri, String value) {
424    Extension ext = getExtension(resource, uri);
425    if (ext != null)
426      ext.setValue(new CodeType(value));
427    else
428      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new CodeType(value)));
429  }
430
431  public static void setIntegerExtension(DomainResource resource, String uri, int value) {
432    Extension ext = getExtension(resource, uri);
433    if (ext != null)
434      ext.setValue(new IntegerType(value));
435    else
436      resource.getExtension().add(new Extension(new UriType(uri)).setValue(new IntegerType(value)));
437  }
438  
439
440  public static void setCodeExtensionMod(DomainResource resource, String uri, String value) {
441    if (Utilities.noString(value))
442      return;
443
444    Extension ext = getExtension(resource, uri);
445    if (ext != null)
446      ext.setValue(new CodeType(value));
447    else
448      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
449  }
450
451  public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) {
452    if (Utilities.noString(value))
453      return;
454
455    Extension ext = getExtension(resource, uri);
456    if (ext != null)
457      ext.setValue(new CodeType(value));
458    else
459      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
460  }
461
462//  public static String getOID(CodeSystem define) {
463//    return readStringExtension(define, EXT_OID);    
464//  }
465//
466//  public static String getOID(ValueSet vs) {
467//    return readStringExtension(vs, EXT_OID);    
468//  }
469//
470//  public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException {
471//    if (!oid.startsWith("urn:oid:"))
472//      throw new FHIRFormatError("Error in OID format");
473//    if (oid.startsWith("urn:oid:urn:oid:"))
474//      throw new FHIRFormatError("Error in OID format");
475//    if (!hasExtension(define, EXT_OID))
476//    define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
477//    else if (!oid.equals(readStringExtension(define, EXT_OID)))
478//      throw new Error("Attempt to assign multiple OIDs to a code system");
479//  }
480//  public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException {
481//    if (!oid.startsWith("urn:oid:"))
482//      throw new FHIRFormatError("Error in OID format");
483//    if (oid.startsWith("urn:oid:urn:oid:"))
484//      throw new FHIRFormatError("Error in OID format");
485//    if (!hasExtension(vs, EXT_OID))
486//    vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
487//    else if (!oid.equals(readStringExtension(vs, EXT_OID)))
488//      throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
489//  }
490
491  public static boolean hasLanguageTranslation(Element element, String lang) {
492    for (Extension e : element.getExtension()) {
493      if (e.getUrl().equals(EXT_TRANSLATION)) {
494        Extension e1 = ExtensionHelper.getExtension(e, "lang");
495
496        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang))
497          return true;
498      }
499    }
500    return false;
501  }
502
503  public static String getLanguageTranslation(Element element, String lang) {
504    for (Extension e : element.getExtension()) {
505      if (e.getUrl().equals(EXT_TRANSLATION)) {
506        Extension e1 = ExtensionHelper.getExtension(e, "lang");
507
508        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang)) {
509          e1 = ExtensionHelper.getExtension(e, "content");
510          return ((StringType) e.getValue()).getValue();
511        }
512      }
513    }
514    return null;
515  }
516
517  public static void addLanguageTranslation(Element element, String lang, String value) {
518    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
519    extension.addExtension().setUrl("lang").setValue(new StringType(lang));
520    extension.addExtension().setUrl("content").setValue(new StringType(value));
521    element.getExtension().add(extension);
522  }
523
524  public static Type getAllowedUnits(ElementDefinition eld) {
525    for (Extension e : eld.getExtension()) 
526      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
527        return e.getValue();
528    return null;
529  }
530
531  public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) {
532    for (Extension e : eld.getExtension()) 
533      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) {
534        e.setValue(cc);
535        return;
536      }
537    eld.getExtension().add(new Extension().setUrl(EXT_ALLOWABLE_UNITS).setValue(cc));
538  }
539
540  public static List<Extension> getExtensions(Element element, String url) {
541    List<Extension> results = new ArrayList<Extension>();
542    for (Extension ex : element.getExtension())
543      if (ex.getUrl().equals(url))
544        results.add(ex);
545    return results;
546  }
547
548  public static List<Extension> getExtensions(DomainResource resource, String url) {
549    List<Extension> results = new ArrayList<Extension>();
550    for (Extension ex : resource.getExtension())
551      if (ex.getUrl().equals(url))
552        results.add(ex);
553    return results;
554  }
555
556  public static void addDEReference(DataElement de, String value) {
557    for (Extension e : de.getExtension()) 
558      if (e.getUrl().equals(EXT_CIMI_REFERENCE)) {
559        e.setValue(new UriType(value));
560        return;
561      }
562    de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value)));
563  }
564
565//  public static void setDeprecated(Element nc) {
566//    for (Extension e : nc.getExtension()) 
567//      if (e.getUrl().equals(EXT_DEPRECATED)) {
568//        e.setValue(new BooleanType(true));
569//        return;
570//      }
571//    nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true)));    
572//  }
573
574  public static void setExtension(Element focus, String url, Coding c) {
575    for (Extension e : focus.getExtension()) 
576      if (e.getUrl().equals(url)) {
577        e.setValue(c);
578        return;
579      }
580    focus.getExtension().add(new Extension().setUrl(url).setValue(c));    
581  }
582
583  public static void removeExtension(DomainResource focus, String url) {
584    Iterator<Extension> i = focus.getExtension().iterator();
585    while (i.hasNext()) {
586      Extension e = i.next(); // must be called before you can call i.remove()
587      if (e.getUrl().equals(url)) {
588        i.remove();
589      }
590    }
591  }
592  
593  public static void removeExtension(Element focus, String url) {
594    Iterator<Extension> i = focus.getExtension().iterator();
595    while (i.hasNext()) {
596      Extension e = i.next(); // must be called before you can call i.remove()
597      if (e.getUrl().equals(url)) {
598        i.remove();
599      }
600    }
601  }
602
603  public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) {
604    Extension ex = ExtensionHelper.getExtension(dr, uri);
605    if (ex == null)
606      return defaultValue;
607    if (ex.getValue() instanceof IntegerType)
608      return ((IntegerType) ex.getValue()).getValue();
609    throw new Error("Unable to read extension "+uri+" as an integer");
610  }
611
612//  public static boolean hasOID(ValueSet vs) {
613//    return hasExtension(vs, EXT_OID);
614//  }
615//  
616//  public static boolean hasOID(CodeSystem cs) {
617//    return hasExtension(cs, EXT_OID);
618//  }
619//  
620  
621}