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