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