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