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