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