
001package org.hl7.fhir.dstu3.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 032 033 034import java.util.List; 035import java.util.Locale; 036import java.util.Set; 037 038import org.hl7.fhir.dstu3.formats.IParser; 039import org.hl7.fhir.dstu3.formats.ParserType; 040import org.hl7.fhir.dstu3.model.*; 041import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent; 042import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; 043import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent; 044import org.hl7.fhir.exceptions.FHIRException; 045import org.hl7.fhir.exceptions.TerminologyServiceException; 046import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 047 048 049/** 050 * This is the standard interface used for access to underlying FHIR 051 * services through the tools and utilities provided by the reference 052 * implementation. 053 * 054 * The functionality it provides is 055 * - get access to parsers, validators, narrative builders etc 056 * (you can't create these directly because they need access 057 * to the right context for their information) 058 * 059 * - find resources that the tools need to carry out their tasks 060 * 061 * - provide access to terminology services they need. 062 * (typically, these terminology service requests are just 063 * passed through to the local implementation's terminology 064 * service) 065 * 066 * @author Grahame 067 */ 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 // -- resource fetchers --------------------------------------------------- 119 120 /** 121 * Find an identified resource. The most common use of this is to access the the 122 * standard conformance resources that are part of the standard - structure 123 * definitions, value sets, concept maps, etc. 124 * 125 * Also, the narrative generator uses this, and may access any kind of resource 126 * 127 * The URI is called speculatively for things that might exist, so not finding 128 * a matching resouce, return null, not an error 129 * 130 * The URI can have one of 3 formats: 131 * - a full URL e.g. http://acme.org/fhir/ValueSet/[id] 132 * - a relative URL e.g. ValueSet/[id] 133 * - a logical id e.g. [id] 134 * 135 * It's an error if the second form doesn't agree with class_. It's an 136 * error if class_ is null for the last form 137 * 138 * @param resource 139 * @param Reference 140 * @return 141 * @throws FHIRException 142 * @throws Exception 143 */ 144 public <T extends Resource> T fetchResource(Class<T> class_, String uri); 145 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException; 146 147 /** 148 * find whether a resource is available. 149 * 150 * Implementations of the interface can assume that if hasResource ruturns 151 * true, the resource will usually be fetched subsequently 152 * 153 * @param class_ 154 * @param uri 155 * @return 156 */ 157 public <T extends Resource> boolean hasResource(Class<T> class_, String uri); 158 159 // -- profile services --------------------------------------------------------- 160 161 public List<String> getResourceNames(); 162 public Set<String> getResourceNamesAsSet(); 163 public List<String> getTypeNames(); 164 public List<StructureDefinition> allStructures(); 165 public List<MetadataResource> allConformanceResources(); 166 167 // -- Terminology services ------------------------------------------------------ 168 169 public ExpansionProfile getExpansionProfile(); 170 public void setExpansionProfile(ExpansionProfile expProfile); 171 172 // these are the terminology services used internally by the tools 173 /** 174 * Find the code system definition for the nominated system uri. 175 * return null if there isn't one (then the tool might try 176 * supportsSystem) 177 * 178 * @param system 179 * @return 180 */ 181 public CodeSystem fetchCodeSystem(String system); 182 183 /** 184 * True if the underlying terminology service provider will do 185 * expansion and code validation for the terminology. Corresponds 186 * to the extension 187 * 188 * http://hl7.org/fhir/StructureDefinition/capabilitystatement-supported-system 189 * 190 * in the Conformance resource 191 * 192 * @param system 193 * @return 194 * @throws Exception 195 */ 196 public boolean supportsSystem(String system) throws TerminologyServiceException; 197 198 /** 199 * find concept maps for a source 200 * @param url 201 * @return 202 */ 203 public List<ConceptMap> findMapsForSource(String url); 204 205 /** 206 * ValueSet Expansion - see $expand 207 * 208 * @param source 209 * @return 210 */ 211 public ValueSetExpansionOutcome expandVS(ValueSet source, boolean cacheOk, boolean heiarchical); 212 213 /** 214 * Value set expanion inside the internal expansion engine - used 215 * for references to supported system (see "supportsSystem") for 216 * which there is no value set. 217 * 218 * @param inc 219 * @return 220 * @throws FHIRException 221 */ 222 public ValueSetExpansionComponent expandVS(ConceptSetComponent inc, boolean heiarchical) throws TerminologyServiceException; 223 224 Locale getLocale(); 225 226 void setLocale(Locale locale); 227 228 String formatMessage(String theMessage, Object... theMessageArguments); 229 230 void setValidationMessageLanguage(Locale locale); 231 232 public class ValidationResult { 233 private ConceptDefinitionComponent definition; 234 private IssueSeverity severity; 235 private String message; 236 private TerminologyServiceErrorClass errorClass; 237 238 public ValidationResult(IssueSeverity severity, String message) { 239 this.severity = severity; 240 this.message = message; 241 } 242 243 public ValidationResult(ConceptDefinitionComponent definition) { 244 this.definition = definition; 245 } 246 247 public ValidationResult(IssueSeverity severity, String message, ConceptDefinitionComponent definition) { 248 this.severity = severity; 249 this.message = message; 250 this.definition = definition; 251 } 252 253 public ValidationResult(IssueSeverity severity, String message, TerminologyServiceErrorClass errorClass) { 254 this.severity = severity; 255 this.message = message; 256 this.errorClass = errorClass; 257 } 258 259 public boolean isOk() { 260 return definition != null; 261 } 262 263 public String getDisplay() { 264// 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 265// return definition == null ? "??" : definition.getDisplay(); 266 return definition == null ? null : definition.getDisplay(); 267 } 268 269 public ConceptDefinitionComponent asConceptDefinition() { 270 return definition; 271 } 272 273 public IssueSeverity getSeverity() { 274 return severity; 275 } 276 277 public String getMessage() { 278 return message; 279 } 280 281 public boolean IsNoService() { 282 return errorClass == TerminologyServiceErrorClass.NOSERVICE; 283 } 284 285 public TerminologyServiceErrorClass getErrorClass() { 286 return errorClass; 287 } 288 289 290 291 public Parameters getOrMakeParameters() { 292 Parameters p = new Parameters(); 293 p.addParameter().setName("result").setValue(new BooleanType(isOk())); 294 if (getMessage() != null) { 295 p.addParameter().setName("message").setValue(new StringType(getMessage())); 296 } 297 if (getDisplay() != null) { 298 p.addParameter().setName("display").setValue(new StringType(getDisplay())); 299 } 300 return p; 301 } 302 } 303 304 /** 305 * Validation of a code - consult the terminology service 306 * to see whether it is known. If known, return a description of it 307 * 308 * note: always return a result, with either an error or a code description 309 * 310 * corresponds to 2 terminology service calls: $validate-code and $lookup 311 * 312 * @param system 313 * @param code 314 * @param display 315 * @return 316 */ 317 public ValidationResult validateCode(String system, String code, String display); 318 319 /** 320 * Validation of a code - consult the terminology service 321 * to see whether it is known. If known, return a description of it 322 * Also, check whether it's in the provided value set 323 * 324 * 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) 325 * 326 * corresponds to 2 terminology service calls: $validate-code and $lookup 327 * 328 * @param system 329 * @param code 330 * @param display 331 * @return 332 */ 333 public ValidationResult validateCode(String system, String code, String display, ValueSet vs); 334 public ValidationResult validateCode(Coding code, ValueSet vs); 335 public ValidationResult validateCode(CodeableConcept code, ValueSet vs); 336 337 /** 338 * Validation of a code - consult the terminology service 339 * to see whether it is known. If known, return a description of it 340 * Also, check whether it's in the provided value set fragment (for supported systems with no value set definition) 341 * 342 * 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) 343 * 344 * corresponds to 2 terminology service calls: $validate-code and $lookup 345 * 346 * @param system 347 * @param code 348 * @param display 349 * @return 350 */ 351 public ValidationResult validateCode(String system, String code, String display, ConceptSetComponent vsi); 352 353 /** 354 * returns the recommended tla for the type 355 * 356 * @param name 357 * @return 358 */ 359 public String getAbbreviation(String name); 360 361 // return a set of types that have tails 362 public Set<String> typeTails(); 363 364 public String oid2Uri(String code); 365 366 public boolean hasCache(); 367 368 public interface ILoggingService { 369 public enum LogCategory { 370 PROGRESS, TX, INIT, CONTEXT, HTML 371 } 372 public void logMessage(String message); // status messages, always display 373 public void logDebugMessage(LogCategory category, String message); // verbose; only when debugging 374 } 375 376 public void setLogger(ILoggingService logger); 377 378 public boolean isNoTerminologyServer(); 379 public StructureDefinition fetchTypeDefinition(String typeName); 380 381 382 /** 383 * Some value sets are just too big to expand. Instead of an expanded value set, 384 * you get back an interface that can test membership - usually on a server somewhere 385 * 386 * @author Grahame 387 */ 388 public class ValueSetExpansionOutcome { 389 private ValueSet valueset; 390 private Object service; // actually a ValueSetChecker, but we shouldn't need this? 391 private String error; 392 private TerminologyServiceErrorClass errorClass; 393 394 public ValueSetExpansionOutcome(ValueSet valueset) { 395 super(); 396 this.valueset = valueset; 397 this.service = null; 398 this.error = null; 399 } 400 public ValueSetExpansionOutcome(ValueSet valueset, String error, TerminologyServiceErrorClass errorClass) { 401 super(); 402 this.valueset = valueset; 403 this.service = null; 404 this.error = error; 405 this.errorClass = errorClass; 406 } 407 public ValueSetExpansionOutcome(Object service, String error, TerminologyServiceErrorClass errorClass) { 408 super(); 409 this.valueset = null; 410 this.service = service; 411 this.error = error; 412 this.errorClass = errorClass; 413 } 414 public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass) { 415 this.valueset = null; 416 this.service = null; 417 this.error = error; 418 this.errorClass = errorClass; 419 } 420 public ValueSet getValueset() { 421 return valueset; 422 } 423 public Object getService() { 424 return service; 425 } 426 public String getError() { 427 return error; 428 } 429 public TerminologyServiceErrorClass getErrorClass() { 430 return errorClass; 431 } 432 433 public boolean isOk() { 434 return error == null; 435 } 436 } 437 438 public enum TerminologyServiceErrorClass { 439 UNKNOWN, NOSERVICE, SERVER_ERROR, VALUESET_UNSUPPORTED; 440 441 public boolean isInfrastructure() { 442 return this == NOSERVICE || this == SERVER_ERROR || this == VALUESET_UNSUPPORTED; 443 } 444 } 445}