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