Search in sources :

Example 71 with NodeStack

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

the class BundleValidator method validateDocumentSubReference.

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

Example 72 with NodeStack

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

the class BundleValidator method validateBundle.

public void validateBundle(List<ValidationMessage> errors, Element bundle, NodeStack stack, boolean checkSpecials, ValidatorHostContext hostContext) {
    List<Element> entries = new ArrayList<Element>();
    bundle.getNamedChildren(ENTRY, entries);
    String type = bundle.getNamedChildValue(TYPE);
    type = StringUtils.defaultString(type);
    if (entries.size() == 0) {
        rule(errors, IssueType.INVALID, stack.getLiteralPath(), !(type.equals(DOCUMENT) || type.equals(MESSAGE)), I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRST);
    } else {
        // Get the first entry, the MessageHeader
        Element firstEntry = entries.get(0);
        // Get the stack of the first entry
        NodeStack firstStack = stack.push(firstEntry, 1, null, null);
        String fullUrl = firstEntry.getNamedChildValue(FULL_URL);
        if (type.equals(DOCUMENT)) {
            Element resource = firstEntry.getNamedChild(RESOURCE);
            if (rule(errors, IssueType.INVALID, firstEntry.line(), firstEntry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), resource != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE)) {
                String id = resource.getNamedChildValue(ID);
                validateDocument(errors, entries, resource, firstStack.push(resource, -1, null, null), fullUrl, id);
            }
            if (!VersionUtilities.isThisOrLater(FHIRVersion._4_0_1.getDisplay(), bundle.getProperty().getStructure().getFhirVersion().getDisplay())) {
                handleSpecialCaseForLastUpdated(bundle, errors, stack);
            }
            checkAllInterlinked(errors, entries, stack, bundle, true);
        }
        if (type.equals(MESSAGE)) {
            Element resource = firstEntry.getNamedChild(RESOURCE);
            String id = resource.getNamedChildValue(ID);
            if (rule(errors, IssueType.INVALID, firstEntry.line(), firstEntry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), resource != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOFIRSTRESOURCE)) {
                validateMessage(errors, entries, resource, firstStack.push(resource, -1, null, null), fullUrl, id);
            }
            checkAllInterlinked(errors, entries, stack, bundle, VersionUtilities.isR5Ver(context.getVersion()));
        }
        if (type.equals(SEARCHSET)) {
            checkSearchSet(errors, bundle, entries, stack);
        }
    // We do not yet have rules requiring that the id and fullUrl match when dealing with messaging Bundles
    // validateResourceIds(errors, entries, stack);
    }
    int count = 0;
    Map<String, Integer> counter = new HashMap<>();
    boolean fullUrlOptional = Utilities.existsInList(type, "transaction", "transaction-response", "batch", "batch-response");
    for (Element entry : entries) {
        NodeStack estack = stack.push(entry, count, null, null);
        String fullUrl = entry.getNamedChildValue(FULL_URL);
        String url = getCanonicalURLForEntry(entry);
        String id = getIdForEntry(entry);
        if (url != null) {
            if (!(!url.equals(fullUrl) || (url.matches(uriRegexForVersion()) && url.endsWith("/" + id))) && !isV3orV2Url(url))
                rule(errors, IssueType.INVALID, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_MISMATCHIDURL, url, fullUrl, id);
            rule(errors, IssueType.INVALID, entry.line(), entry.col(), stack.addToLiteralPath(ENTRY, PATH_ARG), !url.equals(fullUrl) || serverBase == null || (url.equals(Utilities.pathURL(serverBase, entry.getNamedChild(RESOURCE).fhirType(), id))), I18nConstants.BUNDLE_BUNDLE_ENTRY_CANONICAL, url, fullUrl);
        }
        if (!VersionUtilities.isR2Ver(context.getVersion())) {
            rule(errors, IssueType.INVALID, entry.line(), entry.col(), estack.getLiteralPath(), fullUrlOptional || fullUrl != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_FULLURL_REQUIRED);
        }
        // check bundle profile requests
        if (entry.hasChild(RESOURCE)) {
            String rtype = entry.getNamedChild(RESOURCE).fhirType();
            int rcount = counter.containsKey(rtype) ? counter.get(rtype) + 1 : 0;
            counter.put(rtype, rcount);
            for (BundleValidationRule bvr : validator.getBundleValidationRules()) {
                if (meetsRule(bvr, rtype, rcount, count)) {
                    StructureDefinition defn = validator.getContext().fetchResource(StructureDefinition.class, bvr.getProfile());
                    if (defn == null) {
                        throw new Error(validator.getContext().formatMessage(I18nConstants.BUNDLE_RULE_PROFILE_UNKNOWN, bvr.getRule(), bvr.getProfile()));
                    } else {
                        Element res = entry.getNamedChild(RESOURCE);
                        NodeStack rstack = estack.push(res, -1, null, null);
                        if (validator.isCrumbTrails()) {
                            res.addMessage(signpost(errors, IssueType.INFORMATIONAL, res.line(), res.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM, defn.getUrl()));
                        }
                        stack.resetIds();
                        validator.startInner(hostContext, errors, res, res, defn, rstack, false);
                    }
                }
            }
        }
        // todo: check specials
        count++;
    }
}
Also used : BundleValidationRule(org.hl7.fhir.r5.utils.validation.BundleValidationRule) HashMap(java.util.HashMap) 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) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition)

Example 73 with NodeStack

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

the class BundleValidator method validateSections.

private void validateSections(List<ValidationMessage> errors, List<Element> entries, Element focus, NodeStack stack, String fullUrl, String id) {
    List<Element> sections = new ArrayList<Element>();
    focus.getNamedChildren("section", sections);
    int i = 1;
    for (Element section : sections) {
        NodeStack localStack = stack.push(section, i, null, null);
        // technically R4+, but there won't be matches from before that
        validateDocumentReference(errors, entries, section, stack, fullUrl, id, true, "author", "Section");
        validateDocumentReference(errors, entries, section, stack, fullUrl, id, false, "focus", "Section");
        List<Element> sectionEntries = new ArrayList<Element>();
        section.getNamedChildren(ENTRY, sectionEntries);
        int j = 1;
        for (Element sectionEntry : sectionEntries) {
            NodeStack localStack2 = localStack.push(sectionEntry, j, null, null);
            validateBundleReference(errors, entries, sectionEntry, "Section Entry", localStack2, fullUrl, "Composition", id);
            j++;
        }
        validateSections(errors, entries, section, localStack, fullUrl, id);
        i++;
    }
}
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 74 with NodeStack

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

the class BundleValidator method validateResourceIds.

/**
 * Check each resource entry to ensure that the entry's fullURL includes the resource's id
 * value. Adds an ERROR ValidationMessge to errors List for a given entry if it references
 * a resource and fullURL does not include the resource's id.
 *
 * @param errors  List of ValidationMessage objects that new errors will be added to.
 * @param entries List of entry Element objects to be checked.
 * @param stack   Current NodeStack used to create path names in error detail messages.
 */
private void validateResourceIds(List<ValidationMessage> errors, List<Element> entries, NodeStack stack) {
    // TODO: Need to handle _version
    int i = 1;
    for (Element entry : entries) {
        String fullUrl = entry.getNamedChildValue(FULL_URL);
        Element resource = entry.getNamedChild(RESOURCE);
        String id = resource != null ? resource.getNamedChildValue(ID) : null;
        if (id != null && fullUrl != null) {
            String urlId = null;
            if (fullUrl.startsWith("https://") || fullUrl.startsWith("http://")) {
                urlId = fullUrl.substring(fullUrl.lastIndexOf('/') + 1);
            } else if (fullUrl.startsWith("urn:uuid") || fullUrl.startsWith("urn:oid")) {
                urlId = fullUrl.substring(fullUrl.lastIndexOf(':') + 1);
            }
            rule(errors, IssueType.INVALID, entry.line(), entry.col(), stack.addToLiteralPath("entry[" + i + "]"), urlId.equals(id), I18nConstants.BUNDLE_BUNDLE_ENTRY_IDURLMISMATCH, id, fullUrl);
        }
        i++;
    }
}
Also used : IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) Element(org.hl7.fhir.r5.elementmodel.Element)

Example 75 with NodeStack

use of org.hl7.fhir.validation.instance.utils.NodeStack 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);
    }
}
Also used : QuestionnaireItemAnswerOptionComponent(org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent) StringType(org.hl7.fhir.r5.model.StringType) 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)

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