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.Parameters;
062import org.hl7.fhir.r5.model.Resource;
063import org.hl7.fhir.r5.model.StructureDefinition;
064import org.hl7.fhir.r5.model.StructureMap;
065import org.hl7.fhir.r5.model.ValueSet;
066import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
067import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
068import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
069import org.hl7.fhir.r5.utils.validation.IResourceValidator;
070import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
071import org.hl7.fhir.utilities.TimeTracker;
072import org.hl7.fhir.utilities.TranslationServices;
073import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
074import org.hl7.fhir.utilities.npm.NpmPackage;
075import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
076import org.hl7.fhir.utilities.validation.ValidationMessage;
077import org.hl7.fhir.utilities.validation.ValidationOptions;
078
079import com.google.gson.JsonSyntaxException;
080
081import javax.annotation.Nonnull;
082
083
084/**
085 * This is the standard interface used for access to underlying FHIR
086 * services through the tools and utilities provided by the reference
087 * implementation. 
088 * 
089 * The functionality it provides is 
090 *  - get access to parsers, validators, narrative builders etc
091 *    (you can't create these directly because they need access 
092 *    to the right context for their information)
093 *    
094 *  - find resources that the tools need to carry out their tasks
095 *  
096 *  - provide access to terminology services they need. 
097 *    (typically, these terminology service requests are just
098 *    passed through to the local implementation's terminology
099 *    service)    
100 *  
101 * @author Grahame
102 */
103public interface IWorkerContext {
104
105  public interface IPackageLoadingTracker {
106    public void packageLoaded(String pid, String version);
107  }
108
109  public class CodingValidationRequest {
110    private Coding coding;
111    private ValidationResult result;
112    private CacheToken cacheToken;
113    
114    public CodingValidationRequest(Coding coding) {
115      super();
116      this.coding = coding;
117    }
118
119    public ValidationResult getResult() {
120      return result;
121    }
122
123    public void setResult(ValidationResult result) {
124      this.result = result;
125    }
126
127    public Coding getCoding() {
128      return coding;
129    }
130
131    public boolean hasResult() {
132      return result != null;
133    }
134
135    /**
136     * internal logic; external users of batch validation should ignore this property
137     * 
138     * @return
139     */
140    public CacheToken getCacheToken() {
141      return cacheToken;
142    }
143
144    /**
145     * internal logic; external users of batch validation should ignore this property
146     * 
147     * @param cacheToken
148     */
149    public void setCacheToken(CacheToken cacheToken) {
150      this.cacheToken = cacheToken;
151    }
152    
153    
154  }
155
156  public class PackageVersion {
157    private String id;
158    private String version;
159    private Date date;
160    
161    public PackageVersion(String source, Date date) {
162      if (source == null) {
163        throw new Error("Source cannot be null");
164      }
165      if (!source.contains("#")) {
166        throw new FHIRException("Source ");        
167      }
168      id = source.substring(0, source.indexOf("#"));
169      version = source.substring(source.indexOf("#")+1);
170      this.date = date;
171    }
172    public PackageVersion(String id, String version, Date date) {
173      super();
174      this.id = id;
175      this.version = version;
176      this.date = date;
177    }
178    
179    public String getId() {
180      return id;
181    }
182    public String getVersion() {
183      return version;
184    }
185    public boolean isExamplesPackage() {
186      boolean b = id.startsWith("hl7.fhir.") && id.endsWith(".examples");
187      return b;
188    }
189    @Override
190    public String toString() {
191      return id+"#"+version;
192    }
193    public Date getDate() {
194      return date;
195    }
196    public boolean isHTO() {
197      boolean b = id.startsWith("hl7.terminology.r");
198      return b;
199    }
200    
201  }
202
203  public class PackageDetails extends PackageVersion {
204    private String name;
205    private String canonical;
206    private String web;
207    
208    public PackageDetails(String id, String version, String name, String canonical, String web, Date date) {
209      super(id, version, date);
210      this.name = name;
211      this.canonical = canonical;
212      this.web = web;
213    }
214    public String getName() {
215      return name;
216    }
217    public String getCanonical() {
218      return canonical;
219    }
220    public String getWeb() {
221      return web;
222    }
223    
224  }
225
226  public interface ICanonicalResourceLocator {
227    void findResource(Object caller, String url); // if it can be found, put it in the context
228  }
229  
230  public interface IContextResourceLoader {
231    /** 
232     * @return List of the resource types that should be loaded
233     */
234    String[] getTypes();
235    
236    /**
237     * Request to actually load the resources and do whatever is required
238     *  
239     * @param stream
240     * @param isJson
241     * @return A bundle because some single resources become multiple resources after loading
242     * @throws FHIRException
243     * @throws IOException
244     */
245    Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException;
246    
247    /**
248     * Load a single resources (lazy load)
249     * 
250     * @param stream
251     * @param isJson
252     * @return
253     * @throws FHIRException - throw this if you a single resource can't be returned - can't lazy load in this circumstance   
254     * @throws IOException
255     */
256    Resource loadResource(InputStream stream, boolean isJson) throws FHIRException, IOException;
257    
258    /** 
259     * get the path for references to this resource.
260     * @param resource
261     * @return null if not tracking paths
262     */
263    String getResourcePath(Resource resource);
264
265    /**
266     * called when a mew package is being loaded
267     * 
268     * this is called by loadPacakgeAndDependencies when a new package is loaded
269     * @param npm
270     * @return
271     * @throws IOException 
272     * @throws JsonSyntaxException 
273     */
274    IContextResourceLoader getNewLoader(NpmPackage npm) throws JsonSyntaxException, IOException;   
275  }
276
277  /**
278   * Get the versions of the definitions loaded in context
279   * @return
280   */
281  public String getVersion();
282  
283  /**
284   * return the link to the base of the specification for the loaded version e.g. http://hl7.org/fhir/R4
285   */
286  public String getSpecUrl();
287  
288  // get the UCUM service (might not be available)
289  public UcumService getUcumService();
290  
291  // -- Parsers (read and write instances) ----------------------------------------
292
293
294  /**
295   * Get a parser to read/write instances. Use the defined type (will be extended 
296   * as further types are added, though the only currently anticipate type is RDF)
297   * 
298   * XML/JSON - the standard renderers
299   * XHTML - render the narrative only (generate it if necessary)
300   * 
301   * @param type
302   * @return
303   */
304  public IParser getParser(ParserType type);
305
306  /**
307   * Get a parser to read/write instances. Determine the type 
308   * from the stated type. Supported value for type:
309   * - the recommended MIME types
310   * - variants of application/xml and application/json
311   * - _format values xml, json
312   * 
313   * @param type
314   * @return
315   */   
316  public IParser getParser(String type);
317
318  /**
319   * Get a JSON parser
320   * 
321   * @return
322   */
323  public IParser newJsonParser();
324
325  /**
326   * Get an XML parser
327   * 
328   * @return
329   */
330  public IParser newXmlParser();
331
332  /**
333   * Get a validator that can check whether a resource is valid 
334   * 
335   * @return a prepared generator
336   * @throws FHIRException 
337   * @
338   */
339  public IResourceValidator newValidator() throws FHIRException;
340
341  // -- resource fetchers ---------------------------------------------------
342
343  /**
344   * Find an identified resource. The most common use of this is to access the the 
345   * standard conformance resources that are part of the standard - structure 
346   * definitions, value sets, concept maps, etc.
347   * 
348   * Also, the narrative generator uses this, and may access any kind of resource
349   * 
350   * The URI is called speculatively for things that might exist, so not finding 
351   * a matching resouce, return null, not an error
352   * 
353   * The URI can have one of 3 formats:
354   *  - a full URL e.g. http://acme.org/fhir/ValueSet/[id]
355   *  - a relative URL e.g. ValueSet/[id]
356   *  - a logical id e.g. [id]
357   *  
358   * It's an error if the second form doesn't agree with class_. It's an 
359   * error if class_ is null for the last form
360   * 
361   * @param resource
362   * @param Reference
363   * @return
364   * @throws FHIRException 
365   * @throws Exception
366   */
367  public <T extends Resource> T fetchResource(Class<T> class_, String uri);
368  public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException;
369  public <T extends Resource> T fetchResource(Class<T> class_, String uri, String version);
370
371  /** has the same functionality as fetchResource, but passes in information about the source of the 
372   * reference (this may affect resolution of version)
373   *  
374   * @param <T>
375   * @param class_
376   * @param uri
377   * @param canonicalForSource
378   * @return
379   */
380  public <T extends Resource> T fetchResource(Class<T> class_, String uri, CanonicalResource canonicalForSource);
381
382  /**
383   * Variation of fetchResource when you have a string type, and don't need the right class
384   * 
385   * The URI can have one of 3 formats:
386   *  - a full URL e.g. http://acme.org/fhir/ValueSet/[id]
387   *  - a relative URL e.g. ValueSet/[id]
388   *  - a logical id e.g. [id]
389   *  
390   * if type == null, the URI can't be a simple logical id
391   * 
392   * @param type
393   * @param uri
394   * @return
395   */
396  public Resource fetchResourceById(String type, String uri);
397  
398  /**
399   * find whether a resource is available. 
400   * 
401   * Implementations of the interface can assume that if hasResource ruturns 
402   * true, the resource will usually be fetched subsequently
403   * 
404   * @param class_
405   * @param uri
406   * @return
407   */
408  public <T extends Resource> boolean hasResource(Class<T> class_, String uri);
409
410  /**
411   * cache a resource for later retrieval using fetchResource.
412   * 
413   * Note that various context implementations will have their own ways of loading
414   * rseources, and not all need implement cacheResource.
415   * 
416   * If the resource is loaded out of a package, call cacheResourceFromPackage instead
417   * @param res
418   * @throws FHIRException 
419   */
420  public void cacheResource(Resource res) throws FHIRException;
421  
422  /**
423   * cache a resource for later retrieval using fetchResource.
424   * 
425   * The package information is used to help manage the cache internally, and to 
426   * help with reference resolution. Packages should be define using cachePackage (but don't have to be)
427   *    
428   * Note that various context implementations will have their own ways of loading
429   * rseources, and not all need implement cacheResource
430   * 
431   * @param res
432   * @throws FHIRException 
433   */
434  public void cacheResourceFromPackage(Resource res, PackageVersion packageDetails) throws FHIRException;
435  
436  /**
437   * Inform the cache about package dependencies. This can be used to help resolve references
438   * 
439   * Note that the cache doesn't load dependencies
440   *  
441   * @param packageInfo
442   */
443  public void cachePackage(PackageDetails packageDetails, List<PackageVersion> dependencies);
444  
445  // -- profile services ---------------------------------------------------------
446  
447  /**
448   * @return a list of the resource names defined for this version
449   */
450  public List<String> getResourceNames();
451  /**
452   * @return a set of the resource names defined for this version
453   */
454  public Set<String> getResourceNamesAsSet();
455
456  /**
457   * @return a list of the resource names that are canonical resources defined for this version
458   */
459  public List<String> getCanonicalResourceNames();
460  
461  /**
462   * @return a list of the resource and type names defined for this version
463   */
464  public List<String> getTypeNames();
465  
466  /**
467   * @return a list of all structure definitions, with snapshots generated (if possible)
468   */
469  public List<StructureDefinition> allStructures();
470  
471  /**
472   * @return a list of all structure definitions, without trying to generate snapshots
473   */
474  public List<StructureDefinition> getStructures();
475  
476  /**
477   * @return a list of all conformance resources
478   */
479  public List<CanonicalResource> allConformanceResources();
480  
481  /**
482   * Given a structure definition, generate a snapshot (or regenerate it)
483   * @param p
484   * @throws DefinitionException
485   * @throws FHIRException
486   */
487  public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException;
488  public void generateSnapshot(StructureDefinition mr, boolean ifLogical);
489  
490  // -- Terminology services ------------------------------------------------------
491
492  /**
493   * Set the expansion parameters passed through the terminology server when txServer calls are made
494   * 
495   * Note that the Validation Options override these when they are specified on validateCode
496   */
497  public Parameters getExpansionParameters();
498
499  /**
500   * Get the expansion parameters passed through the terminology server when txServer calls are made
501   * 
502   * Note that the Validation Options override these when they are specified on validateCode
503   */
504  public void setExpansionProfile(Parameters expParameters);
505
506  // these are the terminology services used internally by the tools
507  /**
508   * Find the code system definition for the nominated system uri. 
509   * return null if there isn't one (then the tool might try 
510   * supportsSystem)
511   * 
512   * @param system
513   * @return
514   */
515  public CodeSystem fetchCodeSystem(String system);
516  public CodeSystem fetchCodeSystem(String system, String version);
517
518  /**
519   * True if the underlying terminology service provider will do 
520   * expansion and code validation for the terminology. Corresponds
521   * to the extension 
522   * 
523   * http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system
524   * 
525   * in the Conformance resource
526   * 
527   * @param system
528   * @return
529   * @throws Exception 
530   */
531  public boolean supportsSystem(String system) throws TerminologyServiceException;
532
533  /**
534   * find concept maps for a source
535   * @param url
536   * @return
537   * @throws FHIRException 
538   */
539  public List<ConceptMap> findMapsForSource(String url) throws FHIRException;  
540
541  /**
542   * ValueSet Expansion - see $expand
543   *  
544   * @param source
545   * @return
546   */
547  public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical);
548  
549  /**
550   * ValueSet Expansion - see $expand
551   *  
552   * @param source
553   * @return
554   */
555  public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical, boolean incompleteOk);
556  
557  /**
558   * ValueSet Expansion - see $expand, but resolves the binding first
559   *  
560   * @param source
561   * @return
562   * @throws FHIRException 
563   */
564  public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException;
565  
566  /**
567   * Value set expanion inside the internal expansion engine - used 
568   * for references to supported system (see "supportsSystem") for
569   * which there is no value set. 
570   * 
571   * @param inc
572   * @return
573   * @throws FHIRException 
574   */
575  ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean hierarchical, boolean noInactive) throws TerminologyServiceException;
576
577  Locale getLocale();
578
579  void setLocale(Locale locale);
580
581  String formatMessage(String theMessage, Object... theMessageArguments);
582
583  void setValidationMessageLanguage(Locale locale);
584
585  class ValidationResult {
586    private ConceptDefinitionComponent definition;
587    private String system;
588    private IssueSeverity severity;
589    private String message;
590    private TerminologyServiceErrorClass errorClass;
591    private String txLink;
592    
593    @Override
594    public String toString() {
595      return "ValidationResult [definition=" + definition + ", system=" + system + ", severity=" + severity + ", message=" + message + ", errorClass="
596          + errorClass + ", txLink=" + txLink + "]";
597    }
598
599    public ValidationResult(IssueSeverity severity, String message) {
600      this.severity = severity;
601      this.message = message;
602    }
603    
604    public ValidationResult(String system, ConceptDefinitionComponent definition) {
605      this.system = system;
606      this.definition = definition;
607    }
608
609    public ValidationResult(IssueSeverity severity, String message, String system, ConceptDefinitionComponent definition) {
610      this.severity = severity;
611      this.message = message;
612      this.system = system;
613      this.definition = definition;
614    }
615    
616    public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) {
617      this.severity = severity;
618      this.message = message;
619      this.errorClass = errorClass;
620    }
621
622    public boolean isOk() {
623      return severity == null || severity == IssueSeverity.INFORMATION || severity == IssueSeverity.WARNING;
624    }
625
626    public String getSystem() {
627      return system;
628    }
629
630    public String getDisplay() {
631      return definition == null ? null : definition.getDisplay();
632    }
633
634    public String getCode() {
635      return definition == null ? null : definition.getCode();
636    }
637
638    public String getDefinition() {
639      return definition == null ? null : definition.getDefinition();
640    }
641
642    public ConceptDefinitionComponent asConceptDefinition() {
643      return definition;
644    }
645
646    public IssueSeverity getSeverity() {
647      return severity;
648    }
649
650    public String getMessage() {
651      return message;
652    }
653
654    public boolean IsNoService() {
655      return errorClass == TerminologyServiceErrorClass.NOSERVICE;
656    }
657
658    public TerminologyServiceErrorClass getErrorClass() {
659      return errorClass;
660    }
661
662    public ValidationResult setSeverity(IssueSeverity severity) {
663      this.severity = severity;
664      return this;
665    }
666
667    public ValidationResult setMessage(String message) {
668      this.message = message;
669      return this;
670    }
671
672    public ValidationResult setErrorClass(TerminologyServiceErrorClass errorClass) {
673      this.errorClass = errorClass;
674      return this;
675    }
676
677    public String getTxLink() {
678      return txLink;
679    }
680
681    public ValidationResult setTxLink(String txLink) {
682      this.txLink = txLink;
683      return this;
684    }
685
686    public boolean hasMessage() {
687      return message != null;
688    }
689    
690    public Coding asCoding() {
691      if (isOk() && definition != null && definition.getCode() != null) {
692        return new Coding(system, definition.getCode(), definition.getDisplay());
693      } else {
694        return null;
695      }
696    }
697  }
698
699  /**
700   * Validation of a code - consult the terminology infrstructure and/or service 
701   * to see whether it is known. If known, return a description of it
702   * 
703   * note: always return a result, with either an error or a code description
704   *  
705   * corresponds to 2 terminology service calls: $validate-code and $lookup
706   * 
707   * in this case, the system will be inferred from the value set. It's an error to call this one without the value set
708   * 
709   * @param options - validation options (required)
710   * @param code he code to validate (required)
711   * @param vs the applicable valueset (required)
712   * @return
713   */
714  public ValidationResult validateCode(ValidationOptions options, String code, ValueSet vs);
715  
716  /**
717   * Validation of a code - consult the terminology infrstructure and/or service 
718   * to see whether it is known. If known, return a description of it
719   * 
720   * note: always return a result, with either an error or a code description
721   *  
722   * corresponds to 2 terminology service calls: $validate-code and $lookup
723   * 
724   * @param options - validation options (required)
725   * @param system - equals Coding.system (required)
726   * @param code - equals Coding.code (required)
727   * @param display - equals Coding.display (optional)
728   * @return
729   */
730  public ValidationResult validateCode(ValidationOptions options, String system, String version, String code, String display);
731  
732  /**
733   * Validation of a code - consult the terminology infrstructure and/or service 
734   * to see whether it is known. If known, return a description of it
735   * 
736   * note: always return a result, with either an error or a code description
737   *  
738   * corresponds to 2 terminology service calls: $validate-code and $lookup
739   * 
740   * @param options - validation options (required)
741   * @param system - equals Coding.system (required)
742   * @param code - equals Coding.code (required)
743   * @param display - equals Coding.display (optional)
744   * @param vs the applicable valueset (optional)
745   * @return
746   */
747  public ValidationResult validateCode(ValidationOptions options, String system, String version, String code, String display, ValueSet vs);
748
749  /**
750   * Validation of a code - consult the terminology infrstructure and/or service 
751   * to see whether it is known. If known, return a description of it
752   * 
753   * note: always return a result, with either an error or a code description
754   *  
755   * corresponds to 2 terminology service calls: $validate-code and $lookup
756   * 
757   * Note that this doesn't validate binding strength (e.g. is just text allowed?)
758   * 
759   * @param options - validation options (required)
760   * @param code - CodeableConcept to validate
761   * @param vs the applicable valueset (optional)
762   * @return
763   */
764  public ValidationResult validateCode(ValidationOptions options, CodeableConcept code, ValueSet vs);
765
766  /**
767   * Validation of a code - consult the terminology infrstructure and/or service 
768   * to see whether it is known. If known, return a description of it
769   * 
770   * note: always return a result, with either an error or a code description
771   *  
772   * corresponds to 2 terminology service calls: $validate-code and $lookup
773   * 
774   * in this case, the system will be inferred from the value set. It's an error to call this one without the value set
775   * 
776   * @param options - validation options (required)
777   * @param code - Coding to validate
778   * @param vs the applicable valueset (optional)
779   * @return
780   */
781  public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs);
782  
783  public ValidationResult validateCode(ValidationOptions options, Coding code, ValueSet vs, ValidationContextCarrier ctxt);
784
785  public void validateCodeBatch(ValidationOptions options, List<? extends CodingValidationRequest> codes, ValueSet vs);
786  
787  /**
788   * returns the recommended tla for the type  (from the structure definitions)
789   * 
790   * @param name
791   * @return
792   */
793  public String getAbbreviation(String name);
794
795
796  /**
797   * translate an OID to a URI (look through known NamingSystems)
798   * @param code
799   * @return
800   */
801        public String oid2Uri(String code);
802        public Map<String, NamingSystem> getNSUrlMap();
803
804        /** 
805         * @return true if the contxt has a terminology caching service internally
806         */
807  public boolean hasCache();
808
809  public interface ILoggingService {
810    public enum LogCategory {
811      INIT, 
812      PROGRESS,
813      TX, 
814      CONTEXT, 
815      GENERATE,
816      HTML 
817    }
818    public void logMessage(String message); // status messages, always display
819    public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging 
820  }
821
822  public void setLogger(@Nonnull ILoggingService logger);
823  public ILoggingService getLogger();
824
825  public boolean isNoTerminologyServer();
826  public Set<String> getCodeSystemsUsed();
827  public TranslationServices translator();
828  public List<StructureMap> listTransforms();
829  public StructureMap getTransform(String url);
830
831  public String getOverrideVersionNs();
832  public void setOverrideVersionNs(String value);
833
834  public StructureDefinition fetchTypeDefinition(String typeName);
835  public StructureDefinition fetchRawProfile(String url);
836  
837  public void setUcumService(UcumService ucumService);
838
839  public String getLinkForUrl(String corePath, String s);
840
841  /**
842   * Returns a set of keys that can be used to get binaries from this context.
843   *
844   * @return a set of binaries or null
845   */
846  public Set<String> getBinaryKeysAsSet();
847
848  /**
849   * Returns true if this worker context contains a binary for this key.
850   *
851   * @param binaryKey
852   * @return true if binary is available for this key
853   */
854  public boolean hasBinaryKey(String binaryKey);
855
856  /**
857   * Returns the binary for the key
858   * @param binaryKey
859   * @return
860   */
861  public byte[] getBinaryForKey(String binaryKey);
862
863  /**
864   * Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
865   * 
866   * 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
867   * 
868   * @param pi - the package to load
869   * @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
870   * @return the number of resources loaded
871   */
872  int loadFromPackage(NpmPackage pi, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException;
873
874  /**
875   * Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
876   * 
877   * 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
878   *
879   * Deprecated - use the simpler method where the types come from the loader.
880   * 
881   * @param pi - the package to load
882   * @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
883   * @param types - which types of resources to load
884   * @return the number of resources loaded
885   */
886  @Deprecated
887  int loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String[] types) throws FileNotFoundException, IOException, FHIRException;
888
889  /**
890   * Load relevant resources of the appropriate types (as specified by the loader) from the nominated package
891   * 
892   * 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
893   *
894   * This method also loads all the packages that the package depends on (recursively)
895   * 
896   * @param pi - the package to load
897   * @param loader - an implemenation of IContextResourceLoader that knows how to read the resources in the package (e.g. for the appropriate version).
898   * @param pcm - used to find and load additional dependencies
899   * @return the number of resources loaded
900   */
901   int loadFromPackageAndDependencies(NpmPackage pi, IContextResourceLoader loader, BasePackageCacheManager pcm) throws FileNotFoundException, IOException, FHIRException;
902
903   public boolean hasPackage(String id, String ver);
904   public boolean hasPackage(PackageVersion pack);
905   public PackageDetails getPackage(PackageVersion pack);
906
907  public int getClientRetryCount();
908  public IWorkerContext setClientRetryCount(int value);
909  
910  public TimeTracker clock();
911  public IPackageLoadingTracker getPackageTracker();
912  public IWorkerContext setPackageTracker(IPackageLoadingTracker packageTracker);
913
914  public PackageVersion getPackageForUrl(String url);
915}