Search in sources :

Example 11 with Validated

use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.

the class InstanceValidator method checkReference.

private void checkReference(ValidatorHostContext hostContext, List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition container, String parentType, NodeStack stack) throws FHIRException {
    Reference reference = ObjectConverter.readAsReference(element);
    String ref = reference.getReference();
    if (Utilities.noString(ref)) {
        if (!path.contains("element.pattern")) {
            // this business rule doesn't apply to patterns
            if (Utilities.noString(reference.getIdentifier().getSystem()) && Utilities.noString(reference.getIdentifier().getValue())) {
                warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !Utilities.noString(element.getNamedChildValue("display")), I18nConstants.REFERENCE_REF_NODISPLAY);
            }
        }
        return;
    } else if (Utilities.existsInList(ref, "http://tools.ietf.org/html/bcp47")) {
        // special known URLs that can't be validated but are known to be valid
        return;
    }
    warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !isSuspiciousReference(ref), I18nConstants.REFERENCE_REF_SUSPICIOUS, ref);
    ResolvedReference we = localResolve(ref, stack, errors, path, hostContext.getRootResource(), hostContext.getGroupingResource(), element);
    String refType;
    if (ref.startsWith("#")) {
        refType = "contained";
    } else {
        if (we == null) {
            refType = "remote";
        } else {
            refType = "bundled";
        }
    }
    ReferenceValidationPolicy pol;
    if (refType.equals("contained") || refType.equals("bundled")) {
        pol = ReferenceValidationPolicy.CHECK_VALID;
    } else {
        if (policyAdvisor == null)
            pol = ReferenceValidationPolicy.IGNORE;
        else
            pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref);
    }
    if (pol.checkExists()) {
        if (we == null) {
            if (!refType.equals("contained")) {
                if (fetcher == null) {
                    throw new FHIRException(context.formatMessage(I18nConstants.RESOURCE_RESOLUTION_SERVICES_NOT_PROVIDED));
                } else {
                    Element ext = null;
                    if (fetchCache.containsKey(ref)) {
                        ext = fetchCache.get(ref);
                    } else {
                        try {
                            ext = fetcher.fetch(this, hostContext.getAppContext(), ref);
                        } catch (IOException e) {
                            if (STACK_TRACE)
                                e.printStackTrace();
                            throw new FHIRException(e);
                        }
                        if (ext != null) {
                            setParents(ext);
                            fetchCache.put(ref, ext);
                        }
                    }
                    we = ext == null ? null : makeExternalRef(ext, path);
                }
            }
        }
        boolean ok = (allowExamples && (ref.contains("example.org") || ref.contains("acme.com"))) || (we != null || pol == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS);
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_CANTRESOLVE, ref);
    }
    String ft;
    if (we != null) {
        ft = we.getType();
    } else {
        ft = tryParse(ref);
    }
    if (reference.hasType()) {
        // R4 onwards...
        // the type has to match the specified
        String tu = isAbsolute(reference.getType()) ? reference.getType() : "http://hl7.org/fhir/StructureDefinition/" + reference.getType();
        TypeRefComponent containerType = container.getType("Reference");
        if (!containerType.hasTargetProfile(tu) && !containerType.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource") && !containerType.getTargetProfile().isEmpty()) {
            boolean matchingResource = false;
            for (CanonicalType target : containerType.getTargetProfile()) {
                StructureDefinition sd = resolveProfile(profile, target.asStringValue());
                if (rule(errors, IssueType.NOTFOUND, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, target.asStringValue())) {
                    if (("http://hl7.org/fhir/StructureDefinition/" + sd.getType()).equals(tu)) {
                        matchingResource = true;
                        break;
                    }
                }
            }
            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, matchingResource, I18nConstants.REFERENCE_REF_WRONGTARGET, reference.getType(), container.getType("Reference").getTargetProfile());
        }
        // the type has to match the actual
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft == null || ft.equals(reference.getType()), I18nConstants.REFERENCE_REF_BADTARGETTYPE, reference.getType(), ft);
    }
    if (we != null && pol.checkType()) {
        if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft != null, I18nConstants.REFERENCE_REF_NOTYPE)) {
            // we validate as much as we can. First, can we infer a type from the profile?
            boolean ok = false;
            TypeRefComponent type = getReferenceTypeRef(container.getType());
            if (type.hasTargetProfile() && !type.hasTargetProfile("http://hl7.org/fhir/StructureDefinition/Resource")) {
                Set<String> types = new HashSet<>();
                List<StructureDefinition> profiles = new ArrayList<>();
                for (UriType u : type.getTargetProfile()) {
                    StructureDefinition sd = resolveProfile(profile, u.getValue());
                    if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, u.getValue())) {
                        types.add(sd.getType());
                        if (ft.equals(sd.getType())) {
                            ok = true;
                            profiles.add(sd);
                        }
                    }
                }
                if (!pol.checkValid()) {
                    rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() > 0, I18nConstants.REFERENCE_REF_CANTMATCHTYPE, ref, StringUtils.join("; ", type.getTargetProfile()));
                } else {
                    Map<StructureDefinition, List<ValidationMessage>> badProfiles = new HashMap<>();
                    Map<StructureDefinition, List<ValidationMessage>> goodProfiles = new HashMap<>();
                    int goodCount = 0;
                    for (StructureDefinition pr : profiles) {
                        List<ValidationMessage> profileErrors = new ArrayList<ValidationMessage>();
                        validateResource(we.hostContext(hostContext, pr), profileErrors, we.getResource(), we.getFocus(), pr, IdStatus.OPTIONAL, we.getStack().resetIds());
                        if (!hasErrors(profileErrors)) {
                            goodCount++;
                            goodProfiles.put(pr, profileErrors);
                            trackUsage(pr, hostContext, element);
                        } else {
                            badProfiles.put(pr, profileErrors);
                        }
                    }
                    if (goodCount == 1) {
                        if (showMessagesFromReferences) {
                            for (ValidationMessage vm : goodProfiles.values().iterator().next()) {
                                if (!errors.contains(vm)) {
                                    errors.add(vm);
                                }
                            }
                        }
                    } else if (goodProfiles.size() == 0) {
                        if (!isShowMessagesFromReferences()) {
                            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
                            for (StructureDefinition sd : badProfiles.keySet()) {
                                slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
                            }
                        } else {
                            rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile()));
                            for (List<ValidationMessage> messages : badProfiles.values()) {
                                for (ValidationMessage vm : messages) {
                                    if (!errors.contains(vm)) {
                                        errors.add(vm);
                                    }
                                }
                            }
                        }
                    } else {
                        if (!isShowMessagesFromReferences()) {
                            warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
                            for (StructureDefinition sd : badProfiles.keySet()) {
                                slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd)));
                            }
                        } else {
                            warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet()));
                            for (List<ValidationMessage> messages : goodProfiles.values()) {
                                for (ValidationMessage vm : messages) {
                                    if (!errors.contains(vm)) {
                                        errors.add(vm);
                                    }
                                }
                            }
                        }
                    }
                }
                rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString());
            }
            if (type.hasAggregation() && !noCheckAggregation) {
                boolean modeOk = false;
                CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
                for (Enumeration<AggregationMode> mode : type.getAggregation()) {
                    b.append(mode.getCode());
                    if (mode.getValue().equals(AggregationMode.CONTAINED) && refType.equals("contained"))
                        modeOk = true;
                    else if (mode.getValue().equals(AggregationMode.BUNDLED) && refType.equals("bundled"))
                        modeOk = true;
                    else if (mode.getValue().equals(AggregationMode.REFERENCED) && (refType.equals("bundled") || refType.equals("remote")))
                        modeOk = true;
                }
                rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString());
            }
        }
    }
    if (we == null) {
        TypeRefComponent type = getReferenceTypeRef(container.getType());
        boolean okToRef = !type.hasAggregation() || type.hasAggregation(AggregationMode.REFERENCED);
        rule(errors, IssueType.REQUIRED, -1, -1, path, okToRef, I18nConstants.REFERENCE_REF_NOTFOUND_BUNDLE, ref);
    }
    if (we == null && ft != null && assumeValidRestReferences) {
        // if we == null, we inferred ft from the reference. if we are told to treat this as gospel
        TypeRefComponent type = getReferenceTypeRef(container.getType());
        Set<String> types = new HashSet<>();
        StructureDefinition sdFT = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + ft);
        boolean ok = false;
        for (CanonicalType tp : type.getTargetProfile()) {
            StructureDefinition sd = context.fetchResource(StructureDefinition.class, tp.getValue());
            if (sd != null) {
                types.add(sd.getType());
            }
            StructureDefinition sdF = sdFT;
            while (sdF != null) {
                if (sdF.getType().equals(sd.getType())) {
                    ok = true;
                    break;
                }
                sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition()) : null;
            }
        }
        rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE2, ft, ref, types);
    }
    if (pol == ReferenceValidationPolicy.CHECK_VALID) {
    // todo....
    }
}
Also used : ResolvedReference(org.hl7.fhir.validation.instance.utils.ResolvedReference) ValidationMessage(org.hl7.fhir.utilities.validation.ValidationMessage) HashMap(java.util.HashMap) NamedElement(org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement) IndexedElement(org.hl7.fhir.validation.instance.utils.IndexedElement) SpecialElement(org.hl7.fhir.r5.elementmodel.Element.SpecialElement) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) AggregationMode(org.hl7.fhir.r5.model.ElementDefinition.AggregationMode) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) UriType(org.hl7.fhir.r5.model.UriType) StructureDefinition(org.hl7.fhir.r5.model.StructureDefinition) TypeRefComponent(org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) Reference(org.hl7.fhir.r5.model.Reference) ResolvedReference(org.hl7.fhir.validation.instance.utils.ResolvedReference) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException) ContactPoint(org.hl7.fhir.r5.model.ContactPoint)

Example 12 with Validated

use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.

the class EnableWhenEvaluator method isQuestionEnabled.

/**
 * the stack contains a set of QR items that represent the tree of the QR being validated, each tagged with the definition of the item from the Q for the QR being validated
 * <p>
 * the itembeing validated is in the context of the stack. For root items, the stack is empty.
 * <p>
 * The context Questionnaire and QuestionnaireResponse are always available
 */
public boolean isQuestionEnabled(ValidatorHostContext hostContext, QuestionnaireItemComponent qitem, QStack qstack, FHIRPathEngine engine) {
    if (hasExpressionExtension(qitem)) {
        String expr = getExpression(qitem);
        ExpressionNode node = engine.parse(expr);
        return engine.evaluateToBoolean(hostContext, qstack.a, qstack.a, qstack.a, node);
    }
    if (!qitem.hasEnableWhen()) {
        return true;
    }
    List<EnableWhenResult> evaluationResults = new ArrayList<>();
    for (QuestionnaireItemEnableWhenComponent enableCondition : qitem.getEnableWhen()) {
        evaluationResults.add(evaluateCondition(enableCondition, qitem, qstack));
    }
    return checkConditionResults(evaluationResults, qitem);
}
Also used : ExpressionNode(org.hl7.fhir.r5.model.ExpressionNode) ArrayList(java.util.ArrayList) QuestionnaireItemEnableWhenComponent(org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemEnableWhenComponent)

Example 13 with Validated

use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.

the class RdfParser method composeTestScriptTestScriptMetadataCapabilityComponent.

protected void composeTestScriptTestScriptMetadataCapabilityComponent(Complex parent, String parentType, String name, TestScript.TestScriptMetadataCapabilityComponent element, int index) {
    if (element == null)
        return;
    Complex t;
    if (Utilities.noString(parentType))
        t = parent;
    else {
        t = parent.predicate("fhir:" + parentType + '.' + name);
    }
    composeBackboneElement(t, "capability", name, element, index);
    if (element.hasRequiredElement())
        composeBoolean(t, "TestScript", "required", element.getRequiredElement(), -1);
    if (element.hasValidatedElement())
        composeBoolean(t, "TestScript", "validated", element.getValidatedElement(), -1);
    if (element.hasDescriptionElement())
        composeString(t, "TestScript", "description", element.getDescriptionElement(), -1);
    for (int i = 0; i < element.getOrigin().size(); i++) composeInteger(t, "TestScript", "origin", element.getOrigin().get(i), i);
    if (element.hasDestinationElement())
        composeInteger(t, "TestScript", "destination", element.getDestinationElement(), -1);
    for (int i = 0; i < element.getLink().size(); i++) composeUri(t, "TestScript", "link", element.getLink().get(i), i);
    if (element.hasCapabilities())
        composeReference(t, "TestScript", "capabilities", element.getCapabilities(), -1);
}
Also used : Complex(org.hl7.fhir.dstu3.utils.formats.Turtle.Complex)

Example 14 with Validated

use of org.hl7.gravity.refimpl.sdohexchange.dto.Validated in project org.hl7.fhir.core by hapifhir.

the class RdfParser method composeTestScriptTestScriptMetadataCapabilityComponent.

protected void composeTestScriptTestScriptMetadataCapabilityComponent(Complex parent, String parentType, String name, TestScript.TestScriptMetadataCapabilityComponent element, int index) {
    if (element == null)
        return;
    Complex t;
    if (Utilities.noString(parentType))
        t = parent;
    else {
        t = parent.predicate("fhir:" + parentType + '.' + name);
    }
    composeBackboneElement(t, "capability", name, element, index);
    if (element.hasRequiredElement())
        composeBoolean(t, "TestScript", "required", element.getRequiredElement(), -1);
    if (element.hasValidatedElement())
        composeBoolean(t, "TestScript", "validated", element.getValidatedElement(), -1);
    if (element.hasDescriptionElement())
        composeString(t, "TestScript", "description", element.getDescriptionElement(), -1);
    for (int i = 0; i < element.getOrigin().size(); i++) composeInteger(t, "TestScript", "origin", element.getOrigin().get(i), i);
    if (element.hasDestinationElement())
        composeInteger(t, "TestScript", "destination", element.getDestinationElement(), -1);
    for (int i = 0; i < element.getLink().size(); i++) composeUri(t, "TestScript", "link", element.getLink().get(i), i);
    if (element.hasConformance())
        composeReference(t, "TestScript", "conformance", element.getConformance(), -1);
}
Also used : Complex(org.hl7.fhir.dstu2016may.formats.RdfGenerator.Complex)

Aggregations

ArrayList (java.util.ArrayList)7 FHIRException (org.hl7.fhir.exceptions.FHIRException)4 Resource (org.hl7.fhir.r4.model.Resource)4 IOException (java.io.IOException)3 List (java.util.List)3 ResourceNotFoundException (ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException)2 JsonArray (com.google.gson.JsonArray)2 JsonElement (com.google.gson.JsonElement)2 JsonObject (com.google.gson.JsonObject)2 JsonPrimitive (com.google.gson.JsonPrimitive)2 DataFormatException (java.util.zip.DataFormatException)2 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)2 Bundle (org.hl7.fhir.r4.model.Bundle)2 Consent (org.hl7.fhir.r4.model.Consent)2 IdType (org.hl7.fhir.r4.model.IdType)2 Organization (org.hl7.fhir.r4.model.Organization)2 Patient (org.hl7.fhir.r4.model.Patient)2 ServiceRequest (org.hl7.fhir.r4.model.ServiceRequest)2 Task (org.hl7.fhir.r4.model.Task)2 UriType (org.hl7.fhir.r5.model.UriType)2