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