
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.io.ByteArrayInputStream; 035import java.io.FileNotFoundException; 036import java.io.IOException; 037import java.io.InputStream; 038import java.net.URISyntaxException; 039import java.util.ArrayList; 040import java.util.Arrays; 041import java.util.Collections; 042import java.util.HashMap; 043import java.util.HashSet; 044import java.util.List; 045import java.util.Map; 046import java.util.Set; 047import java.util.zip.ZipEntry; 048import java.util.zip.ZipInputStream; 049 050import lombok.extern.slf4j.Slf4j; 051import org.apache.commons.io.IOUtils; 052import org.hl7.fhir.dstu3.conformance.ProfileUtilities; 053import org.hl7.fhir.dstu3.conformance.ProfileUtilities.ProfileKnowledgeProvider; 054import org.hl7.fhir.dstu3.context.IWorkerContext.ILoggingService.LogCategory; 055import org.hl7.fhir.dstu3.formats.IParser; 056import org.hl7.fhir.dstu3.formats.JsonParser; 057import org.hl7.fhir.dstu3.formats.ParserType; 058import org.hl7.fhir.dstu3.formats.XmlParser; 059import org.hl7.fhir.dstu3.model.Bundle; 060import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; 061import org.hl7.fhir.dstu3.model.CodeSystem; 062import org.hl7.fhir.dstu3.model.ConceptMap; 063import org.hl7.fhir.dstu3.model.ElementDefinition.ElementDefinitionBindingComponent; 064import org.hl7.fhir.dstu3.model.MetadataResource; 065import org.hl7.fhir.dstu3.model.NamingSystem; 066import org.hl7.fhir.dstu3.model.NamingSystem.NamingSystemIdentifierType; 067import org.hl7.fhir.dstu3.model.NamingSystem.NamingSystemUniqueIdComponent; 068import org.hl7.fhir.dstu3.model.OperationDefinition; 069import org.hl7.fhir.dstu3.model.Questionnaire; 070import org.hl7.fhir.dstu3.model.Resource; 071import org.hl7.fhir.dstu3.model.ResourceType; 072import org.hl7.fhir.dstu3.model.SearchParameter; 073import org.hl7.fhir.dstu3.model.StructureDefinition; 074import org.hl7.fhir.dstu3.model.StructureDefinition.StructureDefinitionKind; 075import org.hl7.fhir.dstu3.model.StructureDefinition.TypeDerivationRule; 076import org.hl7.fhir.dstu3.model.StructureMap; 077import org.hl7.fhir.dstu3.model.StructureMap.StructureMapModelMode; 078import org.hl7.fhir.dstu3.model.StructureMap.StructureMapStructureComponent; 079import org.hl7.fhir.dstu3.model.ValueSet; 080import org.hl7.fhir.dstu3.terminologies.ValueSetExpansionCache; 081import org.hl7.fhir.dstu3.utils.INarrativeGenerator; 082import org.hl7.fhir.dstu3.utils.NarrativeGenerator; 083import org.hl7.fhir.dstu3.utils.client.FHIRToolingClient; 084import org.hl7.fhir.dstu3.utils.validation.IResourceValidator; 085import org.hl7.fhir.exceptions.DefinitionException; 086import org.hl7.fhir.exceptions.FHIRException; 087import org.hl7.fhir.exceptions.FHIRFormatError; 088import org.hl7.fhir.utilities.OIDUtilities; 089import org.hl7.fhir.utilities.Utilities; 090import org.hl7.fhir.utilities.filesystem.CSFileInputStream; 091import org.hl7.fhir.utilities.filesystem.ManagedFileAccess; 092import org.hl7.fhir.utilities.npm.NpmPackage; 093import org.hl7.fhir.utilities.validation.ValidationMessage; 094import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; 095import org.hl7.fhir.utilities.validation.ValidationMessage.Source; 096 097import ca.uhn.fhir.parser.DataFormatException; 098import org.slf4j.MarkerFactory; 099import org.slf4j.event.Level; 100 101/* 102 * This is a stand alone implementation of worker context for use inside a tool. 103 * It loads from the validation package (validation-min.xml.zip), and has a 104 * very light client to connect to an open unauthenticated terminology service 105 */ 106 107@Deprecated 108@Slf4j 109public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerContext, ProfileKnowledgeProvider { 110 111 public interface IContextResourceLoader { 112 Bundle loadBundle(InputStream stream, boolean isJson) throws FHIRException, IOException; 113 } 114 115 public interface IValidatorFactory { 116 IResourceValidator makeValidator(IWorkerContext ctxts) throws FHIRException; 117 } 118 119 // all maps are to the full URI 120 private Map<String, StructureDefinition> structures = new HashMap<String, StructureDefinition>(); 121 private List<NamingSystem> systems = new ArrayList<NamingSystem>(); 122 private Questionnaire questionnaire; 123 private Map<String, byte[]> binaries = new HashMap<String, byte[]>(); 124 private String version; 125 private String revision; 126 private String date; 127 private IValidatorFactory validatorFactory; 128 129 // -- Initializations 130 /** 131 * Load the working context from the validation pack 132 * 133 * @param path 134 * filename of the validation pack 135 * @return 136 * @throws IOException 137 * @throws FileNotFoundException 138 * @throws FHIRException 139 * @throws Exception 140 */ 141 public static SimpleWorkerContext fromPack(String path) throws FileNotFoundException, IOException, FHIRException { 142 SimpleWorkerContext res = new SimpleWorkerContext(); 143 res.loadFromPack(path, null); 144 return res; 145 } 146 147 public static SimpleWorkerContext fromNothing() throws FileNotFoundException, IOException, FHIRException { 148 SimpleWorkerContext res = new SimpleWorkerContext(); 149 return res; 150 } 151 152 public static SimpleWorkerContext fromPackage(NpmPackage pi, boolean allowDuplicates) throws FileNotFoundException, IOException, FHIRException { 153 SimpleWorkerContext res = new SimpleWorkerContext(); 154 res.setAllowLoadingDuplicates(allowDuplicates); 155 res.loadFromPackage(pi, null); 156 return res; 157 } 158 159 public static SimpleWorkerContext fromPackage(NpmPackage pi) throws FileNotFoundException, IOException, FHIRException { 160 SimpleWorkerContext res = new SimpleWorkerContext(); 161 res.loadFromPackage(pi, null); 162 return res; 163 } 164 165 public static SimpleWorkerContext fromPackage(NpmPackage pi, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException { 166 SimpleWorkerContext res = new SimpleWorkerContext(); 167 res.setAllowLoadingDuplicates(true); 168 res.version = pi.getNpm().asString("version"); 169 res.loadFromPackage(pi, loader); 170 return res; 171 } 172 173 public static SimpleWorkerContext fromPack(String path, boolean allowDuplicates) throws FileNotFoundException, IOException, FHIRException { 174 SimpleWorkerContext res = new SimpleWorkerContext(); 175 res.allowLoadingDuplicates = allowDuplicates; 176 res.loadFromPack(path, null); 177 return res; 178 } 179 180 public static SimpleWorkerContext fromPack(String path, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException { 181 SimpleWorkerContext res = new SimpleWorkerContext(); 182 res.loadFromPack(path, loader); 183 return res; 184 } 185 186 public static SimpleWorkerContext fromClassPath() throws IOException, FHIRException { 187 SimpleWorkerContext res = new SimpleWorkerContext(); 188 res.loadFromStream(SimpleWorkerContext.class.getResourceAsStream("validation.json.zip"), null); 189 return res; 190 } 191 192 public static SimpleWorkerContext fromClassPath(String name) throws IOException, FHIRException { 193 InputStream s = SimpleWorkerContext.class.getResourceAsStream("/"+name); 194 SimpleWorkerContext res = new SimpleWorkerContext(); 195 res.loadFromStream(s, null); 196 return res; 197 } 198 199 public static SimpleWorkerContext fromDefinitions(Map<String, byte[]> source) throws IOException, FHIRException { 200 SimpleWorkerContext res = new SimpleWorkerContext(); 201 for (String name : source.keySet()) { 202 res.loadDefinitionItem(name, new ByteArrayInputStream(source.get(name)), null); 203 } 204 return res; 205 } 206 207 public static SimpleWorkerContext fromDefinitions(Map<String, byte[]> source, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException { 208 SimpleWorkerContext res = new SimpleWorkerContext(); 209 for (String name : source.keySet()) { 210 try { 211 res.loadDefinitionItem(name, new ByteArrayInputStream(source.get(name)), loader); 212 } catch (Exception e) { 213 log.error("Error loading "+name+": "+e.getMessage()); 214 throw new FHIRException("Error loading "+name+": "+e.getMessage(), e); 215 } 216 } 217 return res; 218 } 219 private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader) throws IOException, FHIRException { 220 if (name.endsWith(".xml")) 221 loadFromFile(stream, name, loader); 222 else if (name.endsWith(".json")) 223 loadFromFileJson(stream, name, loader); 224 else if (name.equals("version.info")) 225 readVersionInfo(stream); 226 else 227 loadBytes(name, stream); 228 } 229 230 public String connectToTSServer(String url, String userAgent) throws URISyntaxException { 231 txServer = new FHIRToolingClient(url, userAgent); 232 txServer.setTimeout(30000); 233 return txServer.getCapabilitiesStatementQuick().getSoftware().getVersion(); 234 } 235 236 public void loadFromFile(InputStream stream, String name, IContextResourceLoader loader) throws IOException, FHIRException { 237 Resource f; 238 try { 239 if (loader != null) 240 f = loader.loadBundle(stream, false); 241 else { 242 XmlParser xml = new XmlParser(); 243 f = xml.parse(stream); 244 } 245 } catch (DataFormatException e1) { 246 throw new org.hl7.fhir.exceptions.FHIRFormatError("Error parsing "+name+":" +e1.getMessage(), e1); 247 } catch (Exception e1) { 248 throw new org.hl7.fhir.exceptions.FHIRFormatError("Error parsing "+name+":" +e1.getMessage(), e1); 249 } 250 if (f instanceof Bundle) { 251 Bundle bnd = (Bundle) f; 252 for (BundleEntryComponent e : bnd.getEntry()) { 253 if (e.getFullUrl() == null) { 254 logContextDebugMessage("unidentified resource in " + name+" (no fullUrl)"); 255 } 256 seeResource(e.getFullUrl(), e.getResource()); 257 } 258 } else if (f instanceof MetadataResource) { 259 MetadataResource m = (MetadataResource) f; 260 seeResource(m.getUrl(), m); 261 } 262 } 263 264 private void logContextDebugMessage(String message) { 265 log.makeLoggingEventBuilder(Level.DEBUG) 266 .addMarker(MarkerFactory.getMarker(LogCategory.CONTEXT.name().toLowerCase())) 267 .setMessage(message) 268 .log(); 269 } 270 private void loadFromFileJson(InputStream stream, String name, IContextResourceLoader loader) throws IOException, FHIRException { 271 Bundle f; 272 try { 273 if (loader != null) 274 f = loader.loadBundle(stream, true); 275 else { 276 JsonParser json = new JsonParser(); 277 Resource r = json.parse(stream); 278 if (r instanceof Bundle) 279 f = (Bundle) r; 280 else { 281 f = new Bundle(); 282 f.addEntry().setResource(r); 283 } 284 } 285 } catch (FHIRFormatError e1) { 286 throw new org.hl7.fhir.exceptions.FHIRFormatError(e1.getMessage(), e1); 287 } 288 for (BundleEntryComponent e : f.getEntry()) { 289 if (e.getFullUrl() == null) { 290 logContextDebugMessage("unidentified resource in " + name+" (no fullUrl)"); 291 } 292 seeResource(e.getFullUrl(), e.getResource()); 293 } 294 } 295 296 public void seeResource(String url, Resource r) throws FHIRException { 297 if (r instanceof StructureDefinition) 298 seeProfile(url, (StructureDefinition) r); 299 else if (r instanceof ValueSet) 300 seeValueSet(url, (ValueSet) r); 301 else if (r instanceof CodeSystem) 302 seeCodeSystem(url, (CodeSystem) r); 303 else if (r instanceof OperationDefinition) 304 seeOperationDefinition(url, (OperationDefinition) r); 305 else if (r instanceof ConceptMap) 306 maps.put(((ConceptMap) r).getUrl(), (ConceptMap) r); 307 else if (r instanceof StructureMap) 308 transforms.put(((StructureMap) r).getUrl(), (StructureMap) r); 309 else if (r instanceof NamingSystem) 310 systems.add((NamingSystem) r); 311 } 312 313 private void seeOperationDefinition(String url, OperationDefinition r) { 314 operations.put(r.getUrl(), r); 315 } 316 317 public void seeValueSet(String url, ValueSet vs) throws DefinitionException { 318 if (Utilities.noString(url)) 319 url = vs.getUrl(); 320 if (valueSets.containsKey(vs.getUrl()) && !allowLoadingDuplicates) 321 throw new DefinitionException("Duplicate Profile " + vs.getUrl()); 322 valueSets.put(vs.getId(), vs); 323 valueSets.put(vs.getUrl(), vs); 324 if (!vs.getUrl().equals(url)) 325 valueSets.put(url, vs); 326 } 327 328 public void seeProfile(String url, StructureDefinition p) throws FHIRException { 329 if (Utilities.noString(url)) 330 url = p.getUrl(); 331 332 if (!p.hasSnapshot() && p.getKind() != StructureDefinitionKind.LOGICAL) { 333 if (!p.hasBaseDefinition()) 334 throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+") has no base and no snapshot"); 335 StructureDefinition sd = fetchResource(StructureDefinition.class, p.getBaseDefinition()); 336 if (sd == null) 337 throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+") base "+p.getBaseDefinition()+" could not be resolved"); 338 List<ValidationMessage> msgs = new ArrayList<ValidationMessage>(); 339 List<String> errors = new ArrayList<String>(); 340 ProfileUtilities pu = new ProfileUtilities(this, msgs, this); 341 pu.sortDifferential(sd, p, url, errors); 342 for (String err : errors) 343 msgs.add(new ValidationMessage(Source.ProfileValidator, IssueType.EXCEPTION,p.getUserString("path"), "Error sorting Differential: "+err, ValidationMessage.IssueSeverity.ERROR)); 344 pu.generateSnapshot(sd, p, p.getUrl(), p.getName()); 345 for (ValidationMessage msg : msgs) { 346 if (msg.getLevel() == ValidationMessage.IssueSeverity.ERROR || msg.getLevel() == ValidationMessage.IssueSeverity.FATAL) 347 throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+"). Error generating snapshot: "+msg.getMessage()); 348 } 349 if (!p.hasSnapshot()) 350 throw new DefinitionException("Profile "+p.getName()+" ("+p.getUrl()+"). Error generating snapshot"); 351 pu = null; 352 } 353 if (structures.containsKey(p.getUrl()) && !allowLoadingDuplicates) 354 throw new DefinitionException("Duplicate structures " + p.getUrl()); 355 structures.put(p.getId(), p); 356 structures.put(p.getUrl(), p); 357 if (!p.getUrl().equals(url)) 358 structures.put(url, p); 359 } 360 361 private void loadFromPack(String path, IContextResourceLoader loader) throws FileNotFoundException, IOException, FHIRException { 362 loadFromStream(new CSFileInputStream(path), loader); 363 } 364 365 public void loadFromPackage(NpmPackage pi, IContextResourceLoader loader, String... types) throws FileNotFoundException, IOException, FHIRException { 366 if (types.length == 0) 367 types = new String[] { "StructureDefinition", "ValueSet", "CodeSystem", "SearchParameter", "OperationDefinition", "Questionnaire","ConceptMap","StructureMap", "NamingSystem"}; 368 for (String s : pi.listResources(types)) { 369 loadDefinitionItem(s, pi.load("package", s), loader); 370 } 371 version = pi.version(); 372 } 373 374 public void loadFromFile(String file, IContextResourceLoader loader) throws IOException, FHIRException { 375 loadDefinitionItem(file, new CSFileInputStream(file), loader); 376 } 377 378 private void loadFromStream(InputStream stream, IContextResourceLoader loader) throws IOException, FHIRException { 379 ZipInputStream zip = new ZipInputStream(stream); 380 ZipEntry ze; 381 while ((ze = zip.getNextEntry()) != null) { 382 loadDefinitionItem(ze.getName(), zip, loader); 383 zip.closeEntry(); 384 } 385 zip.close(); 386 } 387 388 private void readVersionInfo(InputStream stream) throws IOException, DefinitionException { 389 byte[] bytes = IOUtils.toByteArray(stream); 390 binaries.put("version.info", bytes); 391 392 String[] vi = new String(bytes).split("\\r?\\n"); 393 for (String s : vi) { 394 if (s.startsWith("version=")) { 395 if (version == null) 396 version = s.substring(8); 397 else if (!version.equals(s.substring(8))) 398 throw new DefinitionException("Version mismatch. The context has version "+version+" loaded, and the new content being loaded is version "+s.substring(8)); 399 } 400 if (s.startsWith("revision=")) 401 revision = s.substring(9); 402 if (s.startsWith("date=")) 403 date = s.substring(5); 404 } 405 } 406 407 private void loadBytes(String name, InputStream stream) throws IOException { 408 byte[] bytes = IOUtils.toByteArray(stream); 409 binaries.put(name, bytes); 410 } 411 412 @Override 413 public IParser getParser(ParserType type) { 414 switch (type) { 415 case JSON: return newJsonParser(); 416 case XML: return newXmlParser(); 417 default: 418 throw new Error("Parser Type "+type.toString()+" not supported"); 419 } 420 } 421 422 @Override 423 public IParser getParser(String type) { 424 if (type.equalsIgnoreCase("JSON")) 425 return new JsonParser(); 426 if (type.equalsIgnoreCase("XML")) 427 return new XmlParser(); 428 throw new Error("Parser Type "+type.toString()+" not supported"); 429 } 430 431 @Override 432 public IParser newJsonParser() { 433 return new JsonParser(); 434 } 435 @Override 436 public IParser newXmlParser() { 437 return new XmlParser(); 438 } 439 440 @Override 441 public <T extends Resource> boolean hasResource(Class<T> class_, String uri) { 442 try { 443 return fetchResource(class_, uri) != null; 444 } catch (Exception e) { 445 return false; 446 } 447 } 448 449 @Override 450 public INarrativeGenerator getNarrativeGenerator(String prefix, String basePath) { 451 return new NarrativeGenerator(prefix, basePath, this); 452 } 453 454 @Override 455 public IResourceValidator newValidator() throws FHIRException { 456 if (validatorFactory == null) 457 throw new Error("No validator configured"); 458 return validatorFactory.makeValidator(this); 459 } 460 461 @Override 462 public <T extends Resource> T fetchResource(Class<T> class_, String uri) { 463 try { 464 return fetchResourceWithException(class_, uri); 465 } catch (FHIRException e) { 466 throw new Error(e); 467 } 468 } 469 @SuppressWarnings("unchecked") 470 @Override 471 public <T extends Resource> T fetchResourceWithException(Class<T> class_, String uri) throws FHIRException { 472 if (class_ == null) { 473 return null; 474 } 475 476 if (class_ == Questionnaire.class) 477 return (T) questionnaire; 478 479 if (class_ == StructureDefinition.class && !uri.contains("/")) 480 uri = "http://hl7.org/fhir/StructureDefinition/"+uri; 481 482 if (uri.startsWith("http:") || uri.startsWith("urn:") ) { 483 if (uri.contains("#")) 484 uri = uri.substring(0, uri.indexOf("#")); 485 if (class_ == Resource.class) { 486 if (structures.containsKey(uri)) 487 return (T) structures.get(uri); 488 if (valueSets.containsKey(uri)) 489 return (T) valueSets.get(uri); 490 if (codeSystems.containsKey(uri)) 491 return (T) codeSystems.get(uri); 492 if (operations.containsKey(uri)) 493 return (T) operations.get(uri); 494 if (searchParameters.containsKey(uri)) 495 return (T) searchParameters.get(uri); 496 if (maps.containsKey(uri)) 497 return (T) maps.get(uri); 498 if (transforms.containsKey(uri)) 499 return (T) transforms.get(uri); 500 return null; 501 } 502 if (class_ == StructureDefinition.class) { 503 if (structures.containsKey(uri)) 504 return (T) structures.get(uri); 505 else 506 return null; 507 } else if (class_ == ValueSet.class) { 508 if (valueSets.containsKey(uri)) 509 return (T) valueSets.get(uri); 510 else 511 return null; 512 } else if (class_ == CodeSystem.class) { 513 if (codeSystems.containsKey(uri)) 514 return (T) codeSystems.get(uri); 515 else 516 return null; 517 } else if (class_ == OperationDefinition.class) { 518 OperationDefinition od = operations.get(uri); 519 return (T) od; 520 } else if (class_ == SearchParameter.class) { 521 SearchParameter od = searchParameters.get(uri); 522 return (T) od; 523 } else if (class_ == ConceptMap.class) { 524 if (maps.containsKey(uri)) 525 return (T) maps.get(uri); 526 else 527 return null; 528 } else if (class_ == StructureMap.class) { 529 if (transforms.containsKey(uri)) 530 return (T) transforms.get(uri); 531 else 532 return null; 533 } 534 } 535 536 throw new FHIRException("fetching "+class_.getName()+" not done yet for URI '"+uri+"'"); 537 } 538 539 540 541 public int totalCount() { 542 return valueSets.size() + maps.size() + structures.size() + transforms.size(); 543 } 544 545 public void setCache(ValueSetExpansionCache cache) { 546 this.expansionCache = cache; 547 } 548 549 @Override 550 public List<String> getResourceNames() { 551 List<String> result = new ArrayList<String>(); 552 for (StructureDefinition sd : structures.values()) { 553 if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) 554 result.add(sd.getName()); 555 } 556 Collections.sort(result); 557 return result; 558 } 559 560 @Override 561 public List<String> getTypeNames() { 562 List<String> result = new ArrayList<String>(); 563 for (StructureDefinition sd : structures.values()) { 564 if (sd.getKind() != StructureDefinitionKind.LOGICAL && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) 565 result.add(sd.getName()); 566 } 567 Collections.sort(result); 568 return result; 569 } 570 571 @Override 572 public String getAbbreviation(String name) { 573 return "xxx"; 574 } 575 576 @Override 577 public boolean isDatatype(String typeSimple) { 578 // TODO Auto-generated method stub 579 return false; 580 } 581 582 @Override 583 public boolean isResource(String t) { 584 StructureDefinition sd; 585 try { 586 sd = fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+t); 587 } catch (Exception e) { 588 return false; 589 } 590 if (sd == null) 591 return false; 592 if (sd.getDerivation() == TypeDerivationRule.CONSTRAINT) 593 return false; 594 return sd.getKind() == StructureDefinitionKind.RESOURCE; 595 } 596 597 @Override 598 public boolean hasLinkFor(String typeSimple) { 599 return false; 600 } 601 602 @Override 603 public String getLinkFor(String corePath, String typeSimple) { 604 return null; 605 } 606 607 @Override 608 public BindingResolution resolveBinding(StructureDefinition profile, ElementDefinitionBindingComponent binding, String path) { 609 return null; 610 } 611 612 @Override 613 public String getLinkForProfile(StructureDefinition profile, String url) { 614 return null; 615 } 616 617 public Questionnaire getQuestionnaire() { 618 return questionnaire; 619 } 620 621 public void setQuestionnaire(Questionnaire questionnaire) { 622 this.questionnaire = questionnaire; 623 } 624 625 @Override 626 public Set<String> typeTails() { 627 return new HashSet<String>(Arrays.asList("Integer","UnsignedInt","PositiveInt","Decimal","DateTime","Date","Time","Instant","String","Uri","Oid","Uuid","Id","Boolean","Code","Markdown","Base64Binary","Coding","CodeableConcept","Attachment","Identifier","Quantity","SampledData","Range","Period","Ratio","HumanName","Address","ContactPoint","Timing","Reference","Annotation","Signature","Meta")); 628 } 629 630 @Override 631 public List<StructureDefinition> allStructures() { 632 List<StructureDefinition> result = new ArrayList<StructureDefinition>(); 633 Set<StructureDefinition> set = new HashSet<StructureDefinition>(); 634 for (StructureDefinition sd : structures.values()) { 635 if (!set.contains(sd)) { 636 result.add(sd); 637 set.add(sd); 638 } 639 } 640 return result; 641 } 642 643 @Override 644 public List<MetadataResource> allConformanceResources() { 645 List<MetadataResource> result = new ArrayList<MetadataResource>(); 646 result.addAll(structures.values()); 647 result.addAll(codeSystems.values()); 648 result.addAll(valueSets.values()); 649 result.addAll(maps.values()); 650 result.addAll(transforms.values()); 651 return result; 652 } 653 654 @Override 655 public String oid2Uri(String oid) { 656 String uri = OIDUtilities.getUriForOid(oid); 657 if (uri != null) 658 return uri; 659 for (NamingSystem ns : systems) { 660 if (hasOid(ns, oid)) { 661 uri = getUri(ns); 662 if (uri != null) 663 return null; 664 } 665 } 666 return null; 667 } 668 669 private String getUri(NamingSystem ns) { 670 for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) { 671 if (id.getType() == NamingSystemIdentifierType.URI) 672 return id.getValue(); 673 } 674 return null; 675 } 676 677 private boolean hasOid(NamingSystem ns, String oid) { 678 for (NamingSystemUniqueIdComponent id : ns.getUniqueId()) { 679 if (id.getType() == NamingSystemIdentifierType.OID && id.getValue().equals(oid)) 680 return true; 681 } 682 return false; 683 } 684 685 686 687 688 public void loadFromFolder(String folder) throws FileNotFoundException, Exception { 689 for (String n : ManagedFileAccess.file(folder).list()) { 690 if (n.endsWith(".json")) 691 loadFromFile(Utilities.path(folder, n), new JsonParser()); 692 else if (n.endsWith(".xml")) 693 loadFromFile(Utilities.path(folder, n), new XmlParser()); 694 } 695 } 696 697 private void loadFromFile(String filename, IParser p) throws FileNotFoundException, Exception { 698 Resource r; 699 try { 700 r = p.parse(ManagedFileAccess.inStream(filename)); 701 if (r.getResourceType() == ResourceType.Bundle) { 702 for (BundleEntryComponent e : ((Bundle) r).getEntry()) { 703 seeResource(null, e.getResource()); 704 } 705 } else { 706 seeResource(null, r); 707 } 708 } catch (Exception e) { 709 return; 710 } 711 } 712 713 714 public Map<String, byte[]> getBinaries() { 715 return binaries; 716 } 717 718 719 @Override 720 public boolean prependLinks() { 721 return false; 722 } 723 724 @Override 725 public boolean hasCache() { 726 return false; 727 } 728 729 @Override 730 public String getVersion() { 731 return version+"-"+revision; 732 } 733 734 public Map<String, StructureMap> getTransforms() { 735 return transforms; 736 } 737 738 public List<StructureMap> findTransformsforSource(String url) { 739 List<StructureMap> res = new ArrayList<StructureMap>(); 740 for (StructureMap map : transforms.values()) { 741 boolean match = false; 742 boolean ok = true; 743 for (StructureMapStructureComponent t : map.getStructure()) { 744 if (t.getMode() == StructureMapModelMode.SOURCE) { 745 match = match || t.getUrl().equals(url); 746 ok = ok && t.getUrl().equals(url); 747 } 748 } 749 if (match && ok) 750 res.add(map); 751 } 752 return res; 753 } 754 755 public IValidatorFactory getValidatorFactory() { 756 return validatorFactory; 757 } 758 759 public void setValidatorFactory(IValidatorFactory validatorFactory) { 760 this.validatorFactory = validatorFactory; 761 } 762 763 764 765}