From 6e9fd79a2adef89cca1fbc2972bed19d562215a0 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 31 Jan 2020 08:20:33 +1100 Subject: [PATCH] Add support for assumeValidRestReferences --- .../fhir/r5/validation/InstanceValidator.java | 16 ++++++++++++++++ .../hl7/fhir/r5/validation/ValidationEngine.java | 6 ++++++ .../org/hl7/fhir/r5/validation/Validator.java | 6 ++++++ .../validation/tests/ValidationTestSuite.java | 4 +++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index ba35d8a97..738105a92 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -156,6 +156,9 @@ import ca.uhn.fhir.util.ObjectUtil; * Thinking of using this in a java program? Don't! * You should use one of the wrappers instead. Either in HAPI, or use ValidationEngine * + * Validation todo: + * - support @default slices + * * @author Grahame Grieve * */ @@ -2434,6 +2437,19 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean okToRef = !type.hasAggregation() || type.hasAggregation(AggregationMode.REFERENCED); rule(errors, IssueType.REQUIRED, -1, -1, path, okToRef, "Bundled or contained reference not found within the bundle/resource " + ref); } + if (we == null && ft != null && assumeValidRestReferences) { + // if we == null, we inferred ft from the reference. if we are told to treat this as gospel + TypeRefComponent type = getReferenceTypeRef(container.getType()); + Set types = new HashSet<>(); + for (CanonicalType tp : type.getTargetProfile()) { + StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue()); + if (sd != null) { + types.add(sd.getType()); + } + } + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || types.contains(ft), "The type '"+ft+"' implied by the reference URL "+ref+" is not a valid Target for this element (must be one of "+types+")"); + + } if (pol == ReferenceValidationPolicy.CHECK_VALID) { // todo.... } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java index e2cd2093d..f0cbdc4f9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/ValidationEngine.java @@ -241,6 +241,7 @@ public class ValidationEngine implements IValidatorResourceFetcher { private boolean debug; private Set loadedIgs = new HashSet<>(); private IValidatorResourceFetcher fetcher; + private boolean assumeValidRestReferences; private class AsteriskFilter implements FilenameFilter { String dir; @@ -1270,6 +1271,7 @@ public class ValidationEngine implements IValidatorResourceFetcher { validator.setAnyExtensionsAllowed(anyExtensionsAllowed); validator.setNoInvariantChecks(isNoInvariantChecks()); validator.setValidationLanguage(language); + validator.setAssumeValidRestReferences(assumeValidRestReferences); validator.setFetcher(this); return validator; } @@ -1689,6 +1691,10 @@ public class ValidationEngine implements IValidatorResourceFetcher { this.fetcher = fetcher; } + public void setAssumeValidRestReferences(boolean assumeValidRestReferences) { + this.assumeValidRestReferences = assumeValidRestReferences; + } + } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/Validator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/Validator.java index bf4c3d31f..043f54ff1 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/Validator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/Validator.java @@ -217,6 +217,8 @@ public class Validator { System.out.println(" referenced implementation guides or profiles as errors. (Default is to only raise information messages.)"); System.out.println("-hintAboutNonMustSupport: If present, raise hints if the instance contains data elements that are not"); System.out.println(" marked as mustSupport=true. Useful to identify elements included that may be ignored by recipients"); + System.out.println("-assumeValidRestReferences: If present, assume that URLs that reference resources follow the RESTful URI pattern"); + System.out.println(" and it is safe to infer the type from the URL"); System.out.println(""); System.out.println("The validator also supports the param -proxy=[address]:[port] for if you use a proxy"); System.out.println(""); @@ -414,6 +416,7 @@ public class Validator { String fhirpath = null; String snomedCT = "900000000000207008"; boolean doDebug = false; + boolean assumeValidRestReferences = false; // load the parameters - so order doesn't matter for (int i = 0; i < args.length; i++) { @@ -447,6 +450,8 @@ public class Validator { questionnaires.add(args[++i]); } else if (args[i].equals("-native")) { doNative = true; + } else if (args[i].equals("-assumeValidRestReferences")) { + assumeValidRestReferences = true; } else if (args[i].equals("-debug")) { doDebug = true; } else if (args[i].equals("-sct")) { @@ -577,6 +582,7 @@ public class Validator { validator.setAnyExtensionsAllowed(anyExtensionsAllowed); validator.setLanguage(lang); validator.setSnomedExtension(snomedCT); + validator.setAssumeValidRestReferences(assumeValidRestReferences); IParser x; if (output != null && output.endsWith(".json")) diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTestSuite.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTestSuite.java index 94f227698..66b5dd003 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTestSuite.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTestSuite.java @@ -177,6 +177,7 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour } else { val.setAllowExamples(true); } + val.setAssumeValidRestReferences(content.has("assumeValidRestReferences") ? content.get("assumeValidRestReferences").getAsBoolean() : false); if (name.endsWith(".json")) val.validate(null, errors, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON); else @@ -199,7 +200,8 @@ public class ValidationTestSuite implements IEvaluationContext, IValidatorResour System.out.println("Name: " + name+" - profile : "+profile.get("source").getAsString()); v = content.has("version") ? content.get("version").getAsString() : Constants.VERSION; StructureDefinition sd = loadProfile(filename, contents, v, messages); - val.getContext().cacheResource(sd); + val.getContext().cacheResource(sd); + val.setAssumeValidRestReferences(profile.has("assumeValidRestReferences") ? profile.get("assumeValidRestReferences").getAsBoolean() : false); List errorsProfile = new ArrayList(); if (name.endsWith(".json")) val.validate(null, errorsProfile, IOUtils.toInputStream(testCaseContent, Charsets.UTF_8), FhirFormat.JSON, asSdList(sd));