Search in sources :

Example 91 with Expression

use of org.hl7.elm.r1.Expression in project org.hl7.fhir.core by hapifhir.

the class OperationOutcomeUtilities method convertToIssue.

public static OperationOutcomeIssueComponent convertToIssue(ValidationMessage message, OperationOutcome op) {
    OperationOutcomeIssueComponent issue = new OperationOutcome.OperationOutcomeIssueComponent();
    issue.setUserData("source.vm", message);
    issue.setCode(convert(message.getType()));
    if (message.getLocation() != null) {
        // message location has a fhirPath in it. We need to populate the expression
        issue.addExpression(message.getLocation());
    }
    // pass through line/col if they're present
    if (message.getLine() >= 0)
        issue.addExtension().setUrl(ToolingExtensions.EXT_ISSUE_LINE).setValue(new IntegerType(message.getLine()));
    if (message.getCol() >= 0)
        issue.addExtension().setUrl(ToolingExtensions.EXT_ISSUE_COL).setValue(new IntegerType(message.getCol()));
    issue.setSeverity(convert(message.getLevel()));
    CodeableConcept c = new CodeableConcept();
    c.setText(message.getMessage());
    issue.setDetails(c);
    if (message.getSource() != null) {
        issue.getExtension().add(ToolingExtensions.makeIssueSource(message.getSource()));
    }
    issue.setUserData("source.msg", message);
    return issue;
}
Also used : IntegerType(org.hl7.fhir.r4b.model.IntegerType) OperationOutcomeIssueComponent(org.hl7.fhir.r4b.model.OperationOutcome.OperationOutcomeIssueComponent) CodeableConcept(org.hl7.fhir.r4b.model.CodeableConcept)

Example 92 with Expression

use of org.hl7.elm.r1.Expression in project org.hl7.fhir.core by hapifhir.

the class GraphDefinitionEngine method processLinkPath.

private void processLinkPath(String focusPath, Resource focus, GraphDefinitionLinkComponent link, int depth) {
    String path = focusPath + " -> " + link.getPath();
    check(link.hasPath(), "Path is needed at " + path);
    check(!link.hasSliceName(), "SliceName is not yet supported at " + path);
    ExpressionNode node;
    if (link.getPathElement().hasUserData(TAG_NAME)) {
        node = (ExpressionNode) link.getPathElement().getUserData(TAG_NAME);
    } else {
        node = engine.parse(link.getPath());
        link.getPathElement().setUserData(TAG_NAME, node);
    }
    List<Base> matches = engine.evaluate(null, focus, focus, focus, node);
    check(!validating || matches.size() >= (link.hasMin() ? link.getMin() : 0), "Link at path " + path + " requires at least " + link.getMin() + " matches, but only found " + matches.size());
    check(!validating || matches.size() <= (link.hasMax() ? Integer.parseInt(link.getMax()) : Integer.MAX_VALUE), "Link at path " + path + " requires at most " + link.getMax() + " matches, but found " + matches.size());
    for (Base sel : matches) {
        // todo: should a URL be ok?
        check(sel.fhirType().equals("Reference"), "Selected node from an expression must be a Reference");
        ReferenceResolution res = services.lookup(appInfo, focus, (Reference) sel);
        if (res != null) {
            // todo
            check(res.getTargetContext() != focus, "how to handle contained resources is not yet resolved");
            for (GraphDefinitionLinkTargetComponent tl : link.getTarget()) {
                if (tl.getType().equals(res.getTarget().fhirType())) {
                    Resource r = (Resource) res.getTarget();
                    if (!isInBundle(r)) {
                        addToBundle(r);
                        for (GraphDefinitionLinkComponent l : graphDefinition.getLink()) {
                            processLink(focus.fhirType(), r, l, depth + 1);
                        }
                    }
                }
            }
        }
    }
}
Also used : GraphDefinitionLinkComponent(org.hl7.fhir.r4b.model.GraphDefinition.GraphDefinitionLinkComponent) ExpressionNode(org.hl7.fhir.r4b.model.ExpressionNode) ReferenceResolution(org.hl7.fhir.utilities.graphql.IGraphQLStorageServices.ReferenceResolution) Resource(org.hl7.fhir.r4b.model.Resource) IBaseResource(org.hl7.fhir.instance.model.api.IBaseResource) GraphDefinitionLinkTargetComponent(org.hl7.fhir.r4b.model.GraphDefinition.GraphDefinitionLinkTargetComponent) Base(org.hl7.fhir.r4b.model.Base)

Example 93 with Expression

use of org.hl7.elm.r1.Expression in project org.hl7.fhir.core by hapifhir.

the class InstanceValidator method buildHumanNameExpression.

private void buildHumanNameExpression(ElementDefinition ed, StringBuilder expression, String discriminator, HumanName name) throws DefinitionException {
    if (name.hasExtension())
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN__EXTENSIONS_ARE_NOT_ALLOWED__FOR_DISCRIMINATOR_FOR_SLICE_, discriminator, ed.getId()));
    boolean first = true;
    expression.append(discriminator + ".where(");
    if (name.hasUse()) {
        first = false;
        expression.append("use = '" + name.getUse().toCode() + "'");
    }
    if (name.hasText()) {
        if (first)
            first = false;
        else
            expression.append(" and ");
        expression.append("text = '" + name.getText() + "'");
    }
    if (name.hasFamily()) {
        if (first)
            first = false;
        else
            expression.append(" and ");
        expression.append("family = '" + name.getFamily() + "'");
    }
    if (name.hasGiven()) {
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE, discriminator, ed.getId(), name.fhirType(), "given"));
    }
    if (name.hasPrefix()) {
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE, discriminator, ed.getId(), name.fhirType(), "prefix"));
    }
    if (name.hasSuffix()) {
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE, discriminator, ed.getId(), name.fhirType(), "suffix"));
    }
    if (name.hasPeriod()) {
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE, discriminator, ed.getId(), name.fhirType(), "period"));
    }
    if (first) {
        throw new DefinitionException(context.formatMessage(I18nConstants.UNSUPPORTED_IDENTIFIER_PATTERN_NO_PROPERTY_NOT_SUPPORTED_FOR_DISCRIMINATOR_FOR_SLICE, discriminator, ed.getId(), name.fhirType()));
    }
    expression.append(").exists()");
}
Also used : DefinitionException(org.hl7.fhir.exceptions.DefinitionException)

Example 94 with Expression

use of org.hl7.elm.r1.Expression in project org.hl7.fhir.core by hapifhir.

the class InstanceValidator method sliceMatches.

/**
 * @param element - the candidate that might be in the slice
 * @param path    - for reporting any errors. the XPath for the element
 * @param slicer  - the definition of how slicing is determined
 * @param ed      - the slice for which to test membership
 * @param errors
 * @param stack
 * @param srcProfile
 * @return
 * @throws DefinitionException
 * @throws DefinitionException
 * @throws IOException
 * @throws FHIRException
 */
private boolean sliceMatches(ValidatorHostContext hostContext, Element element, String path, ElementDefinition slicer, ElementDefinition ed, StructureDefinition profile, List<ValidationMessage> errors, List<ValidationMessage> sliceInfo, NodeStack stack, StructureDefinition srcProfile) throws DefinitionException, FHIRException {
    if (!slicer.getSlicing().hasDiscriminator())
        // cannot validate in this case
        return false;
    ExpressionNode n = (ExpressionNode) ed.getUserData("slice.expression.cache");
    if (n == null) {
        long t = System.nanoTime();
        // GG: this approach is flawed because it treats discriminators individually rather than collectively
        StringBuilder expression = new StringBuilder("true");
        boolean anyFound = false;
        Set<String> discriminators = new HashSet<>();
        for (ElementDefinitionSlicingDiscriminatorComponent s : slicer.getSlicing().getDiscriminator()) {
            String discriminator = s.getPath();
            discriminators.add(discriminator);
            List<ElementDefinition> criteriaElements = getCriteriaForDiscriminator(path, ed, discriminator, profile, s.getType() == DiscriminatorType.PROFILE, srcProfile);
            boolean found = false;
            for (ElementDefinition criteriaElement : criteriaElements) {
                found = true;
                if (s.getType() == DiscriminatorType.TYPE) {
                    String type = null;
                    if (!criteriaElement.getPath().contains("[") && discriminator.contains("[")) {
                        discriminator = discriminator.substring(0, discriminator.indexOf('['));
                        String lastNode = tail(discriminator);
                        type = tail(criteriaElement.getPath()).substring(lastNode.length());
                        type = type.substring(0, 1).toLowerCase() + type.substring(1);
                    } else if (!criteriaElement.hasType() || criteriaElement.getType().size() == 1) {
                        if (discriminator.contains("["))
                            discriminator = discriminator.substring(0, discriminator.indexOf('['));
                        if (criteriaElement.hasType()) {
                            type = criteriaElement.getType().get(0).getWorkingCode();
                        } else if (!criteriaElement.getPath().contains(".")) {
                            type = criteriaElement.getPath();
                        } else {
                            throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
                        }
                    } else if (criteriaElement.getType().size() > 1) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_MULTIPLE_TYPES_, discriminator, ed.getId(), profile.getUrl(), criteriaElement.typeSummary()));
                    } else
                        throw new DefinitionException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_TYPE_BUT_SLICE__IN__HAS_NO_TYPES, discriminator, ed.getId(), profile.getUrl()));
                    if (discriminator.isEmpty())
                        expression.append(" and $this is " + type);
                    else
                        expression.append(" and " + discriminator + " is " + type);
                } else if (s.getType() == DiscriminatorType.PROFILE) {
                    if (criteriaElement.getType().size() == 0) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    }
                    if (criteriaElement.getType().size() != 1) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_ONLY_ONE_TYPE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    }
                    List<CanonicalType> list = discriminator.endsWith(".resolve()") || discriminator.equals("resolve()") ? criteriaElement.getType().get(0).getTargetProfile() : criteriaElement.getType().get(0).getProfile();
                    if (list.size() == 0) {
                        throw new DefinitionException(context.formatMessage(I18nConstants.PROFILE_BASED_DISCRIMINATORS_MUST_HAVE_A_TYPE_WITH_A_PROFILE__IN_PROFILE_, criteriaElement.getId(), profile.getUrl()));
                    } else if (list.size() > 1) {
                        CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(" or ");
                        for (CanonicalType c : list) {
                            b.append(discriminator + ".conformsTo('" + c.getValue() + "')");
                        }
                        expression.append(" and (" + b + ")");
                    } else {
                        expression.append(" and " + discriminator + ".conformsTo('" + list.get(0).getValue() + "')");
                    }
                } else if (s.getType() == DiscriminatorType.EXISTS) {
                    if (criteriaElement.hasMin() && criteriaElement.getMin() >= 1)
                        expression.append(" and (" + discriminator + ".exists())");
                    else if (criteriaElement.hasMax() && criteriaElement.getMax().equals("0"))
                        expression.append(" and (" + discriminator + ".exists().not())");
                    else
                        throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR__IS_BASED_ON_ELEMENT_EXISTENCE_BUT_SLICE__NEITHER_SETS_MIN1_OR_MAX0, discriminator, ed.getId()));
                } else if (criteriaElement.hasFixed()) {
                    buildFixedExpression(ed, expression, discriminator, criteriaElement);
                } else if (criteriaElement.hasPattern()) {
                    buildPattternExpression(ed, expression, discriminator, criteriaElement);
                } else if (criteriaElement.hasBinding() && criteriaElement.getBinding().hasStrength() && criteriaElement.getBinding().getStrength().equals(BindingStrength.REQUIRED) && criteriaElement.getBinding().hasValueSet()) {
                    expression.append(" and (" + discriminator + " memberOf '" + criteriaElement.getBinding().getValueSet() + "')");
                } else {
                    found = false;
                }
                if (found)
                    break;
            }
            if (found)
                anyFound = true;
        }
        if (!anyFound) {
            if (slicer.getSlicing().getDiscriminator().size() > 1)
                throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_ANY_DISCRIMINATORS__FOR_SLICE__IN_PROFILE___NONE_OF_THE_DISCRIMINATOR__HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
            else
                throw new DefinitionException(context.formatMessage(I18nConstants.COULD_NOT_MATCH_DISCRIMINATOR__FOR_SLICE__IN_PROFILE___THE_DISCRIMINATOR__DOES_NOT_HAVE_FIXED_VALUE_BINDING_OR_EXISTENCE_ASSERTIONS, discriminators, ed.getId(), profile.getUrl(), discriminators));
        }
        try {
            n = fpe.parse(fixExpr(expression.toString(), null));
        } catch (FHIRLexerException e) {
            if (STACK_TRACE)
                e.printStackTrace();
            throw new FHIRException(context.formatMessage(I18nConstants.PROBLEM_PROCESSING_EXPRESSION__IN_PROFILE__PATH__, expression, profile.getUrl(), path, e.getMessage()));
        }
        timeTracker.fpe(t);
        ed.setUserData("slice.expression.cache", n);
    }
    ValidatorHostContext shc = hostContext.forSlicing();
    boolean pass = evaluateSlicingExpression(shc, element, path, profile, n);
    if (!pass) {
        slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), (context.formatMessage(I18nConstants.DOES_NOT_MATCH_SLICE_, ed.getSliceName())), "discriminator = " + Utilities.escapeXml(n.toString()), null);
        for (String url : shc.getSliceRecords().keySet()) {
            slicingHint(sliceInfo, IssueType.STRUCTURE, element.line(), element.col(), path, false, isProfile(slicer), context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, stack.getLiteralPath(), url), context.formatMessage(I18nConstants.PROFILE__DOES_NOT_MATCH_FOR__BECAUSE_OF_THE_FOLLOWING_PROFILE_ISSUES__, url, stack.getLiteralPath(), errorSummaryForSlicingAsHtml(shc.getSliceRecords().get(url))), errorSummaryForSlicingAsText(shc.getSliceRecords().get(url)));
        }
    }
    return pass;
}
Also used : CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) FHIRLexerException(org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) CanonicalType(org.hl7.fhir.r5.model.CanonicalType) FHIRException(org.hl7.fhir.exceptions.FHIRException) ElementDefinitionSlicingDiscriminatorComponent(org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionSlicingDiscriminatorComponent) ExpressionNode(org.hl7.fhir.r5.model.ExpressionNode) ValidatorHostContext(org.hl7.fhir.validation.instance.utils.ValidatorHostContext) ArrayList(java.util.ArrayList) List(java.util.List) TypedElementDefinition(org.hl7.fhir.r5.utils.FHIRPathEngine.TypedElementDefinition) ElementDefinition(org.hl7.fhir.r5.model.ElementDefinition) DefinitionException(org.hl7.fhir.exceptions.DefinitionException) HashSet(java.util.HashSet)

Example 95 with Expression

use of org.hl7.elm.r1.Expression in project org.hl7.fhir.core by hapifhir.

the class ValidationEngine method evaluateFhirPath.

public String evaluateFhirPath(String source, String expression) throws FHIRException, IOException {
    Content cnt = igLoader.loadContent(source, "validate", false);
    FHIRPathEngine fpe = this.getValidator(null).getFHIRPathEngine();
    Element e = Manager.parseSingle(context, new ByteArrayInputStream(cnt.focus), cnt.cntType);
    ExpressionNode exp = fpe.parse(expression);
    return fpe.evaluateToString(new ValidatorHostContext(context, e), e, e, e, exp);
}
Also used : FHIRPathEngine(org.hl7.fhir.r5.utils.FHIRPathEngine) Element(org.hl7.fhir.r5.elementmodel.Element) ValidatorHostContext(org.hl7.fhir.validation.instance.utils.ValidatorHostContext)

Aggregations

Test (org.junit.Test)102 Expression (org.apache.commons.jexl2.Expression)98 TermWeightPosition (datawave.ingest.protobuf.TermWeightPosition)66 Zone (datawave.query.jexl.functions.TermFrequencyList.Zone)66 Test (org.junit.jupiter.api.Test)60 ArrayList (java.util.ArrayList)36 HashMap (java.util.HashMap)35 Patient (org.hl7.fhir.r4.model.Patient)29 CqlEvaluator (com.ibm.cohort.cql.evaluation.CqlEvaluator)28 CqlVersionedIdentifier (com.ibm.cohort.cql.library.CqlVersionedIdentifier)28 Expression (io.atlasmap.v2.Expression)26 JexlContext (org.apache.commons.jexl2.JexlContext)26 Expression (org.hl7.elm.r1.Expression)26 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)25 CqlEvaluationResult (com.ibm.cohort.cql.evaluation.CqlEvaluationResult)24 JexlEngine (org.apache.commons.jexl2.JexlEngine)22 MapContext (org.apache.commons.jexl2.MapContext)22 FHIRException (org.hl7.fhir.exceptions.FHIRException)19 FhirServerConfig (com.ibm.cohort.fhir.client.config.FhirServerConfig)16 Coding (org.hl7.fhir.r4.model.Coding)15