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