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