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