fix problem resolving nested contained value sets in QuestionnaireResponses + fix NPE rendering questionnaire + fix bug validating profile on resource at root of Bundle

This commit is contained in:
Grahame Grieve 2021-12-03 06:51:23 +11:00
parent 4babbd9724
commit d303dba48d
8 changed files with 144 additions and 79 deletions

View File

@ -792,7 +792,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer {
private void listOptions(Questionnaire q, QuestionnaireItemComponent i, XhtmlNode select) {
if (i.hasAnswerValueSet()) {
ValueSet vs = null;
if (Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
if (!Utilities.noString(i.getAnswerValueSet()) && i.getAnswerValueSet().startsWith("#")) {
vs = (ValueSet) q.getContained(i.getAnswerValueSet().substring(1));
if (vs != null && !vs.hasUrl()) {
vs = vs.copy();

View File

@ -348,6 +348,7 @@ public class I18nConstants {
public static final String REFERENCE_REF_RESOURCETYPE = "Reference_REF_ResourceType";
public static final String REFERENCE_REF_SUSPICIOUS = "REFERENCE_REF_SUSPICIOUS";
public static final String REFERENCE_REF_WRONGTARGET = "Reference_REF_WrongTarget";
public static final String REFERENCE_REF_WRONGTARGET_LOAD = "REFERENCE_REF_WRONGTARGET_LOAD";
public static final String REFERENCE_TO__CANNOT_BE_RESOLVED = "reference_to__cannot_be_resolved";
public static final String REFERENCE__REFERS_TO_A__NOT_A_VALUESET = "Reference__refers_to_a__not_a_ValueSet";
public static final String RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED = "Resource_resolution_services_not_provided";

View File

@ -120,6 +120,7 @@ Reference_REF_NoType = Unable to determine type of target resource
Reference_REF_NotFound_Bundle = Bundled or contained reference not found within the bundle/resource {0}
Reference_REF_ResourceType = Matching reference for reference {0} has resourceType {1}
Reference_REF_WrongTarget = The type ''{0}'' is not a valid Target for this element (must be one of {1})
REFERENCE_REF_WRONGTARGET_LOAD = The type ''{2}'' is not a valid Target for the element {0} (must be {1})
Resource_RES_ID_Malformed = Invalid Resource id
Resource_RES_ID_Missing = Resource requires an id, but none is present
Resource_RES_ID_Prohibited = Resource has an id, but none is allowed

View File

@ -13,4 +13,6 @@
<appender-ref ref="STDOUT" />
</root>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
</configuration>

View File

@ -31,8 +31,15 @@ package org.hl7.fhir.validation;
*/
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.JsonParser;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
import org.hl7.fhir.r5.utils.XVerExtensionManager;
@ -45,6 +52,8 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
import org.hl7.fhir.validation.instance.utils.IndexedElement;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -986,4 +995,60 @@ public class BaseValidator {
return system;
}
}
protected Resource loadContainedResource(List<ValidationMessage> errors, String path, Element resource, String id, Class class1) throws FHIRException {
for (Element contained : resource.getChildren("contained")) {
if (contained.getIdBase().equals(id)) {
return loadFoundResource(errors, path, contained, class1);
}
}
return null;
}
protected Resource loadFoundResource(List<ValidationMessage> errors, String path, Element resource, Class class1) throws FHIRException {
try {
FhirPublication v = FhirPublication.fromCode(context.getVersion());
ByteArrayOutputStream bs = new ByteArrayOutputStream();
new JsonParser(context).compose(resource, bs, OutputStyle.NORMAL, resource.getIdBase());
byte[] json = bs.toByteArray();
Resource r5 = null;
switch (v) {
case DSTU1:
rule(errors, IssueType.INVALID, resource.line(), resource.col(), path, false, I18nConstants.UNSUPPORTED_VERSION_R1, resource.getIdBase());
return null; // this can't happen
case DSTU2:
org.hl7.fhir.dstu2.model.Resource r2 = new org.hl7.fhir.dstu2.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_10_50.convertResource(r2);
break;
case DSTU2016May:
org.hl7.fhir.dstu2016may.model.Resource r2a = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_14_50.convertResource(r2a);
break;
case STU3:
org.hl7.fhir.dstu3.model.Resource r3 = new org.hl7.fhir.dstu3.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_30_50.convertResource(r3);
break;
case R4:
org.hl7.fhir.r4.model.Resource r4 = new org.hl7.fhir.r4.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_40_50.convertResource(r4);
break;
case R5:
r5 = new org.hl7.fhir.r5.formats.JsonParser().parse(json);
break;
default:
return null; // this can't happen
}
if (class1.isInstance(r5))
return (Resource) r5;
else {
rule(errors, IssueType.INVALID, resource.line(), resource.col(), path, false, I18nConstants.REFERENCE_REF_WRONGTARGET_LOAD, resource.getIdBase(), class1.toString(), r5.fhirType());
return null;
}
} catch (IOException e) {
throw new FHIRException(e);
}
}
}

View File

@ -48,6 +48,7 @@ import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent;
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemEnableWhenComponent;
import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemOperator;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.hl7.fhir.validation.instance.type.QuestionnaireValidator.QuestionnaireWithContext;
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -85,17 +86,17 @@ public class EnableWhenEvaluator {
public static class QStack extends ArrayList<QuestionnaireAnswerPair> {
private static final long serialVersionUID = 1L;
private Questionnaire q;
private QuestionnaireWithContext q;
private Element a;
public QStack(Questionnaire q, Element a) {
public QStack(QuestionnaireWithContext q, Element a) {
super();
this.q = q;
this.a = a;
}
public Questionnaire getQ() {
public QuestionnaireWithContext getQ() {
return q;
}
@ -311,9 +312,9 @@ public class EnableWhenEvaluator {
* - any targetA in groupA are input for the enableWhen decision
*/
private List<Element> findQuestionAnswers(QStack qstack, QuestionnaireItemComponent sourceQ, QuestionnaireItemEnableWhenComponent ew) {
QuestionnaireItemComponent targetQ = qstack.getQ().getQuestion(ew.getQuestion());
QuestionnaireItemComponent targetQ = qstack.getQ().q().getQuestion(ew.getQuestion());
if (targetQ != null) {
QuestionnaireItemComponent groupQ = qstack.getQ().getCommonGroup(sourceQ, targetQ);
QuestionnaireItemComponent groupQ = qstack.getQ().q().getCommonGroup(sourceQ, targetQ);
if (groupQ == null) { // root is Q itself
return findOnItem(qstack.getA(), ew.getQuestion());
} else {

View File

@ -5386,6 +5386,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (first != null && typeMatchesDefn(first.getElement().getType(), defn)) {
element = first.getElement();
stack = first;
resourceName = element.getType(); // todo: consider namespace...?
idstatus = IdStatus.OPTIONAL; // why?
}
// todo: validate everything in this bundle.
@ -5404,7 +5405,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
// validate
if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), resourceName.equals(defn.getType()), I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE,
defn.getType(), resourceName, defn.getUrl())) {
start(hostContext, errors, element, element, defn, stack); // root is both definition and type
} else {
System.out.println("what?");
}
}
}

View File

@ -26,6 +26,7 @@ import org.hl7.fhir.r5.elementmodel.ObjectConverter;
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.DateType;
import org.hl7.fhir.r5.model.DomainResource;
import org.hl7.fhir.r5.model.Enumerations.FHIRVersion;
import org.hl7.fhir.r5.model.FhirPublication;
import org.hl7.fhir.r5.model.IntegerType;
@ -51,6 +52,7 @@ import org.hl7.fhir.validation.cli.utils.QuestionnaireMode;
import org.hl7.fhir.validation.TimeTracker;
import org.hl7.fhir.validation.instance.EnableWhenEvaluator;
import org.hl7.fhir.validation.instance.EnableWhenEvaluator.QStack;
import org.hl7.fhir.validation.instance.type.QuestionnaireValidator.QuestionnaireWithContext;
import org.hl7.fhir.validation.instance.utils.NodeStack;
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
@ -58,6 +60,37 @@ import ca.uhn.fhir.util.ObjectUtil;
public class QuestionnaireValidator extends BaseValidator {
public static class QuestionnaireWithContext {
private Questionnaire q;
private Element container;
private String containerPath;
public static QuestionnaireWithContext fromQuestionnaire(Questionnaire q) {
if (q == null) {
return null;
}
QuestionnaireWithContext res = new QuestionnaireWithContext();
res.q = q;
return res;
}
public static QuestionnaireWithContext fromContainedResource(String path, Element e, Questionnaire q) {
if (q == null) {
return null;
}
QuestionnaireWithContext res = new QuestionnaireWithContext();
res.q = q;
res.container = e;
res.containerPath = path;
return res;
}
public Questionnaire q() {
return q;
}
}
private EnableWhenEvaluator myEnableWhenEvaluator;
private FHIRPathEngine fpe;
private QuestionnaireMode questionnaireMode;
@ -191,7 +224,12 @@ public class QuestionnaireValidator extends BaseValidator {
rule(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), questionnaire != null, I18nConstants.QUESTIONNAIRE_QR_Q_NONE) :
hint(errors, IssueType.REQUIRED, element.line(), element.col(), stack.getLiteralPath(), questionnaire != null, I18nConstants.QUESTIONNAIRE_QR_Q_NONE);
if (ok) {
Questionnaire qsrc = questionnaire.startsWith("#") ? loadQuestionnaire(element, questionnaire.substring(1)) : context.fetchResource(Questionnaire.class, questionnaire);
QuestionnaireWithContext qsrc = null;
if (questionnaire.startsWith("#")) {
qsrc = QuestionnaireWithContext.fromContainedResource(stack.getLiteralPath(), element, (Questionnaire) loadContainedResource(errors, stack.getLiteralPath(), element, questionnaire.substring(1), Questionnaire.class));
} else {
qsrc = QuestionnaireWithContext.fromQuestionnaire(context.fetchResource(Questionnaire.class, questionnaire));
}
if (questionnaireMode == QuestionnaireMode.REQUIRED) {
ok = rule(errors, IssueType.REQUIRED, q.line(), q.col(), stack.getLiteralPath(), qsrc != null, I18nConstants.QUESTIONNAIRE_QR_Q_NOTFOUND, questionnaire);
} else if (questionnaire.startsWith("http://example.org")) {
@ -201,66 +239,12 @@ public class QuestionnaireValidator extends BaseValidator {
}
if (ok) {
boolean inProgress = "in-progress".equals(element.getNamedChildValue("status"));
validateQuestionannaireResponseItems(hostContext, qsrc, qsrc.getItem(), errors, element, stack, inProgress, element, new QStack(qsrc, element));
validateQuestionannaireResponseItems(hostContext, qsrc, qsrc.q().getItem(), errors, element, stack, inProgress, element, new QStack(qsrc, element));
}
}
}
private Questionnaire loadQuestionnaire(Element resource, String id) throws FHIRException {
try {
for (Element contained : resource.getChildren("contained")) {
if (contained.getIdBase().equals(id)) {
FhirPublication v = FhirPublication.fromCode(context.getVersion());
ByteArrayOutputStream bs = new ByteArrayOutputStream();
new JsonParser(context).compose(contained, bs, OutputStyle.NORMAL, id);
byte[] json = bs.toByteArray();
switch (v) {
case DSTU1:
throw new FHIRException(context.formatMessage(I18nConstants.UNSUPPORTED_VERSION_R1));
case DSTU2:
org.hl7.fhir.dstu2.model.Resource r2 = new org.hl7.fhir.dstu2.formats.JsonParser().parse(json);
Resource r5 = VersionConvertorFactory_10_50.convertResource(r2);
if (r5 instanceof Questionnaire)
return (Questionnaire) r5;
else
return null;
case DSTU2016May:
org.hl7.fhir.dstu2016may.model.Resource r2a = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_14_50.convertResource(r2a);
if (r5 instanceof Questionnaire)
return (Questionnaire) r5;
else
return null;
case STU3:
org.hl7.fhir.dstu3.model.Resource r3 = new org.hl7.fhir.dstu3.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_30_50.convertResource(r3);
if (r5 instanceof Questionnaire)
return (Questionnaire) r5;
else
return null;
case R4:
org.hl7.fhir.r4.model.Resource r4 = new org.hl7.fhir.r4.formats.JsonParser().parse(json);
r5 = VersionConvertorFactory_40_50.convertResource(r4);
if (r5 instanceof Questionnaire)
return (Questionnaire) r5;
else
return null;
case R5:
r5 = new org.hl7.fhir.r5.formats.JsonParser().parse(json);
if (r5 instanceof Questionnaire)
return (Questionnaire) r5;
else
return null;
}
}
}
return null;
} catch (IOException e) {
throw new FHIRException(e);
}
}
private void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, Questionnaire qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
private void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
String text = element.getNamedChildValue("text");
rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), Utilities.noString(text) || text.equals(qItem.getText()), I18nConstants.QUESTIONNAIRE_QR_ITEM_TEXT, qItem.getLinkId());
@ -379,7 +363,7 @@ public class QuestionnaireValidator extends BaseValidator {
return !answers.isEmpty() || !qItem.getRequired() || qItem.getType() == QuestionnaireItemType.GROUP;
}
private void validateQuestionnaireResponseItem(ValidatorHostContext hostcontext, Questionnaire qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, List<Element> elements, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
private void validateQuestionnaireResponseItem(ValidatorHostContext hostcontext, QuestionnaireWithContext qsrc, QuestionnaireItemComponent qItem, List<ValidationMessage> errors, List<Element> elements, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
if (elements.size() > 1)
rule(errors, IssueType.INVALID, elements.get(1).line(), elements.get(1).col(), stack.getLiteralPath(), qItem.getRepeats(), I18nConstants.QUESTIONNAIRE_QR_ITEM_ONLYONEI, qItem.getLinkId());
int i = 0;
@ -398,7 +382,7 @@ public class QuestionnaireValidator extends BaseValidator {
return -1;
}
private void validateQuestionannaireResponseItems(ValidatorHostContext hostContext, Questionnaire qsrc, List<QuestionnaireItemComponent> qItems, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
private void validateQuestionannaireResponseItems(ValidatorHostContext hostContext, QuestionnaireWithContext qsrc, List<QuestionnaireItemComponent> qItems, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QStack qstack) {
List<Element> items = new ArrayList<Element>();
element.getNamedChildren("item", items);
// now, sort into stacks
@ -437,7 +421,7 @@ public class QuestionnaireValidator extends BaseValidator {
}
}
public void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, Questionnaire qsrc, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QuestionnaireItemComponent qItem, List<Element> mapItem, QStack qstack) {
public void validateQuestionnaireResponseItem(ValidatorHostContext hostContext, QuestionnaireWithContext qsrc, List<ValidationMessage> errors, Element element, NodeStack stack, boolean inProgress, Element questionnaireResponseRoot, QuestionnaireItemComponent qItem, List<Element> mapItem, QStack qstack) {
boolean enabled = myEnableWhenEvaluator.isQuestionEnabled(hostContext, qItem, qstack, fpe);
if (mapItem != null) {
if (!enabled) {
@ -500,8 +484,8 @@ public class QuestionnaireValidator extends BaseValidator {
return null;
}
private QuestionnaireItemComponent findQuestionnaireItem(Questionnaire qSrc, String linkId) {
return findItem(qSrc.getItem(), linkId);
private QuestionnaireItemComponent findQuestionnaireItem(QuestionnaireWithContext qSrc, String linkId) {
return findItem(qSrc.q.getItem(), linkId);
}
private QuestionnaireItemComponent findItem(List<QuestionnaireItemComponent> list, String linkId) {
@ -515,8 +499,13 @@ public class QuestionnaireValidator extends BaseValidator {
return null;
}
private void validateAnswerCode(List<ValidationMessage> errors, Element value, NodeStack stack, Questionnaire qSrc, String ref, boolean theOpenChoice) {
ValueSet vs = resolveBindingReference(qSrc, ref, qSrc.getUrl());
private void validateAnswerCode(List<ValidationMessage> errors, Element value, NodeStack stack, QuestionnaireWithContext qSrc, String ref, boolean theOpenChoice) {
ValueSet vs = null;
if (ref.startsWith("#") && qSrc.container != null) {
vs = (ValueSet) loadContainedResource(errors, qSrc.containerPath, qSrc.container, ref.substring(1), ValueSet.class);
} else {
vs = resolveBindingReference(qSrc.q(), ref, qSrc.q().getUrl());
}
if (warning(errors, IssueType.CODEINVALID, value.line(), value.col(), stack.getLiteralPath(), vs != null, I18nConstants.TERMINOLOGY_TX_VALUESET_NOTFOUND, describeReference(ref))) {
try {
Coding c = ObjectConverter.readAsCoding(value);
@ -540,7 +529,7 @@ public class QuestionnaireValidator extends BaseValidator {
}
}
private void validateAnswerCode(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean theOpenChoice) {
private void validateAnswerCode(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean theOpenChoice) {
Element v = answer.getNamedChild("valueCoding");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0)
@ -552,11 +541,11 @@ public class QuestionnaireValidator extends BaseValidator {
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOOPTIONS);
}
private void checkOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, String type) {
private void checkOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, String type) {
checkOption(errors, answer, stack, qSrc, qItem, type, false);
}
private void checkOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, String type, boolean openChoice) {
private void checkOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, String type, boolean openChoice) {
if (type.equals("integer")) checkIntegerOption(errors, answer, stack, qSrc, qItem, openChoice);
else if (type.equals("date")) checkDateOption(errors, answer, stack, qSrc, qItem, openChoice);
else if (type.equals("time")) checkTimeOption(errors, answer, stack, qSrc, qItem, openChoice);
@ -564,7 +553,7 @@ public class QuestionnaireValidator extends BaseValidator {
else if (type.equals("Coding")) checkCodingOption(errors, answer, stack, qSrc, qItem, openChoice);
}
private void checkIntegerOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
private void checkIntegerOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueInteger");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0) {
@ -594,7 +583,7 @@ public class QuestionnaireValidator extends BaseValidator {
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_INTNOOPTIONS);
}
private void checkDateOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
private void checkDateOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueDate");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0) {
@ -624,7 +613,7 @@ public class QuestionnaireValidator extends BaseValidator {
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_DATENOOPTIONS);
}
private void checkTimeOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
private void checkTimeOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueTime");
NodeStack ns = stack.push(v, -1, null, null);
if (qItem.getAnswerOption().size() > 0) {
@ -654,7 +643,7 @@ public class QuestionnaireValidator extends BaseValidator {
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_TIMENOOPTIONS);
}
private void checkStringOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
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) {
@ -689,7 +678,7 @@ public class QuestionnaireValidator extends BaseValidator {
}
}
private void checkCodingOption(List<ValidationMessage> errors, Element answer, NodeStack stack, Questionnaire qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
private void checkCodingOption(List<ValidationMessage> errors, Element answer, NodeStack stack, QuestionnaireWithContext qSrc, QuestionnaireItemComponent qItem, boolean openChoice) {
Element v = answer.getNamedChild("valueCoding");
String system = v.getNamedChildValue("system");
String code = v.getNamedChildValue("code");