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