Search in sources :

Example 66 with Rule

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);
                    }
                }
            }
        }
    }
}
Also used : IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack)

Example 67 with Rule

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);
    }
}
Also used : IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element)

Example 68 with Rule

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++;
    }
}
Also used : EntrySummary(org.hl7.fhir.validation.instance.utils.EntrySummary) IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 69 with Rule

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);
}
Also used : QuestionnaireItemAnswerOptionComponent(org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack) FHIRException(org.hl7.fhir.exceptions.FHIRException) TimeType(org.hl7.fhir.r5.model.TimeType)

Example 70 with Rule

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));
        }
    }
}
Also used : Questionnaire(org.hl7.fhir.r5.model.Questionnaire) QuestionnaireWithContext(org.hl7.fhir.validation.instance.type.QuestionnaireValidator.QuestionnaireWithContext) Element(org.hl7.fhir.r5.elementmodel.Element) QStack(org.hl7.fhir.validation.instance.EnableWhenEvaluator.QStack)

Aggregations

FHIRException (org.hl7.fhir.exceptions.FHIRException)76 ArrayList (java.util.ArrayList)46 Element (org.hl7.fhir.r5.elementmodel.Element)38 IOException (java.io.IOException)28 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)26 NodeStack (org.hl7.fhir.validation.instance.utils.NodeStack)23 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)20 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)20 ValidationMessage (org.hl7.fhir.utilities.validation.ValidationMessage)19 IndexedElement (org.hl7.fhir.validation.instance.utils.IndexedElement)17 NotImplementedException (org.apache.commons.lang3.NotImplementedException)16 FHIRFormatError (org.hl7.fhir.exceptions.FHIRFormatError)14 FHIRLexerException (org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException)14 Complex (org.hl7.fhir.dstu3.utils.formats.Turtle.Complex)13 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)13 NamedElement (org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement)13 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)13 ValueSet (org.hl7.fhir.r5.model.ValueSet)13 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)13 SpecialElement (org.hl7.fhir.r5.elementmodel.Element.SpecialElement)12