001package org.hl7.fhir.dstu2016may.utils;
002
003import org.hl7.fhir.dstu2016may.formats.IParser;
004import org.hl7.fhir.dstu2016may.formats.ParserType;
005import org.hl7.fhir.dstu2016may.model.*;
006import org.hl7.fhir.dstu2016may.model.CodeSystem.ConceptDefinitionComponent;
007import org.hl7.fhir.dstu2016may.model.ValueSet.ConceptSetComponent;
008import org.hl7.fhir.dstu2016may.model.ValueSet.ValueSetExpansionComponent;
009import org.hl7.fhir.dstu2016may.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
010import org.hl7.fhir.dstu2016may.validation.IResourceValidator;
011import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
012
013import java.util.List;
014import java.util.Set;
015
016
017/**
018 * This is the standard interface used for access to underlying FHIR
019 * services through the tools and utilities provided by the reference
020 * implementation. 
021 * 
022 * The functionality it provides is 
023 *  - get access to parsers, validators, narrative builders etc
024 *    (you can't create these directly because they need access 
025 *    to the right context for their information)
026 *    
027 *  - find resources that the tools need to carry out their tasks
028 *  
029 *  - provide access to terminology services they need. 
030 *    (typically, these terminology service requests are just
031 *    passed through to the local implementation's terminology
032 *    service)    
033 *  
034 * @author Grahame
035 */
036public interface IWorkerContext {
037
038  // -- Parsers (read and write instances) ----------------------------------------
039
040  /**
041   * Get a parser to read/write instances. Use the defined type (will be extended 
042   * as further types are added, though the only currently anticipate type is RDF)
043   * 
044   * XML/JSON - the standard renderers
045   * XHTML - render the narrative only (generate it if necessary)
046   * 
047   * @param type
048   * @return
049   */
050  public IParser getParser(ParserType type);
051
052  /**
053   * Get a parser to read/write instances. Determine the type 
054   * from the stated type. Supported value for type:
055   * - the recommended MIME types
056   * - variants of application/xml and application/json
057   * - _format values xml, json
058   * 
059   * @param type
060   * @return
061   */   
062  public IParser getParser(String type);
063
064  /**
065   * Get a JSON parser
066   * 
067   * @return
068   */
069  public IParser newJsonParser();
070
071  /**
072   * Get an XML parser
073   * 
074   * @return
075   */
076  public IParser newXmlParser();
077
078  /**
079   * Get a validator that can check whether a resource is valid 
080   * 
081   * @return a prepared generator
082   * @
083   */
084  public IResourceValidator newValidator();
085
086  // -- resource fetchers ---------------------------------------------------
087
088  /**
089   * Find an identified resource. The most common use of this is to access the the 
090   * standard conformance resources that are part of the standard - structure 
091   * definitions, value sets, concept maps, etc.
092   * 
093   * Also, the narrative generator uses this, and may access any kind of resource
094   * 
095   * The URI is called speculatively for things that might exist, so not finding 
096   * a matching resouce, return null, not an error
097   * 
098   * The URI can have one of 3 formats:
099   *  - a full URL e.g. http://acme.org/fhir/ValueSet/[id]
100   *  - a relative URL e.g. ValueSet/[id]
101   *  - a logical id e.g. [id]
102   *  
103   * It's an error if the second form doesn't agree with class_. It's an 
104   * error if class_ is null for the last form
105   * 
106   * @return
107   * @throws Exception
108   */
109  public <T extends Resource> T fetchResource(Class<T> class_, String uri);
110
111  /**
112   * find whether a resource is available. 
113   * 
114   * Implementations of the interface can assume that if hasResource ruturns 
115   * true, the resource will usually be fetched subsequently
116   * 
117   * @param class_
118   * @param uri
119   * @return
120   */
121  public <T extends Resource> boolean hasResource(Class<T> class_, String uri);
122
123  // -- profile services ---------------------------------------------------------
124  
125  public List<String> getResourceNames();
126  public List<StructureDefinition> allStructures();
127  
128  // -- Terminology services ------------------------------------------------------
129
130  // these are the terminology services used internally by the tools
131  /**
132   * Find the code system definition for the nominated system uri. 
133   * return null if there isn't one (then the tool might try 
134   * supportsSystem)
135   * 
136   * @param system
137   * @return
138   */
139  public CodeSystem fetchCodeSystem(String system);
140
141  /**
142   * True if the underlying terminology service provider will do 
143   * expansion and code validation for the terminology. Corresponds
144   * to the extension 
145   * 
146   * http://hl7.org/fhir/StructureDefinition/conformance-supported-system
147   * 
148   * in the Conformance resource
149   * 
150   * @param system
151   * @return
152   */
153  public boolean supportsSystem(String system);
154
155  /**
156   * find concept maps for a source
157   * @param url
158   * @return
159   */
160  public List<ConceptMap> findMapsForSource(String url);  
161
162  /**
163   * ValueSet Expansion - see $expand
164   *  
165   * @param source
166   * @return
167   */
168  public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk);
169  
170  /**
171   * Value set expanion inside the internal expansion engine - used 
172   * for references to supported system (see "supportsSystem") for
173   * which there is no value set. 
174   * 
175   * @param inc
176   * @return
177   */
178  public ValueSetExpansionComponent expandVS(ConceptSetComponent inc);
179  
180  public class ValidationResult {
181    private ConceptDefinitionComponent definition;
182    private IssueSeverity severity;
183    private String message;
184    
185    public ValidationResult(IssueSeverity severity, String message) {
186      this.severity = severity;
187      this.message = message;
188    }
189    
190    public ValidationResult(ConceptDefinitionComponent definition) {
191      this.definition = definition;
192    }
193
194    public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) {
195      this.severity = severity;
196      this.message = message;
197      this.definition = definition;
198    }
199    
200    public boolean isOk() {
201      return definition != null;
202    }
203
204    public String getDisplay() {
205      //Don't want question-marks as that stops something more useful from being displayed, such as the code
206      //return definition == null ? "??" : definition.getDisplay();
207      return definition == null ? null : definition.getDisplay();
208    }
209
210    public ConceptDefinitionComponent asConceptDefinition() {
211      return definition;
212    }
213
214    public IssueSeverity getSeverity() {
215      return severity;
216    }
217
218    public String getMessage() {
219      return message;
220    }
221  }
222
223  /**
224   * Validation of a code - consult the terminology service 
225   * to see whether it is known. If known, return a description of it
226   * 
227   *  note: always return a result, with either an error or a code description
228   *  
229   * corresponds to 2 terminology service calls: $validate-code and $lookup
230   * 
231   * @param system
232   * @param code
233   * @param display
234   * @return
235   */
236  public ValidationResult validateCode(String system, String code, String display);
237
238  /**
239   * Validation of a code - consult the terminology service 
240   * to see whether it is known. If known, return a description of it
241   * Also, check whether it's in the provided value set
242   * 
243   * note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
244   *  
245   * corresponds to 2 terminology service calls: $validate-code and $lookup
246   * 
247   * @param system
248   * @param code
249   * @param display
250   * @return
251   */
252  public ValidationResult validateCode(String system, String code, String display, ValueSet vs);
253  public ValidationResult validateCode(Coding code, ValueSet vs);
254  public ValidationResult validateCode(CodeableConcept code, ValueSet vs);
255  
256  /**
257   * Validation of a code - consult the terminology service 
258   * to see whether it is known. If known, return a description of it
259   * Also, check whether it's in the provided value set fragment (for supported systems with no value set definition)
260   * 
261   * note: always return a result, with either an error or a code description, or both (e.g. known code, but not in the value set)
262   *  
263   * corresponds to 2 terminology service calls: $validate-code and $lookup
264   * 
265   * @param system
266   * @param code
267   * @param display
268   * @return
269   */
270  public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi);
271
272  /**
273   * returns the recommended tla for the type 
274   * 
275   * @param name
276   * @return
277   */
278  public String getAbbreviation(String name);
279
280  // return a set of types that have tails
281  public Set<String> typeTails();
282
283        public String oid2Uri(String code);
284
285
286}