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 fe24e96ef..07f588919 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 @@ -305,9 +305,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (item instanceof Element) { Element e = (Element) item; if (e.getSpecial() == SpecialElement.CONTAINED) { - self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e, ctxt.getRootResource()), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, null, e, validationLanguage)); + self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e, ctxt.getRootResource(), ctxt.getGroupingResource()), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, null, e, validationLanguage)); } else if (e.getSpecial() != null) { - self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, null, e, validationLanguage)); + self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e, ctxt.getRootResource(), ctxt.getRootResource()), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, null, e, validationLanguage)); } else { self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL, new NodeStack(context, null, e, validationLanguage)); } @@ -2891,7 +2891,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !isSuspiciousReference(ref), I18nConstants.REFERENCE_REF_SUSPICIOUS, ref); - ResolvedReference we = localResolve(ref, stack, errors, path, hostContext.getRootResource(), element); + ResolvedReference we = localResolve(ref, stack, errors, path, hostContext.getRootResource(), hostContext.getGroupingResource(), element); String refType; if (ref.startsWith("#")) { refType = "contained"; @@ -3586,7 +3586,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return true; } - private ResolvedReference localResolve(String ref, NodeStack stack, List errors, String path, Element rootResource, Element source) { + private ResolvedReference localResolve(String ref, NodeStack stack, List errors, String path, Element rootResource, Element groupingResource, Element source) { if (ref.startsWith("#")) { // work back through the parent list. // really, there should only be one level for this (contained resources cannot contain @@ -3686,11 +3686,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat stack = stack.getParent(); } // we can get here if we got called via FHIRPath conformsTo which breaks the stack continuity. - if (rootResource != null && BUNDLE.equals(rootResource.fhirType())) { - String type = rootResource.getChildValue(TYPE); - Element entry = getEntryForSource(rootResource, source); + if (groupingResource != null && BUNDLE.equals(groupingResource.fhirType())) { // it could also be a Parameters resource - that case isn't handled yet + String type = groupingResource.getChildValue(TYPE); + Element entry = getEntryForSource(groupingResource, source); fullUrl = entry.getChildValue(FULL_URL); - IndexedElement res = getFromBundle(rootResource, ref, fullUrl, errors, path, type, "transaction".equals(type)); + IndexedElement res = getFromBundle(groupingResource, ref, fullUrl, errors, path, type, "transaction".equals(type)); if (res == null) { return null; } else { @@ -3767,7 +3767,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private Element resolve(Object appContext, String ref, NodeStack stack, List errors, String path) throws IOException, FHIRException { - Element local = localResolve(ref, stack, errors, path, null, null).getFocus(); + Element local = localResolve(ref, stack, errors, path, null, null, null).getFocus(); if (local != null) return local; if (fetcher == null) @@ -4600,7 +4600,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ValidatorHostContext hc = null; if (special == SpecialElement.BUNDLE_ENTRY || special == SpecialElement.BUNDLE_OUTCOME || special == SpecialElement.PARAMETER) { resource = element; - hc = hostContext.forEntry(element); + assert Utilities.existsInList(hostContext.getRootResource().fhirType(), "Bundle", "Parameters"); + hc = hostContext.forEntry(element, hostContext.getRootResource()); // root becomes the grouping resource (should be either bundle or parameters) } else { hc = hostContext.forContained(element); } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java index af29a2188..83a180049 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/ValidatorHostContext.java @@ -16,6 +16,7 @@ public class ValidatorHostContext { private Element resource; // the resource that is the scope of id resolution - either the same as resource, or the resource the contains that resource. This can only be one level deep. private Element rootResource; + private Element groupingResource; // either a bundle or a parameters that holds the rootResource (for reference resolution) private StructureDefinition profile; // the profile that contains the content being validated private boolean checkSpecials = true; @@ -29,7 +30,7 @@ public class ValidatorHostContext { this.appContext = appContext; this.resource = element; this.rootResource = element; - // no container + // no groupingResource (Bundle or Parameters) dump("creating"); } @@ -37,7 +38,15 @@ public class ValidatorHostContext { this.appContext = appContext; this.resource = element; this.rootResource = root; - // no container + // no groupingResource (Bundle or Parameters) + dump("creating"); + } + + public ValidatorHostContext(Object appContext, Element element, Element root, Element groupingResource) { + this.appContext = appContext; + this.resource = element; + this.rootResource = root; + this.groupingResource = groupingResource; dump("creating"); } @@ -65,6 +74,10 @@ public class ValidatorHostContext { return this; } + public Element getGroupingResource() { + return groupingResource; + } + public StructureDefinition getProfile() { return profile; } @@ -106,15 +119,17 @@ public class ValidatorHostContext { res.rootResource = resource; res.resource = element; res.profile = profile; + res.groupingResource = groupingResource; res.dump("forContained"); return res; } - public ValidatorHostContext forEntry(Element element) { + public ValidatorHostContext forEntry(Element element, Element groupingResource) { ValidatorHostContext res = new ValidatorHostContext(appContext); res.rootResource = element; res.resource = element; res.profile = profile; + res.groupingResource = groupingResource; res.dump("forEntry"); return res; } @@ -124,6 +139,7 @@ public class ValidatorHostContext { res.resource = resource; res.rootResource = rootResource; res.profile = profile; + res.groupingResource = groupingResource; res.sliceRecords = sliceRecords != null ? sliceRecords : new HashMap>(); res.dump("forProfile "+profile.getUrl()); return res; @@ -134,6 +150,7 @@ public class ValidatorHostContext { res.resource = resource; res.rootResource = resource; res.profile = profile; + res.groupingResource = groupingResource; res.checkSpecials = false; res.dump("forLocalReference "+profile.getUrl()); return res; @@ -151,6 +168,7 @@ public class ValidatorHostContext { res.resource = resource; res.rootResource = resource; res.profile = profile; + res.groupingResource = null; res.checkSpecials = false; res.dump("forRemoteReference "+profile.getUrl()); return res; @@ -160,6 +178,7 @@ public class ValidatorHostContext { ValidatorHostContext res = new ValidatorHostContext(appContext); res.resource = resource; res.rootResource = resource; + res.groupingResource = groupingResource; res.profile = profile; res.checkSpecials = false; res.sliceRecords = new HashMap>();