* better validation of external references. Note: this is a potentially significant change: things that were called ok before may not be now, and things that were not ok before may become so, depending on the interplay between this and auto-load, further work may be needed here
* Support better validation of version specific profiles in meta.profile. This may also find new errors that were not previously being found * Support auto-determination of the version of FHIR to use when using the java validator * auto-load packages from the package server when references to profiles etc are encountered * look for references inside other parameters in Parameters resource
This commit is contained in:
parent
7616b55213
commit
5299bbe16b
|
@ -0,0 +1,18 @@
|
||||||
|
Validator Fixes:
|
||||||
|
* Support auto-determination of the version of FHIR to use when using the java validator
|
||||||
|
* auto-load packages from the package server when references to profiles etc are encountered
|
||||||
|
* Support better validation of version specific profiles in meta.profile
|
||||||
|
* look for references inside other parameters in Parameters resource
|
||||||
|
|
||||||
|
Other Code changes:
|
||||||
|
* Rendering: add rendering for Parameters resources
|
||||||
|
* Rendering: refactor of resource resolution code to support Parameters
|
||||||
|
* General clean up of rendering consistency & implement additional details when rendering (including patient summary)
|
||||||
|
* Rendering: major overhaul of DiagnosticReport rendering
|
||||||
|
* Fix NPE bug in value set comparison
|
||||||
|
|
||||||
|
|
||||||
|
TODO before commit:
|
||||||
|
* check version of contained resources
|
||||||
|
* review validation of CanonicalResource.url
|
||||||
|
|
|
@ -267,6 +267,11 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SimpleWorkerContext fromNothing() throws FileNotFoundException, FHIRException, IOException {
|
||||||
|
SimpleWorkerContext res = new SimpleWorkerContext();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader, ILoadFilter filter, PackageVersion pi) throws IOException, FHIRException {
|
private void loadDefinitionItem(String name, InputStream stream, IContextResourceLoader loader, ILoadFilter filter, PackageVersion pi) throws IOException, FHIRException {
|
||||||
if (name.endsWith(".xml"))
|
if (name.endsWith(".xml"))
|
||||||
loadFromFile(stream, name, loader, filter);
|
loadFromFile(stream, name, loader, filter);
|
||||||
|
|
|
@ -3,46 +3,58 @@ package org.hl7.fhir.r5.renderers.utils;
|
||||||
import org.hl7.fhir.r5.model.Bundle;
|
import org.hl7.fhir.r5.model.Bundle;
|
||||||
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
|
||||||
import org.hl7.fhir.r5.model.DomainResource;
|
import org.hl7.fhir.r5.model.DomainResource;
|
||||||
|
import org.hl7.fhir.r5.model.Parameters;
|
||||||
|
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContextType;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
public class Resolver {
|
public class Resolver {
|
||||||
|
|
||||||
|
public enum ResourceContextType {
|
||||||
|
PARAMETERS, BUNDLE
|
||||||
|
}
|
||||||
|
|
||||||
public interface IReferenceResolver {
|
public interface IReferenceResolver {
|
||||||
ResourceWithReference resolve(RenderingContext context, String url);
|
ResourceWithReference resolve(RenderingContext context, String url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResourceContext {
|
public static class ResourceContext {
|
||||||
Bundle bundleResource;
|
private ResourceContextType type;
|
||||||
org.hl7.fhir.r5.elementmodel.Element bundleElement;
|
private Resource containerResource;
|
||||||
|
private org.hl7.fhir.r5.elementmodel.Element containerElement;
|
||||||
|
|
||||||
DomainResource resourceResource;
|
DomainResource resourceResource;
|
||||||
org.hl7.fhir.r5.elementmodel.Element resourceElement;
|
org.hl7.fhir.r5.elementmodel.Element resourceElement;
|
||||||
|
|
||||||
public ResourceContext(Bundle bundle, DomainResource dr) {
|
public ResourceContext(ResourceContextType type, Resource bundle, DomainResource dr) {
|
||||||
super();
|
super();
|
||||||
this.bundleResource = bundle;
|
this.type = type;
|
||||||
|
this.containerResource = bundle;
|
||||||
this.resourceResource = dr;
|
this.resourceResource = dr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceContext(org.hl7.fhir.r5.elementmodel.Element bundle, org.hl7.fhir.r5.elementmodel.Element dr) {
|
public ResourceContext(ResourceContextType type, org.hl7.fhir.r5.elementmodel.Element bundle, org.hl7.fhir.r5.elementmodel.Element dr) {
|
||||||
this.bundleElement = bundle;
|
super();
|
||||||
|
this.type = type;
|
||||||
|
this.containerElement = bundle;
|
||||||
this.resourceElement = dr;
|
this.resourceElement = dr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceContext(Object bundle, Element doc) {
|
// public ResourceContext(Object bundle, Element doc) {
|
||||||
// TODO Auto-generated constructor stub
|
// // TODO Auto-generated constructor stub
|
||||||
}
|
// }
|
||||||
|
|
||||||
public Bundle getBundleResource() {
|
// public Bundle getBundleResource() {
|
||||||
return bundleResource;
|
// return containerResource;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public org.hl7.fhir.r5.elementmodel.Element getBundleElement() {
|
|
||||||
return bundleElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// public org.hl7.fhir.r5.elementmodel.Element getBundleElement() {
|
||||||
|
// return containerElement;
|
||||||
|
// }
|
||||||
|
//
|
||||||
public DomainResource getResourceResource() {
|
public DomainResource getResourceResource() {
|
||||||
return resourceResource;
|
return resourceResource;
|
||||||
}
|
}
|
||||||
|
@ -64,13 +76,27 @@ public class Resolver {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (bundleResource != null) {
|
if (type == ResourceContextType.BUNDLE) {
|
||||||
for (BundleEntryComponent be : bundleResource.getEntry()) {
|
if (containerResource != null) {
|
||||||
if (be.getFullUrl().equals(value))
|
for (BundleEntryComponent be : ((Bundle) containerResource).getEntry()) {
|
||||||
return be;
|
if (be.getFullUrl().equals(value))
|
||||||
if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
|
return be;
|
||||||
return be;
|
if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
|
||||||
}
|
return be;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == ResourceContextType.PARAMETERS) {
|
||||||
|
if (containerResource != null) {
|
||||||
|
for (ParametersParameterComponent p : ((Parameters) containerResource).getParameter()) {
|
||||||
|
if (p.getResource() != null && value.equals(p.getResource().fhirType()+"/"+p.getResource().getId())) {
|
||||||
|
BundleEntryComponent be = new BundleEntryComponent();
|
||||||
|
be.setResource(p.getResource());
|
||||||
|
return be;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -85,13 +111,24 @@ public class Resolver {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (bundleElement != null) {
|
if (type == ResourceContextType.BUNDLE) {
|
||||||
for (org.hl7.fhir.r5.elementmodel.Element be : bundleElement.getChildren("entry")) {
|
if (containerElement != null) {
|
||||||
org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
|
for (org.hl7.fhir.r5.elementmodel.Element be : containerElement.getChildren("entry")) {
|
||||||
if (value.equals(be.getChildValue("fullUrl")))
|
org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
|
||||||
return be;
|
if (value.equals(be.getChildValue("fullUrl")))
|
||||||
if (value.equals(res.fhirType()+"/"+res.getChildValue("id")))
|
return be;
|
||||||
return be;
|
if (value.equals(res.fhirType()+"/"+res.getChildValue("id")))
|
||||||
|
return be;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == ResourceContextType.PARAMETERS) {
|
||||||
|
if (containerElement != null) {
|
||||||
|
for (org.hl7.fhir.r5.elementmodel.Element p : containerElement.getChildren("parameter")) {
|
||||||
|
org.hl7.fhir.r5.elementmodel.Element res = p.getNamedChild("resource");
|
||||||
|
if (value.equals(res.fhirType()+"/"+res.getChildValue("id")))
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.hl7.fhir.utilities;
|
package org.hl7.fhir.utilities;
|
||||||
|
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
|
@ -35,6 +36,22 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
public class VersionUtilities {
|
public class VersionUtilities {
|
||||||
|
|
||||||
|
|
||||||
|
public static class VersionURLInfo {
|
||||||
|
private String version;
|
||||||
|
private String url;
|
||||||
|
public VersionURLInfo(String version, String url) {
|
||||||
|
super();
|
||||||
|
this.version = version;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final String CURRENT_VERSION = "4.4";
|
public static final String CURRENT_VERSION = "4.4";
|
||||||
public static final String CURRENT_FULL_VERSION = "4.4.0";
|
public static final String CURRENT_FULL_VERSION = "4.4.0";
|
||||||
|
|
||||||
|
@ -225,4 +242,18 @@ public class VersionUtilities {
|
||||||
throw new FHIRException("Unknown version "+version);
|
throw new FHIRException("Unknown version "+version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VersionURLInfo parseVersionUrl(String url) {
|
||||||
|
if (url.length() < 24) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String v = url.substring(20, 24);
|
||||||
|
if (v.endsWith("/")) {
|
||||||
|
v = v.substring(0, v.length()-1);
|
||||||
|
if (Utilities.existsInList(v, "1.0", "1.4", "3.0", "4.0", "5.0", CURRENT_VERSION)) {
|
||||||
|
return new VersionURLInfo(v, "http://hl7.org/fhir/"+url.substring(24));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1057,6 +1057,26 @@ public class NpmPackage {
|
||||||
public boolean isCore() {
|
public boolean isCore() {
|
||||||
return "fhir.core".equals(JSONUtil.str(npm, "type"));
|
return "fhir.core".equals(JSONUtil.str(npm, "type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasCanonical(String url) {
|
||||||
|
if (url == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String u = url.contains("|") ? url.substring(0, url.indexOf("|")) : url;
|
||||||
|
String v = url.contains("|") ? url.substring(url.indexOf("|")+1) : null;
|
||||||
|
NpmPackageFolder folder = folders.get("package");
|
||||||
|
if (folder != null) {
|
||||||
|
for (JsonElement e : folder.index.getAsJsonArray("files")) {
|
||||||
|
JsonObject o = (JsonObject) e;
|
||||||
|
if (u.equals(JSONUtil.str(o, "url"))) {
|
||||||
|
if (v == null || v.equals(JSONUtil.str(o, "version"))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -25,6 +25,7 @@ public class I18nConstants {
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE = "Bundle_BUNDLE_Entry_NoFirstResource";
|
public static final String BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE = "Bundle_BUNDLE_Entry_NoFirstResource";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_NOFULLURL = "Bundle_BUNDLE_Entry_NoFullUrl";
|
public static final String BUNDLE_BUNDLE_ENTRY_NOFULLURL = "Bundle_BUNDLE_Entry_NoFullUrl";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_NOPROFILE = "Bundle_BUNDLE_Entry_NoProfile";
|
public static final String BUNDLE_BUNDLE_ENTRY_NOPROFILE = "Bundle_BUNDLE_Entry_NoProfile";
|
||||||
|
public static final String BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES = "BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_NOTFOUND = "Bundle_BUNDLE_Entry_NotFound";
|
public static final String BUNDLE_BUNDLE_ENTRY_NOTFOUND = "Bundle_BUNDLE_Entry_NotFound";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_ORPHAN = "Bundle_BUNDLE_Entry_Orphan";
|
public static final String BUNDLE_BUNDLE_ENTRY_ORPHAN = "Bundle_BUNDLE_Entry_Orphan";
|
||||||
public static final String BUNDLE_BUNDLE_ENTRY_TYPE = "Bundle_BUNDLE_Entry_Type";
|
public static final String BUNDLE_BUNDLE_ENTRY_TYPE = "Bundle_BUNDLE_Entry_Type";
|
||||||
|
@ -543,10 +544,14 @@ public class I18nConstants {
|
||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SLICEORDER = "Validation_VAL_Profile_SliceOrder";
|
public static final String VALIDATION_VAL_PROFILE_SLICEORDER = "Validation_VAL_Profile_SliceOrder";
|
||||||
|
public static final String VALIDATION_VAL_PROFILE_OTHER_VERSION = "VALIDATION_VAL_PROFILE_OTHER_VERSION";
|
||||||
|
public static final String VALIDATION_VAL_PROFILE_THIS_VERSION_OK = "VALIDATION_VAL_PROFILE_THIS_VERSION_OK";
|
||||||
|
public static final String VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER = "VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER";
|
||||||
public static final String VALIDATION_VAL_PROFILE_UNKNOWN = "Validation_VAL_Profile_Unknown";
|
public static final String VALIDATION_VAL_PROFILE_UNKNOWN = "Validation_VAL_Profile_Unknown";
|
||||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE = "Validation_VAL_Profile_WrongType";
|
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE = "Validation_VAL_Profile_WrongType";
|
||||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
||||||
public static final String VALIDATION_VAL_UNKNOWN_PROFILE = "Validation_VAL_Unknown_Profile";
|
public static final String VALIDATION_VAL_UNKNOWN_PROFILE = "Validation_VAL_Unknown_Profile";
|
||||||
|
|
||||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
||||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
||||||
public static final String VALUESET_NO_SYSTEM_WARNING = "VALUESET_NO_SYSTEM_WARNING";
|
public static final String VALUESET_NO_SYSTEM_WARNING = "VALUESET_NO_SYSTEM_WARNING";
|
||||||
|
|
|
@ -571,3 +571,7 @@ PACKAGE_VERSION_MISMATCH = FHIR Version mismatch in package {0}: version is {2}
|
||||||
VALUESET_REFERENCE_UNKNOWN = The value set import {0} could not be found so cannot be checked
|
VALUESET_REFERENCE_UNKNOWN = The value set import {0} could not be found so cannot be checked
|
||||||
VALUESET_REFERENCE_INVALID_TYPE = The value set import {0} points to a resource of type {1} which is not valid
|
VALUESET_REFERENCE_INVALID_TYPE = The value set import {0} points to a resource of type {1} which is not valid
|
||||||
SD_MUST_HAVE_DERIVATION = StructureDefinition {0} must have a derivation, since it has a baseDefinition
|
SD_MUST_HAVE_DERIVATION = StructureDefinition {0} must have a derivation, since it has a baseDefinition
|
||||||
|
VALIDATION_VAL_PROFILE_OTHER_VERSION = Profile is for a different version of FHIR ({0}) so has been ignored
|
||||||
|
VALIDATION_VAL_PROFILE_THIS_VERSION_OK = Profile for this version of FHIR - all OK
|
||||||
|
VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER = Profile is for this version of FHIR, but is an invalid type {0}
|
||||||
|
BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES = Multiple profiles found for contained resource. This is not supported at this time. (Type {0}: {1})
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.hl7.fhir.r5.utils.*;
|
||||||
import org.hl7.fhir.r5.utils.IResourceValidator.*;
|
import org.hl7.fhir.r5.utils.IResourceValidator.*;
|
||||||
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
import org.hl7.fhir.r5.utils.StructureMapUtilities.ITransformerServices;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
|
import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller;
|
||||||
import org.hl7.fhir.validation.instance.InstanceValidator;
|
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||||
import org.hl7.fhir.utilities.IniFile;
|
import org.hl7.fhir.utilities.IniFile;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
@ -163,7 +164,42 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @author Grahame Grieve
|
* @author Grahame Grieve
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ValidationEngine implements IValidatorResourceFetcher {
|
public class ValidationEngine implements IValidatorResourceFetcher, IPackageInstaller {
|
||||||
|
|
||||||
|
public static class VersionSourceInformation {
|
||||||
|
|
||||||
|
private List<String> report = new ArrayList<>();
|
||||||
|
private List<String> versions = new ArrayList<>();
|
||||||
|
|
||||||
|
public void see(String version, String src) {
|
||||||
|
version = VersionUtilities.getMajMin(version);
|
||||||
|
report.add(src+": "+version);
|
||||||
|
if (!versions.contains(version)) {
|
||||||
|
versions.add(version);
|
||||||
|
Collections.sort(versions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return versions.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return versions.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String version() {
|
||||||
|
return versions.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getReport() {
|
||||||
|
if (report.isEmpty()) {
|
||||||
|
report.add("(nothing found)");
|
||||||
|
}
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public class ScanOutputItem {
|
public class ScanOutputItem {
|
||||||
private String ref;
|
private String ref;
|
||||||
|
@ -311,9 +347,10 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
|
|
||||||
public ValidationEngine() throws IOException {
|
public ValidationEngine() throws IOException {
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
|
context = SimpleWorkerContext.fromNothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTerminologyServer(String src, String log, FhirPublication version) throws Exception {
|
public void setTerminologyServer(String src, String log, FhirPublication version) throws FHIRException, URISyntaxException {
|
||||||
connectToTSServer(src, log, version);
|
connectToTSServer(src, log, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +379,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
this.showTimes = showTimes;
|
this.showTimes = showTimes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, boolean canRunWithoutTerminologyServer, String vString) throws Exception {
|
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, boolean canRunWithoutTerminologyServer, String vString) throws FHIRException, IOException, URISyntaxException {
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
loadCoreDefinitions(src, false);
|
loadCoreDefinitions(src, false);
|
||||||
context.setCanRunWithoutTerminology(canRunWithoutTerminologyServer);
|
context.setCanRunWithoutTerminology(canRunWithoutTerminologyServer);
|
||||||
|
@ -350,14 +387,14 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
this.version = vString;
|
this.version = vString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, String vString) throws Exception {
|
public ValidationEngine(String src, String txsrvr, String txLog, FhirPublication version, String vString) throws FHIRException, IOException, URISyntaxException {
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
loadCoreDefinitions(src, false);
|
loadCoreDefinitions(src, false);
|
||||||
setTerminologyServer(txsrvr, txLog, version);
|
setTerminologyServer(txsrvr, txLog, version);
|
||||||
this.version = vString;
|
this.version = vString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValidationEngine(String src) throws Exception {
|
public ValidationEngine(String src) throws FHIRException, IOException {
|
||||||
loadCoreDefinitions(src, false);
|
loadCoreDefinitions(src, false);
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -370,7 +407,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCoreDefinitions(String src, boolean recursive) throws Exception {
|
private void loadCoreDefinitions(String src, boolean recursive) throws FHIRException, IOException {
|
||||||
if (pcm == null) {
|
if (pcm == null) {
|
||||||
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -435,7 +472,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return ep;
|
return ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] loadProfileSource(String src) throws Exception {
|
private byte[] loadProfileSource(String src) throws FHIRException, FileNotFoundException, IOException {
|
||||||
if (Utilities.noString(src)) {
|
if (Utilities.noString(src)) {
|
||||||
throw new FHIRException("Profile Source '" + src + "' could not be processed");
|
throw new FHIRException("Profile Source '" + src + "' could not be processed");
|
||||||
} else if (src.startsWith("https:") || src.startsWith("http:")) {
|
} else if (src.startsWith("https:") || src.startsWith("http:")) {
|
||||||
|
@ -447,13 +484,13 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] loadProfileFromUrl(String src) throws Exception {
|
private byte[] loadProfileFromUrl(String src) throws FHIRException {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(src+"?nocache=" + System.currentTimeMillis());
|
URL url = new URL(src+"?nocache=" + System.currentTimeMillis());
|
||||||
URLConnection c = url.openConnection();
|
URLConnection c = url.openConnection();
|
||||||
return IOUtils.toByteArray(c.getInputStream());
|
return IOUtils.toByteArray(c.getInputStream());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new Exception("Unable to find definitions at URL '"+src+"': "+e.getMessage(), e);
|
throw new FHIRException("Unable to find definitions at URL '"+src+"': "+e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,9 +501,10 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return TextFile.fileToBytes(src);
|
return TextFile.fileToBytes(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** explore should be true if we're trying to load an -ig parameter, and false if we're loading source **/
|
/** explore should be true if we're trying to load an -ig parameter, and false if we're loading source
|
||||||
|
* @throws IOException **/
|
||||||
|
|
||||||
private Map<String, byte[]> loadIgSource(String src, boolean recursive, boolean explore) throws Exception {
|
private Map<String, byte[]> loadIgSource(String src, boolean recursive, boolean explore) throws FHIRException, IOException {
|
||||||
// src can be one of the following:
|
// src can be one of the following:
|
||||||
// - a canonical url for an ig - this will be converted to a package id and loaded into the cache
|
// - a canonical url for an ig - this will be converted to a package id and loaded into the cache
|
||||||
// - a package id for an ig - this will be loaded into the cache
|
// - a package id for an ig - this will be loaded into the cache
|
||||||
|
@ -510,11 +548,60 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
} else if ((src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) || src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX)) && !src.endsWith(".zip") && !src.endsWith(".tgz")) {
|
} else if ((src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) || src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX)) && !src.endsWith(".zip") && !src.endsWith(".tgz")) {
|
||||||
return fetchByPackage(src);
|
return fetchByPackage(src);
|
||||||
}
|
}
|
||||||
throw new Exception("Unable to find/resolve/read -ig "+src);
|
throw new FHIRException("Unable to find/resolve/read -ig "+src);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, byte[]> loadIgSourceForVersion(String src, boolean recursive, boolean explore, VersionSourceInformation versions) throws FHIRException, IOException {
|
||||||
|
if (src.startsWith("https:") || src.startsWith("http:")) {
|
||||||
|
String v = null;
|
||||||
|
if (src.contains("|")) {
|
||||||
|
v = src.substring(src.indexOf("|")+1);
|
||||||
|
src = src.substring(0, src.indexOf("|"));
|
||||||
|
}
|
||||||
|
String pid = pcm.getPackageId(src);
|
||||||
|
if (!Utilities.noString(pid)) {
|
||||||
|
versions.see(fetchVersionByPackage(pid+(v == null ? "" : "#"+v)), "Package "+src);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return fetchVersionFromUrl(src+(v == null ? "" : "|"+v), explore, versions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = new File(Utilities.path(src));
|
||||||
|
if (f.exists()) {
|
||||||
|
if (f.isDirectory() && new File(Utilities.path(src, "package.tgz")).exists()) {
|
||||||
|
versions.see(loadPackageForVersion(new FileInputStream(Utilities.path(src, "package.tgz")), Utilities.path(src, "package.tgz")), "Package "+src);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (f.isDirectory() && new File(Utilities.path(src, "igpack.zip")).exists())
|
||||||
|
return readZip(new FileInputStream(Utilities.path(src, "igpack.zip")));
|
||||||
|
if (f.isDirectory() && new File(Utilities.path(src, "validator.pack")).exists())
|
||||||
|
return readZip(new FileInputStream(Utilities.path(src, "validator.pack")));
|
||||||
|
if (f.isDirectory())
|
||||||
|
return scanDirectory(f, recursive);
|
||||||
|
if (src.endsWith(".tgz")) {
|
||||||
|
versions.see(loadPackageForVersion(new FileInputStream(src), src), "Package "+src);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (src.endsWith(".pack"))
|
||||||
|
return readZip(new FileInputStream(src));
|
||||||
|
if (src.endsWith("igpack.zip"))
|
||||||
|
return readZip(new FileInputStream(src));
|
||||||
|
FhirFormat fmt = checkIsResource(src);
|
||||||
|
if (fmt != null) {
|
||||||
|
Map<String, byte[]> res = new HashMap<String, byte[]>();
|
||||||
|
res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), TextFile.fileToBytesNCS(src));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
} else if ((src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) || src.matches(FilesystemPackageCacheManager.PACKAGE_VERSION_REGEX)) && !src.endsWith(".zip") && !src.endsWith(".tgz")) {
|
||||||
|
versions.see(fetchVersionByPackage(src), "Package "+src);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
throw new FHIRException("Unable to find/resolve/read -ig "+src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Map<String, byte[]> fetchFromUrl(String src, boolean explore) throws Exception {
|
private Map<String, byte[]> fetchFromUrl(String src, boolean explore) throws FHIRException, IOException {
|
||||||
if (src.endsWith(".tgz"))
|
if (src.endsWith(".tgz"))
|
||||||
return loadPackage(fetchFromUrlSpecific(src, false), src);
|
return loadPackage(fetchFromUrlSpecific(src, false), src);
|
||||||
if (src.endsWith(".pack"))
|
if (src.endsWith(".pack"))
|
||||||
|
@ -551,15 +638,59 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), cnt);
|
res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), cnt);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
throw new Exception("Unable to find/resolve/read -ig "+src);
|
throw new FHIRException("Unable to find/resolve/read -ig "+src);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream fetchFromUrlSpecific(String source, boolean optional) throws Exception {
|
private Map<String, byte[]> fetchVersionFromUrl(String src, boolean explore, VersionSourceInformation versions) throws FHIRException, IOException {
|
||||||
|
if (src.endsWith(".tgz")) {
|
||||||
|
versions.see(loadPackageForVersion(fetchFromUrlSpecific(src, false), src), "From Package "+src);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (src.endsWith(".pack"))
|
||||||
|
return readZip(fetchFromUrlSpecific(src, false));
|
||||||
|
if (src.endsWith("igpack.zip"))
|
||||||
|
return readZip(fetchFromUrlSpecific(src, false));
|
||||||
|
|
||||||
|
InputStream stream = null;
|
||||||
|
if (explore) {
|
||||||
|
stream = fetchFromUrlSpecific(Utilities.pathURL(src, "package.tgz"), true);
|
||||||
|
if (stream != null) {
|
||||||
|
versions.see(loadPackageForVersion(stream, Utilities.pathURL(src, "package.tgz")), "From Package at "+src);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// todo: these options are deprecated - remove once all IGs have been rebuilt post R4 technical correction
|
||||||
|
stream = fetchFromUrlSpecific(Utilities.pathURL(src, "igpack.zip"), true);
|
||||||
|
if (stream != null)
|
||||||
|
return readZip(stream);
|
||||||
|
stream = fetchFromUrlSpecific(Utilities.pathURL(src, "validator.pack"), true);
|
||||||
|
if (stream != null)
|
||||||
|
return readZip(stream);
|
||||||
|
stream = fetchFromUrlSpecific(Utilities.pathURL(src, "validator.pack"), true);
|
||||||
|
//// -----
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok, having tried all that... now we'll just try to access it directly
|
||||||
|
byte[] cnt;
|
||||||
|
if (stream == null)
|
||||||
|
cnt = fetchFromUrlSpecific(src, "application/json", true);
|
||||||
|
else
|
||||||
|
cnt = TextFile.streamToBytes(stream);
|
||||||
|
|
||||||
|
FhirFormat fmt = checkIsResource(cnt, src);
|
||||||
|
if (fmt != null) {
|
||||||
|
Map<String, byte[]> res = new HashMap<String, byte[]>();
|
||||||
|
res.put(Utilities.changeFileExt(src, "."+fmt.getExtension()), cnt);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
throw new FHIRException("Unable to find/resolve/read -ig "+src);
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream fetchFromUrlSpecific(String source, boolean optional) throws FHIRException, IOException {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(source+"?nocache=" + System.currentTimeMillis());
|
URL url = new URL(source+"?nocache=" + System.currentTimeMillis());
|
||||||
URLConnection c = url.openConnection();
|
URLConnection c = url.openConnection();
|
||||||
return c.getInputStream();
|
return c.getInputStream();
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
if (optional)
|
if (optional)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
|
@ -567,13 +698,13 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] fetchFromUrlSpecific(String source, String contentType, boolean optional) throws Exception {
|
private byte[] fetchFromUrlSpecific(String source, String contentType, boolean optional) throws FHIRException, IOException {
|
||||||
try {
|
try {
|
||||||
URL url = new URL(source+"?nocache=" + System.currentTimeMillis());
|
URL url = new URL(source+"?nocache=" + System.currentTimeMillis());
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
conn.setRequestProperty("Accept", contentType);
|
conn.setRequestProperty("Accept", contentType);
|
||||||
return TextFile.streamToBytes(conn.getInputStream());
|
return TextFile.streamToBytes(conn.getInputStream());
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
if (optional)
|
if (optional)
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
|
@ -604,11 +735,15 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return Utilities.existsInList(Utilities.getFileExtension(ff.getName()).toLowerCase(), "md", "css", "js", "png", "gif", "jpg", "html", "tgz", "pack", "zip");
|
return Utilities.existsInList(Utilities.getFileExtension(ff.getName()).toLowerCase(), "md", "css", "js", "png", "gif", "jpg", "html", "tgz", "pack", "zip");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, byte[]> loadPackage(InputStream stream, String name) throws Exception {
|
private Map<String, byte[]> loadPackage(InputStream stream, String name) throws FHIRException, IOException {
|
||||||
return loadPackage(NpmPackage.fromPackage(stream));
|
return loadPackage(NpmPackage.fromPackage(stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, byte[]> loadPackage(NpmPackage pi) throws Exception {
|
private String loadPackageForVersion(InputStream stream, String name) throws FHIRException, IOException {
|
||||||
|
return NpmPackage.fromPackage(stream).fhirVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, byte[]> loadPackage(NpmPackage pi) throws FHIRException, IOException {
|
||||||
context.getLoadedPackages().add(pi.name()+"#"+pi.version());
|
context.getLoadedPackages().add(pi.name()+"#"+pi.version());
|
||||||
Map<String, byte[]> res = new HashMap<String, byte[]>();
|
Map<String, byte[]> res = new HashMap<String, byte[]>();
|
||||||
for (String s : pi.dependencies()) {
|
for (String s : pi.dependencies()) {
|
||||||
|
@ -652,7 +787,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
System.out.println(message);
|
System.out.println(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, byte[]> fetchByPackage(String src) throws Exception {
|
private Map<String, byte[]> fetchByPackage(String src) throws FHIRException, IOException {
|
||||||
String id = src;
|
String id = src;
|
||||||
String version = null;
|
String version = null;
|
||||||
if (src.contains("#")) {
|
if (src.contains("#")) {
|
||||||
|
@ -679,13 +814,46 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return loadPackage(pi);
|
return loadPackage(pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, byte[]> resolvePackage(String id, String v) throws Exception {
|
private String fetchVersionByPackage(String src) throws FHIRException, IOException {
|
||||||
|
String id = src;
|
||||||
|
String version = null;
|
||||||
|
if (src.contains("#")) {
|
||||||
|
id = src.substring(0, src.indexOf("#"));
|
||||||
|
version = src.substring(src.indexOf("#")+1);
|
||||||
|
}
|
||||||
|
if (pcm == null) {
|
||||||
|
log("Creating Package manager?");
|
||||||
|
pcm = new FilesystemPackageCacheManager(true, ToolsVersion.TOOLS_VERSION);
|
||||||
|
}
|
||||||
|
if (version == null) {
|
||||||
|
version = pcm.getLatestVersion(id);
|
||||||
|
}
|
||||||
|
NpmPackage pi = null;
|
||||||
|
if (version == null) {
|
||||||
|
pi = pcm.loadPackageFromCacheOnly(id);
|
||||||
|
if (pi != null)
|
||||||
|
log(" ... Using version "+pi.version());
|
||||||
|
} else
|
||||||
|
pi = pcm.loadPackageFromCacheOnly(id, version);
|
||||||
|
if (pi == null) {
|
||||||
|
return resolvePackageForVersion(id, version);
|
||||||
|
} else {
|
||||||
|
return pi.fhirVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, byte[]> resolvePackage(String id, String v) throws FHIRException, IOException {
|
||||||
NpmPackage pi = pcm.loadPackage(id, v);
|
NpmPackage pi = pcm.loadPackage(id, v);
|
||||||
if (pi != null && v == null)
|
if (pi != null && v == null)
|
||||||
log(" ... Using version "+pi.version());
|
log(" ... Using version "+pi.version());
|
||||||
return loadPackage(pi);
|
return loadPackage(pi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resolvePackageForVersion(String id, String v) throws FHIRException, IOException {
|
||||||
|
NpmPackage pi = pcm.loadPackage(id, v);
|
||||||
|
return pi.fhirVersion();
|
||||||
|
}
|
||||||
|
|
||||||
public SimpleWorkerContext getContext() {
|
public SimpleWorkerContext getContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +926,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadProfile(String src) throws Exception {
|
public void loadProfile(String src) throws FHIRException, IOException {
|
||||||
if (context.hasResource(StructureDefinition.class, src))
|
if (context.hasResource(StructureDefinition.class, src))
|
||||||
return;
|
return;
|
||||||
if (context.hasResource(ImplementationGuide.class, src))
|
if (context.hasResource(ImplementationGuide.class, src))
|
||||||
|
@ -770,7 +938,13 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
context.cacheResource(r);
|
context.cacheResource(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadIg(String src, boolean recursive) throws IOException, FHIRException, Exception {
|
public void scanForIgVersion(String src, boolean recursive, VersionSourceInformation versions) throws IOException, FHIRException, Exception {
|
||||||
|
Map<String, byte[]> source = loadIgSourceForVersion(src, recursive, true, versions);
|
||||||
|
if (source != null && source.containsKey("version.info"))
|
||||||
|
versions.see(readInfoVersion(source.get("version.info")), "version.info in "+src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadIg(String src, boolean recursive) throws IOException, FHIRException {
|
||||||
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) ? pcm.loadPackage(src, null) : null;
|
NpmPackage npm = src.matches(FilesystemPackageCacheManager.PACKAGE_REGEX) ? pcm.loadPackage(src, null) : null;
|
||||||
if (npm != null) {
|
if (npm != null) {
|
||||||
for (String s : npm.dependencies()) {
|
for (String s : npm.dependencies()) {
|
||||||
|
@ -834,7 +1008,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Resource loadResourceByVersion(String version, byte[] content, String fn) throws IOException, Exception {
|
public Resource loadResourceByVersion(String version, byte[] content, String fn) throws IOException, FHIRException {
|
||||||
Resource r;
|
Resource r;
|
||||||
if (version.startsWith("3.0")) {
|
if (version.startsWith("3.0")) {
|
||||||
org.hl7.fhir.dstu3.model.Resource res;
|
org.hl7.fhir.dstu3.model.Resource res;
|
||||||
|
@ -845,7 +1019,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
res = new org.hl7.fhir.dstu3.utils.StructureMapUtilities(null).parse(new String(content));
|
res = new org.hl7.fhir.dstu3.utils.StructureMapUtilities(null).parse(new String(content));
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
r = VersionConvertor_30_50.convertResource(res, false);
|
r = VersionConvertor_30_50.convertResource(res, false);
|
||||||
} else if (version.startsWith("4.0")) {
|
} else if (version.startsWith("4.0")) {
|
||||||
org.hl7.fhir.r4.model.Resource res;
|
org.hl7.fhir.r4.model.Resource res;
|
||||||
|
@ -856,7 +1030,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
res = new org.hl7.fhir.r4.utils.StructureMapUtilities(null).parse(new String(content), fn);
|
res = new org.hl7.fhir.r4.utils.StructureMapUtilities(null).parse(new String(content), fn);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
r = VersionConvertor_40_50.convertResource(res);
|
r = VersionConvertor_40_50.convertResource(res);
|
||||||
} else if (version.startsWith("1.4")) {
|
} else if (version.startsWith("1.4")) {
|
||||||
org.hl7.fhir.dstu2016may.model.Resource res;
|
org.hl7.fhir.dstu2016may.model.Resource res;
|
||||||
|
@ -865,7 +1039,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
||||||
res = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(new ByteArrayInputStream(content));
|
res = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(new ByteArrayInputStream(content));
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
r = VersionConvertor_14_50.convertResource(res);
|
r = VersionConvertor_14_50.convertResource(res);
|
||||||
} else if (version.startsWith("1.0")) {
|
} else if (version.startsWith("1.0")) {
|
||||||
org.hl7.fhir.dstu2.model.Resource res;
|
org.hl7.fhir.dstu2.model.Resource res;
|
||||||
|
@ -874,7 +1048,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
||||||
res = new org.hl7.fhir.dstu2.formats.JsonParser().parse(new ByteArrayInputStream(content));
|
res = new org.hl7.fhir.dstu2.formats.JsonParser().parse(new ByteArrayInputStream(content));
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
|
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
|
||||||
r = VersionConvertor_10_50.convertResource(res, advisor);
|
r = VersionConvertor_10_50.convertResource(res, advisor);
|
||||||
} else if (version.equals(Constants.VERSION) || "current".equals(version)) {
|
} else if (version.equals(Constants.VERSION) || "current".equals(version)) {
|
||||||
|
@ -887,9 +1061,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
r = new org.hl7.fhir.r5.utils.StructureMapUtilities(null).parse(new String(content), fn);
|
r = new org.hl7.fhir.r5.utils.StructureMapUtilities(null).parse(new String(content), fn);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else
|
} else
|
||||||
throw new Exception("Unsupported version "+version);
|
throw new FHIRException("Unsupported version "+version);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,11 +1097,11 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
FhirFormat cntType = null;
|
FhirFormat cntType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Content loadContent(String source, String opName) throws Exception {
|
public Content loadContent(String source, String opName) throws FHIRException, IOException {
|
||||||
Map<String, byte[]> s = loadIgSource(source, false, false);
|
Map<String, byte[]> s = loadIgSource(source, false, false);
|
||||||
Content res = new Content();
|
Content res = new Content();
|
||||||
if (s.size() != 1)
|
if (s.size() != 1)
|
||||||
throw new Exception("Unable to find resource " + source + " to "+opName);
|
throw new FHIRException("Unable to find resource " + source + " to "+opName);
|
||||||
for (Entry<String, byte[]> t: s.entrySet()) {
|
for (Entry<String, byte[]> t: s.entrySet()) {
|
||||||
res.focus = t.getValue();
|
res.focus = t.getValue();
|
||||||
if (t.getKey().endsWith(".json"))
|
if (t.getKey().endsWith(".json"))
|
||||||
|
@ -939,13 +1113,13 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (t.getKey().endsWith(".txt") || t.getKey().endsWith(".map"))
|
else if (t.getKey().endsWith(".txt") || t.getKey().endsWith(".map"))
|
||||||
res.cntType = FhirFormat.TEXT;
|
res.cntType = FhirFormat.TEXT;
|
||||||
else
|
else
|
||||||
throw new Exception("Todo: Determining resource type is not yet done");
|
throw new FHIRException("Todo: Determining resource type is not yet done");
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// testing entry point
|
// testing entry point
|
||||||
public OperationOutcome validate(FhirFormat format, InputStream stream, List<String> profiles) throws Exception {
|
public OperationOutcome validate(FhirFormat format, InputStream stream, List<String> profiles) throws FHIRException, IOException, EOperationOutcome {
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
InstanceValidator validator = getValidator();
|
InstanceValidator validator = getValidator();
|
||||||
validator.validate(null, messages, stream, format, asSdList(profiles));
|
validator.validate(null, messages, stream, format, asSdList(profiles));
|
||||||
|
@ -966,13 +1140,13 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationOutcome validate(String source, List<String> profiles) throws Exception {
|
public OperationOutcome validate(String source, List<String> profiles) throws FHIRException, IOException {
|
||||||
List<String> l = new ArrayList<String>();
|
List<String> l = new ArrayList<String>();
|
||||||
l.add(source);
|
l.add(source);
|
||||||
return (OperationOutcome)validate(l, profiles);
|
return (OperationOutcome)validate(l, profiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ScanOutputItem> validateScan(List<String> sources, Set<String> guides) throws Exception {
|
public List<ScanOutputItem> validateScan(List<String> sources, Set<String> guides) throws FHIRException, IOException, EOperationOutcome {
|
||||||
List<String> refs = new ArrayList<String>();
|
List<String> refs = new ArrayList<String>();
|
||||||
handleSources(sources, refs);
|
handleSources(sources, refs);
|
||||||
|
|
||||||
|
@ -1048,7 +1222,28 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Resource validate(List<String> sources, List<String> profiles) throws Exception {
|
public void scanForVersions(List<String> sources, VersionSourceInformation versions) throws FHIRException, IOException {
|
||||||
|
List<String> refs = new ArrayList<String>();
|
||||||
|
handleSources(sources, refs);
|
||||||
|
for (String ref : refs) {
|
||||||
|
Content cnt = loadContent(ref, "validate");
|
||||||
|
String s = TextFile.bytesToString(cnt.focus);
|
||||||
|
if (s.contains("http://hl7.org/fhir/3.0")) {
|
||||||
|
versions.see("3.0", "Profile in "+ref);
|
||||||
|
}
|
||||||
|
if (s.contains("http://hl7.org/fhir/1.0")) {
|
||||||
|
versions.see("1.0", "Profile in "+ref);
|
||||||
|
}
|
||||||
|
if (s.contains("http://hl7.org/fhir/4.0")) {
|
||||||
|
versions.see("4.0", "Profile in "+ref);
|
||||||
|
}
|
||||||
|
if (s.contains("http://hl7.org/fhir/1.4")) {
|
||||||
|
versions.see("1.4", "Profile in "+ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Resource validate(List<String> sources, List<String> profiles) throws FHIRException, IOException {
|
||||||
List<String> refs = new ArrayList<String>();
|
List<String> refs = new ArrayList<String>();
|
||||||
boolean asBundle = handleSources(sources, refs);
|
boolean asBundle = handleSources(sources, refs);
|
||||||
Bundle results = new Bundle();
|
Bundle results = new Bundle();
|
||||||
|
@ -1065,7 +1260,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
results.addEntry().setResource(outcome);
|
results.addEntry().setResource(outcome);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Validation Infrastructure fail validating "+ref+": "+e.getMessage());
|
System.out.println("Validation Infrastructure fail validating "+ref+": "+e.getMessage());
|
||||||
throw e;
|
throw new FHIRException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (asBundle)
|
if (asBundle)
|
||||||
|
@ -1082,7 +1277,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationOutcome validateString(String location, String source, FhirFormat format, List<String> profiles) throws Exception {
|
public OperationOutcome validateString(String location, String source, FhirFormat format, List<String> profiles) throws FHIRException, IOException, EOperationOutcome, SAXException {
|
||||||
return validate(location, source.getBytes(), format, profiles);
|
return validate(location, source.getBytes(), format, profiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,14 +1331,14 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return isBundle;
|
return isBundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationOutcome validate(byte[] source, FhirFormat cntType, List<String> profiles) throws Exception {
|
public OperationOutcome validate(byte[] source, FhirFormat cntType, List<String> profiles) throws FHIRException, IOException, EOperationOutcome {
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
InstanceValidator validator = getValidator();
|
InstanceValidator validator = getValidator();
|
||||||
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
|
validator.validate(null, messages, new ByteArrayInputStream(source), cntType, asSdList(profiles));
|
||||||
return messagesToOutcome(messages);
|
return messagesToOutcome(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles) throws Exception {
|
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles) throws FHIRException, IOException, EOperationOutcome, SAXException {
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
if (doNative) {
|
if (doNative) {
|
||||||
if (cntType == FhirFormat.JSON)
|
if (cntType == FhirFormat.JSON)
|
||||||
|
@ -1161,7 +1356,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return messagesToOutcome(messages);
|
return messagesToOutcome(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles, IdStatus resourceIdRule, boolean anyExtensionsAllowed, BestPracticeWarningLevel bpWarnings, CheckDisplayOption displayOption) throws Exception {
|
public OperationOutcome validate(String location, byte[] source, FhirFormat cntType, List<String> profiles, IdStatus resourceIdRule, boolean anyExtensionsAllowed, BestPracticeWarningLevel bpWarnings, CheckDisplayOption displayOption) throws FHIRException, IOException, EOperationOutcome, SAXException {
|
||||||
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
List<ValidationMessage> messages = new ArrayList<ValidationMessage>();
|
||||||
if (doNative) {
|
if (doNative) {
|
||||||
if (cntType == FhirFormat.JSON)
|
if (cntType == FhirFormat.JSON)
|
||||||
|
@ -1254,12 +1449,12 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return issue.getSeverity().toString()+" @ "+issue.getLocation() + " " +issue.getDetails().getText() +(source != null ? " (src = "+source+")" : "");
|
return issue.getSeverity().toString()+" @ "+issue.getLocation() + " " +issue.getDetails().getText() +(source != null ? " (src = "+source+")" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public org.hl7.fhir.r5.elementmodel.Element transform(String source, String map) throws Exception {
|
public org.hl7.fhir.r5.elementmodel.Element transform(String source, String map) throws FHIRException, IOException {
|
||||||
Content cnt = loadContent(source, "validate");
|
Content cnt = loadContent(source, "validate");
|
||||||
return transform(cnt.focus, cnt.cntType, map);
|
return transform(cnt.focus, cnt.cntType, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public org.hl7.fhir.r5.elementmodel.Element transform(byte[] source, FhirFormat cntType, String mapUri) throws Exception {
|
public org.hl7.fhir.r5.elementmodel.Element transform(byte[] source, FhirFormat cntType, String mapUri) throws FHIRException, IOException {
|
||||||
List<Base> outputs = new ArrayList<Base>();
|
List<Base> outputs = new ArrayList<Base>();
|
||||||
|
|
||||||
StructureMapUtilities scu = new StructureMapUtilities(context, new TransformSupportServices(outputs));
|
StructureMapUtilities scu = new StructureMapUtilities(context, new TransformSupportServices(outputs));
|
||||||
|
@ -1299,7 +1494,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return Manager.build(getContext(), structureDefinition);
|
return Manager.build(getContext(), structureDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DomainResource generate(String source, String version) throws Exception {
|
public DomainResource generate(String source, String version) throws FHIRException, IOException, EOperationOutcome {
|
||||||
Content cnt = loadContent(source, "validate");
|
Content cnt = loadContent(source, "validate");
|
||||||
Resource res = loadResourceByVersion(version, cnt.focus, source);
|
Resource res = loadResourceByVersion(version, cnt.focus, source);
|
||||||
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
RenderingContext rc = new RenderingContext(context, null, null, "http://hl7.org/fhir", "", null, ResourceRendererMode.RESOURCE);
|
||||||
|
@ -1307,25 +1502,25 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
return (DomainResource) res;
|
return (DomainResource) res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void convert(String source, String output) throws Exception {
|
public void convert(String source, String output) throws FHIRException, IOException {
|
||||||
Content cnt = loadContent(source, "validate");
|
Content cnt = loadContent(source, "validate");
|
||||||
Element e = Manager.parse(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
|
Element e = Manager.parse(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
|
||||||
Manager.compose(context, e, new FileOutputStream(output), (output.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML), OutputStyle.PRETTY, null);
|
Manager.compose(context, e, new FileOutputStream(output), (output.endsWith(".json") ? FhirFormat.JSON : FhirFormat.XML), OutputStyle.PRETTY, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String evaluateFhirPath(String source, String expression) throws Exception {
|
public String evaluateFhirPath(String source, String expression) throws FHIRException, IOException {
|
||||||
Content cnt = loadContent(source, "validate");
|
Content cnt = loadContent(source, "validate");
|
||||||
FHIRPathEngine fpe = new FHIRPathEngine(context);
|
FHIRPathEngine fpe = new FHIRPathEngine(context);
|
||||||
Element e = Manager.parse(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
|
Element e = Manager.parse(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
|
||||||
return fpe.evaluateToString(e, expression);
|
return fpe.evaluateToString(e, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StructureDefinition snapshot(String source, String version) throws Exception {
|
public StructureDefinition snapshot(String source, String version) throws FHIRException, IOException {
|
||||||
Content cnt = loadContent(source, "validate");
|
Content cnt = loadContent(source, "validate");
|
||||||
Resource res = loadResourceByVersion(version, cnt.focus, Utilities.getFileNameForName(source));
|
Resource res = loadResourceByVersion(version, cnt.focus, Utilities.getFileNameForName(source));
|
||||||
|
|
||||||
if (!(res instanceof StructureDefinition))
|
if (!(res instanceof StructureDefinition))
|
||||||
throw new Exception("Require a StructureDefinition for generating a snapshot");
|
throw new FHIRException("Require a StructureDefinition for generating a snapshot");
|
||||||
StructureDefinition sd = (StructureDefinition) res;
|
StructureDefinition sd = (StructureDefinition) res;
|
||||||
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
StructureDefinition base = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||||
|
|
||||||
|
@ -1670,8 +1865,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException {
|
public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException {
|
||||||
if (!url.startsWith("http://hl7.org/fhir"))
|
if (!url.startsWith("http://") && !url.startsWith("https://")) { // ignore these
|
||||||
return true; // we don't bother with those.
|
return true;
|
||||||
|
}
|
||||||
if (context.fetchResource(Resource.class, url) != null)
|
if (context.fetchResource(Resource.class, url) != null)
|
||||||
return true;
|
return true;
|
||||||
if (Utilities.existsInList(url, "http://hl7.org/fhir/sid/us-ssn", "http://hl7.org/fhir/sid/cvx", "http://hl7.org/fhir/sid/ndc", "http://hl7.org/fhir/sid/us-npi", "http://hl7.org/fhir/sid/icd-10",
|
if (Utilities.existsInList(url, "http://hl7.org/fhir/sid/us-ssn", "http://hl7.org/fhir/sid/cvx", "http://hl7.org/fhir/sid/ndc", "http://hl7.org/fhir/sid/us-npi", "http://hl7.org/fhir/sid/icd-10",
|
||||||
|
@ -1679,6 +1875,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
"http://hl7.org/fhir/workflow", "http://hl7.org/fhir/ConsentPolicy/opt-out", "http://hl7.org/fhir/ConsentPolicy/opt-in")) {
|
"http://hl7.org/fhir/workflow", "http://hl7.org/fhir/ConsentPolicy/opt-out", "http://hl7.org/fhir/ConsentPolicy/opt-in")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (Utilities.existsInList(url, "http://loinc.org", "http://unitsofmeasure.org", "http://snomed.info/sct")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (fetcher != null) {
|
if (fetcher != null) {
|
||||||
return fetcher.resolveURL(appContext, path, url);
|
return fetcher.resolveURL(appContext, path, url);
|
||||||
};
|
};
|
||||||
|
@ -1690,7 +1889,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleOutput(Resource r, String output, String version) throws Exception {
|
public void handleOutput(Resource r, String output, String version) throws FHIRException, IOException {
|
||||||
if (output.startsWith("http://") || output.startsWith("http://")) {
|
if (output.startsWith("http://") || output.startsWith("http://")) {
|
||||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
handleOutputToStream(r, output, bs, version);
|
handleOutputToStream(r, output, bs, version);
|
||||||
|
@ -1719,7 +1918,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleOutputToStream(Resource r, String fn, OutputStream s, String version) throws Exception {
|
private void handleOutputToStream(Resource r, String fn, OutputStream s, String version) throws FHIRException, IOException {
|
||||||
if (fn.endsWith(".html") || fn.endsWith(".htm") && r instanceof DomainResource)
|
if (fn.endsWith(".html") || fn.endsWith(".htm") && r instanceof DomainResource)
|
||||||
new XhtmlComposer(XhtmlComposer.HTML, true).compose(s, ((DomainResource) r).getText().getDiv());
|
new XhtmlComposer(XhtmlComposer.HTML, true).compose(s, ((DomainResource) r).getText().getDiv());
|
||||||
else if (version.startsWith("3.0")) {
|
else if (version.startsWith("3.0")) {
|
||||||
|
@ -1731,7 +1930,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
TextFile.stringToStream(org.hl7.fhir.dstu3.utils.StructureMapUtilities.render((org.hl7.fhir.dstu3.model.StructureMap) res), s, false);
|
TextFile.stringToStream(org.hl7.fhir.dstu3.utils.StructureMapUtilities.render((org.hl7.fhir.dstu3.model.StructureMap) res), s, false);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else if (version.startsWith("4.0")) {
|
} else if (version.startsWith("4.0")) {
|
||||||
org.hl7.fhir.r4.model.Resource res = VersionConvertor_40_50.convertResource(r);
|
org.hl7.fhir.r4.model.Resource res = VersionConvertor_40_50.convertResource(r);
|
||||||
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
||||||
|
@ -1741,7 +1940,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
TextFile.stringToStream(org.hl7.fhir.r4.utils.StructureMapUtilities.render((org.hl7.fhir.r4.model.StructureMap) res), s, false);
|
TextFile.stringToStream(org.hl7.fhir.r4.utils.StructureMapUtilities.render((org.hl7.fhir.r4.model.StructureMap) res), s, false);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else if (version.startsWith("1.4")) {
|
} else if (version.startsWith("1.4")) {
|
||||||
org.hl7.fhir.dstu2016may.model.Resource res = VersionConvertor_14_50.convertResource(r);
|
org.hl7.fhir.dstu2016may.model.Resource res = VersionConvertor_14_50.convertResource(r);
|
||||||
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
||||||
|
@ -1749,7 +1948,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
||||||
new org.hl7.fhir.dstu2016may.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2016may.formats.IParser.OutputStyle.PRETTY).compose(s, res);
|
new org.hl7.fhir.dstu2016may.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2016may.formats.IParser.OutputStyle.PRETTY).compose(s, res);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else if (version.startsWith("1.0")) {
|
} else if (version.startsWith("1.0")) {
|
||||||
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
|
VersionConvertorAdvisor50 advisor = new org.hl7.fhir.convertors.misc.IGR2ConvertorAdvisor5();
|
||||||
org.hl7.fhir.dstu2.model.Resource res = VersionConvertor_10_50.convertResource(r, advisor);
|
org.hl7.fhir.dstu2.model.Resource res = VersionConvertor_10_50.convertResource(r, advisor);
|
||||||
|
@ -1758,7 +1957,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
else if (fn.endsWith(".json") && !fn.endsWith("template.json"))
|
||||||
new org.hl7.fhir.dstu2.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2.formats.IParser.OutputStyle.PRETTY).compose(s, res);
|
new org.hl7.fhir.dstu2.formats.JsonParser().setOutputStyle(org.hl7.fhir.dstu2.formats.IParser.OutputStyle.PRETTY).compose(s, res);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else if (version.equals(Constants.VERSION)) {
|
} else if (version.equals(Constants.VERSION)) {
|
||||||
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
if (fn.endsWith(".xml") && !fn.endsWith("template.xml"))
|
||||||
new XmlParser().setOutputStyle(org.hl7.fhir.r5.formats.IParser.OutputStyle.PRETTY).compose(s, r);
|
new XmlParser().setOutputStyle(org.hl7.fhir.r5.formats.IParser.OutputStyle.PRETTY).compose(s, r);
|
||||||
|
@ -1767,9 +1966,9 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
else if (fn.endsWith(".txt") || fn.endsWith(".map") )
|
||||||
TextFile.stringToStream(org.hl7.fhir.r5.utils.StructureMapUtilities.render((org.hl7.fhir.r5.model.StructureMap) r), s, false);
|
TextFile.stringToStream(org.hl7.fhir.r5.utils.StructureMapUtilities.render((org.hl7.fhir.r5.model.StructureMap) r), s, false);
|
||||||
else
|
else
|
||||||
throw new Exception("Unsupported format for "+fn);
|
throw new FHIRException("Unsupported format for "+fn);
|
||||||
} else
|
} else
|
||||||
throw new Exception("Encounted unsupported configured version "+version+" loading "+fn);
|
throw new FHIRException("Encounted unsupported configured version "+version+" loading "+fn);
|
||||||
|
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
@ -1833,7 +2032,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
} else if (VersionUtilities.isR4Ver(version)) {
|
} else if (VersionUtilities.isR4Ver(version)) {
|
||||||
return convertVersionNativeR4(targetVer, cnt, format);
|
return convertVersionNativeR4(targetVer, cnt, format);
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Source version not supported yet: "+version);
|
throw new FHIRException("Source version not supported yet: "+version);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Conversion failed using Java convertor: "+e.getMessage());
|
System.out.println("Conversion failed using Java convertor: "+e.getMessage());
|
||||||
|
@ -1940,7 +2139,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Target Version not supported yet: "+targetVer);
|
throw new FHIRException("Target Version not supported yet: "+targetVer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2009,7 +2208,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Target Version not supported yet: "+targetVer);
|
throw new FHIRException("Target Version not supported yet: "+targetVer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2078,7 +2277,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Target Version not supported yet: "+targetVer);
|
throw new FHIRException("Target Version not supported yet: "+targetVer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2147,7 +2346,7 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
throw new FHIRException("Unsupported output format: "+cnt.cntType.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Exception("Target Version not supported yet: "+targetVer);
|
throw new FHIRException("Target Version not supported yet: "+targetVer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2165,5 +2364,10 @@ public class ValidationEngine implements IValidatorResourceFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FilesystemPackageCacheManager getPcm() {
|
||||||
|
return pcm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -65,6 +65,7 @@ import org.hl7.fhir.r5.model.ImplementationGuide;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.validation.ValidationEngine.VersionSourceInformation;
|
||||||
import org.hl7.fhir.validation.cli.ValidatorGui;
|
import org.hl7.fhir.validation.cli.ValidatorGui;
|
||||||
import org.hl7.fhir.validation.cli.services.ComparisonService;
|
import org.hl7.fhir.validation.cli.services.ComparisonService;
|
||||||
import org.hl7.fhir.validation.cli.services.ValidationService;
|
import org.hl7.fhir.validation.cli.services.ValidationService;
|
||||||
|
@ -171,6 +172,10 @@ public class Validator {
|
||||||
Display.printCliArgumentsAndInfo(args);
|
Display.printCliArgumentsAndInfo(args);
|
||||||
cliContext = Params.loadCliContext(args);
|
cliContext = Params.loadCliContext(args);
|
||||||
|
|
||||||
|
if (cliContext.getSv() == null) {
|
||||||
|
cliContext.setSv(determineVersion(cliContext));
|
||||||
|
}
|
||||||
|
|
||||||
// Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long). Version gets spit out a couple of lines later after we've loaded the context
|
// Comment this out because definitions filename doesn't necessarily contain version (and many not even be 14 characters long). Version gets spit out a couple of lines later after we've loaded the context
|
||||||
String definitions = VersionUtilities.packageForVersion(cliContext.getSv()) + "#" + VersionUtilities.getCurrentVersion(cliContext.getSv());
|
String definitions = VersionUtilities.packageForVersion(cliContext.getSv()) + "#" + VersionUtilities.getCurrentVersion(cliContext.getSv());
|
||||||
ValidationEngine validator = ValidationService.getValidator(cliContext, definitions);
|
ValidationEngine validator = ValidationService.getValidator(cliContext, definitions);
|
||||||
|
@ -204,5 +209,27 @@ public class Validator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String determineVersion(CliContext cliContext) throws Exception {
|
||||||
|
if (cliContext.getMode() != EngineMode.VALIDATION) {
|
||||||
|
return "current";
|
||||||
|
}
|
||||||
|
System.out.println("Scanning for versions (no -version parameter):");
|
||||||
|
VersionSourceInformation versions = ValidationService.scanForVersions(cliContext);
|
||||||
|
for (String s : versions.getReport()) {
|
||||||
|
System.out.println(" "+s);
|
||||||
|
}
|
||||||
|
if (versions.isEmpty()) {
|
||||||
|
System.out.println("-> Using Default version '"+VersionUtilities.CURRENT_VERSION+"'");
|
||||||
|
return "current";
|
||||||
|
}
|
||||||
|
if (versions.size() == 1) {
|
||||||
|
System.out.println("-> use version "+versions.version());
|
||||||
|
return versions.version();
|
||||||
|
}
|
||||||
|
throw new Exception("-> Multiple versions found. Specify a particular version using the -version parameter");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -36,7 +36,7 @@ public class CliContext {
|
||||||
@JsonProperty("txServer")
|
@JsonProperty("txServer")
|
||||||
private String txServer = "http://tx.fhir.org";
|
private String txServer = "http://tx.fhir.org";
|
||||||
@JsonProperty("sv")
|
@JsonProperty("sv")
|
||||||
private String sv = "current";
|
private String sv = null;
|
||||||
@JsonProperty("txLog")
|
@JsonProperty("txLog")
|
||||||
private String txLog = null;
|
private String txLog = null;
|
||||||
@JsonProperty("mapLog")
|
@JsonProperty("mapLog")
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
package org.hl7.fhir.validation.cli.services;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
|
import org.hl7.fhir.r5.utils.IResourceValidator.IValidatorResourceFetcher;
|
||||||
|
import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
||||||
|
import org.hl7.fhir.utilities.cache.BasePackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.cache.FilesystemPackageCacheManager;
|
||||||
|
import org.hl7.fhir.utilities.cache.NpmPackage;
|
||||||
|
import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher.IPackageInstaller;
|
||||||
|
|
||||||
|
public class StandAloneValidatorFetcher implements IValidatorResourceFetcher {
|
||||||
|
|
||||||
|
public interface IPackageInstaller {
|
||||||
|
public void loadIg(String src, boolean recursive) throws IOException, FHIRException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasePackageCacheManager pcm;
|
||||||
|
private IWorkerContext context;
|
||||||
|
private IPackageInstaller installer;
|
||||||
|
|
||||||
|
public StandAloneValidatorFetcher(FilesystemPackageCacheManager pcm, IWorkerContext context, IPackageInstaller installer) {
|
||||||
|
super();
|
||||||
|
this.pcm = pcm;
|
||||||
|
this.context = context;
|
||||||
|
this.installer = installer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
|
throw new Error("Not done yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) {
|
||||||
|
throw new Error("Not done yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException {
|
||||||
|
if (!Utilities.isAbsoluteUrl(url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if we've got to here, it's a reference to a FHIR URL. We're going to try to resolve it on the fly
|
||||||
|
|
||||||
|
// first possibility: it's a reference to a version specific URL http://hl7.org/fhir/X.X/...
|
||||||
|
VersionURLInfo vu = VersionUtilities.parseVersionUrl(url);
|
||||||
|
if (vu != null) {
|
||||||
|
NpmPackage pi = pcm.loadPackage(VersionUtilities.packageForVersion(vu.getVersion()), VersionUtilities.getCurrentVersion(vu.getVersion()));
|
||||||
|
return pi.hasCanonical(vu.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok maybe it's a reference to a package we know
|
||||||
|
String base = findBaseUrl(url);
|
||||||
|
String pid = pcm.getPackageId(base);
|
||||||
|
if (url.contains("|")) {
|
||||||
|
pid = pid+"#"+url.substring(url.indexOf("|")+1);
|
||||||
|
}
|
||||||
|
if (pid != null) {
|
||||||
|
installer.loadIg(pid, false);
|
||||||
|
NpmPackage pi = pcm.loadPackage(pid);
|
||||||
|
return pi.hasCanonical(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!url.startsWith("http://hl7.org/fhir")) {
|
||||||
|
return true; // we don't bother with those in the standalone validator - we assume they are valid
|
||||||
|
}
|
||||||
|
|
||||||
|
// we assume it's invalid at this point
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String findBaseUrl(String url) {
|
||||||
|
String[] p = url.split("\\/");
|
||||||
|
for (int i = 1; i< p.length; i++) {
|
||||||
|
if (Utilities.existsInList(p[i], context.getResourceNames())) {
|
||||||
|
StringBuilder b = new StringBuilder(p[0]);
|
||||||
|
for (int j = 1; j < i; j++) {
|
||||||
|
b.append("/");
|
||||||
|
b.append(p[j]);
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] fetchRaw(String url) throws MalformedURLException, IOException {
|
||||||
|
throw new Error("Not done yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLocale(Locale locale) {
|
||||||
|
throw new Error("Not done yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.validation.ValidationEngine;
|
import org.hl7.fhir.validation.ValidationEngine;
|
||||||
|
import org.hl7.fhir.validation.ValidationEngine.VersionSourceInformation;
|
||||||
import org.hl7.fhir.validation.cli.model.*;
|
import org.hl7.fhir.validation.cli.model.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -52,6 +53,15 @@ public class ValidationService {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static VersionSourceInformation scanForVersions(CliContext cliContext) throws Exception {
|
||||||
|
VersionSourceInformation versions = new VersionSourceInformation();
|
||||||
|
ValidationEngine ve = new ValidationEngine();
|
||||||
|
for (String src : cliContext.getIgs()) {
|
||||||
|
ve.scanForIgVersion(src, cliContext.isRecursive(), versions);
|
||||||
|
}
|
||||||
|
ve.scanForVersions(cliContext.getSources(), versions);
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
public static void validateSources(CliContext cliContext, ValidationEngine validator, long loadStart) throws Exception {
|
public static void validateSources(CliContext cliContext, ValidationEngine validator, long loadStart) throws Exception {
|
||||||
validator.doneLoading(loadStart);
|
validator.doneLoading(loadStart);
|
||||||
if (cliContext.getProfiles().size() > 0) {
|
if (cliContext.getProfiles().size() > 0) {
|
||||||
|
@ -205,6 +215,7 @@ public class ValidationService {
|
||||||
validator.setSecurityChecks(cliContext.isSecurityChecks());
|
validator.setSecurityChecks(cliContext.isSecurityChecks());
|
||||||
validator.setCrumbTrails(cliContext.isCrumbTrails());
|
validator.setCrumbTrails(cliContext.isCrumbTrails());
|
||||||
validator.setShowTimes(cliContext.isShowTimes());
|
validator.setShowTimes(cliContext.isShowTimes());
|
||||||
|
validator.setFetcher(new StandAloneValidatorFetcher(validator.getPcm(), validator.getContext(), validator));
|
||||||
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
TerminologyCache.setNoCaching(cliContext.isNoInternalCaching());
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,7 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
||||||
import org.hl7.fhir.utilities.VersionUtilities;
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
import org.hl7.fhir.utilities.validation.ValidationOptions;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
|
@ -592,8 +593,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
throw new FHIRException(e1);
|
throw new FHIRException(e1);
|
||||||
}
|
}
|
||||||
timeTracker.load(t);
|
timeTracker.load(t);
|
||||||
if (e != null)
|
if (e != null) {
|
||||||
validate(appContext, errors, e, profiles);
|
validate(appContext, errors, e, profiles);
|
||||||
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1856,7 +1858,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (fetcher != null) {
|
if (fetcher != null) {
|
||||||
boolean found;
|
boolean found;
|
||||||
try {
|
try {
|
||||||
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com"))) || (url.startsWith("http://hl7.org/fhir/tools")) || fetcher.resolveURL(appContext, path, url);
|
found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) || fetcher.resolveURL(appContext, path, url);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
found = false;
|
found = false;
|
||||||
}
|
}
|
||||||
|
@ -2928,7 +2930,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return rr;
|
return rr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stack.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY) {
|
if (stack.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || stack.getElement().getSpecial() == SpecialElement.PARAMETER) {
|
||||||
return null; // we don't try to resolve contained references across this boundary
|
return null; // we don't try to resolve contained references across this boundary
|
||||||
}
|
}
|
||||||
stack = stack.getParent();
|
stack = stack.getParent();
|
||||||
|
@ -2963,6 +2965,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return rr;
|
return rr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stack.getElement().getSpecial() == SpecialElement.PARAMETER && stack.getParent() != null) {
|
||||||
|
NodeStack tgt = findInParams(stack.getParent().getParent(), ref);
|
||||||
|
if (tgt != null) {
|
||||||
|
ResolvedReference rr = new ResolvedReference();
|
||||||
|
rr.setResource(tgt.getElement());
|
||||||
|
rr.setFocus(tgt.getElement());
|
||||||
|
rr.setExternal(false);
|
||||||
|
rr.setStack(tgt);
|
||||||
|
rr.getStack().qualifyPath(".ofType("+tgt.getElement().fhirType()+")");
|
||||||
|
return rr;
|
||||||
|
}
|
||||||
|
}
|
||||||
stack = stack.getParent();
|
stack = stack.getParent();
|
||||||
}
|
}
|
||||||
// we can get here if we got called via FHIRPath conformsTo which breaks the stack continuity.
|
// we can get here if we got called via FHIRPath conformsTo which breaks the stack continuity.
|
||||||
|
@ -2989,6 +3003,42 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NodeStack findInParams(NodeStack params, String ref) {
|
||||||
|
int i = 0;
|
||||||
|
for (Element child : params.getElement().getChildren("parameter")) {
|
||||||
|
NodeStack p = params.push(child, i, child.getProperty().getDefinition(), child.getProperty().getDefinition());
|
||||||
|
if (child.hasChild("resource")) {
|
||||||
|
Element res = child.getNamedChild("resource");
|
||||||
|
if ((res.fhirType()+"/"+res.getIdBase()).equals(ref)) {
|
||||||
|
return p.push(res, -1, res.getProperty().getDefinition(), res.getProperty().getDefinition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NodeStack pc = findInParamParts(p, child, ref);
|
||||||
|
if (pc != null) {
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeStack findInParamParts(NodeStack pp, Element param, String ref) {
|
||||||
|
int i = 0;
|
||||||
|
for (Element child : param.getChildren("part")) {
|
||||||
|
NodeStack p = pp.push(child, i, child.getProperty().getDefinition(), child.getProperty().getDefinition());
|
||||||
|
if (child.hasChild("resource")) {
|
||||||
|
Element res = child.getNamedChild("resource");
|
||||||
|
if ((res.fhirType()+"/"+res.getIdBase()).equals(ref)) {
|
||||||
|
return p.push(res, -1, res.getProperty().getDefinition(), res.getProperty().getDefinition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NodeStack pc = findInParamParts(p, child, ref);
|
||||||
|
if (pc != null) {
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private Element getEntryForSource(Element bundle, Element element) {
|
private Element getEntryForSource(Element bundle, Element element) {
|
||||||
List<Element> entries = new ArrayList<Element>();
|
List<Element> entries = new ArrayList<Element>();
|
||||||
bundle.getNamedChildren(ENTRY, entries);
|
bundle.getNamedChildren(ENTRY, entries);
|
||||||
|
@ -3432,7 +3482,18 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
for (Element profile : profiles) {
|
for (Element profile : profiles) {
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, profile.primitiveValue());
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, profile.primitiveValue());
|
||||||
if (!defn.getUrl().equals(profile.primitiveValue())) {
|
if (!defn.getUrl().equals(profile.primitiveValue())) {
|
||||||
if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", sd != null, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN, profile.primitiveValue())) {
|
// is this a version specific reference?
|
||||||
|
VersionURLInfo vu = VersionUtilities.parseVersionUrl(profile.primitiveValue());
|
||||||
|
if (vu != null) {
|
||||||
|
if (!VersionUtilities.versionsCompatible(vu.getVersion(), context.getVersion())) {
|
||||||
|
hint(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_OTHER_VERSION, vu.getVersion());
|
||||||
|
} else if (vu.getUrl().equals(defn.getUrl())) {
|
||||||
|
hint(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_THIS_VERSION_OK);
|
||||||
|
} else {
|
||||||
|
StructureDefinition sdt = context.fetchResource(StructureDefinition.class, vu.getUrl());
|
||||||
|
rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_THIS_VERSION_OTHER, sdt == null ? "null" : sdt.getType());
|
||||||
|
}
|
||||||
|
} else if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", sd != null, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN, profile.primitiveValue())) {
|
||||||
signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl());
|
signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl());
|
||||||
stack.resetIds();
|
stack.resetIds();
|
||||||
startInner(hostContext, errors, resource, element, sd, stack, false);
|
startInner(hostContext, errors, resource, element, sd, stack, false);
|
||||||
|
@ -3658,9 +3719,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (trr == null) {
|
if (trr == null) {
|
||||||
rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE, resourceName);
|
rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE, resourceName);
|
||||||
} else if (isValidResourceType(resourceName, trr)) {
|
} else if (isValidResourceType(resourceName, trr)) {
|
||||||
long t = System.nanoTime();
|
|
||||||
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + resourceName);
|
|
||||||
timeTracker.sd(t);
|
|
||||||
// special case: resource wrapper is reset if we're crossing a bundle boundary, but not otherwise
|
// special case: resource wrapper is reset if we're crossing a bundle boundary, but not otherwise
|
||||||
ValidatorHostContext hc = null;
|
ValidatorHostContext hc = null;
|
||||||
if (element.getSpecial() == SpecialElement.BUNDLE_ENTRY || element.getSpecial() == SpecialElement.BUNDLE_OUTCOME || element.getSpecial() == SpecialElement.PARAMETER) {
|
if (element.getSpecial() == SpecialElement.BUNDLE_ENTRY || element.getSpecial() == SpecialElement.BUNDLE_OUTCOME || element.getSpecial() == SpecialElement.PARAMETER) {
|
||||||
|
@ -3669,10 +3727,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
} else {
|
} else {
|
||||||
hc = hostContext.forContained(element);
|
hc = hostContext.forContained(element);
|
||||||
}
|
}
|
||||||
trackUsage(profile, hostContext, element);
|
|
||||||
stack.resetIds();
|
stack.resetIds();
|
||||||
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) {
|
if (trr.getProfile().size() == 1) {
|
||||||
validateResource(hc, errors, resource, element, profile, idstatus, stack);
|
long t = System.nanoTime();
|
||||||
|
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, trr.getProfile().get(0).asStringValue());
|
||||||
|
timeTracker.sd(t);
|
||||||
|
trackUsage(profile, hostContext, element);
|
||||||
|
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) {
|
||||||
|
validateResource(hc, errors, resource, element, profile, idstatus, stack);
|
||||||
|
}
|
||||||
|
} else if (trr.getProfile().size() == 0) {
|
||||||
|
long t = System.nanoTime();
|
||||||
|
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + resourceName);
|
||||||
|
timeTracker.sd(t);
|
||||||
|
trackUsage(profile, hostContext, element);
|
||||||
|
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) {
|
||||||
|
validateResource(hc, errors, resource, element, profile, idstatus, stack);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
|
||||||
|
for (CanonicalType u : trr.getProfile()) {
|
||||||
|
b.append(u.asStringValue());
|
||||||
|
}
|
||||||
|
rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES, trr.getCode(), b.toString());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<String> types = new ArrayList<>();
|
List<String> types = new ArrayList<>();
|
||||||
|
|
Loading…
Reference in New Issue