From fa0b61d9b8129a5c23907580c6d9ac6a37370cdd Mon Sep 17 00:00:00 2001 From: Matti Uusitalo Date: Wed, 21 Nov 2018 15:35:54 +0200 Subject: [PATCH] Thread questionnaireResponse root element through questionnaire validation so implementations of enablewhen may validate against the complete resource --- .../fhir/r4/validation/InstanceValidator.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java index 9b8a01bfee4..474fd7d7fa2 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java @@ -2625,12 +2625,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat sdTime = sdTime + (System.nanoTime() - t); if (warning(errors, IssueType.REQUIRED, q.line(), q.col(), stack.getLiteralPath(), qsrc != null, "The questionnaire could not be resolved, so no validation can be performed against the base questionnaire")) { boolean inProgress = "in-progress".equals(element.getNamedChildValue("status")); - validateQuestionannaireResponseItems(qsrc, qsrc.getItem(), errors, element, stack, inProgress); + validateQuestionannaireResponseItems(qsrc, qsrc.getItem(), errors, element, stack, inProgress, element); } } } - private void validateQuestionannaireResponseItem(Questionnaire qsrc, QuestionnaireItemComponent qItem, List errors, Element element, NodeStack stack, boolean inProgress) { + private void validateQuestionannaireResponseItem(Questionnaire qsrc, QuestionnaireItemComponent qItem, List errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot) { String text = element.getNamedChildValue("text"); rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), Utilities.noString(text) || text.equals(qItem.getText()), "If text exists, it must match the questionnaire definition for linkId "+qItem.getLinkId()); @@ -2714,7 +2714,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // no validation break; } - validateQuestionannaireResponseItems(qsrc, qItem.getItem(), errors, answer, stack, inProgress); + validateQuestionannaireResponseItems(qsrc, qItem.getItem(), errors, answer, stack, inProgress, questionnaireResponseRoot); } if (qItem.getType() == null) { fail(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, "Definition for item "+qItem.getLinkId() + " does not contain a type"); @@ -2723,16 +2723,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat element.getNamedChildren("item", items); rule(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath(), items.isEmpty(), "Items not of type DISPLAY should not have items - linkId {0}", qItem.getLinkId()); } else { - validateQuestionannaireResponseItems(qsrc, qItem.getItem(), errors, element, stack, inProgress); + validateQuestionannaireResponseItems(qsrc, qItem.getItem(), errors, element, stack, inProgress, questionnaireResponseRoot); } } - private void validateQuestionannaireResponseItem(Questionnaire qsrc, QuestionnaireItemComponent qItem, List errors, List elements, NodeStack stack, boolean inProgress) { + private void validateQuestionannaireResponseItem(Questionnaire qsrc, QuestionnaireItemComponent qItem, List errors, List elements, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot) { if (elements.size() > 1) rule(errors, IssueType.INVALID, elements.get(1).line(), elements.get(1).col(), stack.getLiteralPath(), qItem.getRepeats(), "Only one response item with this linkId allowed - " + qItem.getLinkId()); for (Element element : elements) { NodeStack ns = stack.push(element, -1, null, null); - validateQuestionannaireResponseItem(qsrc, qItem, errors, element, ns, inProgress); + validateQuestionannaireResponseItem(qsrc, qItem, errors, element, ns, inProgress, questionnaireResponseRoot); } } @@ -2744,7 +2744,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return -1; } - private void validateQuestionannaireResponseItems(Questionnaire qsrc, List qItems, List errors, Element element, NodeStack stack, boolean inProgress) { + private void validateQuestionannaireResponseItems(Questionnaire qsrc, List qItems, List errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot) { List items = new ArrayList(); element.getNamedChildren("item", items); // now, sort into stacks @@ -2759,7 +2759,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (qItem != null) { rule(errors, IssueType.STRUCTURE, item.line(), item.col(), stack.getLiteralPath(), index > -1, "Structural Error: item is in the wrong place"); NodeStack ns = stack.push(item, -1, null, null); - validateQuestionannaireResponseItem(qsrc, qItem, errors, element, ns, inProgress); + validateQuestionannaireResponseItem(qsrc, qItem, errors, element, ns, inProgress, null); } else rule(errors, IssueType.NOTFOUND, item.line(), item.col(), stack.getLiteralPath(), index > -1, "LinkId \""+linkId+"\" not found in questionnaire"); @@ -2782,11 +2782,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat for (QuestionnaireItemComponent qItem : qItems) { List mapItem = map.get(qItem.getLinkId()); if (mapItem != null){ - rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), myEnableWhenEvaluator.isQuestionEnabled(qItem, element), "Item has answer, even though it is not enabled "+qItem.getLinkId()); - validateQuestionannaireResponseItem(qsrc, qItem, errors, mapItem, stack, inProgress); + rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), myEnableWhenEvaluator.isQuestionEnabled(qItem, questionnaireResponseRoot), "Item has answer, even though it is not enabled "+qItem.getLinkId()); + validateQuestionannaireResponseItem(qsrc, qItem, errors, mapItem, stack, inProgress, null); } else { //item is missing, is the question enabled? - if (myEnableWhenEvaluator.isQuestionEnabled(qItem, element)) { + if (myEnableWhenEvaluator.isQuestionEnabled(qItem, questionnaireResponseRoot)) { rule(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), !qItem.getRequired(), "No response found for required item "+qItem.getLinkId()); } }