001package org.hl7.fhir.r5.utils;
002
003import java.lang.reflect.Field;
004import java.lang.reflect.Modifier;
005
006/*
007  Copyright (c) 2011+, HL7, Inc.
008  All rights reserved.
009
010  Redistribution and use in source and binary forms, with or without modification, 
011  are permitted provided that the following conditions are met:
012
013 * Redistributions of source code must retain the above copyright notice, this 
014     list of conditions and the following disclaimer.
015 * Redistributions in binary form must reproduce the above copyright notice, 
016     this list of conditions and the following disclaimer in the documentation 
017     and/or other materials provided with the distribution.
018 * Neither the name of HL7 nor the names of its contributors may be used to 
019     endorse or promote products derived from this software without specific 
020     prior written permission.
021
022  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
023  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
024  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
025  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
026  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
027  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
028  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
029  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
030  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
031  POSSIBILITY OF SUCH DAMAGE.
032
033 */
034
035
036
037/*
038Copyright (c) 2011+, HL7, Inc
039All rights reserved.
040
041Redistribution and use in source and binary forms, with or without modification, 
042are permitted provided that the following conditions are met:
043
044 * Redistributions of source code must retain the above copyright notice, this 
045   list of conditions and the following disclaimer.
046 * Redistributions in binary form must reproduce the above copyright notice, 
047   this list of conditions and the following disclaimer in the documentation 
048   and/or other materials provided with the distribution.
049 * Neither the name of HL7 nor the names of its contributors may be used to 
050   endorse or promote products derived from this software without specific 
051   prior written permission.
052
053THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
054ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
055WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
056IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
057INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
058NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
059PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
060WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
061ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
062POSSIBILITY OF SUCH DAMAGE.
063
064 */
065
066import java.util.ArrayList;
067import java.util.HashMap;
068import java.util.Iterator;
069import java.util.List;
070import java.util.Map;
071import java.util.Set;
072import java.util.HashSet;
073
074import org.apache.commons.lang3.StringUtils;
075import org.fhir.ucum.Utilities;
076import org.hl7.fhir.exceptions.FHIRException;
077import org.hl7.fhir.r5.model.BackboneElement;
078import org.hl7.fhir.r5.model.Base;
079import org.hl7.fhir.r5.model.BooleanType;
080import org.hl7.fhir.r5.model.CanonicalType;
081import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent;
082import org.hl7.fhir.r5.model.CodeType;
083import org.hl7.fhir.r5.model.CodeableConcept;
084import org.hl7.fhir.r5.model.Coding;
085import org.hl7.fhir.r5.model.DataType;
086import org.hl7.fhir.r5.model.DecimalType;
087import org.hl7.fhir.r5.model.DomainResource;
088import org.hl7.fhir.r5.model.Element;
089import org.hl7.fhir.r5.model.ElementDefinition;
090import org.hl7.fhir.r5.model.Extension;
091import org.hl7.fhir.r5.model.ExtensionHelper;
092import org.hl7.fhir.r5.model.Factory;
093import org.hl7.fhir.r5.model.Integer64Type;
094import org.hl7.fhir.r5.model.IntegerType;
095import org.hl7.fhir.r5.model.MarkdownType;
096import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
097import org.hl7.fhir.r5.model.PrimitiveType;
098import org.hl7.fhir.r5.model.Property;
099import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
100import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType;
101import org.hl7.fhir.r5.model.StringType;
102import org.hl7.fhir.r5.model.UriType;
103import org.hl7.fhir.r5.model.UrlType;
104import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent;
105import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
106import org.hl7.fhir.utilities.StandardsStatus;
107import org.hl7.fhir.utilities.validation.ValidationMessage;
108import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
109import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
110import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
111
112
113public class ToolingExtensions {
114
115  public static final String EXT_ISSUE_MSG_ID = "http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id";
116  public static final String EXT_ISSUE_LINE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line";
117  public static final String EXT_ISSUE_COL = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col";
118  public static final String EXT_OO_FILE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-file";  
119  public static final String EXT_RESOURCE_IMPLEMENTS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-implements";
120  public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; // r2 - r3
121  public static final String EXT_XML_NAME_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name";  
122  public static final String EXT_XML_NAME = "http://hl7.org/fhir/tools/StructureDefinition/xml-name";  
123  public static final String EXT_EXPLICIT_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-explicit-type-name";
124
125  public static final String EXT_IGP_RESOURCES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-resource";
126  public static final String EXT_IGP_PAGES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-pages"; 
127  public static final String EXT_IGP_SPREADSHEET = "http://hl7.org/fhir/StructureDefinition/igpublisher-spreadsheet";
128  public static final String EXT_IGP_MAPPING_CSV = "http://hl7.org/fhir/StructureDefinition/igpublisher-mapping-csv";
129  public static final String EXT_IGP_BUNDLE = "http://hl7.org/fhir/tools/StructureDefinition/igpublisher-bundle";
130  public static final String EXT_IGP_BASE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-base";
131  public static final String EXT_IGP_DEFNS = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-defns";
132  public static final String EXT_IGP_FORMAT = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-format";
133  public static final String EXT_IGP_SOURCE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-source";
134  public static final String EXT_IGP_CONTAINED_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/contained-resource-information";
135  public static final String EXT_BINARY_FORMAT_OLD = "http://hl7.org/fhir/StructureDefinition/implementationguide-resource-format";
136  public static final String EXT_BINARY_FORMAT_NEW = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-format";
137  public static final String EXT_BINARY_LOGICAL = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-logical";
138  public static final String EXT_IGP_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/resource-information";
139  public static final String EXT_IGP_LOADVERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-loadversion";
140  public static final String EXT_LIST_PACKAGE = "http://hl7.org/fhir/StructureDefinition/list-packageId";
141  public static final String EXT_JSON_NAME_DEPRECATED = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-json-name";   
142  public static final String EXT_JSON_NAME = "http://hl7.org/fhir/tools/StructureDefinition/json-name";  
143  public static final String EXT_BINDING_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-binding-style";
144  public static final String EXT_EXTENSION_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-extension-style";
145  public static final String EXT_LOGICAL_TARGET = "http://hl7.org/fhir/tools/StructureDefinition/logical-target";
146  public static final String EXT_LOGICAL_CONTAINER = "http://hl7.org/fhir/tools/StructureDefinition/logical-container";
147  public static final String EXT_PROFILE_MAPPING = "http://hl7.org/fhir/tools/StructureDefinition/profile-mapping";
148  public static final String EXT_CS_ALTERNATE_USE = "http://hl7.org/fhir/StructureDefinition/alternate-code-use";
149  public static final String EXT_CS_ALTERNATE_STATUS = "http://hl7.org/fhir/StructureDefinition/alternate-code-status";
150  public static final String EXT_OBLIGATION_PROFILE_FLAG = "http://hl7.org/fhir/tools/StructureDefinition/obligation-profile";
151  public static final String EXT_OBLIGATION_INHERITS = "http://hl7.org/fhir/tools/StructureDefinition/inherit-obligations";
152  public static final String EXT_DAR = "http://hl7.org/fhir/StructureDefinition/data-absent-reason";
153  public static final String EXT_NF = "http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor";
154  public static final String EXT_OT = "http://hl7.org/fhir/StructureDefinition/originalText";
155  public static final String EXT_CQF_EXP = "http://hl7.org/fhir/StructureDefinition/cqf-expression";
156
157  public static final String EXT_PATTERN = "http://hl7.org/fhir/StructureDefinition/elementdefinition-pattern";
158  public static final String EXT_ALLOWEDRESOURCE = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceResource";
159  private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits";
160  private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType";
161  public static final String EXT_ALLOWED_TYPE =  "http://hl7.org/fhir/StructureDefinition/operationdefinition-allowed-type";
162  public static final String EXT_BEST_PRACTICE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice"; 
163  public static final String EXT_BEST_PRACTICE_EXPLANATION = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice-explanation"; 
164  public static final String EXT_BINDING_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName";
165  public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl";  
166  public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-concept-comments"; 
167  public static final String EXT_CS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/codesystem-keyWord"; 
168  public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition"; 
169  public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint";  
170  public static final String EXT_EXPAND_GROUP = "http://hl7.org/fhir/StructureDefinition/valueset-expand-group";
171  public static final String EXT_EXPAND_RULES = "http://hl7.org/fhir/StructureDefinition/valueset-expand-rules";
172  public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly";
173  public static final String EXT_FHIR_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type";
174  public static final String EXT_FMM_DERIVED = "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom";
175  public static final String EXT_FMM_LEVEL = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm";
176  public static final String EXT_FMM_SUPPORT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support";
177  public static final String EXT_HIERARCHY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-hierarchy"; 
178  public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source";  
179  public static final String EXT_MAXOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs"; 
180  public static final String EXT_MAX_DECIMALS = "http://hl7.org/fhir/StructureDefinition/maxDecimalPlaces";
181  public static final String EXT_MAX_SIZE = "http://hl7.org/fhir/StructureDefinition/maxSize";
182  public static final String EXT_MAX_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet";
183  public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs";  
184  public static final String EXT_MIN_LENGTH = "http://hl7.org/fhir/StructureDefinition/minLength";
185  public static final String EXT_MIN_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-minValueSet";
186  public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support";
187  public static final String EXT_NORMATIVE_VERSION = "http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version";
188  public static final String EXT_PROFILE_ELEMENT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-profile-element";
189  public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType";
190  public static final String EXT_Q_UNIT = "http://hl7.org/fhir/StructureDefinition/questionnaire-unit";
191  public static final String EXT_REFERENCEFILTER = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter"; 
192  public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/regex";  
193  public static final String EXT_RENDERED_VALUE = "http://hl7.org/fhir/StructureDefinition/rendered-value";
194  public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/codesystem-replacedby";
195  public static final String EXT_RESOURCE_CATEGORY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-category";
196  public static final String EXT_RESOURCE_INTERFACE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-interface";
197  public static final String EXT_SEC_CAT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-security-category";
198  public static final String EXT_STANDARDS_STATUS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status";
199  public static final String EXT_STANDARDS_STATUS_REASON = "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status-reason";
200  public static final String EXT_TABLE_NAME = "http://hl7.org/fhir/StructureDefinition/structuredefinition-table-name";
201  public static final String EXT_TARGET_ID = "http://hl7.org/fhir/StructureDefinition/targetElement";
202  public static final String EXT_TARGET_PATH = "http://hl7.org/fhir/StructureDefinition/targetPath";
203  public static final String EXT_TRANSLATABLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable";
204  public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation"; 
205  public static final String EXT_UNCLOSED = "http://hl7.org/fhir/StructureDefinition/valueset-unclosed";
206  public static final String EXT_VALUESET_SYSTEM = "http://hl7.org/fhir/StructureDefinition/valueset-system";
207  public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-concept-comments"; 
208  public static final String EXT_VS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/valueset-keyWord";  
209  public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg";
210  public static final String EXT_XML_NAMESPACE_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace";
211  public static final String EXT_XML_NAMESPACE = "http://hl7.org/fhir/tools/StructureDefinition/xml-namespace";
212  public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence";
213  public static final String EXT_Q_IS_SUBJ = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject"; 
214  public static final String EXT_Q_HIDDEN = "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden";
215  public static final String EXT_Q_OTP_DISP = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay"; 
216  public static final String EXT_O_LINK_PERIOD = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod"; 
217  public static final String EXT_Q_CHOICE_ORIENT = "http://hl7.org/fhir/StructureDefinition/questionnaire-choiceOrientation";
218  public static final String EXT_Q_DISPLAY_CAT = "http://hl7.org/fhir/StructureDefinition/questionnaire-displayCategory";
219  public static final String EXT_REND_MD = "http://hl7.org/fhir/StructureDefinition/rendering-markdown";
220  public static final String EXT_CAP_STMT_EXPECT = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation";
221  public static final String EXT_ED_HIERARCHY = "http://hl7.org/fhir/StructureDefinition/elementdefinition-hierarchy";
222  public static final String EXT_SD_IMPOSE_PROFILE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-imposeProfile";
223  public static final String EXT_SD_COMPLIES_WITH_PROFILE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-compliesWithProfile";
224  public static final String EXT_DEF_TYPE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype";
225  public static final String EXT_TYPE_SPEC = "http://hl7.org/fhir/tools/StructureDefinition/type-specifier";
226  public static final String EXT_TYPE_CHARACTERISTICS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-type-characteristics";
227  
228  // in the tooling IG
229  public static final String EXT_PRIVATE_BASE = "http://hl7.org/fhir/tools/";
230  public static final String EXT_BINDING_ADDITIONAL = "http://hl7.org/fhir/tools/StructureDefinition/additional-binding";
231  public static final String EXT_JSON_PROP_KEY = "http://hl7.org/fhir/tools/StructureDefinition/json-property-key";
232  public static final String EXT_JSON_EMPTY = "http://hl7.org/fhir/tools/StructureDefinition/json-empty-behavior";
233  public static final String EXT_JSON_NULLABLE = "http://hl7.org/fhir/tools/StructureDefinition/json-nullable";
234  public static final String EXT_IMPLIED_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/implied-string-prefix";
235  public static final String EXT_DATE_FORMAT = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-date-format";
236  public static final String EXT_ID_EXPECTATION = "http://hl7.org/fhir/tools/StructureDefinition/id-expectation";
237  public static final String EXT_JSON_PRIMITIVE_CHOICE = "http://hl7.org/fhir/tools/StructureDefinition/json-primitive-choice";
238  public static final String EXT_SUMMARY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-summary";
239  public static final String EXT_BINDING_DEFINITION = "http://hl7.org/fhir/tools/StructureDefinition/binding-definition";
240
241
242  // unregistered? - don't know what these are used for 
243  public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix";
244  public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix";
245
246  // for the v2 mapping project 
247  public static final String EXT_MAPPING_NAME = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-name";
248  public static final String EXT_MAPPING_TYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-type";
249  public static final String EXT_MAPPING_CARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-cardinality";
250  public static final String EXT_MAPPING_TGTTYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-type";
251  public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality";
252  
253  public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions";
254  public static final String WEB_BINDING_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/StructureDefinition-binding-style.html";
255  public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment";
256  public static final String EXT_XPATH_CONSTRAINT = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.constraint.xpath";
257  public static final String EXT_OBLIGATION_TOOLS = "http://hl7.org/fhir/tools/StructureDefinition/obligation";
258  public static final String EXT_OBLIGATION_CORE = "http://hl7.org/fhir/StructureDefinition/obligation";
259  public static final String EXT_NO_BINDING = "http://hl7.org/fhir/tools/StructureDefinition/no-binding";
260  public static final String EXT_ID_CHOICE_GROUP = "http://hl7.org/fhir/tools/StructureDefinition/xml-choice-group";
261  public static final String EXT_DATE_RULES = "http://hl7.org/fhir/tools/StructureDefinition/elementdefinition-date-rules";
262  public static final String EXT_PROFILE_STYLE = "http://hl7.org/fhir/tools/StructureDefinition/type-profile-style";
263  public static final String EXT_RESOURCE_NAME = "http://hl7.org/fhir/StructureDefinition/resource-instance-name";
264  public static final String EXT_RESOURCE_DESC = "http://hl7.org/fhir/StructureDefinition/resource-instance-description";
265  public static final String EXT_ARTIFACT_NAME = "http://hl7.org/fhir/StructureDefinition/artifact-name";
266  public static final String EXT_ARTIFACT_DESC = "http://hl7.org/fhir/StructureDefinition/artifact-description";  
267  public static final String EXT_ED_SUPPRESS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-suppress";
268  public static final String EXT_SEARCH_PARAMETER_BASE = "http://hl7.org/fhir/tools/StructureDefinition/searchparameter-base-type";
269  public static final String EXT_ISSUE_SLICE_INFO = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-slicetext";
270  public static final String EXT_ISSUE_SERVER = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server";
271  public static final String EXT_WEB_SOURCE = "http://hl7.org/fhir/tools/StructureDefinition/web-source";
272  public static final String EXT_APPLICABLE_VERSION = "http://hl7.org/fhir/StructureDefinition/version-specific-use";
273  public static final String EXT_APPLICABLE_VERSION_VALUE = "http://hl7.org/fhir/StructureDefinition/version-specific-value";
274  public static final String EXT_IG_URL = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-resource-uri";
275  public static final String EXT_VS_CS_SUPPL_NEEDED = "http://hl7.org/fhir/StructureDefinition/valueset-supplement";
276  public static final String EXT_TYPE_PARAMETER = "http://hl7.org/fhir/tools/StructureDefinition/type-parameter";
277  
278  // specific extension helpers
279
280  public static Extension makeIssueSource(Source source) {
281    Extension ex = new Extension();
282    // todo: write this up and get it published with the pack (and handle the redirect?)
283    ex.setUrl(ToolingExtensions.EXT_ISSUE_SOURCE);
284    StringType c = new StringType();
285    c.setValue(source.toString());
286    ex.setValue(c);
287    return ex;
288  }
289
290  public static Extension makeIssueMessageId(String msgId) {
291    Extension ex = new Extension();
292    // todo: write this up and get it published with the pack (and handle the redirect?)
293    ex.setUrl(ToolingExtensions.EXT_ISSUE_MSG_ID);
294    CodeType c = new CodeType();
295    c.setValue(msgId);
296    ex.setValue(c);
297    return ex;
298  }
299
300  public static boolean hasExtension(DomainResource de, String url) {
301    return getExtension(de, url) != null;
302  }
303
304  public static boolean hasExtension(Element e, String url) {
305    return getExtension(e, url) != null;
306  }
307
308  //  public static void addStringExtension(DomainResource dr, String url, String content) {
309  //    if (!StringUtils.isBlank(content)) {
310  //      Extension ex = getExtension(dr, url);
311  //      if (ex != null)
312  //        ex.setValue(new StringType(content));
313  //      else
314  //        dr.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
315  //    }
316  //  }
317
318  public static void addMarkdownExtension(DomainResource dr, String url, String content) {
319    if (!StringUtils.isBlank(content)) {
320      Extension ex = getExtension(dr, url);
321      if (ex != null)
322        ex.setValue(new StringType(content));
323      else
324        dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true));   
325    }
326  }
327
328  public static void addStringExtension(Element e, String url, String content) {
329    if (!StringUtils.isBlank(content)) {
330      Extension ex = getExtension(e, url);
331      if (ex != null)
332        ex.setValue(new StringType(content));
333      else
334        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
335    }
336  }
337
338  public static void addCodeExtension(Element e, String url, String content) {
339    if (!StringUtils.isBlank(content)) {
340      Extension ex = getExtension(e, url);
341      if (ex != null)
342        ex.setValue(new CodeType(content));
343      else
344        e.getExtension().add(Factory.newExtension(url, new CodeType(content), true));   
345    }
346  }
347
348  public static void addStringExtension(DomainResource e, String url, String content) {
349    if (!StringUtils.isBlank(content)) {
350      Extension ex = getExtension(e, url);
351      if (ex != null)
352        ex.setValue(new StringType(content));
353      else
354        e.getExtension().add(Factory.newExtension(url, new StringType(content), true));   
355    }
356  }
357
358
359  public static void addBooleanExtension(Element e, String url, boolean content) {
360    Extension ex = getExtension(e, url);
361    if (ex != null)
362      ex.setValue(new BooleanType(content));
363    else
364      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));   
365  }
366
367  public static void addBooleanExtension(DomainResource e, String url, boolean content) {
368    Extension ex = getExtension(e, url);
369    if (ex != null)
370      ex.setValue(new BooleanType(content));
371    else
372      e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true));   
373  }
374
375  public static void addIntegerExtension(DomainResource dr, String url, int value) {
376    Extension ex = getExtension(dr, url);
377    if (ex != null)
378      ex.setValue(new IntegerType(value));
379    else
380      dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true));   
381  }
382
383  public static void addCodeExtension(DomainResource dr, String url, String value) {
384    Extension ex = getExtension(dr, url);
385    if (ex != null)
386      ex.setValue(new CodeType(value));
387    else
388      dr.getExtension().add(Factory.newExtension(url, new CodeType(value), true));   
389  }
390
391  public static void addVSComment(ConceptSetComponent nc, String comment) {
392    if (!StringUtils.isBlank(comment))
393      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
394  }
395  public static void addVSComment(ConceptReferenceComponent nc, String comment) {
396    if (!StringUtils.isBlank(comment))
397      nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true));   
398  }
399
400  public static void addCSComment(ConceptDefinitionComponent nc, String comment) {
401    if (!StringUtils.isBlank(comment))
402      nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true));   
403  }
404
405  //  public static void markDeprecated(Element nc) {
406  //    setDeprecated(nc);   
407  //  }
408  //
409
410  public static void addDefinition(Element nc, String definition) {
411    if (!StringUtils.isBlank(definition))
412      nc.getExtension().add(Factory.newExtension(EXT_DEFINITION, Factory.newString_(definition), true));   
413  }
414
415  public static void addDisplayHint(Element def, String hint) {
416    if (!StringUtils.isBlank(hint))
417      def.getExtension().add(Factory.newExtension(EXT_DISPLAY_HINT, Factory.newString_(hint), true));   
418  }
419
420  public static String getDisplayHint(Element def) {
421    return readStringExtension(def, EXT_DISPLAY_HINT);    
422  }
423
424  public static String readStringExtension(Element c, String... uris) {
425    for (String uri : uris) {
426      if (hasExtension(c, uri)) {
427        return readStringExtension(c, uri);
428      }
429    }
430    return null;
431  }
432
433  public static String readStringFromExtension(Extension ext) {
434    if (ext.hasValue() && ext.getValue().isPrimitive()) {
435      return ext.getValue().primitiveValue();
436    }
437    return null;
438  }
439  
440  public static String readStringExtension(Element c, String uri) {
441    Extension ex = ExtensionHelper.getExtension(c, uri);
442    if (ex == null)
443      return null;
444    if (ex.getValue() instanceof UriType)
445      return ((UriType) ex.getValue()).getValue();
446    if (ex.getValue() instanceof CanonicalType)
447      return ((CanonicalType) ex.getValue()).getValue();
448    if (ex.getValue() instanceof CodeType)
449      return ((CodeType) ex.getValue()).getValue();
450    if (ex.getValue() instanceof IntegerType)
451      return ((IntegerType) ex.getValue()).asStringValue();
452    if (ex.getValue() instanceof Integer64Type)
453      return ((Integer64Type) ex.getValue()).asStringValue();
454    if (ex.getValue() instanceof DecimalType)
455      return ((DecimalType) ex.getValue()).asStringValue();
456    if ((ex.getValue() instanceof MarkdownType))
457      return ((MarkdownType) ex.getValue()).getValue();
458    if ((ex.getValue() instanceof PrimitiveType))
459      return ((PrimitiveType) ex.getValue()).primitiveValue();
460    if (!(ex.getValue() instanceof StringType))
461      return null;
462    return ((StringType) ex.getValue()).getValue();
463  }
464
465  public static String readStringExtension(DomainResource c, String... uris) {
466    for (String uri : uris) {
467      if (hasExtension(c, uri)) {
468        return readStringExtension(c, uri);
469      }
470    }
471    return null;
472  }
473  public static String readStringExtension(DomainResource c, String uri) {
474    Extension ex = getExtension(c, uri);
475    if (ex == null)
476      return null;
477    if ((ex.getValue() instanceof StringType))
478      return ((StringType) ex.getValue()).getValue();
479    if ((ex.getValue() instanceof UriType))
480      return ((UriType) ex.getValue()).getValue();
481    if (ex.getValue() instanceof CodeType)
482      return ((CodeType) ex.getValue()).getValue();
483    if (ex.getValue() instanceof IntegerType)
484      return ((IntegerType) ex.getValue()).asStringValue();
485    if (ex.getValue() instanceof Integer64Type)
486      return ((Integer64Type) ex.getValue()).asStringValue();
487    if (ex.getValue() instanceof DecimalType)
488      return ((DecimalType) ex.getValue()).asStringValue();
489    if ((ex.getValue() instanceof MarkdownType))
490      return ((MarkdownType) ex.getValue()).getValue();
491    return null;
492  }
493
494  @SuppressWarnings("unchecked")
495  public static PrimitiveType<DataType> readPrimitiveExtension(DomainResource c, String uri) {
496    Extension ex = getExtension(c, uri);
497    if (ex == null)
498      return null;
499    return (PrimitiveType<DataType>) ex.getValue();
500  }
501
502  public static boolean findStringExtension(Element c, String uri) {
503    Extension ex = ExtensionHelper.getExtension(c, uri);
504    if (ex == null)
505      return false;
506    if (!(ex.getValue() instanceof StringType))
507      return false;
508    return !StringUtils.isBlank(((StringType) ex.getValue()).getValue());
509  }
510
511  public static Boolean readBooleanExtension(Element c, String uri) {
512    Extension ex = ExtensionHelper.getExtension(c, uri);
513    if (ex == null)
514      return null;
515    if (!(ex.getValue() instanceof BooleanType))
516      return null;
517    return ((BooleanType) ex.getValue()).getValue();
518  }
519
520  public static boolean findBooleanExtension(Element c, String uri) {
521    Extension ex = ExtensionHelper.getExtension(c, uri);
522    if (ex == null)
523      return false;
524    if (!(ex.getValue() instanceof BooleanType))
525      return false;
526    return true;
527  }
528
529  public static Boolean readBooleanExtension(DomainResource c, String uri) {
530    Extension ex = ExtensionHelper.getExtension(c, uri);
531    if (ex == null)
532      return null;
533    if (!(ex.getValue() instanceof BooleanType))
534      return null;
535    return ((BooleanType) ex.getValue()).getValue();
536  }
537
538  public static boolean readBoolExtension(DomainResource c, String uri) {
539    Extension ex = ExtensionHelper.getExtension(c, uri);
540    if (ex == null)
541      return false;
542    if (!(ex.getValue() instanceof BooleanType))
543      return false;
544    return ((BooleanType) ex.getValue()).getValue();
545  }
546
547  public static boolean readBoolExtension(Element e, String uri) {
548    Extension ex = ExtensionHelper.getExtension(e, uri);
549    if (ex == null)
550      return false;
551    if (!(ex.getValue() instanceof BooleanType))
552      return false;
553    if (!(ex.getValue().hasPrimitiveValue()))
554      return false;
555    return ((BooleanType) ex.getValue()).getValue();
556  }
557
558  public static boolean findBooleanExtension(DomainResource c, String uri) {
559    Extension ex = ExtensionHelper.getExtension(c, uri);
560    if (ex == null)
561      return false;
562    if (!(ex.getValue() instanceof BooleanType))
563      return false;
564    return true;
565  }
566
567  public static String getCSComment(ConceptDefinitionComponent c) {
568    return readStringExtension(c, EXT_CS_COMMENT);    
569  }
570  //
571  //  public static Boolean getDeprecated(Element c) {
572  //    return readBooleanExtension(c, EXT_DEPRECATED);    
573  //  }
574
575  public static boolean hasCSComment(ConceptDefinitionComponent c) {
576    return findStringExtension(c, EXT_CS_COMMENT);    
577  }
578
579  //  public static boolean hasDeprecated(Element c) {
580  //    return findBooleanExtension(c, EXT_DEPRECATED);    
581  //  }
582
583  public static void addFlyOver(QuestionnaireItemComponent item, String text, String linkId){
584    if (!StringUtils.isBlank(text)) {
585      QuestionnaireItemComponent display = item.addItem();
586      display.setType(QuestionnaireItemType.DISPLAY);
587      display.setText(text);
588      display.setLinkId(linkId);
589      display.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true));
590    }
591  }
592
593  public static void addMin(QuestionnaireItemComponent item, int min) {
594    item.getExtension().add(Factory.newExtension(EXT_MINOCCURS, Factory.newInteger(min), true));
595  }
596
597  public static void addMax(QuestionnaireItemComponent item, int max) {
598    item.getExtension().add(Factory.newExtension(EXT_MAXOCCURS, Factory.newInteger(max), true));
599  }
600
601  public static void addFhirType(QuestionnaireItemComponent group, String value) {
602    group.getExtension().add(Factory.newExtension(EXT_FHIRTYPE, Factory.newString_(value), true));       
603  }
604
605  public static void addControl(QuestionnaireItemComponent group, String value) {
606    group.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true));
607  }
608
609  public static void addAllowedResource(QuestionnaireItemComponent group, String value) {
610    group.getExtension().add(Factory.newExtension(EXT_ALLOWEDRESOURCE, Factory.newCode(value), true));       
611  }
612
613  public static void addReferenceFilter(QuestionnaireItemComponent group, String value) {
614    group.getExtension().add(Factory.newExtension(EXT_REFERENCEFILTER, Factory.newString_(value), true));       
615  }
616
617  //  public static void addIdentifier(Element element, Identifier value) {
618  //    element.getExtension().add(Factory.newExtension(EXT_IDENTIFIER, value, true));       
619  //  }
620
621  /**
622   * @param name the identity of the extension of interest
623   * @return The extension, if on this element, else null
624   */
625  public static Extension getExtension(DomainResource resource, String name) {
626    if (resource == null || name == null)
627      return null;
628    if (!resource.hasExtension())
629      return null;
630    for (Extension e : resource.getExtension()) {
631      if (name.equals(e.getUrl()))
632        return e;
633    }
634    return null;
635  }
636
637  public static Extension getExtension(Element el, String name) {
638    if (name == null)
639      return null;
640    if (!el.hasExtension())
641      return null;
642    for (Extension e : el.getExtension()) {
643      if (name.equals(e.getUrl()))
644        return e;
645    }
646    return null;
647  }
648
649  public static void setStringExtension(DomainResource resource, String uri, String value) {
650    if (Utilities.noString(value))
651      return;
652    Extension ext = getExtension(resource, uri);
653    if (ext != null)
654      ext.setValue(new StringType(value));
655    else
656      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
657  }
658
659  public static void setStringExtension(Element resource, String uri, String value) {
660    if (Utilities.noString(value))
661      return;
662    Extension ext = getExtension(resource, uri);
663    if (ext != null)
664      ext.setValue(new StringType(value));
665    else
666      resource.getExtension().add(new Extension(uri).setValue(new StringType(value)));
667  }
668
669  public static void setUriExtension(DomainResource resource, String uri, String value) {
670    if (Utilities.noString(value))
671      return;
672    Extension ext = getExtension(resource, uri);
673    if (ext != null)
674      ext.setValue(new UriType(value));
675    else
676      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
677  }
678
679  public static void setUriExtension(Element resource, String uri, String value) {
680    if (Utilities.noString(value))
681      return;
682    Extension ext = getExtension(resource, uri);
683    if (ext != null)
684      ext.setValue(new UriType(value));
685    else
686      resource.getExtension().add(new Extension(uri).setValue(new UriType(value)));
687  }
688
689  public static void setUrlExtension(DomainResource resource, String uri, String value) {
690    if (Utilities.noString(value))
691      return;
692    Extension ext = getExtension(resource, uri);
693    if (ext != null)
694      ext.setValue(new UrlType(value));
695    else
696      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
697  }
698
699  public static void setUrlExtension(Element resource, String uri, String value) {
700    if (Utilities.noString(value))
701      return;
702    Extension ext = getExtension(resource, uri);
703    if (ext != null)
704      ext.setValue(new UrlType(value));
705    else
706      resource.getExtension().add(new Extension(uri).setValue(new UrlType(value)));
707  }
708
709  public static void setCodeExtension(DomainResource resource, String uri, String value) {
710    if (Utilities.noString(value))
711      return;
712
713    Extension ext = getExtension(resource, uri);
714    if (ext != null)
715      ext.setValue(new CodeType(value));
716    else
717      resource.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
718  }
719
720  public static void setCodeExtensionMod(DomainResource resource, String uri, String value) {
721    if (Utilities.noString(value))
722      return;
723
724    Extension ext = getExtension(resource, uri);
725    if (ext != null)
726      ext.setValue(new CodeType(value));
727    else
728      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
729  }
730
731  public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) {
732    if (Utilities.noString(value))
733      return;
734
735    Extension ext = getExtension(resource, uri);
736    if (ext != null)
737      ext.setValue(new CodeType(value));
738    else
739      resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value)));
740  }
741
742  public static void setCodeExtension(Element element, String uri, String value) {
743    if (Utilities.noString(value))
744      return;
745
746    Extension ext = getExtension(element, uri);
747    if (ext != null)
748      ext.setValue(new CodeType(value));
749    else
750      element.getExtension().add(new Extension(uri).setValue(new CodeType(value)));
751  }
752
753  public static void setIntegerExtension(DomainResource resource, String uri, int value) {
754    Extension ext = getExtension(resource, uri);
755    if (ext != null)
756      ext.setValue(new IntegerType(value));
757    else
758      resource.getExtension().add(new Extension(uri).setValue(new IntegerType(value)));
759  }
760
761  //  public static String getOID(CodeSystem define) {
762  //    return readStringExtension(define, EXT_OID);    
763  //  }
764  //
765  //  public static String getOID(ValueSet vs) {
766  //    return readStringExtension(vs, EXT_OID);    
767  //  }
768  //
769  //  public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException {
770  //    if (!oid.startsWith("urn:oid:"))
771  //      throw new FHIRFormatError("Error in OID format");
772  //    if (oid.startsWith("urn:oid:urn:oid:"))
773  //      throw new FHIRFormatError("Error in OID format");
774  //    if (!hasExtension(define, EXT_OID))
775  //    define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
776  //    else if (!oid.equals(readStringExtension(define, EXT_OID)))
777  //      throw new Error("Attempt to assign multiple OIDs to a code system");
778  //  }
779  //  public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException {
780  //    if (!oid.startsWith("urn:oid:"))
781  //      throw new FHIRFormatError("Error in OID format");
782  //    if (oid.startsWith("urn:oid:urn:oid:"))
783  //      throw new FHIRFormatError("Error in OID format");
784  //    if (!hasExtension(vs, EXT_OID))
785  //    vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false));       
786  //    else if (!oid.equals(readStringExtension(vs, EXT_OID)))
787  //      throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid);
788  //  }
789
790  public static boolean hasLanguageTranslations(Element element) {
791    for (Extension e : element.getExtension()) {
792      if (e.getUrl().equals(EXT_TRANSLATION)) {
793        return true;
794      }
795    }
796    return false;
797  }
798
799  public static boolean hasLanguageTranslation(Element element, String lang) {
800    for (Extension e : element.getExtension()) {
801      if (e.getUrl().equals(EXT_TRANSLATION)) {
802        Extension e1 = ExtensionHelper.getExtension(e, "lang");
803
804        if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang))
805          return true;
806      }
807    }
808    return false;
809  }
810
811  public static String getLanguageTranslation(Element element, String lang) {
812    for (Extension e : element.getExtension()) {
813      if (e.getUrl().equals(EXT_TRANSLATION)) {
814        Extension e1 = ExtensionHelper.getExtension(e, "lang");
815
816        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
817          e1 = ExtensionHelper.getExtension(e, "content");
818          return ((StringType) e1.getValue()).getValue();
819        }
820      }
821    }
822    return null;
823  }
824
825  public static StringType getLanguageTranslationElement(Element element, String lang) {
826    for (Extension e : element.getExtension()) {
827      if (e.getUrl().equals(EXT_TRANSLATION)) {
828        Extension e1 = ExtensionHelper.getExtension(e, "lang");
829
830        if (e1 != null && e1.getValue() != null && e1.getValue() instanceof CodeType && ((CodeType) e1.getValue()).getValue().equals(lang)) {
831          e1 = ExtensionHelper.getExtension(e, "content");
832          return ((StringType) e1.getValue());
833        }
834      }
835    }
836    return null;
837  }
838
839  public static void addLanguageTranslation(Element element, String lang, String value) {
840    if (Utilities.noString(lang) || Utilities.noString(value))
841      return;
842
843    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
844    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
845    extension.addExtension().setUrl("content").setValue(new StringType(value));
846    element.getExtension().add(extension);
847  }
848
849  public static void setLanguageTranslation(Element element, String lang, String value) {
850    if (Utilities.noString(lang) || Utilities.noString(value))
851      return;
852
853    for (Extension extension : element.getExtension()) {
854      if (EXT_TRANSLATION.equals(extension.getUrl())) {
855        String l = extension.getExtensionString("lang");
856        if (lang.equals(l)) {
857          setStringExtension(extension, "content", value);
858          return;
859        }
860      }
861    }
862    
863    Extension extension = new Extension().setUrl(EXT_TRANSLATION);
864    extension.addExtension().setUrl("lang").setValue(new CodeType(lang));
865    extension.addExtension().setUrl("content").setValue(new StringType(value));
866    element.getExtension().add(extension);
867  }
868
869  public static boolean hasAllowedUnits(ElementDefinition eld) {
870    for (Extension e : eld.getExtension()) 
871      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
872        return true;
873    return false;
874  }
875
876  public static DataType getAllowedUnits(ElementDefinition eld) {
877    for (Extension e : eld.getExtension()) 
878      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 
879        return e.getValue();
880    return null;
881  }
882
883  public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) {
884    for (Extension e : eld.getExtension()) 
885      if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) {
886        e.setValue(cc);
887        return;
888      }
889    eld.getExtension().add(new Extension().setUrl(EXT_ALLOWABLE_UNITS).setValue(cc));
890  }
891
892  public static List<Extension> getExtensions(Element element, String url) {
893    List<Extension> results = new ArrayList<Extension>();
894    for (Extension ex : element.getExtension())
895      if (ex.getUrl().equals(url))
896        results.add(ex);
897    return results;
898  }
899
900  public static List<Extension> getExtensions(DomainResource resource, String url) {
901    List<Extension> results = new ArrayList<Extension>();
902    for (Extension ex : resource.getExtension())
903      if (ex.getUrl().equals(url))
904        results.add(ex);
905    return results;
906  }
907
908  //  public static void addDEReference(DataElement de, String value) {
909  //    for (Extension e : de.getExtension()) 
910  //      if (e.getUrl().equals(EXT_CIMI_REFERENCE)) {
911  //        e.setValue(new UriType(value));
912  //        return;
913  //      }
914  //    de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value)));
915  //  }
916
917  //  public static void setDeprecated(Element nc) {
918  //    for (Extension e : nc.getExtension()) 
919  //      if (e.getUrl().equals(EXT_DEPRECATED)) {
920  //        e.setValue(new BooleanType(true));
921  //        return;
922  //      }
923  //    nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true)));    
924  //  }
925
926  public static void setExtension(Element focus, String url, Coding c) {
927    for (Extension e : focus.getExtension()) 
928      if (e.getUrl().equals(url)) {
929        e.setValue(c);
930        return;
931      }
932    focus.getExtension().add(new Extension().setUrl(url).setValue(c));    
933  }
934
935  public static void removeExtension(DomainResource focus, String url) {
936    Iterator<Extension> i = focus.getExtension().iterator();
937    while (i.hasNext()) {
938      Extension e = i.next(); // must be called before you can call i.remove()
939      if (url.equals(e.getUrl())) {
940        i.remove();
941      }
942    }
943  }
944
945  public static void removeExtension(Element focus, String url) {
946    Iterator<Extension> i = focus.getExtension().iterator();
947    while (i.hasNext()) {
948      Extension e = i.next(); // must be called before you can call i.remove()
949      if (e.getUrl().equals(url)) {
950        i.remove();
951      }
952    }
953  }
954
955  public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) {
956    Extension ex = ExtensionHelper.getExtension(dr, uri);
957    if (ex == null)
958      return defaultValue;
959    if (ex.getValue() instanceof IntegerType)
960      return ((IntegerType) ex.getValue()).getValue();
961    throw new Error("Unable to read extension "+uri+" as an integer");
962  }
963
964  public static int readIntegerExtension(Element e, String uri, int defaultValue) {
965    Extension ex = ExtensionHelper.getExtension(e, uri);
966    if (ex == null)
967      return defaultValue;
968    if (ex.getValue() instanceof IntegerType)
969      return ((IntegerType) ex.getValue()).getValue();
970    throw new Error("Unable to read extension "+uri+" as an integer");
971  }
972
973  public static Map<String, String> getLanguageTranslations(Element e) {
974    Map<String, String> res = new HashMap<String, String>();
975    for (Extension ext : e.getExtension()) {
976      if (ext.getUrl().equals(EXT_TRANSLATION)) {
977        String lang = readStringExtension(ext, "lang");
978        String value = readStringExtension(ext, "content");
979        res.put(lang,  value);
980      }
981    }
982    return res;
983  }
984
985  public static StandardsStatus getStandardsStatus(DomainResource dr) throws FHIRException {
986    return StandardsStatus.fromCode(ToolingExtensions.readStringExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS));
987  }
988
989  public static StandardsStatus getStandardsStatus(Element e) throws FHIRException {
990    return StandardsStatus.fromCode(ToolingExtensions.readStringExtension(e, ToolingExtensions.EXT_STANDARDS_STATUS));
991  }
992
993  public static void setStandardsStatus(DomainResource dr, StandardsStatus status, String normativeVersion) {
994    if (status == null)
995      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS);
996    else
997      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode());
998    if (normativeVersion == null)
999      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION);
1000    else
1001      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion);
1002  }
1003
1004  public static void setStandardsStatus(Element dr, StandardsStatus status, String normativeVersion) {
1005    if (status == null)
1006      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS);
1007    else
1008      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode());
1009    if (normativeVersion == null)
1010      ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION);
1011    else
1012      ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion);
1013  }
1014
1015  public static ValidationMessage readValidationMessage(OperationOutcomeIssueComponent issue, Source source) {
1016    ValidationMessage vm = new ValidationMessage();
1017    vm.setSource(source);
1018    vm.setLevel(mapSeverity(issue.getSeverity()));
1019    vm.setType(mapType(issue.getCode()));
1020    if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_LINE))
1021      vm.setLine(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, 0));
1022    if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_COL))
1023      vm.setCol(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, 0));
1024    if (issue.hasExpression())
1025      vm.setLocation(issue.getExpression().get(0).asStringValue());
1026    vm.setMessage(issue.getDetails().getText());
1027    if (issue.hasExtension("http://hl7.org/fhir/StructureDefinition/rendering-xhtml"))
1028      vm.setHtml(ToolingExtensions.readStringExtension(issue, "http://hl7.org/fhir/StructureDefinition/rendering-xhtml"));
1029    return vm;
1030  }
1031
1032  private static IssueType mapType(org.hl7.fhir.r5.model.OperationOutcome.IssueType code) {
1033    switch (code) {
1034    case BUSINESSRULE: return IssueType.BUSINESSRULE;
1035    case CODEINVALID: return IssueType.CODEINVALID;
1036    case CONFLICT: return IssueType.CONFLICT;
1037    case DELETED: return IssueType.DELETED;
1038    case DUPLICATE: return IssueType.DUPLICATE;
1039    case EXCEPTION: return IssueType.EXCEPTION;
1040    case EXPIRED: return IssueType.EXPIRED;
1041    case EXTENSION: return IssueType.EXTENSION;
1042    case FORBIDDEN: return IssueType.FORBIDDEN;
1043    case INCOMPLETE: return IssueType.INCOMPLETE;
1044    case INFORMATIONAL: return IssueType.INFORMATIONAL;
1045    case INVALID: return IssueType.INVALID;
1046    case INVARIANT: return IssueType.INVARIANT;
1047    case LOCKERROR: return IssueType.LOCKERROR;
1048    case LOGIN: return IssueType.LOGIN;
1049    case MULTIPLEMATCHES: return IssueType.MULTIPLEMATCHES;
1050    case NOSTORE: return IssueType.NOSTORE;
1051    case NOTFOUND: return IssueType.NOTFOUND;
1052    case NOTSUPPORTED: return IssueType.NOTSUPPORTED;
1053    case NULL: return IssueType.NULL;
1054    case PROCESSING: return IssueType.PROCESSING;
1055    case REQUIRED: return IssueType.REQUIRED;
1056    case SECURITY: return IssueType.SECURITY;
1057    case STRUCTURE: return IssueType.STRUCTURE;
1058    case SUPPRESSED: return IssueType.SUPPRESSED;
1059    case THROTTLED: return IssueType.THROTTLED;
1060    case TIMEOUT: return IssueType.TIMEOUT;
1061    case TOOCOSTLY: return IssueType.TOOCOSTLY;
1062    case TOOLONG: return IssueType.TOOLONG;
1063    case TRANSIENT: return IssueType.TRANSIENT;
1064    case UNKNOWN: return IssueType.UNKNOWN;
1065    case VALUE: return IssueType.VALUE;
1066    default: return null;
1067    }
1068  }
1069
1070  private static IssueSeverity mapSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity severity) {
1071    switch (severity) {
1072    case ERROR: return IssueSeverity.ERROR;
1073    case FATAL: return IssueSeverity.FATAL;
1074    case INFORMATION: return IssueSeverity.INFORMATION;
1075    case WARNING: return IssueSeverity.WARNING;
1076    default: return null;
1077    }
1078  }
1079
1080  public static String getPresentation(PrimitiveType<?> type) {
1081    if (type.hasExtension(EXT_RENDERED_VALUE))
1082      return readStringExtension(type, EXT_RENDERED_VALUE);
1083    return type.primitiveValue();
1084  }
1085
1086  public static String getPresentation(Element holder, PrimitiveType<?> type) {
1087    if (holder.hasExtension(EXT_RENDERED_VALUE))
1088      return readStringExtension(holder, EXT_RENDERED_VALUE);
1089    if (type.hasExtension(EXT_RENDERED_VALUE))
1090      return readStringExtension(type, EXT_RENDERED_VALUE);
1091    return type.primitiveValue();
1092  }
1093
1094  //  public static boolean hasOID(ValueSet vs) {
1095  //    return hasExtension(vs, EXT_OID);
1096  //  }
1097  //  
1098  //  public static boolean hasOID(CodeSystem cs) {
1099  //    return hasExtension(cs, EXT_OID);
1100  //  }
1101  //  
1102  public static void addUrlExtension(Element e, String url, String content) {
1103    if (!StringUtils.isBlank(content)) {
1104      Extension ex = getExtension(e, url);
1105      if (ex != null)
1106        ex.setValue(new UrlType(content));
1107      else
1108        e.getExtension().add(Factory.newExtension(url, new UrlType(content), true));   
1109    }
1110  }
1111
1112  public static void addUrlExtension(DomainResource dr, String url, String value) {
1113    Extension ex = getExtension(dr, url);
1114    if (ex != null)
1115      ex.setValue(new UrlType(value));
1116    else
1117      dr.getExtension().add(Factory.newExtension(url, new UrlType(value), true));   
1118  }
1119
1120  public static void addUriExtension(Element e, String url, String content) {
1121    if (!StringUtils.isBlank(content)) {
1122      Extension ex = getExtension(e, url);
1123      if (ex != null)
1124        ex.setValue(new UriType(content));
1125      else
1126        e.getExtension().add(Factory.newExtension(url, new UriType(content), true));   
1127    }
1128  }
1129
1130  public static void addUriExtension(DomainResource dr, String url, String value) {
1131    Extension ex = getExtension(dr, url);
1132    if (ex != null)
1133      ex.setValue(new UriType(value));
1134    else
1135      dr.getExtension().add(Factory.newExtension(url, new UriType(value), true));   
1136  }
1137
1138  public static boolean usesExtension(String url, Base base) {
1139    if ("Extension".equals(base.fhirType())) {
1140      Property p = base.getNamedProperty("url");
1141      for (Base b : p.getValues()) {
1142        if (url.equals(b.primitiveValue())) {
1143          return true;
1144        }
1145      }
1146    }
1147
1148    for (Property p : base.children() ) {
1149      for (Base v : p.getValues()) {
1150        if (usesExtension(url, v)) {
1151          return true;
1152        }
1153      }
1154    }
1155    return false;
1156  }
1157
1158  private static Set<String> cachedConsts;
1159  
1160  public static Set<String> allConsts() {
1161    if (cachedConsts == null) {
1162      Set<String> list = new HashSet<>();
1163      for (Field field : ToolingExtensions.class.getDeclaredFields()) {
1164        int modifiers = field.getModifiers();
1165        if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) {
1166          try {
1167            list.add(field.get(field.getType()).toString());
1168          } catch (Exception e) {
1169          }
1170        }
1171      }
1172      cachedConsts = list;
1173    }
1174    return cachedConsts;
1175  }
1176
1177  public static boolean hasAnyOfExtensions(Element d, String... urls) {
1178    for (String url : urls) {
1179      if (d.hasExtension(url)) {
1180        return true;
1181      }
1182    }
1183    return false;
1184  }
1185
1186  public static boolean hasAnyOfExtensions(DomainResource dr, String... urls) {
1187    for (String url : urls) {
1188      if (dr.hasExtension(url)) {
1189        return true;
1190      }
1191    }
1192    return false;
1193  }
1194
1195  public static int countExtensions(ElementDefinition d, String... urls) {
1196    int res = 0;
1197    for (String url : urls) {
1198      if (d.hasExtension(url)) {
1199        res++;
1200      }
1201    }
1202    return res;
1203  }
1204
1205}