use of org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent in project CRD by HL7-DaVinci.
the class SubQuestionnaireProcessor method processItem.
/**
* Determines if this item is a sub-questionnaire reference and returns the items to replace it with. Returns the same list
* otherwise. Also recursively continues scanning if this is just a grouping item.
*
* @param item The item to check for sub-questionnaire referece.
* @param fileStore The FileStore to be used for fetching sub-questionnaires.
* @param baseUrl The base url from the server.
* @param containedList List of contained resources to put in the assembled Questionnaire. This will be filled while iterating.
* @param extensionList List of extensions to put in the assembled Questionnaire. This will be filled while iterating.
* @return New list of items to replace this item with.
*/
private List<QuestionnaireItemComponent> processItem(QuestionnaireItemComponent item, FileStore fileStore, String baseUrl, Hashtable<String, org.hl7.fhir.r4.model.Resource> containedList, List<Extension> extensionList) {
// find if item has an extension is sub-questionnaire
Extension e = item.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/sub-questionnaire");
if (e != null) {
// read sub questionnaire from file store
CanonicalType value = e.castToCanonical(e.getValue());
logger.info("SubQuestionnaireProcessor::parseItem(): Looking for SubQuestionnaire " + value);
// strip the type off of the id if it is there
String id = value.asStringValue();
String[] parts = id.split("/");
if (parts.length > 1) {
id = parts[1];
}
boolean expandRootItem = false;
Extension expand = item.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/sub-questionnaire-expand");
if (expand != null) {
expandRootItem = expand.castToBoolean(expand.getValue()).booleanValue();
}
FileResource subFileResource = fileStore.getFhirResourceById("R4", "questionnaire", id, baseUrl, false);
if (subFileResource != null) {
Questionnaire subQuestionnaire = (Questionnaire) this.parseFhirFileResource(subFileResource);
if (subQuestionnaire != null) {
// merge extensions
for (Extension subExtension : subQuestionnaire.getExtension()) {
if (extensionList.stream().noneMatch(ext -> ext.equalsDeep(subExtension))) {
extensionList.add(subExtension);
}
}
// merge contained resources
for (org.hl7.fhir.r4.model.Resource r : subQuestionnaire.getContained()) {
containedList.put(r.getId(), r);
}
List<QuestionnaireItemComponent> rootItems = subQuestionnaire.getItem();
// there are more than one root items in sub questionnaire, don't expand
if (!expandRootItem || rootItems.size() > 1) {
return rootItems;
} else {
return rootItems.get(0).getItem();
}
} else {
// SubQuestionnaire could not be loaded
logger.warn("SubQuestionnaireProcessor::parseItem(): Could not load SubQuestionnaire " + value.asStringValue());
return Arrays.asList(item);
}
} else {
// SubQuestionnaire could not be found
logger.warn("SubQuestionnaireProcessor::parseItem(): Could not find SubQuestionnaire " + value.asStringValue());
return Arrays.asList(item);
}
}
// parse sub-items
this.processItemList(item.getItem(), fileStore, baseUrl, containedList, extensionList);
return Arrays.asList(item);
}
use of org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent in project CRD by HL7-DaVinci.
the class QuestionnaireController method addQuestionSetToQuestionnaireResponse.
/**
* Adds the given set of questions to the contained questionniare in the questionnaire response.
* @param inputQuestionnaireResponse
* @param questionSet
*/
private static void addQuestionSetToQuestionnaireResponse(QuestionnaireResponse inputQuestionnaireResponse, List<QuestionnaireItemComponent> questionSet) {
// Add the next question set to the QuestionnaireResponse.contained[0].item[].
Questionnaire containedQuestionnaire = (Questionnaire) inputQuestionnaireResponse.getContained().get(0);
questionSet.forEach(questionItem -> containedQuestionnaire.addItem(questionItem));
}
use of org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class EnableWhenEvaluator method isQuestionEnabled.
/**
* the stack contains a set of QR items that represent the tree of the QR being validated, each tagged with the definition of the item from the Q for the QR being validated
* <p>
* the itembeing validated is in the context of the stack. For root items, the stack is empty.
* <p>
* The context Questionnaire and QuestionnaireResponse are always available
*/
public boolean isQuestionEnabled(ValidatorHostContext hostContext, QuestionnaireItemComponent qitem, QStack qstack, FHIRPathEngine engine) {
if (hasExpressionExtension(qitem)) {
String expr = getExpression(qitem);
ExpressionNode node = engine.parse(expr);
return engine.evaluateToBoolean(hostContext, qstack.a, qstack.a, qstack.a, node);
}
if (!qitem.hasEnableWhen()) {
return true;
}
List<EnableWhenResult> evaluationResults = new ArrayList<>();
for (QuestionnaireItemEnableWhenComponent enableCondition : qitem.getEnableWhen()) {
evaluationResults.add(evaluateCondition(enableCondition, qitem, qstack));
}
return checkConditionResults(evaluationResults, qitem);
}
use of org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method checkStringOption.
private void checkStringOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueString");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0) {
List<StringType> list = new ArrayList<StringType>();
for (QuestionnaireItemAnswerOptionComponent components : qItem.getAnswerOption()) {
try {
if (components.getValue() != null) {
list.add(components.getValueStringType());
}
} catch (FHIRException e) {
// If it's the wrong type, just keep going
}
}
if (!openChoice) {
if (list.isEmpty()) {
rule(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOOPTIONSSTRING);
} else {
boolean found = false;
for (StringType item : list) {
if (item.getValue().equals((v.primitiveValue()))) {
found = true;
break;
}
}
if (!found) {
rule(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), found, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOSTRING, v.primitiveValue());
}
}
}
} else {
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_STRINGNOOPTIONS);
}
}
use of org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method validateQuestionnaireResponseItem.
public void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, QuestionnaireWithContext qsrc, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QuestionnaireItemComponent qItem, List<ElementWithIndex> mapItem, QStack qstack) {
boolean enabled = myEnableWhenEvaluator.isQuestionEnabled(hostContext, qItem, qstack, fpe);
if (mapItem != null) {
if (!enabled) {
for (ElementWithIndex e : mapItem) {
NodeStack ns = stack.push(e.getElement(), e.getElement().getIndex(), e.getElement().getProperty().getDefinition(), e.getElement().getProperty().getDefinition());
rule(errors, IssueType.INVALID, e.getElement().line(), e.getElement().col(), ns.getLiteralPath(), enabled, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOTENABLED2, qItem.getLinkId());
}
}
// Recursively validate child items
validateQuestionnaireResponseItem(hostContext, qsrc, qItem, errors, mapItem, stack, inProgress, questionnaireResponseRoot, qstack);
} else {
// item is missing, is the question enabled?
if (enabled && qItem.getRequired()) {
String message = context.formatMessage(I18nConstants.QUESTIONNAIRE_QR_ITEM_MISSING, qItem.getLinkId());
if (inProgress) {
warning(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, message);
} else {
rule(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), false, message);
}
}
}
}
Aggregations