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