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