Search in sources :

Example 31 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack 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 32 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.

the class BundleValidator method followResourceLinks.

private void followResourceLinks(Element entry, Map<String, Element> visitedResources, Map<Element, Element> candidateEntries, List<Element> candidateResources, List<ValidationMessage> errors, NodeStack stack, int depth) {
    Element resource = entry.getNamedChild(RESOURCE);
    if (visitedResources.containsValue(resource))
        return;
    visitedResources.put(entry.getNamedChildValue(FULL_URL), resource);
    String type = null;
    Set<String> references = findReferences(resource);
    for (String reference : references) {
        // We don't want errors when just retrieving the element as they will be caught (with better path info) in subsequent processing
        IndexedElement r = getFromBundle(stack.getElement(), reference, entry.getChildValue(FULL_URL), new ArrayList<ValidationMessage>(), stack.addToLiteralPath("entry[" + candidateResources.indexOf(resource) + "]"), type, "transaction".equals(stack.getElement().getChildValue(TYPE)));
        if (r != null && !visitedResources.containsValue(r.getMatch())) {
            followResourceLinks(candidateEntries.get(r.getMatch()), visitedResources, candidateEntries, candidateResources, errors, stack, depth + 1);
        }
    }
}
Also used : IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element)

Example 33 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.

the class BundleValidator method validateDocumentReference.

public void validateDocumentReference(List<ValidationMessage> errors, List<Element> entries, Element composition, NodeStack stack, String fullUrl, String id, boolean repeats, String propName, String title) {
    if (repeats) {
        List<Element> list = new ArrayList<>();
        composition.getNamedChildren(propName, list);
        int i = 1;
        for (Element elem : list) {
            validateBundleReference(errors, entries, elem, title + "." + propName, stack.push(elem, i, null, null), fullUrl, "Composition", id);
            i++;
        }
    } else {
        Element elem = composition.getNamedChild(propName);
        if (elem != null) {
            validateBundleReference(errors, entries, elem, title + "." + propName, stack.push(elem, -1, null, null), fullUrl, "Composition", id);
        }
    }
}
Also used : IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList)

Example 34 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack 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 35 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack 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

Element (org.hl7.fhir.r5.elementmodel.Element)50 ArrayList (java.util.ArrayList)35 NodeStack (org.hl7.fhir.validation.instance.utils.NodeStack)32 FHIRException (org.hl7.fhir.exceptions.FHIRException)22 IndexedElement (org.hl7.fhir.validation.instance.utils.IndexedElement)22 IOException (java.io.IOException)14 SpecialElement (org.hl7.fhir.r5.elementmodel.Element.SpecialElement)14 NamedElement (org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement)13 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)12 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)12 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)12 ValueSet (org.hl7.fhir.r5.model.ValueSet)12 FHIRLexerException (org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException)11 NotImplementedException (org.apache.commons.lang3.NotImplementedException)10 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)10 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)10 ValidationResult (org.hl7.fhir.r5.context.IWorkerContext.ValidationResult)10 List (java.util.List)8 CodeSystem (org.hl7.fhir.r5.model.CodeSystem)8 Coding (org.hl7.fhir.r5.model.Coding)8