
001package org.hl7.fhir.r5.terminologies; 002 003import java.util.Calendar; 004import java.util.Collections; 005import java.util.Comparator; 006import java.util.HashSet; 007import java.util.List; 008import java.util.Set; 009 010/* 011 Copyright (c) 2011+, HL7, Inc. 012 All rights reserved. 013 014 Redistribution and use in source and binary forms, with or without modification, 015 are permitted provided that the following conditions are met: 016 017 * Redistributions of source code must retain the above copyright notice, this 018 list of conditions and the following disclaimer. 019 * Redistributions in binary form must reproduce the above copyright notice, 020 this list of conditions and the following disclaimer in the documentation 021 and/or other materials provided with the distribution. 022 * Neither the name of HL7 nor the names of its contributors may be used to 023 endorse or promote products derived from this software without specific 024 prior written permission. 025 026 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 027 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 028 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 029 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 030 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 031 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 032 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 033 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 034 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 035 POSSIBILITY OF SUCH DAMAGE. 036 037 */ 038 039 040import org.hl7.fhir.exceptions.FHIRException; 041import org.hl7.fhir.exceptions.FHIRFormatError; 042import org.hl7.fhir.r5.context.IWorkerContext; 043import org.hl7.fhir.r5.model.BooleanType; 044import org.hl7.fhir.r5.model.CanonicalType; 045import org.hl7.fhir.r5.model.CodeSystem; 046import org.hl7.fhir.r5.model.DateTimeType; 047import org.hl7.fhir.r5.model.StringType; 048import org.hl7.fhir.r5.model.IntegerType; 049import org.hl7.fhir.r5.model.Enumerations.FilterOperator; 050import org.hl7.fhir.r5.model.Enumerations.PublicationStatus; 051import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; 052import org.hl7.fhir.r5.model.Identifier; 053import org.hl7.fhir.r5.model.Meta; 054import org.hl7.fhir.r5.model.Parameters; 055import org.hl7.fhir.r5.model.UriType; 056import org.hl7.fhir.r5.model.ValueSet; 057import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 058import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent; 059import org.hl7.fhir.r5.model.CodeType; 060import org.hl7.fhir.r5.model.Coding; 061import org.hl7.fhir.r5.model.DataType; 062import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent; 063import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; 064import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent; 065import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; 066import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; 067import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent; 068import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptDefinitionComponentSorter; 069import org.hl7.fhir.r5.terminologies.CodeSystemUtilities.ConceptStatus; 070import org.hl7.fhir.r5.terminologies.utilities.TerminologyCache.SourcedValueSet; 071import org.hl7.fhir.r5.utils.CanonicalResourceUtilities; 072import org.hl7.fhir.r5.utils.ToolingExtensions; 073import org.hl7.fhir.r5.utils.UserDataNames; 074import org.hl7.fhir.utilities.StandardsStatus; 075import org.hl7.fhir.utilities.Utilities; 076import org.hl7.fhir.utilities.VersionUtilities; 077 078public class ValueSetUtilities extends TerminologyUtilities { 079 080 081 public static class ValueSetSorter implements Comparator<ValueSet> { 082 083 @Override 084 public int compare(ValueSet o1, ValueSet o2) { 085 String url1 = o1.getUrl(); 086 String url2 = o2.getUrl(); 087 int c = compareString(url1, url2); 088 if (c == 0) { 089 String ver1 = o1.getVersion(); 090 String ver2 = o2.getVersion(); 091 c = VersionUtilities.compareVersions(ver1, ver2); 092 if (c == 0) { 093 String d1 = o1.getDateElement().asStringValue(); 094 String d2 = o2.getDateElement().asStringValue(); 095 c = compareString(url1, url2); 096 } 097 } 098 return c; 099 } 100 101 private int compareString(String s1, String s2) { 102 if (s1 == null) { 103 return s2 == null ? 0 : 1; 104 } else { 105 return s1.compareTo(s2); 106 } 107 } 108 109 } 110 111 112 public static boolean isServerSide(String url) { 113 return Utilities.existsInList(url, "http://hl7.org/fhir/sid/cvx"); 114 } 115 116 public static ValueSet makeShareable(ValueSet vs) { 117 if (!vs.hasExperimental()) { 118 vs.setExperimental(false); 119 } 120 if (!vs.hasMeta()) 121 vs.setMeta(new Meta()); 122 for (UriType t : vs.getMeta().getProfile()) 123 if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset")) 124 return vs; 125 vs.getMeta().getProfile().add(new CanonicalType("http://hl7.org/fhir/StructureDefinition/shareablevalueset")); 126 return vs; 127 } 128 129 public static boolean makeVSShareable(ValueSet vs) { 130 if (!vs.hasMeta()) 131 vs.setMeta(new Meta()); 132 for (UriType t : vs.getMeta().getProfile()) 133 if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset")) 134 return false; 135 vs.getMeta().getProfile().add(new CanonicalType("http://hl7.org/fhir/StructureDefinition/shareablevalueset")); 136 return true; 137 } 138 139 public static void checkShareable(ValueSet vs) { 140 if (!vs.hasMeta()) 141 throw new Error("ValueSet "+vs.getUrl()+" is not shareable"); 142 for (UriType t : vs.getMeta().getProfile()) { 143 if (t.getValue().equals("http://hl7.org/fhir/StructureDefinition/shareablevalueset")) 144 return; 145 } 146 throw new Error("ValueSet "+vs.getUrl()+" is not shareable"); 147 } 148 149 public static boolean hasOID(ValueSet vs) { 150 return getOID(vs) != null; 151 } 152 153 public static String getOID(ValueSet vs) { 154 for (Identifier id : vs.getIdentifier()) { 155 if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:")) 156 return id.getValue().substring(8); 157 } 158 return null; 159 } 160 161 public static void setOID(ValueSet vs, String oid) { 162 if (!oid.startsWith("urn:oid:")) 163 oid = "urn:oid:" + oid; 164 for (Identifier id : vs.getIdentifier()) { 165 if ("urn:ietf:rfc:3986".equals(id.getSystem()) && id.hasValue() && id.getValue().startsWith("urn:oid:")) { 166 id.setValue(oid); 167 return; 168 } 169 } 170 vs.addIdentifier().setSystem("urn:ietf:rfc:3986").setValue(oid); 171 } 172 173 public static void markStatus(ValueSet vs, String wg, StandardsStatus status, String pckage, String fmm, IWorkerContext context, String normativeVersion) throws FHIRException { 174 if (vs.hasUserData(UserDataNames.render_external_link)) 175 return; 176 177 if (wg != null) { 178 if (!ToolingExtensions.hasExtension(vs, ToolingExtensions.EXT_WORKGROUP) || 179 (!Utilities.existsInList(ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_WORKGROUP), "fhir", "vocab") && Utilities.existsInList(wg, "fhir", "vocab"))) { 180 CanonicalResourceUtilities.setHl7WG(vs, wg); 181 } 182 } 183 if (status != null) { 184 StandardsStatus ss = ToolingExtensions.getStandardsStatus(vs); 185 if (ss == null || ss.isLowerThan(status)) 186 ToolingExtensions.setStandardsStatus(vs, status, normativeVersion); 187 if (pckage != null) { 188 if (!vs.hasUserData(UserDataNames.kindling_ballot_package)) 189 vs.setUserData(UserDataNames.kindling_ballot_package, pckage); 190 else if (!pckage.equals(vs.getUserString(UserDataNames.kindling_ballot_package))) 191 if (!"infrastructure".equals(vs.getUserString(UserDataNames.kindling_ballot_package))) 192 System.out.println("Value Set "+vs.getUrl()+": ownership clash "+pckage+" vs "+vs.getUserString(UserDataNames.kindling_ballot_package)); 193 } 194 if (status == StandardsStatus.NORMATIVE) { 195 vs.setStatus(PublicationStatus.ACTIVE); 196 } 197 } 198 if (fmm != null) { 199 String sfmm = ToolingExtensions.readStringExtension(vs, ToolingExtensions.EXT_FMM_LEVEL); 200 if (Utilities.noString(sfmm) || Integer.parseInt(sfmm) < Integer.parseInt(fmm)) { 201 ToolingExtensions.setIntegerExtension(vs, ToolingExtensions.EXT_FMM_LEVEL, Integer.parseInt(fmm)); 202 } 203 } 204 if (vs.hasUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM)) 205 CodeSystemUtilities.markStatus((CodeSystem) vs.getUserData(UserDataNames.TX_ASSOCIATED_CODESYSTEM), wg, status, pckage, fmm, normativeVersion); 206 else if (status == StandardsStatus.NORMATIVE && context != null) { 207 for (ConceptSetComponent csc : vs.getCompose().getInclude()) { 208 if (csc.hasSystem()) { 209 CodeSystem cs = context.fetchCodeSystem(csc.getSystem()); 210 if (cs != null) { 211 CodeSystemUtilities.markStatus(cs, wg, status, pckage, fmm, normativeVersion); 212 } 213 } 214 } 215 } 216 } 217 218 private static int ssval(String status) { 219 if ("Draft".equals("status")) 220 return 1; 221 if ("Informative".equals("status")) 222 return 2; 223 if ("External".equals("status")) 224 return 3; 225 if ("Trial Use".equals("status")) 226 return 3; 227 if ("Normative".equals("status")) 228 return 4; 229 return -1; 230 } 231 232 public static ValueSet generateImplicitValueSet(String uri) { 233 if (uri.startsWith("http://snomed.info/sct")) 234 return generateImplicitSnomedValueSet(uri); 235 if (uri.startsWith("http://loinc.org/vs")) 236 return generateImplicitLoincValueSet(uri); 237 if (uri.equals("http://hl7.org/fhir/ValueSet/mimetypes")) { 238 return generateImplicitMimetypesValueSet(uri); 239 } 240 return null; 241 } 242 243 private static ValueSet generateImplicitMimetypesValueSet(String theUri) { 244 ValueSet valueSet = new ValueSet(); 245 valueSet.setStatus(PublicationStatus.ACTIVE); 246 valueSet.setUrl(theUri); 247 valueSet.setDescription("This value set includes all possible codes from BCP-13 (http://tools.ietf.org/html/bcp13)"); 248 valueSet.getCompose() 249 .addInclude().setSystem("urn:ietf:bcp:13"); 250 return valueSet; 251 } 252 253 private static ValueSet generateImplicitLoincValueSet(String uri) { 254 if ("http://loinc.org/vs".equals(uri)) 255 return makeLoincValueSet(); 256 if (uri.startsWith("http://loinc.org/vs/LL")) 257 return makeAnswerList(makeLoincValueSet(), uri); 258 return null; 259 } 260 261 private static ValueSet makeAnswerList(ValueSet vs, String uri) { 262 vs.setUrl(uri); 263 String c = uri.substring(20); 264 vs.setName("LOINCAnswers"+c); 265 vs.setTitle("LOINC Answer Codes for "+c); 266 vs.getCompose().getIncludeFirstRep().addFilter().setProperty("LIST").setOp(FilterOperator.EQUAL).setValue(c); 267 return vs; 268 } 269 270 private static ValueSet makeLoincValueSet() { 271 ValueSet vs = new ValueSet(); 272 vs.setUrl("http://loinc.org/vs"); 273 vs.setName("LOINCCodes"); 274 vs.setTitle("All LOINC codes"); 275 vs.setCopyright("This content LOINC® is copyright © 1995 Regenstrief Institute, Inc. and the LOINC Committee, and available at no cost under the license at http://loinc.org/terms-of-use"); 276 vs.setStatus(PublicationStatus.ACTIVE); 277 vs.getCompose().addInclude().setSystem("http://loinc.org"); 278 return vs; 279 } 280 281 private static ValueSet generateImplicitSnomedValueSet(String uri) { 282 if ("http://snomed.info/sct?fhir_vs".equals(uri)) 283 return makeImplicitSnomedValueSet(uri); 284 return null; 285 } 286 287 private static ValueSet makeImplicitSnomedValueSet(String uri) { 288 ValueSet vs = new ValueSet(); 289 vs.setUrl(uri); 290 vs.setName("SCTValueSet"); 291 vs.setTitle("SCT ValueSet"); 292 vs.setDescription("All SNOMED CT Concepts"); 293 vs.setCopyright("This value set includes content from SNOMED CT, which is copyright © 2002+ International Health Terminology Standards Development Organisation (SNOMED International), and distributed by agreement between SNOMED International and HL7. Implementer use of SNOMED CT is not covered by this agreement"); 294 vs.setStatus(PublicationStatus.ACTIVE); 295 vs.getCompose().addInclude().setSystem("http://snomed.info/sct"); 296 return vs; 297 } 298 299 public static void setDeprecated(List<ValueSetExpansionPropertyComponent> vsProp, ValueSetExpansionContainsComponent n) { 300 n.addProperty().setCode("status").setValue(new CodeType("deprecated")); 301 for (ValueSetExpansionPropertyComponent o : vsProp) { 302 if ("status".equals(o.getCode())) { 303 return; 304 } 305 } 306 vsProp.add(new ValueSetExpansionPropertyComponent().setCode("status").setUri("http://hl7.org/fhir/concept-properties#status")); 307 } 308 309 310 public static class ConceptReferenceComponentSorter implements Comparator<ConceptReferenceComponent> { 311 312 @Override 313 public int compare(ConceptReferenceComponent o1, ConceptReferenceComponent o2) { 314 return o1.getCode().compareToIgnoreCase(o2.getCode()); 315 } 316 } 317 318 319 public static void sortInclude(ConceptSetComponent inc) { 320 Collections.sort(inc.getConcept(), new ConceptReferenceComponentSorter()); 321 } 322 323 public static String getAllCodesSystem(ValueSet vs) { 324 if (vs.hasCompose()) { 325 ValueSetComposeComponent c = vs.getCompose(); 326 if (c.getExclude().isEmpty() && c.getInclude().size() == 1) { 327 ConceptSetComponent i = c.getIncludeFirstRep(); 328 if (i.hasSystem() && !i.hasValueSet() && !i.hasConcept() && !i.hasFilter()) { 329 return i.getSystem(); 330 } 331 } 332 } 333 return null; 334 } 335 336 public static boolean isDeprecated(ValueSet vs, ValueSetExpansionContainsComponent c) { 337 try { 338 for (org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent p : c.getProperty()) { 339 if ("status".equals(p.getCode()) && p.hasValue() && p.hasValueCodeType() && "deprecated".equals(p.getValueCodeType().getCode())) { 340 return true; 341 } 342 // this, though status should also be set 343 if ("deprecationDate".equals(p.getCode()) && p.hasValue() && p.getValue() instanceof DateTimeType) 344 return ((DateTimeType) p.getValue()).before(new DateTimeType(Calendar.getInstance())); 345 // legacy 346 if ("deprecated".equals(p.getCode()) && p.hasValue() && p.getValue() instanceof BooleanType) 347 return ((BooleanType) p.getValue()).getValue(); 348 } 349 StandardsStatus ss = ToolingExtensions.getStandardsStatus(c); 350 if (ss == StandardsStatus.DEPRECATED) { 351 return true; 352 } 353 return false; 354 } catch (FHIRException e) { 355 return false; 356 } 357 } 358 359 public static boolean hasCodeInExpansion(ValueSet vs, Coding code) { 360 return hasCodeInExpansion(vs.getExpansion().getContains(), code); 361 } 362 363 private static boolean hasCodeInExpansion(List<ValueSetExpansionContainsComponent> list, Coding code) { 364 for (ValueSetExpansionContainsComponent c : list) { 365 if (c.getSystem().equals(code.getSystem()) && c.getCode().equals(code.getCode())) { 366 return true; 367 } 368 if (hasCodeInExpansion(c.getContains(), code)) { 369 return true; 370 } 371 } 372 return false; 373 } 374 375 public static org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent addProperty(ValueSet vs, ValueSetExpansionContainsComponent ctxt, String url, String code, String value) { 376 if (value != null) { 377 return addProperty(vs, ctxt, url, code, new StringType(value)); 378 } else { 379 return null; 380 } 381 } 382 383 public static org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent addProperty(ValueSet vs, ValueSetExpansionContainsComponent ctxt, String url, String code, Integer value) { 384 if (value != null) { 385 return addProperty(vs, ctxt, url, code, new IntegerType(value)); 386 } else { 387 return null; 388 } 389 } 390 391 public static org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent addProperty(ValueSet vs, ValueSetExpansionContainsComponent ctxt, String url, String code, DataType value) { 392 code = defineProperty(vs, url, code); 393 org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent p = getProperty(ctxt.getProperty(), code); 394 if (p != null) { 395 p.setValue(value); 396 } else { 397 p = ctxt.addProperty().setCode(code).setValue(value); 398 } 399 return p; 400 } 401 402 private static org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent getProperty(List<org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent> list, String code) { 403 for (org.hl7.fhir.r5.model.ValueSet.ConceptPropertyComponent t : list) { 404 if (code.equals(t.getCode())) { 405 return t; 406 } 407 } 408 return null; 409 } 410 411 private static String defineProperty(ValueSet vs, String url, String code) { 412 for (ValueSetExpansionPropertyComponent p : vs.getExpansion().getProperty()) { 413 if (p.hasUri() && p.getUri().equals(url)) { 414 return p.getCode(); 415 } 416 } 417 for (ValueSetExpansionPropertyComponent p : vs.getExpansion().getProperty()) { 418 if (p.hasCode() && p.getCode().equals(code)) { 419 p.setUri(url); 420 return code; 421 } 422 } 423 ValueSetExpansionPropertyComponent p = vs.getExpansion().addProperty(); 424 p.setUri(url); 425 p.setCode(code); 426 return code; 427 } 428 429 public static int countExpansion(ValueSet valueset) { 430 int i = valueset.getExpansion().getContains().size(); 431 for (ValueSetExpansionContainsComponent t : valueset.getExpansion().getContains()) { 432 i = i + countExpansion(t); 433 } 434 return i; 435 } 436 437 public static int countExpansion(List<ValueSetExpansionContainsComponent> list) { 438 int i = list.size(); 439 for (ValueSetExpansionContainsComponent t : list) { 440 i = i + countExpansion(t); 441 } 442 return i; 443 } 444 445 private static int countExpansion(ValueSetExpansionContainsComponent c) { 446 int i = c.getContains().size(); 447 for (ValueSetExpansionContainsComponent t : c.getContains()) { 448 i = i + countExpansion(t); 449 } 450 return i; 451 } 452 453 public static Set<String> listSystems(IWorkerContext ctxt, ValueSet vs) { 454 Set<String> systems = new HashSet<>(); 455 for (ConceptSetComponent inc : vs.getCompose().getInclude()) { 456 for (CanonicalType ct : inc.getValueSet()) { 457 ValueSet vsr = ctxt.findTxResource(ValueSet.class, ct.asStringValue(), vs); 458 if (vsr != null) { 459 systems.addAll(listSystems(ctxt, vsr)); 460 } 461 } 462 if (inc.hasSystem()) { 463 systems.add(inc.getSystem()); 464 } 465 } 466 return systems; 467 } 468 469 470 public static boolean isIncompleteExpansion(ValueSet valueSet) { 471 if (valueSet.hasExpansion()) { 472 ValueSetExpansionComponent exp = valueSet.getExpansion(); 473 if (exp.hasTotal()) { 474 if (exp.getTotal() != countExpansion(exp.getContains())) { 475 return true; 476 } 477 } 478 } 479 return false; 480 } 481 482 483 public static Set<String> codes(ValueSet vs, CodeSystem cs) { 484 Set<String> res = new HashSet<>(); 485 for (ConceptSetComponent inc : vs.getCompose().getInclude()) { 486 if (inc.getSystem().equals(cs.getUrl())) { 487 addCodes(res, inc, cs.getConcept()); 488 } 489 } 490 return res; 491 } 492 493 private static void addCodes(Set<String> res, ConceptSetComponent inc, List<ConceptDefinitionComponent> list) { 494 for (ConceptDefinitionComponent cd : list) { 495 if (cd.hasCode() && (!inc.hasConcept() || inc.hasConcept(cd.getCode()))) { 496 res.add(cd.getCode()); 497 } 498 if (cd.hasConcept()) { 499 addCodes(res, inc, cd.getConcept()); 500 } 501 } 502 } 503 504 public static String versionFromExpansionParams(Parameters expParameters, String system, String defaultVersion) { 505 if (expParameters != null) { 506 for (ParametersParameterComponent p : expParameters.getParameter()) { 507 if ("system-version".equals(p.getName()) || "force-system-version".equals(p.getName())) { 508 String v = p.getValue().primitiveValue(); 509 if (v.startsWith(system+"|")) { 510 String ver = v.substring(v.indexOf("|")+1); 511 if (defaultVersion == null || ver.startsWith(defaultVersion) || "force-system-version".equals(p.getName())) { 512 return ver; 513 } 514 } 515 } 516 } 517 } 518 return defaultVersion; 519 } 520 521 public static boolean isImplicitLoincValueSet(String url) { 522 return url.startsWith("http://loinc.org/vs"); 523 } 524 525 public static boolean isImplicitSCTValueSet(String url) { 526 return url.startsWith("http://snomed.info/sct") && url.contains("?fhir_vs"); 527 } 528 529 public static ValueSet makeImplicitValueSet(String url, String version) { 530 if (url.startsWith("http://snomed.info/sct")) { 531 return makeImplicitSCTVS(url, version); 532 } else if (url.startsWith("http://loinc.org/vs")) { 533 return makeImplicitLoincVS(url, version); 534 } else { 535 throw new FHIRException("Unknown implicit value set URL "+url); 536 } 537 } 538 539 private static ValueSet makeImplicitSCTVS(String url, String version) { 540 String query = url.substring(url.indexOf("?")+1); 541 if ("fhir_vs".equals(query)) { 542 ValueSet vs = new ValueSet(); 543 vs.setUrl(url); 544 vs.setVersion(version); 545 vs.getCompose().addInclude().setSystem("http://snomed.info/sct"); 546 return vs; 547 } else if (query.startsWith("fhir_vs=isa/")) { 548 ValueSet vs = new ValueSet(); 549 vs.setUrl(url); 550 vs.setVersion(version); 551 vs.getCompose().addInclude().setSystem("http://snomed.info/sct").addFilter().setProperty("concept").setOp(FilterOperator.ISA).setValue(query.substring(12)); 552 return vs; 553 } else if (query.equals("fhir_vs=refset")) { 554 ValueSet vs = new ValueSet(); 555 vs.setUrl(url); 556 vs.setVersion(version); 557 vs.getCompose().addInclude().setSystem("http://snomed.info/sct").addFilter().setProperty("concept").setOp(FilterOperator.ISA).setValue("refset-base"); 558 return vs; 559 } else if (query.startsWith("fhir_vs=refset/")) { 560 ValueSet vs = new ValueSet(); 561 vs.setUrl(url); 562 vs.setVersion(version); 563 vs.getCompose().addInclude().setSystem("http://snomed.info/sct").addFilter().setProperty("concept").setOp(FilterOperator.IN).setValue(query.substring(15)); 564 return vs; 565 } else { 566 throw new FHIRException("Unknown implicit SNOMED CT value set URL "+url); 567 } 568 } 569 570 private static ValueSet makeImplicitLoincVS(String url, String version) { 571 if (url.equals("http://loinc.org/vs")) { 572 ValueSet vs = new ValueSet(); 573 vs.setUrl(url); 574 vs.setVersion(version); 575 vs.getCompose().addInclude().setSystem("http://loinc.org"); 576 return vs; 577 } else if (url.startsWith("http://loinc.org/vs/LP")) { 578 ValueSet vs = new ValueSet(); 579 vs.setUrl(url); 580 vs.setVersion(version); 581 vs.getCompose().addInclude().setSystem("http://loinc.org").addFilter().setProperty("ancestor").setOp(FilterOperator.EQUAL).setValue(url.substring(21)); 582 return vs; 583 } else if (url.startsWith("http://loinc.org/vs/LL")) { 584 ValueSet vs = new ValueSet(); 585 vs.setUrl(url); 586 vs.setVersion(version); 587 // this isn't the actual definition, but it won't matter to us internally 588 vs.getCompose().addInclude().setSystem("http://loinc.org").addFilter().setProperty("answer-list").setOp(FilterOperator.EQUAL).setValue(url.substring(21)); 589 return vs; 590 } else { 591 throw new FHIRException("Unknown implicit LOINC value set URL "+url); 592 } 593 } 594 595 596}