001package org.hl7.fhir.instance.utils; 002 003import java.net.URISyntaxException; 004import java.util.ArrayList; 005import java.util.Calendar; 006import java.util.Date; 007import java.util.HashMap; 008import java.util.List; 009import java.util.Map; 010 011import org.hl7.fhir.instance.client.FeedFormat; 012import org.hl7.fhir.instance.client.IFHIRClient; 013import org.hl7.fhir.instance.client.ResourceFormat; 014import org.hl7.fhir.instance.model.Bundle; 015import org.hl7.fhir.instance.model.ConceptMap; 016import org.hl7.fhir.instance.model.Conformance; 017import org.hl7.fhir.instance.model.DataElement; 018import org.hl7.fhir.instance.model.ElementDefinition.TypeRefComponent; 019import org.hl7.fhir.instance.model.OperationOutcome; 020import org.hl7.fhir.instance.model.Parameters; 021import org.hl7.fhir.instance.model.Questionnaire; 022import org.hl7.fhir.instance.model.Resource; 023import org.hl7.fhir.instance.model.SearchParameter; 024import org.hl7.fhir.instance.model.StructureDefinition; 025import org.hl7.fhir.instance.model.ValueSet; 026import org.hl7.fhir.instance.model.ValueSet.ConceptDefinitionComponent; 027import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent; 028import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent; 029import org.hl7.fhir.instance.terminologies.ITerminologyServices; 030import org.hl7.fhir.instance.terminologies.ValueSetExpander.ValueSetExpansionOutcome; 031 032/* 033 * private static Map<String, StructureDefinition> loadProfiles() throws Exception { 034 HashMap<String, StructureDefinition> result = new HashMap<String, StructureDefinition>(); 035 Bundle feed = new XmlParser().parseGeneral(new FileInputStream(PROFILES)).getFeed(); 036 for (AtomEntry<? extends Resource> e : feed.getEntryList()) { 037 if (e.getReference() instanceof StructureDefinition) { 038 result.put(e.getId(), (StructureDefinition) e.getReference()); 039 } 040 } 041 return result; 042 } 043 private static final String TEST_PROFILE = "C:\\work\\org.hl7.fhir\\build\\publish\\namespace.profile.xml"; 044 private static final String PROFILES = "C:\\work\\org.hl7.fhir\\build\\publish\\profiles-resources.xml"; 045 igtodo - things to add: 046 - version 047 - list of resource names 048 */ 049public class WorkerContext implements NameResolver { 050 051 private ITerminologyServices terminologyServices = new NullTerminologyServices(); 052 private IFHIRClient client = new NullClient(); 053 private Map<String, ValueSet> codeSystems = new HashMap<String, ValueSet>(); 054 private Map<String, DataElement> dataElements = new HashMap<String, DataElement>(); 055 private Map<String, ValueSet> valueSets = new HashMap<String, ValueSet>(); 056 private Map<String, ConceptMap> maps = new HashMap<String, ConceptMap>(); 057 private Map<String, StructureDefinition> profiles = new HashMap<String, StructureDefinition>(); 058 private Map<String, SearchParameter> searchParameters = new HashMap<String, SearchParameter>(); 059 private Map<String, StructureDefinition> extensionDefinitions = new HashMap<String, StructureDefinition>(); 060 private String version; 061 private List<String> resourceNames = new ArrayList<String>(); 062 private Map<String, Questionnaire> questionnaires = new HashMap<String, Questionnaire>(); 063 064 public WorkerContext() { 065 super(); 066 } 067 068 public WorkerContext(ITerminologyServices conceptLocator, IFHIRClient client, Map<String, ValueSet> codeSystems, 069 Map<String, ValueSet> valueSets, Map<String, ConceptMap> maps, Map<String, StructureDefinition> profiles) { 070 super(); 071 if (conceptLocator != null) 072 this.terminologyServices = conceptLocator; 073 if (client != null) 074 this.client = client; 075 if (codeSystems != null) 076 this.codeSystems = codeSystems; 077 if (valueSets != null) 078 this.valueSets = valueSets; 079 if (maps != null) 080 this.maps = maps; 081 if (profiles != null) 082 this.profiles = profiles; 083 } 084 085 public ITerminologyServices getTerminologyServices() { 086 return terminologyServices; 087 } 088 089 public boolean hasClient() { 090 return !(client == null || client instanceof NullClient); 091 } 092 093 public IFHIRClient getClient() { 094 return client; 095 } 096 097 public Map<String, ValueSet> getCodeSystems() { 098 return codeSystems; 099 } 100 101 public Map<String, DataElement> getDataElements() { 102 return dataElements; 103 } 104 105 public Map<String, ValueSet> getValueSets() { 106 return valueSets; 107 } 108 109 public Map<String, ConceptMap> getMaps() { 110 return maps; 111 } 112 113 public StructureDefinition getProfile(String theId) { 114 return profiles.get(theId); 115 } 116 117 /** 118 * @deprecated Use {@link #getProfile(String)} instead 119 */ 120 @Deprecated 121 public Map<String, StructureDefinition> getProfiles() { 122 return profiles; 123 } 124 125 public Map<String, StructureDefinition> getExtensionDefinitions() { 126 return extensionDefinitions; 127 } 128 129 public Map<String, Questionnaire> getQuestionnaires() { 130 return questionnaires; 131 } 132 133 public WorkerContext setTerminologyServices(ITerminologyServices terminologyServices) { 134 this.terminologyServices = terminologyServices; 135 return this; 136 } 137 138 public WorkerContext clone(IFHIRClient altClient) { 139 WorkerContext res = new WorkerContext(terminologyServices, null, codeSystems, valueSets, maps, profiles); 140 res.extensionDefinitions.putAll(extensionDefinitions); 141 res.version = version; 142 res.client = altClient; 143 return res; 144 } 145 146 public void seeExtensionDefinition(String url, StructureDefinition ed) throws Exception { 147 if (extensionDefinitions.get(ed.getUrl()) != null) 148 throw new Exception("duplicate extension definition: " + ed.getUrl()); 149 extensionDefinitions.put(ed.getId(), ed); 150 extensionDefinitions.put(url, ed); 151 extensionDefinitions.put(ed.getUrl(), ed); 152 } 153 154 public void seeQuestionnaire(String url, Questionnaire theQuestionnaire) throws Exception { 155 if (questionnaires.get(theQuestionnaire.getId()) != null) 156 throw new Exception("duplicate extension definition: "+theQuestionnaire.getId()); 157 questionnaires.put(theQuestionnaire.getId(), theQuestionnaire); 158 questionnaires.put(url, theQuestionnaire); 159 } 160 161 public void seeValueSet(String url, ValueSet vs) throws Exception { 162 if (valueSets.containsKey(vs.getUrl())) 163 throw new Exception("Duplicate Profile "+vs.getUrl()); 164 valueSets.put(vs.getId(), vs); 165 valueSets.put(url, vs); 166 valueSets.put(vs.getUrl(), vs); 167 if (vs.hasCodeSystem()) { 168 codeSystems.put(vs.getCodeSystem().getSystem().toString(), vs); 169 } 170 } 171 172 public void seeProfile(String url, StructureDefinition p) { 173 if (profiles.containsKey(p.getUrl())) 174 throw new IllegalArgumentException("Duplicate Profile "+p.getUrl()); 175 profiles.put(p.getId(), p); 176 profiles.put(url, p); 177 profiles.put(p.getUrl(), p); 178 } 179 180 public class NullClient implements IFHIRClient { 181 182 @Override 183 public VersionInfo getVersions() { 184 throw new Error("call to NullClient"); 185 } 186 187 @Override 188 public IFHIRClient initialize(String baseServiceUrl) throws URISyntaxException { 189 throw new Error("call to NullClient"); 190 } 191 192 @Override 193 public void initialize(String baseServiceUrl, int recordCount) throws URISyntaxException { 194 throw new Error("call to NullClient"); 195 } 196 197 @Override 198 public void setPreferredResourceFormat(ResourceFormat resourceFormat) { 199 throw new Error("call to NullClient"); 200 } 201 202 @Override 203 public String getPreferredResourceFormat() { 204 throw new Error("call to NullClient"); 205 } 206 207 @Override 208 public void setPreferredFeedFormat(FeedFormat feedFormat) { 209 throw new Error("call to NullClient"); 210 } 211 212 @Override 213 public String getPreferredFeedFormat() { 214 throw new Error("call to NullClient"); 215 } 216 217 @Override 218 public int getMaximumRecordCount() { 219 throw new Error("call to NullClient"); 220 } 221 222 @Override 223 public void setMaximumRecordCount(int recordCount) { 224 throw new Error("call to NullClient"); 225 } 226 227 @Override 228 public Conformance getConformanceStatement() { 229 throw new Error("call to NullClient"); 230 } 231 232 @Override 233 public Conformance getConformanceStatement(boolean useOptionsVerb) { 234 throw new Error("call to NullClient"); 235 } 236 237 @Override 238 public <T extends Resource> T read(Class<T> resource, String id) { 239 throw new Error("call to NullClient"); 240 } 241 242 @Override 243 public <T extends Resource> T vread(Class<T> resource, String id, String versionid) { 244 throw new Error("call to NullClient"); 245 } 246 247 @Override 248 public <T extends Resource> T update(Class<T> resourceClass, T resource, String id) { 249 throw new Error("call to NullClient"); 250 } 251 252 @Override 253 public <T extends Resource> boolean delete(Class<T> resourceClass, String id) { 254 throw new Error("call to NullClient"); 255 } 256 257 @Override 258 public <T extends Resource> OperationOutcome create(Class<T> resourceClass, T resource) { 259 throw new Error("call to NullClient"); 260 } 261 262 @Override 263 public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass, String id) { 264 throw new Error("call to NullClient"); 265 } 266 267 @Override 268 public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass, String id) { 269 throw new Error("call to NullClient"); 270 } 271 272 @Override 273 public <T extends Resource> Bundle history(Class<T> resource, String id) { 274 throw new Error("call to NullClient"); 275 } 276 277 @Override 278 public <T extends Resource> Bundle history(Calendar lastUpdate, Class<T> resourceClass) { 279 throw new Error("call to NullClient"); 280 } 281 282 @Override 283 public <T extends Resource> Bundle history(Date lastUpdate, Class<T> resourceClass) { 284 throw new Error("call to NullClient"); 285 } 286 287 @Override 288 public <T extends Resource> Bundle history(Class<T> resourceClass) { 289 throw new Error("call to NullClient"); 290 } 291 292 @Override 293 public <T extends Resource> Bundle history(Calendar lastUpdate) { 294 throw new Error("call to NullClient"); 295 } 296 297 @Override 298 public <T extends Resource> Bundle history(Date lastUpdate) { 299 throw new Error("call to NullClient"); 300 } 301 302 @Override 303 public <T extends Resource> Bundle history() { 304 throw new Error("call to NullClient"); 305 } 306 307 @Override 308 public <T extends Resource> OperationOutcome validate(Class<T> resourceClass, T resource, String id) { 309 throw new Error("call to NullClient"); 310 } 311 312 @Override 313 public <T extends Resource> Bundle search(Class<T> resourceClass, Map<String, String> params) { 314 throw new Error("call to NullClient"); 315 } 316 317 @Override 318 public <T extends Resource> Bundle searchPost(Class<T> resourceClass, T resource, Map<String, String> params) { 319 throw new Error("call to NullClient"); 320 } 321 322 @Override 323 public Bundle transaction(Bundle batch) { 324 throw new Error("call to NullClient"); 325 } 326 327 @Override 328 public Bundle fetchFeed(String url) { 329 throw new Error("call to NullClient"); 330 } 331 332 @Override 333 public ValueSet expandValueset(ValueSet source) throws Exception { 334 throw new Error("call to NullClient"); 335 } 336 337 @Override 338 public <T extends Resource> Parameters operateType(Class<T> resourceClass, String name, Parameters params) { 339 throw new Error("call to NullClient"); 340 } 341 342 @Override 343 public Conformance getConformanceStatementQuick() { 344 throw new Error("call to NullClient"); 345 } 346 347 @Override 348 public Conformance getConformanceStatementQuick(boolean useOptionsVerb) { 349 throw new Error("call to NullClient"); 350 } 351 352 @Override 353 public String getAddress() { 354 throw new Error("call to NullClient"); 355 } 356 357 } 358 359 public StructureDefinition getExtensionStructure(StructureDefinition context, String url) throws Exception { 360 if (url.startsWith("#")) { 361 throw new Error("Contained extensions not done yet"); 362 } else { 363 if (url.contains("#")) 364 url = url.substring(0, url.indexOf("#")); 365 StructureDefinition res = extensionDefinitions.get(url); 366 if (res == null) 367 res = profiles.get(url); 368 if (res == null) 369 return null; 370 if (res.getSnapshot() == null || res.getSnapshot().getElement().isEmpty()) 371 throw new Exception("no snapshot on extension for url " + url); 372 return res; 373 } 374 } 375 376 public class NullTerminologyServices implements ITerminologyServices { 377 378 @Override 379 public boolean supportsSystem(String system) { 380 return false; 381 } 382 383 @Override 384 public ConceptDefinitionComponent getCodeDefinition(String system, String code) { 385 throw new Error("call to NullTerminologyServices"); 386 } 387 388 @Override 389 public ValidationResult validateCode(String system, String code, String display) { 390 throw new Error("call to NullTerminologyServices"); 391 } 392 393 @Override 394 public ValueSetExpansionComponent expandVS(ConceptSetComponent inc) throws Exception { 395 throw new Error("call to NullTerminologyServices"); 396 } 397 398 @Override 399 public boolean checkVS(ConceptSetComponent vsi, String system, String code) { 400 throw new Error("call to NullTerminologyServices"); 401 } 402 403 @Override 404 public boolean verifiesSystem(String system) { 405 return false; 406 } 407 408 @Override 409 public ValueSetExpansionOutcome expand(ValueSet vs) { 410 throw new Error("call to NullTerminologyServices"); 411 } 412 413 } 414 415 public String getVersion() { 416 return version; 417 } 418 419 public void setVersion(String version) { 420 this.version = version; 421 } 422 423 @Override 424 public boolean isResource(String name) { 425 if (resourceNames.contains(name)) 426 return true; 427 StructureDefinition sd = profiles.get("http://hl7.org/fhir/StructureDefinition/" + name); 428 return sd != null && (sd.getBase().endsWith("Resource") || sd.getBase().endsWith("DomainResource")); 429 } 430 431 public List<String> getResourceNames() { 432 return resourceNames; 433 } 434 435 public StructureDefinition getTypeStructure(TypeRefComponent type) { 436 if (type.hasProfile()) 437 return profiles.get(type.getProfile().get(0).getValue()); 438 else 439 return profiles.get(type.getCode()); 440 } 441 442 public Map<String, SearchParameter> getSearchParameters() { 443 return searchParameters; 444 } 445 446}