001package org.hl7.fhir.r5.utils; 002 003/* 004 Copyright (c) 2011+, HL7, Inc. 005 All rights reserved. 006 007 Redistribution and use in source and binary forms, with or without modification, 008 are permitted provided that the following conditions are met: 009 010 * Redistributions of source code must retain the above copyright notice, this 011 list of conditions and the following disclaimer. 012 * Redistributions in binary form must reproduce the above copyright notice, 013 this list of conditions and the following disclaimer in the documentation 014 and/or other materials provided with the distribution. 015 * Neither the name of HL7 nor the names of its contributors may be used to 016 endorse or promote products derived from this software without specific 017 prior written permission. 018 019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 022 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 024 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 025 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 POSSIBILITY OF SUCH DAMAGE. 029 030 */ 031 032 033 034/* 035Copyright (c) 2011+, HL7, Inc 036All rights reserved. 037 038Redistribution and use in source and binary forms, with or without modification, 039are permitted provided that the following conditions are met: 040 041 * Redistributions of source code must retain the above copyright notice, this 042 list of conditions and the following disclaimer. 043 * Redistributions in binary form must reproduce the above copyright notice, 044 this list of conditions and the following disclaimer in the documentation 045 and/or other materials provided with the distribution. 046 * Neither the name of HL7 nor the names of its contributors may be used to 047 endorse or promote products derived from this software without specific 048 prior written permission. 049 050THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 051ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 052WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 053IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 054INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 055NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 056PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 057WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 058ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 059POSSIBILITY OF SUCH DAMAGE. 060 061 */ 062 063import java.util.ArrayList; 064import java.util.HashMap; 065import java.util.Iterator; 066import java.util.List; 067import java.util.Map; 068 069import org.apache.commons.lang3.StringUtils; 070import org.fhir.ucum.Utilities; 071import org.hl7.fhir.exceptions.FHIRException; 072import org.hl7.fhir.r5.model.Base; 073import org.hl7.fhir.r5.model.BooleanType; 074import org.hl7.fhir.r5.model.CanonicalResource; 075import org.hl7.fhir.r5.model.CanonicalType; 076import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 077import org.hl7.fhir.r5.model.CodeType; 078import org.hl7.fhir.r5.model.CodeableConcept; 079import org.hl7.fhir.r5.model.Coding; 080import org.hl7.fhir.r5.model.DataType; 081import org.hl7.fhir.r5.model.DecimalType; 082import org.hl7.fhir.r5.model.DomainResource; 083import org.hl7.fhir.r5.model.Element; 084import org.hl7.fhir.r5.model.ElementDefinition; 085import org.hl7.fhir.r5.model.Extension; 086import org.hl7.fhir.r5.model.ExtensionHelper; 087import org.hl7.fhir.r5.model.Factory; 088import org.hl7.fhir.r5.model.Identifier; 089import org.hl7.fhir.r5.model.Integer64Type; 090import org.hl7.fhir.r5.model.IntegerType; 091import org.hl7.fhir.r5.model.MarkdownType; 092import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; 093import org.hl7.fhir.r5.model.PrimitiveType; 094import org.hl7.fhir.r5.model.Property; 095import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; 096import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType; 097import org.hl7.fhir.r5.model.StringType; 098import org.hl7.fhir.r5.model.UriType; 099import org.hl7.fhir.r5.model.UrlType; 100import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent; 101import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; 102import org.hl7.fhir.utilities.StandardsStatus; 103import org.hl7.fhir.utilities.validation.ValidationMessage; 104import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 105import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; 106import org.hl7.fhir.utilities.validation.ValidationMessage.Source; 107 108 109public class ToolingExtensions { 110 111 // validated 112// private static final String EXT_OID = "http://hl7.org/fhir/StructureDefinition/valueset-oid"; 113// public static final String EXT_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/codesystem-deprecated"; 114 public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition"; 115 public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-concept-comments"; 116 public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-concept-comments"; 117 public static final String EXT_CS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/codesystem-keyWord"; 118 public static final String EXT_VS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/valueset-keyWord"; 119 private static final String EXT_IDENTIFIER = "http://hl7.org/fhir/StructureDefinition/identifier"; 120 public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation"; 121 public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source"; 122 public static final String EXT_ISSUE_LINE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line"; 123 public static final String EXT_ISSUE_COL = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col"; 124 public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint"; 125 public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/valueset-replacedby"; 126 public static final String EXT_REGEX = "http://hl7.org/fhir/StructureDefinition/regex"; 127 public static final String EXT_CONTROL = "http://hl7.org/fhir/StructureDefinition/questionnaire-itemControl"; 128 public static final String EXT_MINOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-minOccurs"; 129 public static final String EXT_MAXOCCURS = "http://hl7.org/fhir/StructureDefinition/questionnaire-maxOccurs"; 130 public static final String EXT_ALLOWEDRESOURCE = "http://hl7.org/fhir/StructureDefinition/questionnaire-allowedResource"; 131 public static final String EXT_REFERENCEFILTER = "http://hl7.org/fhir/StructureDefinition/questionnaire-referenceFilter"; 132 public static final String EXT_CODE_GENERATION_PARENT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super"; 133 public static final String EXT_HIERARCHY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-hierarchy"; 134 public static final String EXT_BEST_PRACTICE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice"; 135 public static final String EXT_BEST_PRACTICE_EXPLANATION = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice-explanation"; 136 // unregistered? 137 public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix"; 138 public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix"; 139 140// public static final String EXT_FLYOVER = "http://hl7.org/fhir/Profile/questionnaire-extensions#flyover"; 141 public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType"; 142// private static final String EXT_QREF = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; 143// private static final String EXTENSION_FILTER_ONLY = "http://www.healthintersections.com.au/fhir/Profile/metadata#expandNeedsFilter"; 144// private static final String EXT_TYPE = "http://www.healthintersections.com.au/fhir/Profile/metadata#type"; 145// private static final String EXT_REFERENCE = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; 146 private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType"; 147 private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits"; 148 public static final String EXT_CIMI_REFERENCE = "http://hl7.org/fhir/StructureDefinition/cimi-reference"; 149 public static final String EXT_UNCLOSED = "http://hl7.org/fhir/StructureDefinition/valueset-unclosed"; 150 public static final String EXT_FMM_LEVEL = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm"; 151 public static final String EXT_FMM_SUPPORT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support"; 152 public static final String EXT_FMM_DERIVED = "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom"; 153 public static final String EXT_SEC_CAT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-security-category"; 154 public static final String EXT_RESOURCE_CATEGORY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-category"; 155 public static final String EXT_RESOURCE_INTERFACE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-interface"; 156 public static final String EXT_TABLE_NAME = "http://hl7.org/fhir/StructureDefinition/structuredefinition-table-name"; 157 public static final String EXT_OO_FILE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-file"; 158 public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg"; 159 public static final String EXT_STANDARDS_STATUS = "http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status"; 160 public static final String EXT_NORMATIVE_VERSION = "http://hl7.org/fhir/StructureDefinition/structuredefinition-normative-version"; 161 public static final String EXT_IGP_BASE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-base"; 162 public static final String EXT_IGP_DEFNS = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-defns"; 163 public static final String EXT_IGP_FORMAT = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-format"; 164 public static final String EXT_IGP_SOURCE = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-source"; 165 public static final String EXT_IGP_VERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-res-version"; 166 public static final String EXT_IGP_RESOURCES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-resource"; 167 public static final String EXT_IGP_PAGES = "http://hl7.org/fhir/StructureDefinition/igpublisher-folder-pages"; 168 public static final String EXT_IGP_SPREADSHEET = "http://hl7.org/fhir/StructureDefinition/igpublisher-spreadsheet"; 169 public static final String EXT_IGP_MAPPING_CSV = "http://hl7.org/fhir/StructureDefinition/igpublisher-mapping-csv"; 170 public static final String EXT_IGP_BUNDLE = "http://hl7.org/fhir/StructureDefinition/igpublisher-bundle"; 171 public static final String EXT_IGP_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/resource-information"; 172 public static final String EXT_IGP_CONTAINED_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/contained-resource-information"; 173 public static final String EXT_IGP_LOADVERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-loadversion"; 174 public static final String EXT_MAX_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"; 175 public static final String EXT_MIN_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-minValueSet"; 176 public static final String EXT_PROFILE_ELEMENT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-profile-element"; 177 public static final String EXT_LIST_PACKAGE = "http://hl7.org/fhir/StructureDefinition/list-packageId"; 178 public static final String EXT_MAPPING_NAME = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-name"; 179 public static final String EXT_MAPPING_TYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-type"; 180 public static final String EXT_MAPPING_CARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-source-cardinality"; 181 public static final String EXT_MAPPING_TGTTYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-type"; 182 public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality"; 183 public static final String EXT_PRIVATE_BASE = "http://hl7.org/fhir/tools/"; 184 public static final String EXT_ALLOWED_TYPE = "http://hl7.org/fhir/StructureDefinition/operationdefinition-allowed-type"; 185 public static final String EXT_FHIR_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type"; 186 public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; 187 public static final String EXT_RENDERED_VALUE = "http://hl7.org/fhir/StructureDefinition/rendered-value"; 188 public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence"; 189 public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly"; 190 public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support"; 191 public static final String EXT_TRANSLATABLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable"; 192 public static final String EXT_PATTERN = "http://hl7.org/fhir/StructureDefinition/elementdefinition-pattern"; 193 public static final String EXT_BINDING_METHOD = "http://hl7.org/fhir/StructureDefinition/elementdefinition-binding-method"; 194 public static final String EXT_XML_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"; 195 public static final String EXT_XML_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-xml-name"; 196 public static final String EXT_BINDING_STYLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-binding-style"; 197 public static final String EXT_BINARY_FORMAT = "http://hl7.org/fhir/StructureDefinition/implementationguide-resource-format"; 198 public static final String EXT_TARGET_ID = "http://hl7.org/fhir/StructureDefinition/targetElement"; 199 public static final String EXT_TARGET_PATH = "http://hl7.org/fhir/StructureDefinition/targetPath"; 200 public static final String EXT_VALUESET_SYSTEM = "http://hl7.org/fhir/StructureDefinition/valueset-system"; 201 public static final String EXT_EXPAND_RULES = "http://hl7.org/fhir/StructureDefinition/valueset-expand-rules"; 202 public static final String EXT_EXPAND_GROUP = "http://hl7.org/fhir/StructureDefinition/valueset-expand-group"; 203 204 // specific extension helpers 205 206 public static Extension makeIssueSource(Source source) { 207 Extension ex = new Extension(); 208 // todo: write this up and get it published with the pack (and handle the redirect?) 209 ex.setUrl(ToolingExtensions.EXT_ISSUE_SOURCE); 210 CodeType c = new CodeType(); 211 c.setValue(source.toString()); 212 ex.setValue(c); 213 return ex; 214 } 215 216 public static boolean hasExtension(DomainResource de, String url) { 217 return getExtension(de, url) != null; 218 } 219 220 public static boolean hasExtension(Element e, String url) { 221 return getExtension(e, url) != null; 222 } 223 224// public static void addStringExtension(DomainResource dr, String url, String content) { 225// if (!StringUtils.isBlank(content)) { 226// Extension ex = getExtension(dr, url); 227// if (ex != null) 228// ex.setValue(new StringType(content)); 229// else 230// dr.getExtension().add(Factory.newExtension(url, new StringType(content), true)); 231// } 232// } 233 234 public static void addMarkdownExtension(DomainResource dr, String url, String content) { 235 if (!StringUtils.isBlank(content)) { 236 Extension ex = getExtension(dr, url); 237 if (ex != null) 238 ex.setValue(new StringType(content)); 239 else 240 dr.getExtension().add(Factory.newExtension(url, new MarkdownType(content), true)); 241 } 242 } 243 244 public static void addStringExtension(Element e, String url, String content) { 245 if (!StringUtils.isBlank(content)) { 246 Extension ex = getExtension(e, url); 247 if (ex != null) 248 ex.setValue(new StringType(content)); 249 else 250 e.getExtension().add(Factory.newExtension(url, new StringType(content), true)); 251 } 252 } 253 254 public static void addCodeExtension(Element e, String url, String content) { 255 if (!StringUtils.isBlank(content)) { 256 Extension ex = getExtension(e, url); 257 if (ex != null) 258 ex.setValue(new CodeType(content)); 259 else 260 e.getExtension().add(Factory.newExtension(url, new CodeType(content), true)); 261 } 262 } 263 264 public static void addStringExtension(DomainResource e, String url, String content) { 265 if (!StringUtils.isBlank(content)) { 266 Extension ex = getExtension(e, url); 267 if (ex != null) 268 ex.setValue(new StringType(content)); 269 else 270 e.getExtension().add(Factory.newExtension(url, new StringType(content), true)); 271 } 272 } 273 274 275 public static void addBooleanExtension(Element e, String url, boolean content) { 276 Extension ex = getExtension(e, url); 277 if (ex != null) 278 ex.setValue(new BooleanType(content)); 279 else 280 e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true)); 281 } 282 283 public static void addBooleanExtension(DomainResource e, String url, boolean content) { 284 Extension ex = getExtension(e, url); 285 if (ex != null) 286 ex.setValue(new BooleanType(content)); 287 else 288 e.getExtension().add(Factory.newExtension(url, new BooleanType(content), true)); 289 } 290 291 public static void addIntegerExtension(DomainResource dr, String url, int value) { 292 Extension ex = getExtension(dr, url); 293 if (ex != null) 294 ex.setValue(new IntegerType(value)); 295 else 296 dr.getExtension().add(Factory.newExtension(url, new IntegerType(value), true)); 297 } 298 299 public static void addCodeExtension(DomainResource dr, String url, String value) { 300 Extension ex = getExtension(dr, url); 301 if (ex != null) 302 ex.setValue(new CodeType(value)); 303 else 304 dr.getExtension().add(Factory.newExtension(url, new CodeType(value), true)); 305 } 306 307 public static void addVSComment(ConceptSetComponent nc, String comment) { 308 if (!StringUtils.isBlank(comment)) 309 nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true)); 310 } 311 public static void addVSComment(ConceptReferenceComponent nc, String comment) { 312 if (!StringUtils.isBlank(comment)) 313 nc.getExtension().add(Factory.newExtension(EXT_VS_COMMENT, Factory.newString_(comment), true)); 314 } 315 316 public static void addCSComment(ConceptDefinitionComponent nc, String comment) { 317 if (!StringUtils.isBlank(comment)) 318 nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true)); 319 } 320 321// public static void markDeprecated(Element nc) { 322// setDeprecated(nc); 323// } 324// 325 326 public static void addDefinition(Element nc, String definition) { 327 if (!StringUtils.isBlank(definition)) 328 nc.getExtension().add(Factory.newExtension(EXT_DEFINITION, Factory.newString_(definition), true)); 329 } 330 331 public static void addDisplayHint(Element def, String hint) { 332 if (!StringUtils.isBlank(hint)) 333 def.getExtension().add(Factory.newExtension(EXT_DISPLAY_HINT, Factory.newString_(hint), true)); 334 } 335 336 public static String getDisplayHint(Element def) { 337 return readStringExtension(def, EXT_DISPLAY_HINT); 338 } 339 340 public static String readStringExtension(Element c, String uri) { 341 Extension ex = ExtensionHelper.getExtension(c, uri); 342 if (ex == null) 343 return null; 344 if (ex.getValue() instanceof UriType) 345 return ((UriType) ex.getValue()).getValue(); 346 if (ex.getValue() instanceof CanonicalType) 347 return ((CanonicalType) ex.getValue()).getValue(); 348 if (ex.getValue() instanceof CodeType) 349 return ((CodeType) ex.getValue()).getValue(); 350 if (ex.getValue() instanceof IntegerType) 351 return ((IntegerType) ex.getValue()).asStringValue(); 352 if (ex.getValue() instanceof Integer64Type) 353 return ((Integer64Type) ex.getValue()).asStringValue(); 354 if (ex.getValue() instanceof DecimalType) 355 return ((DecimalType) ex.getValue()).asStringValue(); 356 if ((ex.getValue() instanceof MarkdownType)) 357 return ((MarkdownType) ex.getValue()).getValue(); 358 if ((ex.getValue() instanceof PrimitiveType)) 359 return ((PrimitiveType) ex.getValue()).primitiveValue(); 360 if (!(ex.getValue() instanceof StringType)) 361 return null; 362 return ((StringType) ex.getValue()).getValue(); 363 } 364 365 public static String readStringExtension(DomainResource c, String uri) { 366 Extension ex = getExtension(c, uri); 367 if (ex == null) 368 return null; 369 if ((ex.getValue() instanceof StringType)) 370 return ((StringType) ex.getValue()).getValue(); 371 if ((ex.getValue() instanceof UriType)) 372 return ((UriType) ex.getValue()).getValue(); 373 if (ex.getValue() instanceof CodeType) 374 return ((CodeType) ex.getValue()).getValue(); 375 if (ex.getValue() instanceof IntegerType) 376 return ((IntegerType) ex.getValue()).asStringValue(); 377 if (ex.getValue() instanceof Integer64Type) 378 return ((Integer64Type) ex.getValue()).asStringValue(); 379 if (ex.getValue() instanceof DecimalType) 380 return ((DecimalType) ex.getValue()).asStringValue(); 381 if ((ex.getValue() instanceof MarkdownType)) 382 return ((MarkdownType) ex.getValue()).getValue(); 383 return null; 384 } 385 386 @SuppressWarnings("unchecked") 387 public static PrimitiveType<DataType> readPrimitiveExtension(DomainResource c, String uri) { 388 Extension ex = getExtension(c, uri); 389 if (ex == null) 390 return null; 391 return (PrimitiveType<DataType>) ex.getValue(); 392 } 393 394 public static boolean findStringExtension(Element c, String uri) { 395 Extension ex = ExtensionHelper.getExtension(c, uri); 396 if (ex == null) 397 return false; 398 if (!(ex.getValue() instanceof StringType)) 399 return false; 400 return !StringUtils.isBlank(((StringType) ex.getValue()).getValue()); 401 } 402 403 public static Boolean readBooleanExtension(Element c, String uri) { 404 Extension ex = ExtensionHelper.getExtension(c, uri); 405 if (ex == null) 406 return null; 407 if (!(ex.getValue() instanceof BooleanType)) 408 return null; 409 return ((BooleanType) ex.getValue()).getValue(); 410 } 411 412 public static boolean findBooleanExtension(Element c, String uri) { 413 Extension ex = ExtensionHelper.getExtension(c, uri); 414 if (ex == null) 415 return false; 416 if (!(ex.getValue() instanceof BooleanType)) 417 return false; 418 return true; 419 } 420 421 public static Boolean readBooleanExtension(DomainResource c, String uri) { 422 Extension ex = ExtensionHelper.getExtension(c, uri); 423 if (ex == null) 424 return null; 425 if (!(ex.getValue() instanceof BooleanType)) 426 return null; 427 return ((BooleanType) ex.getValue()).getValue(); 428 } 429 430 public static boolean readBoolExtension(DomainResource c, String uri) { 431 Extension ex = ExtensionHelper.getExtension(c, uri); 432 if (ex == null) 433 return false; 434 if (!(ex.getValue() instanceof BooleanType)) 435 return false; 436 return ((BooleanType) ex.getValue()).getValue(); 437 } 438 439 public static boolean readBoolExtension(Element e, String uri) { 440 Extension ex = ExtensionHelper.getExtension(e, uri); 441 if (ex == null) 442 return false; 443 if (!(ex.getValue() instanceof BooleanType)) 444 return false; 445 return ((BooleanType) ex.getValue()).getValue(); 446 } 447 448 public static boolean findBooleanExtension(DomainResource c, String uri) { 449 Extension ex = ExtensionHelper.getExtension(c, uri); 450 if (ex == null) 451 return false; 452 if (!(ex.getValue() instanceof BooleanType)) 453 return false; 454 return true; 455 } 456 457 public static String getCSComment(ConceptDefinitionComponent c) { 458 return readStringExtension(c, EXT_CS_COMMENT); 459 } 460// 461// public static Boolean getDeprecated(Element c) { 462// return readBooleanExtension(c, EXT_DEPRECATED); 463// } 464 465 public static boolean hasCSComment(ConceptDefinitionComponent c) { 466 return findStringExtension(c, EXT_CS_COMMENT); 467 } 468 469// public static boolean hasDeprecated(Element c) { 470// return findBooleanExtension(c, EXT_DEPRECATED); 471// } 472 473 public static void addFlyOver(QuestionnaireItemComponent item, String text, String linkId){ 474 if (!StringUtils.isBlank(text)) { 475 QuestionnaireItemComponent display = item.addItem(); 476 display.setType(QuestionnaireItemType.DISPLAY); 477 display.setText(text); 478 display.setLinkId(linkId); 479 display.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept("flyover", "http://hl7.org/fhir/questionnaire-item-control", "Fly-over"), true)); 480 } 481 } 482 483 public static void addMin(QuestionnaireItemComponent item, int min) { 484 item.getExtension().add(Factory.newExtension(EXT_MINOCCURS, Factory.newInteger(min), true)); 485 } 486 487 public static void addMax(QuestionnaireItemComponent item, int max) { 488 item.getExtension().add(Factory.newExtension(EXT_MAXOCCURS, Factory.newInteger(max), true)); 489 } 490 491 public static void addFhirType(QuestionnaireItemComponent group, String value) { 492 group.getExtension().add(Factory.newExtension(EXT_FHIRTYPE, Factory.newString_(value), true)); 493 } 494 495 public static void addControl(QuestionnaireItemComponent group, String value) { 496 group.getExtension().add(Factory.newExtension(EXT_CONTROL, Factory.newCodeableConcept(value, "http://hl7.org/fhir/questionnaire-item-control", value), true)); 497 } 498 499 public static void addAllowedResource(QuestionnaireItemComponent group, String value) { 500 group.getExtension().add(Factory.newExtension(EXT_ALLOWEDRESOURCE, Factory.newCode(value), true)); 501 } 502 503 public static void addReferenceFilter(QuestionnaireItemComponent group, String value) { 504 group.getExtension().add(Factory.newExtension(EXT_REFERENCEFILTER, Factory.newString_(value), true)); 505 } 506 507 public static void addIdentifier(Element element, Identifier value) { 508 element.getExtension().add(Factory.newExtension(EXT_IDENTIFIER, value, true)); 509 } 510 511 /** 512 * @param name the identity of the extension of interest 513 * @return The extension, if on this element, else null 514 */ 515 public static Extension getExtension(DomainResource resource, String name) { 516 if (resource == null || name == null) 517 return null; 518 if (!resource.hasExtension()) 519 return null; 520 for (Extension e : resource.getExtension()) { 521 if (name.equals(e.getUrl())) 522 return e; 523 } 524 return null; 525 } 526 527 public static Extension getExtension(Element el, String name) { 528 if (name == null) 529 return null; 530 if (!el.hasExtension()) 531 return null; 532 for (Extension e : el.getExtension()) { 533 if (name.equals(e.getUrl())) 534 return e; 535 } 536 return null; 537 } 538 539 public static void setStringExtension(DomainResource resource, String uri, String value) { 540 if (Utilities.noString(value)) 541 return; 542 Extension ext = getExtension(resource, uri); 543 if (ext != null) 544 ext.setValue(new StringType(value)); 545 else 546 resource.getExtension().add(new Extension(uri).setValue(new StringType(value))); 547 } 548 549 public static void setStringExtension(Element resource, String uri, String value) { 550 if (Utilities.noString(value)) 551 return; 552 Extension ext = getExtension(resource, uri); 553 if (ext != null) 554 ext.setValue(new StringType(value)); 555 else 556 resource.getExtension().add(new Extension(uri).setValue(new StringType(value))); 557 } 558 559 public static void setCodeExtension(DomainResource resource, String uri, String value) { 560 if (Utilities.noString(value)) 561 return; 562 563 Extension ext = getExtension(resource, uri); 564 if (ext != null) 565 ext.setValue(new CodeType(value)); 566 else 567 resource.getExtension().add(new Extension(uri).setValue(new CodeType(value))); 568 } 569 570 public static void setCodeExtension(Element element, String uri, String value) { 571 if (Utilities.noString(value)) 572 return; 573 574 Extension ext = getExtension(element, uri); 575 if (ext != null) 576 ext.setValue(new CodeType(value)); 577 else 578 element.getExtension().add(new Extension(uri).setValue(new CodeType(value))); 579 } 580 581 public static void setIntegerExtension(DomainResource resource, String uri, int value) { 582 Extension ext = getExtension(resource, uri); 583 if (ext != null) 584 ext.setValue(new IntegerType(value)); 585 else 586 resource.getExtension().add(new Extension(uri).setValue(new IntegerType(value))); 587 } 588 589// public static String getOID(CodeSystem define) { 590// return readStringExtension(define, EXT_OID); 591// } 592// 593// public static String getOID(ValueSet vs) { 594// return readStringExtension(vs, EXT_OID); 595// } 596// 597// public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException { 598// if (!oid.startsWith("urn:oid:")) 599// throw new FHIRFormatError("Error in OID format"); 600// if (oid.startsWith("urn:oid:urn:oid:")) 601// throw new FHIRFormatError("Error in OID format"); 602// if (!hasExtension(define, EXT_OID)) 603// define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); 604// else if (!oid.equals(readStringExtension(define, EXT_OID))) 605// throw new Error("Attempt to assign multiple OIDs to a code system"); 606// } 607// public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException { 608// if (!oid.startsWith("urn:oid:")) 609// throw new FHIRFormatError("Error in OID format"); 610// if (oid.startsWith("urn:oid:urn:oid:")) 611// throw new FHIRFormatError("Error in OID format"); 612// if (!hasExtension(vs, EXT_OID)) 613// vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); 614// else if (!oid.equals(readStringExtension(vs, EXT_OID))) 615// throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid); 616// } 617 618 public static boolean hasLanguageTranslation(Element element, String lang) { 619 for (Extension e : element.getExtension()) { 620 if (e.getUrl().equals(EXT_TRANSLATION)) { 621 Extension e1 = ExtensionHelper.getExtension(e, "lang"); 622 623 if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang)) 624 return true; 625 } 626 } 627 return false; 628 } 629 630 public static String getLanguageTranslation(Element element, String lang) { 631 for (Extension e : element.getExtension()) { 632 if (e.getUrl().equals(EXT_TRANSLATION)) { 633 Extension e1 = ExtensionHelper.getExtension(e, "lang"); 634 635 if (e1 != null && e1.getValue() instanceof CodeType && ((CodeType) e.getValue()).getValue().equals(lang)) { 636 e1 = ExtensionHelper.getExtension(e, "content"); 637 return ((StringType) e.getValue()).getValue(); 638 } 639 } 640 } 641 return null; 642 } 643 644 public static void addLanguageTranslation(Element element, String lang, String value) { 645 if (Utilities.noString(lang) || Utilities.noString(value)) 646 return; 647 648 Extension extension = new Extension().setUrl(EXT_TRANSLATION); 649 extension.addExtension().setUrl("lang").setValue(new CodeType(lang)); 650 extension.addExtension().setUrl("content").setValue(new StringType(value)); 651 element.getExtension().add(extension); 652 } 653 654 public static DataType getAllowedUnits(ElementDefinition eld) { 655 for (Extension e : eld.getExtension()) 656 if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) 657 return e.getValue(); 658 return null; 659 } 660 661 public static void setAllowableUnits(ElementDefinition eld, CodeableConcept cc) { 662 for (Extension e : eld.getExtension()) 663 if (e.getUrl().equals(EXT_ALLOWABLE_UNITS)) { 664 e.setValue(cc); 665 return; 666 } 667 eld.getExtension().add(new Extension().setUrl(EXT_ALLOWABLE_UNITS).setValue(cc)); 668 } 669 670 public static List<Extension> getExtensions(Element element, String url) { 671 List<Extension> results = new ArrayList<Extension>(); 672 for (Extension ex : element.getExtension()) 673 if (ex.getUrl().equals(url)) 674 results.add(ex); 675 return results; 676 } 677 678 public static List<Extension> getExtensions(DomainResource resource, String url) { 679 List<Extension> results = new ArrayList<Extension>(); 680 for (Extension ex : resource.getExtension()) 681 if (ex.getUrl().equals(url)) 682 results.add(ex); 683 return results; 684 } 685 686// public static void addDEReference(DataElement de, String value) { 687// for (Extension e : de.getExtension()) 688// if (e.getUrl().equals(EXT_CIMI_REFERENCE)) { 689// e.setValue(new UriType(value)); 690// return; 691// } 692// de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value))); 693// } 694 695// public static void setDeprecated(Element nc) { 696// for (Extension e : nc.getExtension()) 697// if (e.getUrl().equals(EXT_DEPRECATED)) { 698// e.setValue(new BooleanType(true)); 699// return; 700// } 701// nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true))); 702// } 703 704 public static void setExtension(Element focus, String url, Coding c) { 705 for (Extension e : focus.getExtension()) 706 if (e.getUrl().equals(url)) { 707 e.setValue(c); 708 return; 709 } 710 focus.getExtension().add(new Extension().setUrl(url).setValue(c)); 711 } 712 713 public static void removeExtension(DomainResource focus, String url) { 714 Iterator<Extension> i = focus.getExtension().iterator(); 715 while (i.hasNext()) { 716 Extension e = i.next(); // must be called before you can call i.remove() 717 if (e.getUrl().equals(url)) { 718 i.remove(); 719 } 720 } 721 } 722 723 public static void removeExtension(Element focus, String url) { 724 Iterator<Extension> i = focus.getExtension().iterator(); 725 while (i.hasNext()) { 726 Extension e = i.next(); // must be called before you can call i.remove() 727 if (e.getUrl().equals(url)) { 728 i.remove(); 729 } 730 } 731 } 732 733 public static int readIntegerExtension(DomainResource dr, String uri, int defaultValue) { 734 Extension ex = ExtensionHelper.getExtension(dr, uri); 735 if (ex == null) 736 return defaultValue; 737 if (ex.getValue() instanceof IntegerType) 738 return ((IntegerType) ex.getValue()).getValue(); 739 throw new Error("Unable to read extension "+uri+" as an integer"); 740 } 741 742 public static int readIntegerExtension(Element e, String uri, int defaultValue) { 743 Extension ex = ExtensionHelper.getExtension(e, uri); 744 if (ex == null) 745 return defaultValue; 746 if (ex.getValue() instanceof IntegerType) 747 return ((IntegerType) ex.getValue()).getValue(); 748 throw new Error("Unable to read extension "+uri+" as an integer"); 749 } 750 751 public static Map<String, String> getLanguageTranslations(Element e) { 752 Map<String, String> res = new HashMap<String, String>(); 753 for (Extension ext : e.getExtension()) { 754 if (ext.getUrl().equals(EXT_TRANSLATION)) { 755 String lang = readStringExtension(ext, "lang"); 756 String value = readStringExtension(ext, "content"); 757 res.put(lang, value); 758 } 759 } 760 return res; 761 } 762 763 public static StandardsStatus getStandardsStatus(DomainResource dr) throws FHIRException { 764 return StandardsStatus.fromCode(ToolingExtensions.readStringExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS)); 765 } 766 767 public static void setStandardsStatus(DomainResource dr, StandardsStatus status, String normativeVersion) { 768 if (status == null) 769 ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS); 770 else 771 ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode()); 772 if (normativeVersion == null) 773 ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION); 774 else 775 ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion); 776 } 777 778 public static void setStandardsStatus(Element dr, StandardsStatus status, String normativeVersion) { 779 if (status == null) 780 ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS); 781 else 782 ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_STANDARDS_STATUS, status.toCode()); 783 if (normativeVersion == null) 784 ToolingExtensions.removeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION); 785 else 786 ToolingExtensions.setCodeExtension(dr, ToolingExtensions.EXT_NORMATIVE_VERSION, normativeVersion); 787 } 788 789 public static ValidationMessage readValidationMessage(OperationOutcomeIssueComponent issue, Source source) { 790 ValidationMessage vm = new ValidationMessage(); 791 vm.setSource(source); 792 vm.setLevel(mapSeverity(issue.getSeverity())); 793 vm.setType(mapType(issue.getCode())); 794 if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_LINE)) 795 vm.setLine(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, 0)); 796 if (issue.hasExtension(ToolingExtensions.EXT_ISSUE_COL)) 797 vm.setCol(ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, 0)); 798 if (issue.hasExpression()) 799 vm.setLocation(issue.getExpression().get(0).asStringValue()); 800 vm.setMessage(issue.getDetails().getText()); 801 if (issue.hasExtension("http://hl7.org/fhir/StructureDefinition/rendering-xhtml")) 802 vm.setHtml(ToolingExtensions.readStringExtension(issue, "http://hl7.org/fhir/StructureDefinition/rendering-xhtml")); 803 return vm; 804 } 805 806 private static IssueType mapType(org.hl7.fhir.r5.model.OperationOutcome.IssueType code) { 807 switch (code) { 808 case BUSINESSRULE: return IssueType.BUSINESSRULE; 809 case CODEINVALID: return IssueType.CODEINVALID; 810 case CONFLICT: return IssueType.CONFLICT; 811 case DELETED: return IssueType.DELETED; 812 case DUPLICATE: return IssueType.DUPLICATE; 813 case EXCEPTION: return IssueType.EXCEPTION; 814 case EXPIRED: return IssueType.EXPIRED; 815 case EXTENSION: return IssueType.EXTENSION; 816 case FORBIDDEN: return IssueType.FORBIDDEN; 817 case INCOMPLETE: return IssueType.INCOMPLETE; 818 case INFORMATIONAL: return IssueType.INFORMATIONAL; 819 case INVALID: return IssueType.INVALID; 820 case INVARIANT: return IssueType.INVARIANT; 821 case LOCKERROR: return IssueType.LOCKERROR; 822 case LOGIN: return IssueType.LOGIN; 823 case MULTIPLEMATCHES: return IssueType.MULTIPLEMATCHES; 824 case NOSTORE: return IssueType.NOSTORE; 825 case NOTFOUND: return IssueType.NOTFOUND; 826 case NOTSUPPORTED: return IssueType.NOTSUPPORTED; 827 case NULL: return IssueType.NULL; 828 case PROCESSING: return IssueType.PROCESSING; 829 case REQUIRED: return IssueType.REQUIRED; 830 case SECURITY: return IssueType.SECURITY; 831 case STRUCTURE: return IssueType.STRUCTURE; 832 case SUPPRESSED: return IssueType.SUPPRESSED; 833 case THROTTLED: return IssueType.THROTTLED; 834 case TIMEOUT: return IssueType.TIMEOUT; 835 case TOOCOSTLY: return IssueType.TOOCOSTLY; 836 case TOOLONG: return IssueType.TOOLONG; 837 case TRANSIENT: return IssueType.TRANSIENT; 838 case UNKNOWN: return IssueType.UNKNOWN; 839 case VALUE: return IssueType.VALUE; 840 default: return null; 841 } 842 } 843 844 private static IssueSeverity mapSeverity(org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity severity) { 845 switch (severity) { 846 case ERROR: return IssueSeverity.ERROR; 847 case FATAL: return IssueSeverity.FATAL; 848 case INFORMATION: return IssueSeverity.INFORMATION; 849 case WARNING: return IssueSeverity.WARNING; 850 default: return null; 851 } 852 } 853 854 public static String getPresentation(PrimitiveType<?> type) { 855 if (type.hasExtension(EXT_RENDERED_VALUE)) 856 return readStringExtension(type, EXT_RENDERED_VALUE); 857 return type.primitiveValue(); 858 } 859 860 public static String getPresentation(Element holder, PrimitiveType<?> type) { 861 if (holder.hasExtension(EXT_RENDERED_VALUE)) 862 return readStringExtension(holder, EXT_RENDERED_VALUE); 863 if (type.hasExtension(EXT_RENDERED_VALUE)) 864 return readStringExtension(type, EXT_RENDERED_VALUE); 865 return type.primitiveValue(); 866 } 867 868// public static boolean hasOID(ValueSet vs) { 869// return hasExtension(vs, EXT_OID); 870// } 871// 872// public static boolean hasOID(CodeSystem cs) { 873// return hasExtension(cs, EXT_OID); 874// } 875// 876 public static void addUrlExtension(Element e, String url, String content) { 877 if (!StringUtils.isBlank(content)) { 878 Extension ex = getExtension(e, url); 879 if (ex != null) 880 ex.setValue(new UrlType(content)); 881 else 882 e.getExtension().add(Factory.newExtension(url, new UrlType(content), true)); 883 } 884 } 885 886 public static void addUrlExtension(DomainResource dr, String url, String value) { 887 Extension ex = getExtension(dr, url); 888 if (ex != null) 889 ex.setValue(new UrlType(value)); 890 else 891 dr.getExtension().add(Factory.newExtension(url, new UrlType(value), true)); 892 } 893 894 public static void addUriExtension(Element e, String url, String content) { 895 if (!StringUtils.isBlank(content)) { 896 Extension ex = getExtension(e, url); 897 if (ex != null) 898 ex.setValue(new UriType(content)); 899 else 900 e.getExtension().add(Factory.newExtension(url, new UriType(content), true)); 901 } 902 } 903 904 public static void addUriExtension(DomainResource dr, String url, String value) { 905 Extension ex = getExtension(dr, url); 906 if (ex != null) 907 ex.setValue(new UriType(value)); 908 else 909 dr.getExtension().add(Factory.newExtension(url, new UriType(value), true)); 910 } 911 912 public static boolean usesExtension(String url, Base base) { 913 if ("Extension".equals(base.fhirType())) { 914 Property p = base.getNamedProperty("url"); 915 for (Base b : p.getValues()) { 916 if (url.equals(b.primitiveValue())) { 917 return true; 918 } 919 } 920 } 921 922 for (Property p : base.children() ) { 923 for (Base v : p.getValues()) { 924 if (usesExtension(url, v)) { 925 return true; 926 } 927 } 928 } 929 return false; 930 } 931 932 933}