private List<org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent> findAnswersByLinkId( List<org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent> theQuestion, String theLinkId) { Validate.notBlank(theLinkId, "theLinkId must not be blank"); ArrayList<org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent> retVal = new ArrayList<QuestionnaireResponse.QuestionComponent>(); for (org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent next : theQuestion) { if (theLinkId.equals(next.getLinkId())) { retVal.add(next); } } return retVal; }
private void validateGroup( List<ValidationMessage> theErrors, GroupComponent theQuestGroup, org.hl7.fhir.instance.model.QuestionnaireResponse.GroupComponent theAnsGroup, LinkedList<String> thePathStack, QuestionnaireResponse theAnswers, boolean theValidateRequired) { for (org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent next : theAnsGroup.getQuestion()) { rule( theErrors, IssueType.INVALID, thePathStack, isNotBlank(next.getLinkId()), "Question found with no linkId"); } Set<String> allowedQuestions = new HashSet<String>(); for (QuestionComponent nextQuestion : theQuestGroup.getQuestion()) { allowedQuestions.add(nextQuestion.getLinkId()); } for (int i = 0; i < theQuestGroup.getQuestion().size(); i++) { QuestionComponent nextQuestion = theQuestGroup.getQuestion().get(i); validateQuestion( theErrors, nextQuestion, theAnsGroup, thePathStack, theAnswers, theValidateRequired); } // Check that there are no extra answers for (int i = 0; i < theAnsGroup.getQuestion().size(); i++) { org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent nextQuestion = theAnsGroup.getQuestion().get(i); thePathStack.add("question[" + i + "]"); rule( theErrors, IssueType.BUSINESSRULE, thePathStack, allowedQuestions.contains(nextQuestion.getLinkId()), "Found answer with linkId[{0}] but this ID is not allowed at this position", nextQuestion.getLinkId()); thePathStack.remove(); } validateGroupGroups( theErrors, theQuestGroup, theAnsGroup, thePathStack, theAnswers, theValidateRequired); }
private void validateQuestionGroups( List<ValidationMessage> theErrors, QuestionComponent theQuestion, org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent theAnswerQuestion, LinkedList<String> thePathSpec, QuestionnaireResponse theAnswers, boolean theValidateRequired) { for (QuestionAnswerComponent nextAnswer : theAnswerQuestion.getAnswer()) { validateGroups( theErrors, theQuestion.getGroup(), nextAnswer.getGroup(), thePathSpec, theAnswers, theValidateRequired); } }
private void validateQuestionAnswers( List<ValidationMessage> theErrors, QuestionComponent theQuestion, LinkedList<String> thePathStack, AnswerFormat type, org.hl7.fhir.instance.model.QuestionnaireResponse.QuestionComponent answerQuestion, QuestionnaireResponse theAnswers, boolean theValidateRequired) { String linkId = theQuestion.getLinkId(); Set<Class<? extends Type>> allowedAnswerTypes = determineAllowedAnswerTypes(type); if (allowedAnswerTypes.isEmpty()) { for (QuestionAnswerComponent nextAnswer : answerQuestion.getAnswer()) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, ElementUtil.isEmpty(nextAnswer.getValue()), "Question with linkId[{0}] has no answer type but an answer was provided", linkId); } } else { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, !(answerQuestion.getAnswer().size() > 1 && !theQuestion.getRepeats()), "Multiple answers to non repeating question with linkId[{0}]", linkId); if (theValidateRequired) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, !(theQuestion.getRequired() && answerQuestion.getAnswer().isEmpty()), "Missing answer to required question with linkId[{0}]", linkId); } else { hint( theErrors, IssueType.BUSINESSRULE, thePathStack, !(theQuestion.getRequired() && answerQuestion.getAnswer().isEmpty()), "Missing answer to required question with linkId[{0}]", linkId); } } int answerIdx = -1; for (QuestionAnswerComponent nextAnswer : answerQuestion.getAnswer()) { answerIdx++; try { thePathStack.add("answer[" + answerIdx + "]"); Type nextValue = nextAnswer.getValue(); if (nextValue == null) { continue; } if (!allowedAnswerTypes.contains(nextValue.getClass())) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Answer to question with linkId[{0}] found of type [{1}] but this is invalid for question of type [{2}]", linkId, nextValue.getClass().getSimpleName(), type.toCode()); continue; } // Validate choice answers if (type == AnswerFormat.CHOICE || type == AnswerFormat.OPENCHOICE) { if (nextAnswer.getValue() instanceof StringType) { StringType answer = (StringType) nextAnswer.getValue(); if (answer == null || isBlank(answer.getValueAsString())) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Answer to question with linkId[{0}] is required but answer does not have a value", linkId); continue; } } else { Coding coding = (Coding) nextAnswer.getValue(); if (isBlank(coding.getCode())) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Answer to question with linkId[{0}] is of type {1} but coding answer does not have a code", linkId, type.name()); continue; } if (isBlank(coding.getSystem())) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Answer to question with linkId[{0}] is of type {1} but coding answer does not have a system", linkId, type.name()); continue; } String optionsRef = theQuestion.getOptions().getReference(); if (isNotBlank(optionsRef)) { ValueSet valueSet = getValueSet(theAnswers, theQuestion.getOptions()); if (valueSet == null) { rule( theErrors, IssueType.BUSINESSRULE, thePathStack, false, "Question with linkId[{0}] has options ValueSet[{1}] but this ValueSet can not be found", linkId, optionsRef); continue; } boolean found = false; if (coding.getSystem().equals(valueSet.getCodeSystem().getSystem())) { for (ConceptDefinitionComponent next : valueSet.getCodeSystem().getConcept()) { if (coding.getCode().equals(next.getCode())) { found = true; break; } } } if (!found) { for (ConceptSetComponent nextCompose : valueSet.getCompose().getInclude()) { if (coding.getSystem().equals(nextCompose.getSystem())) { for (ConceptReferenceComponent next : nextCompose.getConcept()) { if (coding.getCode().equals(next.getCode())) { found = true; break; } } } if (found) { break; } } } rule( theErrors, IssueType.BUSINESSRULE, thePathStack, found, "Question with linkId[{0}] has answer with system[{1}] and code[{2}] but this is not a valid answer for ValueSet[{3}]", linkId, coding.getSystem(), coding.getCode(), optionsRef); } } } } finally { thePathStack.removeLast(); } } // for answers }