From eded933a2da1910dfe5b1daeea6fb355d64a15b2 Mon Sep 17 00:00:00 2001 From: markiantorno Date: Fri, 21 Feb 2020 15:43:15 -0500 Subject: [PATCH] Refactoring ResolvedReference --- .../r5/validation/EnableWhenEvaluator.java | 2 +- .../instancevalidator/InstanceValidator.java | 143 +++------------- .../ValidatorHostContext.java | 158 ++++++++++++++++++ .../utils/ResolvedReference.java | 3 +- 4 files changed, 184 insertions(+), 122 deletions(-) create mode 100644 org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/ValidatorHostContext.java diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java index 039938219..0ec899f69 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/EnableWhenEvaluator.java @@ -28,7 +28,7 @@ import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.*; import org.hl7.fhir.r5.model.Questionnaire.*; import org.hl7.fhir.r5.utils.FHIRPathEngine; -import org.hl7.fhir.r5.validation.instancevalidator.InstanceValidator.ValidatorHostContext; +import org.hl7.fhir.r5.validation.instancevalidator.ValidatorHostContext; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/InstanceValidator.java index f5a6358aa..735d86cda 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/InstanceValidator.java @@ -172,104 +172,7 @@ import ca.uhn.fhir.util.ObjectUtil; public class InstanceValidator extends BaseValidator implements IResourceValidator { - public class ValidatorHostContext { - private Object appContext; - private Element container; // bundle, or parameters - private Element resource; - private Element rootResource; - private StructureDefinition profile; // the profile that contains the content being validated - private boolean checkSpecials = true; - private Map> sliceRecords; - - public ValidatorHostContext(Object appContext) { - this.appContext = appContext; - } - - public ValidatorHostContext(Object appContext, Element element) { - this.appContext = appContext; - this.resource = element; - this.rootResource = element; - } - - public ValidatorHostContext forContained(Element element) { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.rootResource = resource; - res.resource = element; - res.container = resource; - res.profile = profile; - return res; - } - - public ValidatorHostContext forEntry(Element element) { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.rootResource = element; - res.resource = element; - res.container = resource; - res.profile = profile; - return res; - } - - public ValidatorHostContext forProfile(StructureDefinition profile) { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.resource = resource; - res.rootResource = rootResource; - res.container = container; - res.profile = profile; - res.sliceRecords = sliceRecords != null ? sliceRecords : new HashMap>(); - return res; - } - - public ValidatorHostContext forLocalReference(StructureDefinition profile, Element resource) { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.resource = resource; - res.rootResource = resource; - res.container = container; - res.profile = profile; - res.checkSpecials = false; - return res; - } - - public ValidatorHostContext forRemoteReference(StructureDefinition profile, Element resource) { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.resource = resource; - res.rootResource = resource; - res.container = resource; - res.profile = profile; - res.checkSpecials = false; - return res; - } - - public boolean isCheckSpecials() { - return checkSpecials; - } - - public void setCheckSpecials(boolean checkSpecials) { - this.checkSpecials = checkSpecials; - } - - public Base getResource() { - return resource; - } - - public void sliceNotes(String url, List record) { - sliceRecords.put(url, record); - } - - public ValidatorHostContext forSlicing() { - ValidatorHostContext res = new ValidatorHostContext(appContext); - res.resource = resource; - res.rootResource = resource; - res.container = resource; - res.profile = profile; - res.checkSpecials = false; - res.sliceRecords = new HashMap>(); - return res; - } - - - } - - private class ValidatorHostServices implements IEvaluationContext { + private class ValidatorHostServices implements IEvaluationContext { // private Stack>> @@ -277,7 +180,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat public Base resolveConstant(Object appContext, String name, boolean beforeContext) throws PathEngineException { ValidatorHostContext c = (ValidatorHostContext) appContext; if (externalHostServices != null) - return externalHostServices.resolveConstant(c.appContext, name, beforeContext); + return externalHostServices.resolveConstant(c.getAppContext(), name, beforeContext); else return null; } @@ -286,7 +189,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat public TypeDetails resolveConstantType(Object appContext, String name) throws PathEngineException { ValidatorHostContext c = (ValidatorHostContext) appContext; if (externalHostServices != null) - return externalHostServices.resolveConstantType(c.appContext, name); + return externalHostServices.resolveConstantType(c.getAppContext(), name); else return null; } @@ -322,24 +225,24 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return (Base) refContext.getUserData("validator.bundle.resolution"); } - if (c.appContext instanceof Element) { - Element bnd = (Element) c.appContext; + if (c.getAppContext() instanceof Element) { + Element bnd = (Element) c.getAppContext(); Base res = resolveInBundle(url, bnd); if (res != null) return res; } - Base res = resolveInBundle(url, c.resource); + Base res = resolveInBundle(url, c.getResource()); if (res != null) return res; - res = resolveInBundle(url, c.container); + res = resolveInBundle(url, c.getContainer()); if (res != null) return res; if (externalHostServices != null) - return externalHostServices.resolveReference(c.appContext, url, refContext); + return externalHostServices.resolveReference(c.getAppContext(), url, refContext); else if (fetcher != null) try { - return fetcher.fetch(c.appContext, url); + return fetcher.fetch(c.getAppContext(), url); } catch (IOException e) { throw new FHIRException(e); } @@ -380,14 +283,14 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (item instanceof Resource) { try { Element e = new ObjectConverter(context).convert((Resource) item); - self.validateResource(new ValidatorHostContext(ctxt.appContext, e), valerrors, e, e, sd, IdStatus.OPTIONAL,new NodeStack(e)); + self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL,new NodeStack(e)); } catch (IOException e1) { throw new FHIRException(e1); } } else if (item instanceof Element) { Element e = (Element) item; if (e.isResource()) { - self.validateResource(new ValidatorHostContext(ctxt.appContext, e), valerrors, e, e, sd, IdStatus.OPTIONAL,new NodeStack(e)); + self.validateResource(new ValidatorHostContext(ctxt.getAppContext(), e), valerrors, e, e, sd, IdStatus.OPTIONAL,new NodeStack(e)); } else { throw new FHIRException("Not supported yet"); } @@ -410,8 +313,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat @Override public ValueSet resolveValueSet(Object appContext, String url) { ValidatorHostContext c = (ValidatorHostContext) appContext; - if (c.profile != null && url.startsWith("#")) { - for (Resource r : c.profile.getContained()) { + if (c.getProfile() != null && url.startsWith("#")) { + for (Resource r : c.getProfile().getContained()) { if (r.getId().equals(url.substring(1))) { if (r instanceof ValueSet) return (ValueSet) r; @@ -1708,7 +1611,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (ctxt.getType() == ExtensionContextType.FHIRPATH) { contexts.append("p:"+ctxt.getExpression()); // The context is all elements that match the FHIRPath query found in the expression. - List res = fpe.evaluate(hostContext, resource, hostContext.rootResource, container, fpe.parse(ctxt.getExpression())); + List res = fpe.evaluate(hostContext, resource, hostContext.getRootResource(), container, fpe.parse(ctxt.getExpression())); if (res.contains(container)) { ok = true; } @@ -1722,7 +1625,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else { if (definition.hasContextInvariant()) { for (StringType s : definition.getContextInvariant()) { - if (!fpe.evaluateToBoolean(hostContext, resource, hostContext.rootResource, container, fpe.parse(s.getValue()))) { + if (!fpe.evaluateToBoolean(hostContext, resource, hostContext.getRootResource(), container, fpe.parse(s.getValue()))) { rule(errors, IssueType.STRUCTURE, container.line(), container.col(), stack.literalPath, false, "The extension " + extUrl + " is not allowed to be used at this point (based on context invariant '"+s.getValue()+"')"); return false; @@ -2246,7 +2149,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return; } - ResolvedReference we = localResolve(ref, stack, errors, path, (Element) hostContext.appContext, element); + ResolvedReference we = localResolve(ref, stack, errors, path, (Element) hostContext.getAppContext(), element); String refType; if (ref.startsWith("#")) { refType = "contained"; @@ -2257,7 +2160,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat refType = "bundled"; } } - ReferenceValidationPolicy pol = refType.equals("contained") || refType.equals("bundled") ? ReferenceValidationPolicy.CHECK_VALID : fetcher == null ? ReferenceValidationPolicy.IGNORE : fetcher.validationPolicy(hostContext.appContext, path, ref); + ReferenceValidationPolicy pol = refType.equals("contained") || refType.equals("bundled") ? ReferenceValidationPolicy.CHECK_VALID : fetcher == null ? ReferenceValidationPolicy.IGNORE : fetcher.validationPolicy(hostContext.getAppContext(), path, ref); if (pol.checkExists()) { if (we == null) { @@ -2270,7 +2173,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ext = fetchCache.get(ref); } else { try { - ext = fetcher.fetch(hostContext.appContext, ref); + ext = fetcher.fetch(hostContext.getAppContext(), ref); } catch (IOException e) { throw new FHIRException(e); } @@ -3323,9 +3226,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean pass = evaluateSlicingExpression(shc, element, path, profile, n); if (!pass) { slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Does not match slice'"+ed.getSliceName(), "discriminator = "+Utilities.escapeXml(n.toString())); - for (String url : shc.sliceRecords.keySet()) { + for (String url : shc.getSliceRecords().keySet()) { slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, "Details for "+stack.getLiteralPath()+" against profile "+url, - "Profile "+url+" does not match for "+stack.getLiteralPath()+" because of the following profile issues: "+errorSummaryForSlicingAsHtml(shc.sliceRecords.get(url))); + "Profile "+url+" does not match for "+stack.getLiteralPath()+" because of the following profile issues: "+errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))); } } return pass; @@ -3336,7 +3239,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean ok; try { long t = System.nanoTime(); - ok = fpe.evaluateToBoolean(hostContext.forProfile(profile), hostContext.resource, hostContext.rootResource, element, n); + ok = fpe.evaluateToBoolean(hostContext.forProfile(profile), hostContext.getResource(), hostContext.getRootResource(), element, n); fpeTime = fpeTime + (System.nanoTime() - t); msg = fpe.forLog(); } catch (Exception ex) { @@ -5010,7 +4913,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L private void trackUsage(StructureDefinition profile, ValidatorHostContext hostContext, Element element) { if (tracker != null) { - tracker.recordProfileUsage(profile, hostContext.appContext, element); + tracker.recordProfileUsage(profile, hostContext.getAppContext(), element); } } @@ -5343,7 +5246,7 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L boolean ok; try { long t = System.nanoTime(); - ok = fpe.evaluateToBoolean(hostContext, resource, hostContext.rootResource, element, n); + ok = fpe.evaluateToBoolean(hostContext, resource, hostContext.getRootResource(), element, n); fpeTime = fpeTime + (System.nanoTime() - t); msg = fpe.forLog(); } catch (Exception ex) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/ValidatorHostContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/ValidatorHostContext.java new file mode 100644 index 000000000..f471e96cb --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/ValidatorHostContext.java @@ -0,0 +1,158 @@ +package org.hl7.fhir.r5.validation.instancevalidator; + +import org.hl7.fhir.r5.elementmodel.Element; +import org.hl7.fhir.r5.model.Base; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.utilities.validation.ValidationMessage; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ValidatorHostContext { + + private Object appContext; + private Element container; // bundle, or parameters + private Element resource; + private Element rootResource; + private StructureDefinition profile; // the profile that contains the content being validated + private boolean checkSpecials = true; + private Map> sliceRecords; + + public ValidatorHostContext(Object appContext) { + this.appContext = appContext; + } + + public ValidatorHostContext(Object appContext, Element element) { + this.appContext = appContext; + this.resource = element; + this.rootResource = element; + } + + public Object getAppContext() { + return appContext; + } + + public ValidatorHostContext setAppContext(Object appContext) { + this.appContext = appContext; + return this; + } + + public Element getContainer() { + return container; + } + + public ValidatorHostContext setContainer(Element container) { + this.container = container; + return this; + } + + public ValidatorHostContext setResource(Element resource) { + this.resource = resource; + return this; + } + + public Element getRootResource() { + return rootResource; + } + + public ValidatorHostContext setRootResource(Element rootResource) { + this.rootResource = rootResource; + return this; + } + + public StructureDefinition getProfile() { + return profile; + } + + public ValidatorHostContext setProfile(StructureDefinition profile) { + this.profile = profile; + return this; + } + + public Map> getSliceRecords() { + return sliceRecords; + } + + public ValidatorHostContext setSliceRecords(Map> sliceRecords) { + this.sliceRecords = sliceRecords; + return this; + } + + public boolean isCheckSpecials() { + return checkSpecials; + } + + public void setCheckSpecials(boolean checkSpecials) { + this.checkSpecials = checkSpecials; + } + + public Element getResource() { + return resource; + } + + public void sliceNotes(String url, List record) { + sliceRecords.put(url, record); + } + + public ValidatorHostContext forContained(Element element) { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.rootResource = resource; + res.resource = element; + res.container = resource; + res.profile = profile; + return res; + } + + public ValidatorHostContext forEntry(Element element) { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.rootResource = element; + res.resource = element; + res.container = resource; + res.profile = profile; + return res; + } + + public ValidatorHostContext forProfile(StructureDefinition profile) { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.resource = resource; + res.rootResource = rootResource; + res.container = container; + res.profile = profile; + res.sliceRecords = sliceRecords != null ? sliceRecords : new HashMap>(); + return res; + } + + public ValidatorHostContext forLocalReference(StructureDefinition profile, Element resource) { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.resource = resource; + res.rootResource = resource; + res.container = container; + res.profile = profile; + res.checkSpecials = false; + return res; + } + + public ValidatorHostContext forRemoteReference(StructureDefinition profile, Element resource) { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.resource = resource; + res.rootResource = resource; + res.container = resource; + res.profile = profile; + res.checkSpecials = false; + return res; + } + + public ValidatorHostContext forSlicing() { + ValidatorHostContext res = new ValidatorHostContext(appContext); + res.resource = resource; + res.rootResource = resource; + res.container = resource; + res.profile = profile; + res.checkSpecials = false; + res.sliceRecords = new HashMap>(); + return res; + } + + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/utils/ResolvedReference.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/utils/ResolvedReference.java index 0d77dc288..30738889f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/utils/ResolvedReference.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/instancevalidator/utils/ResolvedReference.java @@ -3,6 +3,7 @@ package org.hl7.fhir.r5.validation.instancevalidator.utils; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.validation.instancevalidator.InstanceValidator; +import org.hl7.fhir.r5.validation.instancevalidator.ValidatorHostContext; public class ResolvedReference { @@ -51,7 +52,7 @@ public class ResolvedReference { return focus; } - public InstanceValidator.ValidatorHostContext hostContext(InstanceValidator.ValidatorHostContext hostContext, StructureDefinition profile) { + public ValidatorHostContext hostContext(ValidatorHostContext hostContext, StructureDefinition profile) { if (external) { return hostContext.forRemoteReference(profile, resource); } else {