From 3a319a5d57758e756e92fb9fa184cf9d0f243f9a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Jun 2021 20:35:38 +1000 Subject: [PATCH] Fix pathing issues in the validator --- .../validation/ValidationMessage.java | 3 ++- .../src/main/resources/Messages.properties | 2 +- .../hl7/fhir/validation/BaseValidator.java | 9 +++---- .../instance/InstanceValidator.java | 25 +++++++++++++------ .../instance/type/BundleValidator.java | 4 ++- .../instance/utils/ChildIterator.java | 9 ++++--- .../validation/instance/utils/NodeStack.java | 2 +- 7 files changed, 33 insertions(+), 21 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java index cbd5662d7..e54ad176a 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/ValidationMessage.java @@ -790,8 +790,9 @@ public class ValidationMessage implements Comparator, Compara return signpost; } - public void setSignpost(boolean signpost) { + public ValidationMessage setSignpost(boolean signpost) { this.signpost = signpost; + return this; } diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 606d16d73..8a9d622a3 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -526,7 +526,7 @@ TYPE_CHECKS_FIXED_CC_US = The pattern [system {0}, code {1}, display ''{2}'' and VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN = Global Profile reference ''{0}'' from IG {1} could not be resolved, so has not been checked VALIDATION_VAL_PROFILE_SIGNPOST_BASE = Validate resource against profile VALIDATION_VAL_PROFILE_SIGNPOST = Validate resource against profile {0} -VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} - listed in meta +VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} (per meta) VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = Validate resource against profile {0} - provided as bundle param VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = Validate resource against profile {0} - a global profile in {1} ERROR_GENERATING_SNAPSHOT = Error generating Snapshot: {0} (this usually arises from a problem in the differential) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index da3947d4c..798a47d7c 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -284,12 +284,9 @@ public class BaseValidator { return thePass; } - protected boolean signpost(List errors, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { - if (!thePass) { - String message = context.formatMessage(theMessage, theMessageArguments); - addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage).setSignpost(true); - } - return thePass; + protected ValidationMessage signpost(List errors, IssueType type, int line, int col, String path, String theMessage, Object... theMessageArguments) { + String message = context.formatMessage(theMessage, theMessageArguments); + return addValidationMessage(errors, type, line, col, path, message, IssueSeverity.INFORMATION, theMessage).setSignpost(true); } protected boolean txHint(List errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String theMessage, Object... theMessageArguments) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index bded58268..729963403 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -3270,8 +3270,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rr.setResource(nstack.getElement()); rr.setFocus(nstack.getElement()); rr.setExternal(false); - rr.setStack(nstack.push(nstack.getElement(), -1, nstack.getElement().getProperty().getDefinition(), nstack.getElement().getProperty().getDefinition())); - rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")"); + rr.setStack(nstack); +// rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")"); + System.out.println("-->"+nstack.getLiteralPath()); return rr; } if (nstack.getElement().getSpecial() == SpecialElement.CONTAINED) { @@ -3951,7 +3952,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // checkSpecials = we're only going to run these tests if we are actually validating this content (as opposed to we looked it up) private void start(ValidatorHostContext hostContext, List errors, Element resource, Element element, StructureDefinition defn, NodeStack stack) throws FHIRException { checkLang(resource, stack); - signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST, defn.getUrl()); + if (crumbTrails) { + element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST, defn.getUrl())); + } if (BUNDLE.equals(element.fhirType())) { resolveBundleReferences(element, new ArrayList()); @@ -3996,7 +3999,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (sd != null) { - signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl()); + if (crumbTrails) { + element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_META, sd.getUrl())); + } stack.resetIds(); startInner(hostContext, errors, resource, element, sd, stack, false); } @@ -4011,7 +4016,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (rt.equals(gl.getType())) { StructureDefinition sd = context.fetchResource(StructureDefinition.class, gl.getProfile()); if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), sd != null, I18nConstants.VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN, gl.getProfile())) { - signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), !crumbTrails, I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL, sd.getUrl(), ig.getUrl()); + if (crumbTrails) { + element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL, sd.getUrl(), ig.getUrl())); + } stack.resetIds(); startInner(hostContext, errors, resource, element, sd, stack, false); } @@ -4517,13 +4524,15 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat type = null; } } - NodeStack localStack = stack.push(ei.getElement(), ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType())); + NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType())); // if (debug) { // System.out.println(" check " + localStack.getLiteralPath()+" against "+ei.getDefinition().getId()+" in profile "+profile.getUrl()); // } - String localStackLiterapPath = localStack.getLiteralPath(); + String localStackLiteralPath = localStack.getLiteralPath(); String eiPath = ei.getPath(); - assert (eiPath.equals(localStackLiterapPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiterapPath; + if (!eiPath.equals(localStackLiteralPath)) { + assert (eiPath.equals(localStackLiteralPath)) : "ei.path: " + ei.getPath() + " - localStack.getLiteralPath: " + localStackLiteralPath; + } boolean thisIsCodeableConcept = false; String thisExtension = null; boolean checkDisplay = true; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java index f321ac948..78a06b761 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java @@ -112,7 +112,9 @@ public class BundleValidator extends BaseValidator{ } else { Element res = entry.getNamedChild(RESOURCE); NodeStack rstack = estack.push(res, -1, null, null); - signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), !validator.isCrumbTrails(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl()); + if (validator.isCrumbTrails()) { + res.addMessage(signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl())); + } stack.resetIds(); validator.startInner(hostContext, errors, res, res, defn, rstack, false); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java index 7d1520046..398f947f5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ChildIterator.java @@ -70,9 +70,12 @@ public class ChildIterator { String nb = cursor == 0 ? "--" : parent.getChildren().get(cursor - 1).getName(); String na = cursor >= parent.getChildren().size() - 1 ? "--" : parent.getChildren().get(cursor + 1).getName(); if (name().equals(nb) || name().equals(na)) { - return lastCount; - } else - return -1; + return lastCount; + } else if (element().isBaseList()) { + return 0; + } else { + return -1; + } } public boolean next() { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java index abb85ac64..d1f7fe45d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/NodeStack.java @@ -34,7 +34,7 @@ public class NodeStack { this.context = context; ids = new HashMap<>(); this.element = element; - literalPath = element.getName(); + literalPath = element.getPath(); workingLang = validationLanguage; if (!element.getName().equals(element.fhirType())) { logicalPaths = new ArrayList<>();