001package org.hl7.fhir.r4.context; 002 003/*- 004 * #%L 005 * org.hl7.fhir.r4 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.Map; 026import java.util.Set; 027 028import org.fhir.ucum.UcumService; 029import org.hl7.fhir.exceptions.DefinitionException; 030import org.hl7.fhir.exceptions.FHIRException; 031import org.hl7.fhir.exceptions.TerminologyServiceException; 032import org.hl7.fhir.r4.formats.IParser; 033import org.hl7.fhir.r4.formats.ParserType; 034import org.hl7.fhir.r4.model.CodeSystem; 035import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent; 036import org.hl7.fhir.r4.model.CodeableConcept; 037import org.hl7.fhir.r4.model.Coding; 038import org.hl7.fhir.r4.model.ConceptMap; 039import org.hl7.fhir.r4.model.ElementDefinition.ElementDefinitionBindingComponent; 040import org.hl7.fhir.r4.model.MetadataResource; 041import org.hl7.fhir.r4.model.Parameters; 042import org.hl7.fhir.r4.model.Resource; 043import org.hl7.fhir.r4.model.StructureDefinition; 044import org.hl7.fhir.r4.model.StructureMap; 045import org.hl7.fhir.r4.model.ValueSet; 046import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; 047import org.hl7.fhir.r4.terminologies.ValueSetExpander.TerminologyServiceErrorClass; 048import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome; 049import org.hl7.fhir.r4.utils.INarrativeGenerator; 050import org.hl7.fhir.r4.utils.IResourceValidator; 051import org.hl7.fhir.utilities.TerminologyServiceOptions; 052import org.hl7.fhir.utilities.TranslationServices; 053import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 054 055 056/** 057 * This is the standard interface used for access to underlying FHIR 058 * services through the tools and utilities provided by the reference 059 * implementation. 060 * 061 * The functionality it provides is 062 * - get access to parsers, validators, narrative builders etc 063 * (you can't create these directly because they need access 064 * to the right context for their information) 065 * 066 * - find resources that the tools need to carry out their tasks 067 * 068 * - provide access to terminology services they need. 069 * (typically, these terminology service requests are just 070 * passed through to the local implementation's terminology 071 * service) 072 * 073 * @author Grahame 074 */ 075public interface IWorkerContext { 076 077 /** 078 * Get the versions of the definitions loaded in context 079 * @return 080 */ 081 public String getVersion(); 082 083 // get the UCUM service (might not be available) 084 public UcumService getUcumService(); 085 086 // -- Parsers (read and write instances) ---------------------------------------- 087 088 089 /** 090 * Get a parser to read/write instances. Use the defined type (will be extended 091 * as further types are added, though the only currently anticipate type is RDF) 092 * 093 * XML/JSON - the standard renderers 094 * XHTML - render the narrative only (generate it if necessary) 095 * 096 * @param type 097 * @return 098 */ 099 public IParser getParser(ParserType type); 100 101 /** 102 * Get a parser to read/write instances. Determine the type 103 * from the stated type. Supported value for type: 104 * - the recommended MIME types 105 * - variants of application/xml and application/json 106 * - _format values xml, json 107 * 108 * @param type 109 * @return 110 */ 111 public IParser getParser(String type); 112 113 /** 114 * Get a JSON parser 115 * 116 * @return 117 */ 118 public IParser newJsonParser(); 119 120 /** 121 * Get an XML parser 122 * 123 * @return 124 */ 125 public IParser newXmlParser(); 126 127 /** 128 * Get a generator that can generate narrative for the instance 129 * 130 * @return a prepared generator 131 */ 132 public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath); 133 134 /** 135 * Get a validator that can check whether a resource is valid 136 * 137 * @return a prepared generator 138 * @throws FHIRException 139 * @ 140 */ 141 public IResourceValidator newValidator() throws FHIRException; 142 143 // -- resource fetchers --------------------------------------------------- 144 145 /** 146 * Find an identified resource. The most common use of this is to access the the 147 * standard conformance resources that are part of the standard - structure 148 * definitions, value sets, concept maps, etc. 149 * 150 * Also, the narrative generator uses this, and may access any kind of resource 151 * 152 * The URI is called speculatively for things that might exist, so not finding 153 * a matching resouce, return null, not an error 154 * 155 * The URI can have one of 3 formats: 156 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 157 * - a relative URL e.g. ValueSet/[id] 158 * - a logical id e.g. [id] 159 * 160 * It's an error if the second form doesn't agree with class_. It's an 161 * error if class_ is null for the last form 162 * 163 * @param resource 164 * @param Reference 165 * @return 166 * @throws FHIRException 167 * @throws Exception 168 */ 169 public <T extends Resource> T fetchResource(Class<T> class_, String uri); 170 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException; 171 172 /** 173 * Variation of fetchResource when you have a string type, and don't need the right class 174 * 175 * The URI can have one of 3 formats: 176 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 177 * - a relative URL e.g. ValueSet/[id] 178 * - a logical id e.g. [id] 179 * 180 * if type == null, the URI can't be a simple logical id 181 * 182 * @param type 183 * @param uri 184 * @return 185 */ 186 public Resource fetchResourceById(String type, String uri); 187 188 /** 189 * find whether a resource is available. 190 * 191 * Implementations of the interface can assume that if hasResource ruturns 192 * true, the resource will usually be fetched subsequently 193 * 194 * @param class_ 195 * @param uri 196 * @return 197 */ 198 public <T extends Resource> boolean hasResource(Class<T> class_, String uri); 199 200 /** 201 * cache a resource for later retrieval using fetchResource. 202 * 203 * Note that various context implementations will have their own ways of loading 204 * rseources, and not all need implement cacheResource 205 * @param res 206 * @throws FHIRException 207 */ 208 public void cacheResource(Resource res) throws FHIRException; 209 210 // -- profile services --------------------------------------------------------- 211 212 public List<String> getResourceNames(); 213 public Set<String> getResourceNamesAsSet(); 214 public List<String> getTypeNames(); 215 public List<StructureDefinition> allStructures(); // ensure snapshot exists... 216 public List<StructureDefinition> getStructures(); 217 public List<MetadataResource> allConformanceResources(); 218 public void generateSnapshot(StructureDefinition p) throws DefinitionException, FHIRException; 219 220 // -- Terminology services ------------------------------------------------------ 221 222 public Parameters getExpansionParameters(); 223 public void setExpansionProfile(Parameters expParameters); 224 225 // these are the terminology services used internally by the tools 226 /** 227 * Find the code system definition for the nominated system uri. 228 * return null if there isn't one (then the tool might try 229 * supportsSystem) 230 * 231 * @param system 232 * @return 233 */ 234 public CodeSystem fetchCodeSystem(String system); 235 236 /** 237 * True if the underlying terminology service provider will do 238 * expansion and code validation for the terminology. Corresponds 239 * to the extension 240 * 241 * http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system 242 * 243 * in the Conformance resource 244 * 245 * @param system 246 * @return 247 * @throws Exception 248 */ 249 public boolean supportsSystem(String system) throws TerminologyServiceException; 250 251 /** 252 * find concept maps for a source 253 * @param url 254 * @return 255 * @throws FHIRException 256 */ 257 public List<ConceptMap> findMapsForSource(String url) throws FHIRException; 258 259 /** 260 * ValueSet Expansion - see $expand 261 * 262 * @param source 263 * @return 264 */ 265 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical); 266 267 /** 268 * ValueSet Expansion - see $expand, but resolves the binding first 269 * 270 * @param source 271 * @return 272 * @throws FHIRException 273 */ 274 public ValueSetExpansionOutcome expandVS(ElementDefinitionBindingComponent binding, boolean cacheOk, boolean heiarchical) throws FHIRException; 275 /** 276 * Value set expanion inside the internal expansion engine - used 277 * for references to supported system (see "supportsSystem") for 278 * which there is no value set. 279 * 280 * @param inc 281 * @return 282 * @throws FHIRException 283 */ 284 public ValueSetExpansionOutcome expandVS(ConceptSetComponent inc, boolean heirarchical) throws TerminologyServiceException; 285 286 public class ValidationResult { 287 private ConceptDefinitionComponent definition; 288 private IssueSeverity severity; 289 private String message; 290 private TerminologyServiceErrorClass errorClass; 291 private String txLink; 292 293 public ValidationResult(IssueSeverity severity, String message) { 294 this.severity = severity; 295 this.message = message; 296 } 297 298 public ValidationResult(ConceptDefinitionComponent definition) { 299 this.definition = definition; 300 } 301 302 public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) { 303 this.severity = severity; 304 this.message = message; 305 this.definition = definition; 306 } 307 308 public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) { 309 this.severity = severity; 310 this.message = message; 311 this.errorClass = errorClass; 312 } 313 314 public boolean isOk() { 315 return severity == null || severity == IssueSeverity.INFORMATION || severity == IssueSeverity.WARNING; 316 } 317 318 public String getDisplay() { 319// 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 320// return definition == null ? "??" : definition.getDisplay(); 321 return definition == null ? null : definition.getDisplay(); 322 } 323 324 public ConceptDefinitionComponent asConceptDefinition() { 325 return definition; 326 } 327 328 public IssueSeverity getSeverity() { 329 return severity; 330 } 331 332 public String getMessage() { 333 return message; 334 } 335 336 public boolean IsNoService() { 337 return errorClass == TerminologyServiceErrorClass.NOSERVICE; 338 } 339 340 public TerminologyServiceErrorClass getErrorClass() { 341 return errorClass; 342 } 343 344 public ValidationResult setSeverity(IssueSeverity severity) { 345 this.severity = severity; 346 return this; 347 } 348 349 public ValidationResult setMessage(String message) { 350 this.message = message; 351 return this; 352 } 353 354 public String getTxLink() { 355 return txLink; 356 } 357 358 public ValidationResult setTxLink(String txLink) { 359 this.txLink = txLink; 360 return this; 361 } 362 363 364 } 365 366 /** 367 * Validation of a code - consult the terminology service 368 * to see whether it is known. If known, return a description of it 369 * 370 * note: always return a result, with either an error or a code description 371 * 372 * corresponds to 2 terminology service calls: $validate-code and $lookup 373 * 374 * @param system 375 * @param code 376 * @param display 377 * @return 378 */ 379 public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display); 380 381 /** 382 * Validation of a code - consult the terminology service 383 * to see whether it is known. If known, return a description of it 384 * Also, check whether it's in the provided value set 385 * 386 * 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) 387 * 388 * corresponds to 2 terminology service calls: $validate-code and $lookup 389 * 390 * @param system 391 * @param code 392 * @param display 393 * @return 394 */ 395 public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ValueSet vs); 396 public ValidationResult validateCode(TerminologyServiceOptions options, String code, ValueSet vs); 397 public ValidationResult validateCode(TerminologyServiceOptions options, Coding code, ValueSet vs); 398 public ValidationResult validateCode(TerminologyServiceOptions options, CodeableConcept code, ValueSet vs); 399 400 /** 401 * Validation of a code - consult the terminology service 402 * to see whether it is known. If known, return a description of it 403 * Also, check whether it's in the provided value set fragment (for supported systems with no value set definition) 404 * 405 * 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) 406 * 407 * corresponds to 2 terminology service calls: $validate-code and $lookup 408 * 409 * @param system 410 * @param code 411 * @param display 412 * @return 413 */ 414 public ValidationResult validateCode(TerminologyServiceOptions options, String system, String code, String display, ConceptSetComponent vsi); 415 416 /** 417 * returns the recommended tla for the type 418 * 419 * @param name 420 * @return 421 */ 422 public String getAbbreviation(String name); 423 424 // return a set of types that have tails 425 public Set<String> typeTails(); 426 427 public String oid2Uri(String code); 428 429 public boolean hasCache(); 430 431 public interface ILoggingService { 432 public enum LogCategory { 433 PROGRESS, TX, INIT, CONTEXT, HTML 434 } 435 public void logMessage(String message); // status messages, always display 436 public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging 437 } 438 439 public void setLogger(ILoggingService logger); 440 public ILoggingService getLogger(); 441 442 public boolean isNoTerminologyServer(); 443 444 public TranslationServices translator(); 445 public List<StructureMap> listTransforms(); 446 public StructureMap getTransform(String url); 447 448 public String getOverrideVersionNs(); 449 public void setOverrideVersionNs(String value); 450 451 public StructureDefinition fetchTypeDefinition(String typeName); 452 453 public void setUcumService(UcumService ucumService); 454 455 public String getLinkForUrl(String corePath, String s); 456}