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