use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class BundleValidator method checkSearchSet.
private void checkSearchSet(List<ValidationMessage> errors, Element bundle, List<Element> entries, NodeStack stack) {
// warning: should have self link
List<Element> links = new ArrayList<Element>();
bundle.getNamedChildren(LINK, links);
Element selfLink = getSelfLink(links);
List<String> types = new ArrayList<>();
if (selfLink == null) {
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_SEARCH_NOSELF);
} else {
readSearchResourceTypes(selfLink.getNamedChildValue("url"), types);
if (types.size() == 0) {
hint(errors, IssueType.INVALID, bundle.line(), bundle.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_SEARCH_SELF_NOT_UNDERSTOOD);
}
}
Boolean searchMode = readHasSearchMode(entries);
if (searchMode != null && searchMode == false) {
// if no resources have search mode
boolean typeProblem = false;
String rtype = null;
int count = 0;
for (Element entry : entries) {
NodeStack estack = stack.push(entry, count, null, null);
count++;
Element res = entry.getNamedChild("resource");
if (rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), estack.getLiteralPath(), res != null, I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE)) {
NodeStack rstack = estack.push(res, -1, null, null);
String rt = res.fhirType();
Boolean ok = checkSearchType(types, rt);
if (ok == null) {
typeProblem = true;
hint(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), selfLink == null, I18nConstants.BUNDLE_SEARCH_ENTRY_TYPE_NOT_SURE);
String id = res.getNamedChildValue("id");
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), id != null || "OperationOutcome".equals(rt), I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE_ID);
} else if (ok) {
if (!"OperationOutcome".equals(rt)) {
String id = res.getNamedChildValue("id");
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), id != null, I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE_ID);
if (rtype != null && !rt.equals(rtype)) {
typeProblem = true;
} else if (rtype == null) {
rtype = rt;
}
}
} else {
typeProblem = true;
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), estack.getLiteralPath(), false, I18nConstants.BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_NO_MODE, rt, types);
}
}
}
if (typeProblem) {
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), stack.getLiteralPath(), !typeProblem, I18nConstants.BUNDLE_SEARCH_NO_MODE);
} else {
hint(errors, IssueType.INVALID, bundle.line(), bundle.col(), stack.getLiteralPath(), !typeProblem, I18nConstants.BUNDLE_SEARCH_NO_MODE);
}
} else {
int count = 0;
for (Element entry : entries) {
NodeStack estack = stack.push(entry, count, null, null);
count++;
Element res = entry.getNamedChild("resource");
String sm = null;
Element s = entry.getNamedChild("search");
if (s != null) {
sm = s.getNamedChildValue("mode");
}
warning(errors, IssueType.INVALID, bundle.line(), bundle.col(), estack.getLiteralPath(), sm != null, I18nConstants.BUNDLE_SEARCH_NO_MODE);
if (rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), estack.getLiteralPath(), res != null, I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE)) {
NodeStack rstack = estack.push(res, -1, null, null);
String rt = res.fhirType();
String id = res.getNamedChildValue("id");
if (sm != null) {
if ("match".equals(sm)) {
rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), id != null, I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE_ID);
rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), types.size() == 0 || checkSearchType(types, rt), I18nConstants.BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_MODE, rt, types);
} else if ("include".equals(sm)) {
rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), id != null, I18nConstants.BUNDLE_SEARCH_ENTRY_NO_RESOURCE_ID);
} else {
// outcome
rule(errors, IssueType.INVALID, bundle.line(), bundle.col(), rstack.getLiteralPath(), "OperationOutcome".equals(rt), I18nConstants.BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_OUTCOME, rt);
}
}
}
}
}
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class BundleValidator method validateBundleReference.
private void validateBundleReference(List<ValidationMessage> errors, List<Element> entries, Element ref, String name, NodeStack stack, String fullUrl, String type, String id) {
String reference = null;
try {
reference = ref.getNamedChildValue("reference");
} catch (Error e) {
}
if (ref != null && !Utilities.noString(reference) && !reference.startsWith("#")) {
Element target = resolveInBundle(entries, reference, fullUrl, type, id);
rule(errors, IssueType.INVALID, ref.line(), ref.col(), stack.addToLiteralPath("reference"), target != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, reference, name);
}
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class BundleValidator method checkAllInterlinked.
private void checkAllInterlinked(List<ValidationMessage> errors, List<Element> entries, NodeStack stack, Element bundle, boolean isError) {
List<EntrySummary> entryList = new ArrayList<>();
int i = 0;
for (Element entry : entries) {
Element r = entry.getNamedChild(RESOURCE);
if (r != null) {
EntrySummary e = new EntrySummary(i, entry, r);
entryList.add(e);
// System.out.println("Found entry "+e.dbg());
}
i++;
}
for (EntrySummary e : entryList) {
Set<String> references = findReferences(e.getEntry());
for (String ref : references) {
Element tgt = resolveInBundle(entries, ref, e.getEntry().getChildValue(FULL_URL), e.getResource().fhirType(), e.getResource().getIdBase());
if (tgt != null) {
EntrySummary t = entryForTarget(entryList, tgt);
if (t != null) {
if (t != e) {
// System.out.println("Entry "+e.getIndex()+" refers to "+t.getIndex()+" by ref '"+ref+"'");
e.getTargets().add(t);
} else {
// System.out.println("Entry "+e.getIndex()+" refers to itself by '"+ref+"'");
}
}
}
}
}
Set<EntrySummary> visited = new HashSet<>();
visitLinked(visited, entryList.get(0));
boolean foundRevLinks;
do {
foundRevLinks = false;
for (EntrySummary e : entryList) {
if (!visited.contains(e)) {
// System.out.println("Not visited "+e.getIndex()+" - check for reverse links");
boolean add = false;
for (EntrySummary t : e.getTargets()) {
if (visited.contains(t)) {
add = true;
}
}
if (add) {
warning(errors, IssueType.INFORMATIONAL, e.getEntry().line(), e.getEntry().col(), stack.addToLiteralPath(ENTRY + '[' + (i + 1) + ']'), isExpectedToBeReverse(e.getResource().fhirType()), I18nConstants.BUNDLE_BUNDLE_ENTRY_REVERSE, (e.getEntry().getChildValue(FULL_URL) != null ? "'" + e.getEntry().getChildValue(FULL_URL) + "'" : ""));
// System.out.println("Found reverse links for "+e.getIndex());
foundRevLinks = true;
visitLinked(visited, e);
}
}
}
} while (foundRevLinks);
i = 0;
for (EntrySummary e : entryList) {
Element entry = e.getEntry();
if (isError) {
rule(errors, IssueType.INFORMATIONAL, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY + '[' + (i + 1) + ']'), visited.contains(e), I18nConstants.BUNDLE_BUNDLE_ENTRY_ORPHAN, (entry.getChildValue(FULL_URL) != null ? "'" + entry.getChildValue(FULL_URL) + "'" : ""));
} else {
warning(errors, IssueType.INFORMATIONAL, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY + '[' + (i + 1) + ']'), visited.contains(e), I18nConstants.BUNDLE_BUNDLE_ENTRY_ORPHAN, (entry.getChildValue(FULL_URL) != null ? "'" + entry.getChildValue(FULL_URL) + "'" : ""));
}
i++;
}
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method checkTimeOption.
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) {
List<TimeType> list = new ArrayList<TimeType>();
for (QuestionnaireItemAnswerOptionComponent components : qItem.getAnswerOption()) {
try {
list.add(components.getValueTimeType());
} catch (FHIRException e) {
// If it's the wrong type, just keep going
}
}
if (list.isEmpty() && !openChoice) {
rule(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_NOOPTIONSTIME);
} else {
boolean found = false;
for (TimeType 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_NOTIME, v.primitiveValue());
}
}
} else
hint(errors, IssueType.STRUCTURE, v.line(), v.col(), stack.getLiteralPath(), false, I18nConstants.QUESTIONNAIRE_QR_ITEM_TIMENOOPTIONS);
}
use of org.hl7.fhir.utilities.xml.SchematronWriter.Rule in project org.hl7.fhir.core by hapifhir.
the class QuestionnaireValidator method validateQuestionannaireResponse.
public void validateQuestionannaireResponse(ValidatorHostContext hostContext, List<ValidationMessage> errors, Element element, NodeStack stack) throws FHIRException {
if (questionnaireMode == QuestionnaireMode.NONE) {
return;
}
Element q = element.getNamedChild("questionnaire");
String questionnaire = null;
if (q != null) {
/*
* q.getValue() is correct for R4 content, but we'll also accept the second
* option just in case we're validating raw STU3 content. Being lenient here
* isn't the end of the world since if someone is actually doing the reference
* wrong in R4 content it'll get flagged elsewhere by the validator too
*/
if (isNotBlank(q.getValue())) {
questionnaire = q.getValue();
} else if (isNotBlank(q.getChildValue("reference"))) {
questionnaire = q.getChildValue("reference");
}
}
boolean ok = questionnaireMode == QuestionnaireMode.REQUIRED ? 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) {
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")) {
ok = hint(errors, IssueType.REQUIRED, q.line(), q.col(), stack.getLiteralPath(), qsrc != null, I18nConstants.QUESTIONNAIRE_QR_Q_NOTFOUND, questionnaire);
} else {
ok = warning(errors, IssueType.REQUIRED, q.line(), q.col(), stack.getLiteralPath(), qsrc != null, I18nConstants.QUESTIONNAIRE_QR_Q_NOTFOUND, questionnaire);
}
if (ok) {
boolean inProgress = "in-progress".equals(element.getNamedChildValue("status"));
validateQuestionannaireResponseItems(hostContext, qsrc, qsrc.q().getItem(), errors, element, stack, inProgress, element, new QStack(qsrc, element));
}
}
}
Aggregations