001package org.hl7.fhir.dstu3.context; 002 003/*- 004 * #%L 005 * org.hl7.fhir.dstu3 006 * %% 007 * Copyright (C) 2014 - 2019 Health Level 7 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023 024import java.util.List; 025import java.util.Set; 026 027import org.hl7.fhir.dstu3.formats.IParser; 028import org.hl7.fhir.dstu3.formats.ParserType; 029import org.hl7.fhir.dstu3.model.CodeSystem; 030import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent; 031import org.hl7.fhir.dstu3.model.CodeableConcept; 032import org.hl7.fhir.dstu3.model.Coding; 033import org.hl7.fhir.dstu3.model.ConceptMap; 034import org.hl7.fhir.dstu3.model.ExpansionProfile; 035import org.hl7.fhir.dstu3.model.MetadataResource; 036import org.hl7.fhir.dstu3.model.Resource; 037import org.hl7.fhir.dstu3.model.StructureDefinition; 038import org.hl7.fhir.dstu3.model.ValueSet; 039import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; 040import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent; 041import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.TerminologyServiceErrorClass; 042import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome; 043import org.hl7.fhir.dstu3.utils.INarrativeGenerator; 044import org.hl7.fhir.dstu3.utils.IResourceValidator; 045import org.hl7.fhir.exceptions.FHIRException; 046import org.hl7.fhir.exceptions.TerminologyServiceException; 047import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 048 049 050/** 051 * This is the standard interface used for access to underlying FHIR 052 * services through the tools and utilities provided by the reference 053 * implementation. 054 * 055 * The functionality it provides is 056 * - get access to parsers, validators, narrative builders etc 057 * (you can't create these directly because they need access 058 * to the right context for their information) 059 * 060 * - find resources that the tools need to carry out their tasks 061 * 062 * - provide access to terminology services they need. 063 * (typically, these terminology service requests are just 064 * passed through to the local implementation's terminology 065 * service) 066 * 067 * @author Grahame 068 */ 069public interface IWorkerContext { 070 071 /** 072 * Get the versions of the definitions loaded in context 073 * @return 074 */ 075 public String getVersion(); 076 077 // -- Parsers (read and write instances) ---------------------------------------- 078 079 080 /** 081 * Get a parser to read/write instances. Use the defined type (will be extended 082 * as further types are added, though the only currently anticipate type is RDF) 083 * 084 * XML/JSON - the standard renderers 085 * XHTML - render the narrative only (generate it if necessary) 086 * 087 * @param type 088 * @return 089 */ 090 public IParser getParser(ParserType type); 091 092 /** 093 * Get a parser to read/write instances. Determine the type 094 * from the stated type. Supported value for type: 095 * - the recommended MIME types 096 * - variants of application/xml and application/json 097 * - _format values xml, json 098 * 099 * @param type 100 * @return 101 */ 102 public IParser getParser(String type); 103 104 /** 105 * Get a JSON parser 106 * 107 * @return 108 */ 109 public IParser newJsonParser(); 110 111 /** 112 * Get an XML parser 113 * 114 * @return 115 */ 116 public IParser newXmlParser(); 117 118 /** 119 * Get a generator that can generate narrative for the instance 120 * 121 * @return a prepared generator 122 */ 123 public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath); 124 125 /** 126 * Get a validator that can check whether a resource is valid 127 * 128 * @return a prepared generator 129 * @throws FHIRException 130 * @ 131 */ 132 public IResourceValidator newValidator() throws FHIRException; 133 134 // -- resource fetchers --------------------------------------------------- 135 136 /** 137 * Find an identified resource. The most common use of this is to access the the 138 * standard conformance resources that are part of the standard - structure 139 * definitions, value sets, concept maps, etc. 140 * 141 * Also, the narrative generator uses this, and may access any kind of resource 142 * 143 * The URI is called speculatively for things that might exist, so not finding 144 * a matching resouce, return null, not an error 145 * 146 * The URI can have one of 3 formats: 147 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 148 * - a relative URL e.g. ValueSet/[id] 149 * - a logical id e.g. [id] 150 * 151 * It's an error if the second form doesn't agree with class_. It's an 152 * error if class_ is null for the last form 153 * 154 * @param resource 155 * @param Reference 156 * @return 157 * @throws FHIRException 158 * @throws Exception 159 */ 160 public <T extends Resource> T fetchResource(Class<T> class_, String uri); 161 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException; 162 163 /** 164 * find whether a resource is available. 165 * 166 * Implementations of the interface can assume that if hasResource ruturns 167 * true, the resource will usually be fetched subsequently 168 * 169 * @param class_ 170 * @param uri 171 * @return 172 */ 173 public <T extends Resource> boolean hasResource(Class<T> class_, String uri); 174 175 // -- profile services --------------------------------------------------------- 176 177 public List<String> getResourceNames(); 178 public Set<String> getResourceNamesAsSet(); 179 public List<String> getTypeNames(); 180 public List<StructureDefinition> allStructures(); 181 public List<MetadataResource> allConformanceResources(); 182 183 // -- Terminology services ------------------------------------------------------ 184 185 public ExpansionProfile getExpansionProfile(); 186 public void setExpansionProfile(ExpansionProfile expProfile); 187 188 // these are the terminology services used internally by the tools 189 /** 190 * Find the code system definition for the nominated system uri. 191 * return null if there isn't one (then the tool might try 192 * supportsSystem) 193 * 194 * @param system 195 * @return 196 */ 197 public CodeSystem fetchCodeSystem(String system); 198 199 /** 200 * True if the underlying terminology service provider will do 201 * expansion and code validation for the terminology. Corresponds 202 * to the extension 203 * 204 * http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system 205 * 206 * in the Conformance resource 207 * 208 * @param system 209 * @return 210 * @throws Exception 211 */ 212 public boolean supportsSystem(String system) throws TerminologyServiceException; 213 214 /** 215 * find concept maps for a source 216 * @param url 217 * @return 218 */ 219 public List<ConceptMap> findMapsForSource(String url); 220 221 /** 222 * ValueSet Expansion - see $expand 223 * 224 * @param source 225 * @return 226 */ 227 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical); 228 229 /** 230 * Value set expanion inside the internal expansion engine - used 231 * for references to supported system (see "supportsSystem") for 232 * which there is no value set. 233 * 234 * @param inc 235 * @return 236 * @throws FHIRException 237 */ 238 public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heiarchical) throws TerminologyServiceException; 239 240 public class ValidationResult { 241 private ConceptDefinitionComponent definition; 242 private IssueSeverity severity; 243 private String message; 244 private TerminologyServiceErrorClass errorClass; 245 246 public ValidationResult(IssueSeverity severity, String message) { 247 this.severity = severity; 248 this.message = message; 249 } 250 251 public ValidationResult(ConceptDefinitionComponent definition) { 252 this.definition = definition; 253 } 254 255 public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) { 256 this.severity = severity; 257 this.message = message; 258 this.definition = definition; 259 } 260 261 public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) { 262 this.severity = severity; 263 this.message = message; 264 this.errorClass = errorClass; 265 } 266 267 public boolean isOk() { 268 return definition != null; 269 } 270 271 public String getDisplay() { 272// We don't want to return question-marks because that prevents something more useful from being displayed (e.g. the code) if there's no display value 273// return definition == null ? "??" : definition.getDisplay(); 274 return definition == null ? null : definition.getDisplay(); 275 } 276 277 public ConceptDefinitionComponent asConceptDefinition() { 278 return definition; 279 } 280 281 public IssueSeverity getSeverity() { 282 return severity; 283 } 284 285 public String getMessage() { 286 return message; 287 } 288 289 public boolean IsNoService() { 290 return errorClass == TerminologyServiceErrorClass.NOSERVICE; 291 } 292 293 public TerminologyServiceErrorClass getErrorClass() { 294 return errorClass; 295 } 296 297 298 } 299 300 /** 301 * Validation of a code - consult the terminology service 302 * to see whether it is known. If known, return a description of it 303 * 304 * note: always return a result, with either an error or a code description 305 * 306 * corresponds to 2 terminology service calls: $validate-code and $lookup 307 * 308 * @param system 309 * @param code 310 * @param display 311 * @return 312 */ 313 public ValidationResult validateCode(String system, String code, String display); 314 315 /** 316 * Validation of a code - consult the terminology service 317 * to see whether it is known. If known, return a description of it 318 * Also, check whether it's in the provided value set 319 * 320 * 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) 321 * 322 * corresponds to 2 terminology service calls: $validate-code and $lookup 323 * 324 * @param system 325 * @param code 326 * @param display 327 * @return 328 */ 329 public ValidationResult validateCode(String system, String code, String display, ValueSet vs); 330 public ValidationResult validateCode(Coding code, ValueSet vs); 331 public ValidationResult validateCode(CodeableConcept code, ValueSet vs); 332 333 /** 334 * Validation of a code - consult the terminology service 335 * to see whether it is known. If known, return a description of it 336 * Also, check whether it's in the provided value set fragment (for supported systems with no value set definition) 337 * 338 * 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) 339 * 340 * corresponds to 2 terminology service calls: $validate-code and $lookup 341 * 342 * @param system 343 * @param code 344 * @param display 345 * @return 346 */ 347 public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi); 348 349 /** 350 * returns the recommended tla for the type 351 * 352 * @param name 353 * @return 354 */ 355 public String getAbbreviation(String name); 356 357 // return a set of types that have tails 358 public Set<String> typeTails(); 359 360 public String oid2Uri(String code); 361 362 public boolean hasCache(); 363 364 public interface ILoggingService { 365 public enum LogCategory { 366 PROGRESS, TX, INIT, CONTEXT, HTML 367 } 368 public void logMessage(String message); // status messages, always display 369 public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging 370 } 371 372 public void setLogger(ILoggingService logger); 373 374 public boolean isNoTerminologyServer(); 375 public StructureDefinition fetchTypeDefinition(String typeName); 376 377}