
001package org.hl7.fhir.r5.context; 002 003import java.io.FileNotFoundException; 004import java.io.IOException; 005import java.util.ArrayList; 006import java.util.Collection; 007import java.util.Collections; 008import java.util.Comparator; 009import java.util.Date; 010import java.util.HashSet; 011 012/* 013 Copyright (c) 2011+, HL7, Inc. 014 All rights reserved. 015 016 Redistribution and use in source and binary forms, with or without modification, 017 are permitted provided that the following conditions are met: 018 019 * Redistributions of source code must retain the above copyright notice, this 020 list of conditions and the following disclaimer. 021 * Redistributions in binary form must reproduce the above copyright notice, 022 this list of conditions and the following disclaimer in the documentation 023 and/or other materials provided with the distribution. 024 * Neither the name of HL7 nor the names of its contributors may be used to 025 endorse or promote products derived from this software without specific 026 prior written permission. 027 028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 029 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 030 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 031 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 032 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 033 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 034 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 035 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 036 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 037 POSSIBILITY OF SUCH DAMAGE. 038 039 */ 040 041 042 043import java.util.List; 044import java.util.Locale; 045import java.util.Map; 046import java.util.Set; 047 048import lombok.Getter; 049import org.fhir.ucum.UcumService; 050import org.hl7.fhir.exceptions.DefinitionException; 051import org.hl7.fhir.exceptions.FHIRException; 052import org.hl7.fhir.exceptions.TerminologyServiceException; 053import org.hl7.fhir.r5.context.IWorkerContext.OIDDefinition; 054import org.hl7.fhir.r5.context.IWorkerContext.OIDDefinitionComparer; 055import org.hl7.fhir.r5.context.IWorkerContext.ITerminologyOperationDetails; 056import org.hl7.fhir.r5.elementmodel.Element; 057import org.hl7.fhir.r5.formats.IParser; 058import org.hl7.fhir.r5.formats.ParserType; 059import org.hl7.fhir.r5.model.CanonicalResource; 060import org.hl7.fhir.r5.model.CodeSystem; 061import org.hl7.fhir.r5.model.CodeableConcept; 062import org.hl7.fhir.r5.model.Coding; 063import org.hl7.fhir.r5.model.ConceptMap; 064import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent; 065import org.hl7.fhir.r5.model.NamingSystem; 066import org.hl7.fhir.r5.model.OperationOutcome; 067import org.hl7.fhir.r5.model.PackageInformation; 068import org.hl7.fhir.r5.model.Parameters; 069import org.hl7.fhir.r5.model.Resource; 070import org.hl7.fhir.r5.model.StructureDefinition; 071import org.hl7.fhir.r5.model.StructureMap; 072import org.hl7.fhir.r5.model.ValueSet; 073import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; 074import org.hl7.fhir.r5.profilemodel.PEDefinition; 075import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; 076import org.hl7.fhir.r5.profilemodel.PEBuilder; 077import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; 078import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest; 079import org.hl7.fhir.r5.terminologies.utilities.ValidationResult; 080import org.hl7.fhir.r5.utils.validation.IResourceValidator; 081import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; 082import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; 083import org.hl7.fhir.utilities.FhirPublication; 084import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 085import org.hl7.fhir.utilities.TimeTracker; 086import org.hl7.fhir.utilities.npm.BasePackageCacheManager; 087import org.hl7.fhir.utilities.npm.NpmPackage; 088import org.hl7.fhir.utilities.validation.ValidationMessage; 089import org.hl7.fhir.utilities.validation.ValidationOptions; 090 091import javax.annotation.Nonnull; 092 093 094/** 095 * This is the standard interface used for access to underlying FHIR 096 * services through the tools and utilities provided by the reference 097 * implementation. 098 * 099 * The functionality it provides is 100 * - get access to canonical resources,terminology services, and validator 101 * (you can't create a validator directly because it needs access 102 * to the right context for their information) 103 * 104 * - find resources that the tools need to carry out their tasks 105 * 106 * - provide access to terminology services they need. 107 * (typically, these terminology service requests are just 108 * passed through to the local implementation's terminology 109 * service) 110 * 111 * @author Grahame 112 */ 113 114@MarkedToMoveToAdjunctPackage 115public interface IWorkerContext { 116 117 public interface ITerminologyOperationDetails { 118 119 public void seeSupplement(CodeSystem supp); 120 } 121 public class OIDDefinitionComparer implements Comparator<OIDDefinition> { 122 123 @Override 124 public int compare(OIDDefinition o1, OIDDefinition o2) { 125 if (o1.getUrl().equals(o2.getUrl())) { 126 return -o1.getVersion().compareTo(o2.getVersion()); 127 } else { 128 return o1.getUrl().compareTo(o2.getUrl()); 129 } 130 } 131 } 132 133 public class OIDDefinition { 134 private String type; 135 private String oid; 136 private String url; 137 private String version; 138 private String packageSrc; 139 private String status; 140 protected OIDDefinition(String type, String oid, String url, String version, String status, String packageSrc) { 141 super(); 142 this.type = type; 143 this.oid = oid; 144 this.url = url; 145 this.version = version == null ? "" : version; 146 this.packageSrc = packageSrc; 147 this.status = status; 148 } 149 public String getType() { 150 return type; 151 } 152 public String getOid() { 153 return oid; 154 } 155 public String getUrl() { 156 return url; 157 } 158 public String getVersion() { 159 return version; 160 } 161 public String getStatus() { 162 return status; 163 } 164 public String getPackageSrc() { 165 return packageSrc; 166 } 167 public String summary() { 168 return url+(version == null ? "" : "|"+version)+(packageSrc != null ? "("+packageSrc+")" : ""); 169 } 170 public boolean matches(OIDDefinition t) { 171 return url.equals(t.url) && version.equals(t.version); 172 } 173 174 } 175 176 public class OIDSummary { 177 private List<OIDDefinition> definitions = new ArrayList<>(); 178 private List<String> urls = new ArrayList<>(); 179 180 public void addOID(OIDDefinition d) { 181 for (OIDDefinition t : definitions) { 182 if (d.matches(t)) { 183 return; 184 } 185 } 186 definitions.add(d); 187 if (!urls.contains(d.getUrl())) { 188 urls.add(d.getUrl()); 189 } 190 } 191 192 public void addOIDs(Collection<OIDDefinition> collection) { 193 for (OIDDefinition t : collection) { 194 addOID(t); 195 } 196 } 197 198 public List<OIDDefinition> getDefinitions() { 199 return definitions; 200 } 201 202 public void sort() { 203 Collections.sort(definitions, new OIDDefinitionComparer()); 204 Collections.sort(urls); 205 } 206 public String describe() { 207 CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); 208 for (OIDDefinition d : definitions) { 209 b.append(d.summary()); 210 } 211 return b.toString(); 212 } 213 214 public String chooseBestUrl() { 215 for (OIDDefinition d : definitions) { 216 if (d.getPackageSrc() == null) { 217 return d.getUrl(); 218 } 219 } 220 for (OIDDefinition d : definitions) { 221 if (d.getUrl().startsWith("http://hl7.org/fhir/")) { 222 return d.getUrl(); 223 } 224 } 225 for (OIDDefinition d : definitions) { 226 if (!d.getUrl().contains("vsac")) { 227 return d.getUrl(); 228 } 229 } 230 return null; 231 } 232 233 public int urlCount() { 234 return urls.size(); 235 } 236 237 public String getUrl() { 238 return urls.iterator().next(); 239 } 240 } 241 /** 242 * Get the version of the base definitions loaded in context 243 * This *does not* have to be 5.0 (R5) - the context can load other versions 244 * 245 * Note that more than one version might be loaded at once, but one version is always the default / master 246 * 247 * @return 248 */ 249 public String getVersion(); 250 251 /** 252 * Get the UCUM service that provides access to units of measure reasoning services 253 * 254 * This service might not be available 255 * 256 * @return 257 */ 258 public UcumService getUcumService(); 259 public void setUcumService(UcumService ucumService); 260 261 /** 262 * Get a validator that can check whether a resource is valid 263 * 264 * @return a prepared generator 265 * @throws FHIRException 266 * @ 267 */ 268 public IResourceValidator newValidator() throws FHIRException; 269 270 // -- resource fetchers --------------------------------------------------- 271 272 /** 273 * Find an identified resource. The most common use of this is to access the the 274 * standard conformance resources that are part of the standard - structure 275 * definitions, value sets, concept maps, etc. 276 * 277 * Also, the narrative generator uses this, and may access any kind of resource 278 * 279 * The URI is called speculatively for things that might exist, so not finding 280 * a matching resource, return null, not an error 281 * 282 * The URI can have one of 3 formats: 283 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 284 * - a relative URL e.g. ValueSet/[id] 285 * - a logical id e.g. [id] 286 * 287 * It's an error if the second form doesn't agree with class_. It's an 288 * error if class_ is null for the last form 289 * 290 * class can be Resource, DomainResource or CanonicalResource, which means resource of all kinds 291 * 292 * @param resource 293 * @param Reference 294 * @return 295 * @throws FHIRException 296 * @throws Exception 297 */ 298 public <T extends Resource> T fetchResource(Class<T> class_, String uri); 299 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException; 300 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri, Resource sourceOfReference) throws FHIRException; 301 public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version); 302 public <T extends Resource> T fetchResource(Class<T> class_, String uri, FhirPublication fhirVersion); 303 public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version, FhirPublication fhirVersion); 304 305 /** 306 * Find an identified resource, but do not do any processing on it. 307 * The usual processing that happens is ensuring that the snapshot is 308 * generated before returning it; This routine is used in the snapshot 309 * generation routines to avoid circular dependency challenges generating 310 * snapshots. 311 * 312 * class can be Resource, DomainResource or CanonicalResource, which means resource of all kinds 313 * 314 * @param class_ 315 * @param uri 316 * @return 317 * @throws FHIRException 318 * @throws Exception 319 */ 320 public <T extends Resource> T fetchResourceRaw(Class<T> class_, String uri); 321 322 323 /** has the same functionality as fetchResource, but passes in information about the source of the 324 * reference (this may affect resolution of version) 325 * 326 * @param <T> 327 * @param class_ 328 * @param uri 329 * @param canonicalForSource 330 * @return 331 */ 332 public <T extends Resource> T fetchResource(Class<T> class_, String uri, Resource sourceOfReference); 333 334 /** 335 * Fetch all the resources of a particular type. if class == (null | Resource | DomainResource | CanonicalResource) return everything 336 * 337 * @param <T> 338 * @param class_ 339 * @param uri 340 * @param canonicalForSource 341 * @return 342 */ 343 public <T extends Resource> List<T> fetchResourcesByType(Class<T> class_); 344 public <T extends Resource> List<T> fetchResourceVersionsByTypeAndUrl(Class<T> class_, String url); 345 @Deprecated 346 public <T extends Resource> List<T> fetchResourcesByType(Class<T> class_, FhirPublication fhirVersion); 347 348 349 /** 350 * Fetch all the resources for the given URL - all matching versions 351 * 352 * @param url 353 * @return 354 */ 355 public <T extends Resource> List<T> fetchResourcesByUrl(Class<T> class_, String url); 356 357 /** 358 * Variation of fetchResource when you have a string type, and don't need the right class 359 * 360 * The URI can have one of 3 formats: 361 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 362 * - a relative URL e.g. ValueSet/[id] 363 * - a logical id e.g. [id] 364 * 365 * if type == null, the URI can't be a simple logical id 366 * 367 * @param type 368 * @param uri 369 * @return 370 */ 371 public Resource fetchResourceById(String type, String uri); 372 public Resource fetchResourceById(String type, String uri, FhirPublication fhirVersion); 373 374 /** 375 * find whether a resource is available. 376 * 377 * Implementations of the interface can assume that if hasResource ruturns 378 * true, the resource will usually be fetched subsequently 379 * 380 * @param class_ 381 * @param uri 382 * @return 383 */ 384 public <T extends Resource> boolean hasResource(Class<T> class_, String uri); 385 public <T extends Resource> boolean hasResource(Class<T> class_, String uri, Resource sourceOfReference); 386 public <T extends Resource> boolean hasResource(Class<T> class_, String uri, FhirPublication fhirVersion); 387 388 /** 389 * cache a resource for later retrieval using fetchResource. 390 * 391 * Note that various context implementations will have their own ways of loading 392 * rseources, and not all need implement cacheResource. 393 * 394 * If the resource is loaded out of a package, call cacheResourceFromPackage instead 395 * @param res 396 * @throws FHIRException 397 */ 398 public void cacheResource(Resource res) throws FHIRException; 399 400 /** 401 * cache a resource for later retrieval using fetchResource. 402 * 403 * The package information is used to help manage the cache internally, and to 404 * help with reference resolution. Packages should be define using cachePackage (but don't have to be) 405 * 406 * Note that various context implementations will have their own ways of loading 407 * rseources, and not all need implement cacheResource 408 * 409 * @param res 410 * @throws FHIRException 411 */ 412 public void cacheResourceFromPackage(Resource res, PackageInformation packageInfo) throws FHIRException; 413 414 /** 415 * Inform the cache about package dependencies. This can be used to help resolve references 416 * 417 * Note that the cache doesn't load dependencies 418 * 419 * @param packageInfo 420 */ 421 public void cachePackage(PackageInformation packageInfo); 422 423 // -- profile services --------------------------------------------------------- 424 425 /** 426 * @return a list of the resource names defined for this version 427 */ 428 public List<String> getResourceNames(); 429 public List<String> getResourceNames(FhirPublication fhirVersion); 430 /** 431 * @return a set of the resource names defined for this version 432 */ 433 public Set<String> getResourceNamesAsSet(); 434 public Set<String> getResourceNamesAsSet(FhirPublication fhirVersion); 435 436 // -- Terminology services ------------------------------------------------------ 437 438 /** 439 * Set the expansion parameters passed through the terminology server when txServer calls are made 440 * 441 * Note that the Validation Options override these when they are specified on validateCode 442 */ 443 public Parameters getExpansionParameters(); 444 445 /** 446 * Get the expansion parameters passed through the terminology server when txServer calls are made 447 * 448 * Note that the Validation Options override these when they are specified on validateCode 449 */ 450 public void setExpansionParameters(Parameters expParameters); 451 452 // these are the terminology services used internally by the tools 453 /** 454 * Find the code system definition for the nominated system uri. 455 * return null if there isn't one (then the tool might try 456 * supportsSystem) 457 * 458 * This is a short cut for fetchResource(CodeSystem.class...) 459 * 460 * @param system 461 * @return 462 */ 463 public CodeSystem fetchCodeSystem(String system); 464 public CodeSystem fetchCodeSystem(String system, String version); 465 public CodeSystem fetchCodeSystem(String system, FhirPublication fhirVersion); 466 public CodeSystem fetchCodeSystem(String system, String version, FhirPublication fhirVersion); 467 468 /** 469 * Like fetchCodeSystem, except that the context will find any CodeSysetm supplements and merge them into the 470 * @param system 471 * @return 472 */ 473 public CodeSystem fetchSupplementedCodeSystem(String system); 474 public CodeSystem fetchSupplementedCodeSystem(String system, String version); 475 public CodeSystem fetchSupplementedCodeSystem(String system, FhirPublication fhirVersion); 476 public CodeSystem fetchSupplementedCodeSystem(String system, String version, FhirPublication fhirVersion); 477 478 /** 479 * True if the underlying terminology service provider will do 480 * expansion and code validation for the terminology. Corresponds 481 * to the extension 482 * 483 * http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system 484 * 485 * in the Conformance resource 486 * 487 * Not that not all supported code systems have an available CodeSystem resource 488 * 489 * @param system 490 * @return 491 * @throws Exception 492 */ 493 @Deprecated 494 public boolean supportsSystem(String system) throws TerminologyServiceException; 495 @Deprecated 496 public boolean supportsSystem(String system, FhirPublication fhirVersion) throws TerminologyServiceException; 497 498 /** 499 * return the System Support Information for the server that serves the specified code system 500 * @param system 501 * @param version 502 * @return 503 */ 504 public SystemSupportInformation getTxSupportInfo(String system, String version); 505 public SystemSupportInformation getTxSupportInfo(String system); 506 507 /** 508 * ValueSet Expansion - see $expand 509 * 510 * @param source 511 * @return 512 */ 513 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical); 514 515 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, int count); 516 517 /** 518 * ValueSet Expansion - see $expand 519 * 520 * @param source 521 * @return 522 */ 523 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, boolean incompleteOk); 524 525 public ValueSetExpansionOutcome expandVS(String uri, boolean cacheOk, boolean heiarchical, int count); // set to 0 to just check existence 526 527 /** 528 * ValueSet Expansion - see $expand, but resolves the binding first 529 * 530 * @param source 531 * @return 532 * @throws FHIRException 533 */ 534 public ValueSetExpansionOutcome expandVS(Resource src, ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException; 535 536 /** 537 * Value set expanion inside the internal expansion engine - used 538 * for references to supported system (see "supportsSystem") for 539 * which there is no value set. 540 * 541 * @param inc 542 * @return 543 * @throws FHIRException 544 */ 545 ValueSetExpansionOutcome expandVS(ITerminologyOperationDetails opCtxt, ConceptSetComponent inc, boolean hierarchical, boolean noInactive) throws TerminologyServiceException; 546 547 /** 548 * get/set the locale used when creating messages 549 * 550 * todo: what's the difference? 551 * 552 * @return 553 */ 554 Locale getLocale(); 555 void setLocale(Locale locale); 556 557 @Deprecated 558 void setValidationMessageLanguage(Locale locale); 559 560 /** 561 * Access to the contexts internationalised error messages 562 * 563 * For rendering internationalization, see RenderingContext 564 * 565 * @param theMessage 566 * @param theMessageArguments 567 * @return 568 */ 569 String formatMessage(String theMessage, Object... theMessageArguments); 570 String formatMessagePlural(Integer pluralNum, String theMessage, Object... theMessageArguments); 571 572 /** 573 * Validation of a code - consult the terminology infrstructure and/or service 574 * to see whether it is known. If known, return a description of it 575 * 576 * note: always return a result, with either an error or a code description 577 * 578 * corresponds to 2 terminology service calls: $validate-code and $lookup 579 * 580 * in this case, the system will be inferred from the value set. It's an error to call this one without the value set 581 * 582 * @param options - validation options (required) 583 * @param code he code to validate (required) 584 * @param vs the applicable valueset (required) 585 * @return 586 */ 587 public ValidationResult validateCode(ValidationOptions options, String code, ValueSet vs); 588 589 /** 590 * Validation of a code - consult the terminology infrstructure and/or service 591 * to see whether it is known. If known, return a description of it 592 * 593 * note: always return a result, with either an error or a code description 594 * 595 * corresponds to 2 terminology service calls: $validate-code and $lookup 596 * 597 * @param options - validation options (required) 598 * @param system - equals Coding.system (required) 599 * @param code - equals Coding.code (required) 600 * @param display - equals Coding.display (optional) 601 * @return 602 */ 603 public ValidationResult validateCode(ValidationOptions options, String system, String version, String code, String display); 604 605 /** 606 * Validation of a code - consult the terminology infrstructure and/or service 607 * to see whether it is known. If known, return a description of it 608 * 609 * note: always return a result, with either an error or a code description 610 * 611 * corresponds to 2 terminology service calls: $validate-code and $lookup 612 * 613 * @param options - validation options (required) 614 * @param system - equals Coding.system (required) 615 * @param code - equals Coding.code (required) 616 * @param display - equals Coding.display (optional) 617 * @param vs the applicable valueset (optional) 618 * @return 619 */ 620 public ValidationResult validateCode(ValidationOptions options, String system, String version, String code, String display, ValueSet vs); 621 622 /** 623 * Validation of a code - consult the terminology infrstructure and/or service 624 * to see whether it is known. If known, return a description of it 625 * 626 * note: always return a result, with either an error or a code description 627 * 628 * corresponds to 2 terminology service calls: $validate-code and $lookup 629 * 630 * Note that this doesn't validate binding strength (e.g. is just text allowed?) 631 * 632 * @param options - validation options (required) 633 * @param code - CodeableConcept to validate 634 * @param vs the applicable valueset (optional) 635 * @return 636 */ 637 public ValidationResult validateCode(ValidationOptions options, CodeableConcept code, ValueSet vs); 638 639 /** 640 * Validation of a code - consult the terminology infrstructure and/or service 641 * to see whether it is known. If known, return a description of it 642 * 643 * note: always return a result, with either an error or a code description 644 * 645 * corresponds to 2 terminology service calls: $validate-code and $lookup 646 * 647 * in this case, the system will be inferred from the value set. It's an error to call this one without the value set 648 * 649 * @param options - validation options (required) 650 * @param code - Coding to validate 651 * @param vs the applicable valueset (optional) 652 * @return 653 */ 654 public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs); 655 656 /** 657 * See comments in ValidationContextCarrier. This is called when there might be additional value sets etc 658 * available in the context, but we don't want to pre-process them. 659 * 660 * @param options 661 * @param code 662 * @param vs 663 * @param ctxt 664 * @return 665 */ 666 public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs, ValidationContextCarrier ctxt); 667 668 /** 669 * Batch validate code - reduce latency and do a bunch of codes in a single server call. 670 * Each is the same as a validateCode 671 * 672 * @param options 673 * @param codes 674 * @param vs 675 */ 676 public void validateCodeBatch(ValidationOptions options, List<? extends CodingValidationRequest> codes, ValueSet vs, boolean passVS); 677 public OperationOutcome validateTxResource(ValidationOptions options, Resource resource); 678 679 // todo: figure these out 680 public Map<String, NamingSystem> getNSUrlMap(); 681 682 public void setLogger(@Nonnull org.hl7.fhir.r5.context.ILoggingService logger); 683 public org.hl7.fhir.r5.context.ILoggingService getLogger(); 684 685 public boolean isNoTerminologyServer(); 686 public Set<String> getCodeSystemsUsed(); 687 public int getClientRetryCount(); 688 public IWorkerContext setClientRetryCount(int value); 689 690 public TimeTracker clock(); 691 692 /** 693 * This is a short cut for fetchResource(StructureDefinition.class, ...) 694 * but it accepts a typename - that is, it resolves based on StructureDefinition.type 695 * or StructureDefinition.url. This only resolves to http://hl7.org/fhir/StructureDefinition/{typename} 696 * 697 * @param typeName 698 * @return 699 */ 700 public StructureDefinition fetchTypeDefinition(String typeName); 701 public StructureDefinition fetchTypeDefinition(String typeName, FhirPublication fhirVersion); 702 703 /** 704 * This finds all the structure definitions that have the given typeName 705 * 706 * @param typeName 707 * @return 708 */ 709 public List<StructureDefinition> fetchTypeDefinitions(String n); 710 public List<StructureDefinition> fetchTypeDefinitions(String n, FhirPublication fhirVersion); 711 712 /** 713 * return whether type is primitive type. This is called a lot, and needs a high performance implementation 714 * @param type 715 * @return 716 */ 717 public boolean isPrimitiveType(String type); 718 719 /** 720 * return whether type is data type. This is called a lot, and needs a high performance implementation 721 * @param type 722 * @return 723 */ 724 public boolean isDataType(String type); 725 726 /** 727 * Returns a set of keys that can be used to get binaries from this context. 728 * The binaries come from the loaded packages (mostly the pubpack) 729 * 730 * @return a set of binaries or null 731 */ 732 public Set<String> getBinaryKeysAsSet(); 733 734 /** 735 * Returns true if this worker context contains a binary for this key. 736 * 737 * @param binaryKey 738 * @return true if binary is available for this key 739 */ 740 public boolean hasBinaryKey(String binaryKey); 741 742 /** 743 * Returns the binary for the key 744 * @param binaryKey 745 * @return 746 */ 747 public byte[] getBinaryForKey(String binaryKey); 748 749 /* 750 * Todo: move these loaders out to IWorkerContextManager 751 * 752 */ 753 /** 754 * Load relevant resources of the appropriate types (as specified by the loader) from the nominated package 755 * 756 * note that the package system uses lazy loading; the loader will be called later when the classes that use the context need the relevant resource 757 * 758 * @param pi - the package to load 759 * @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version). 760 * @return the number of resources loaded 761 */ 762 int loadFromPackage(NpmPackage pi, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException; 763 764 /** 765 * Load relevant resources of the appropriate types (as specified by the loader) from the nominated package 766 * 767 * note that the package system uses lazy loading; the loader will be called later when the classes that use the context need the relevant resource 768 * 769 * This method also loads all the packages that the package depends on (recursively) 770 * 771 * @param pi - the package to load 772 * @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version). 773 * @param pcm - used to find and load additional dependencies 774 * @return the number of resources loaded 775 */ 776 int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException; 777 778 public boolean hasPackage(String id, String ver); 779 public boolean hasPackage(PackageInformation pack); 780 public PackageInformation getPackage(String id, String ver); 781 public PackageInformation getPackageForUrl(String url); 782 783 public IWorkerContextManager.IPackageLoadingTracker getPackageTracker(); 784 public IWorkerContext setPackageTracker(IWorkerContextManager.IPackageLoadingTracker packageTracker); 785 786 public String getSpecUrl(); 787 788 public PEBuilder getProfiledElementBuilder(PEElementPropertiesPolicy elementProps, boolean fixedProps); 789 790 public boolean isForPublication(); 791 public void setForPublication(boolean value); 792 793 /** 794 * 795 * @param oid 796 * @param resourceType - null to search on all resource types 797 * @return 798 */ 799 public OIDSummary urlsForOid(String oid, String resourceType); 800 801 /** 802 * this first does a fetch resource, and if nothing is found, looks in the 803 * terminology eco-system for a matching definition for the resource 804 * 805 * usually used (and so far only tested with) ValueSet.class 806 * 807 * @param value 808 * @return 809 */ 810 public <T extends Resource> T findTxResource(Class<T> class_, String canonical, Resource sourceOfReference); 811 public <T extends Resource> T findTxResource(Class<T> class_, String canonical); 812 public <T extends Resource> T findTxResource(Class<T> class_, String canonical, String version); 813 814 /** 815 * ask the terminology system whether parent subsumes child. 816 * 817 * @return true if it does, false if it doesn't, and null if it's not know whether it does 818 */ 819 public Boolean subsumes(ValidationOptions options, Coding parent, Coding child); 820 821 public boolean isServerSideSystem(String url); 822 823 class SystemSupportInformation { 824 // whether the ssytem(/version) is supported 825 @Getter 826 private boolean supported; 827 828 // the server that supports the system(/version) 829 // maybe null for some systems where we never consult any server 830 @Getter 831 private String server; 832 833 // if the server supports it, the set of test cases the server claims to pass (or null) 834 @Getter 835 private String testVersion; 836 837 public SystemSupportInformation(boolean supported, String server, String testVersion) { 838 this.supported = supported; 839 this.server = server; 840 this.testVersion = testVersion; 841 } 842 843 public SystemSupportInformation(boolean supported) { 844 this.supported = supported; 845 } 846 } 847}