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