Search in sources :

Example 1 with PathTraversalInput

use of au.csiro.pathling.fhirpath.operator.PathTraversalInput in project pathling by aehrc.

the class ExtensionFunction method invoke.

@Nonnull
@Override
public FhirPath invoke(@Nonnull final NamedFunctionInput input) {
    final String expression = NamedFunction.expressionFromInput(input, NAME);
    checkUserInput(input.getArguments().size() == 1, "extension function must have one argument: " + expression);
    final FhirPath urlArgument = input.getArguments().get(0);
    checkUserInput(urlArgument instanceof StringLiteralPath, "extension function must have argument of type String literal: " + expression);
    final NonLiteralPath inputPath = input.getInput();
    final ElementPath extensionPath = new PathTraversalOperator().invoke(new PathTraversalInput(input.getContext(), inputPath, ExtensionSupport.EXTENSION_ELEMENT_NAME()));
    // Now we need to create a correct argument context for the `where` call.
    final ParserContext argumentContext = input.getContext();
    final FhirPath extensionUrlPath = new PathTraversalOperator().invoke(new PathTraversalInput(argumentContext, extensionPath.toThisPath(), "url"));
    final FhirPath extensionUrCondition = new ComparisonOperator(ComparisonOperation.EQUALS).invoke(new OperatorInput(argumentContext, extensionUrlPath, urlArgument));
    // Override the expression in the function input.
    return new WhereFunction().invoke(new NamedFunctionInput(input.getContext(), extensionPath, Collections.singletonList(extensionUrCondition), expression));
}
Also used : PathTraversalInput(au.csiro.pathling.fhirpath.operator.PathTraversalInput) ComparisonOperator(au.csiro.pathling.fhirpath.operator.ComparisonOperator) FhirPath(au.csiro.pathling.fhirpath.FhirPath) StringLiteralPath(au.csiro.pathling.fhirpath.literal.StringLiteralPath) ElementPath(au.csiro.pathling.fhirpath.element.ElementPath) OperatorInput(au.csiro.pathling.fhirpath.operator.OperatorInput) PathTraversalOperator(au.csiro.pathling.fhirpath.operator.PathTraversalOperator) ParserContext(au.csiro.pathling.fhirpath.parser.ParserContext) NonLiteralPath(au.csiro.pathling.fhirpath.NonLiteralPath) Nonnull(javax.annotation.Nonnull)

Example 2 with PathTraversalInput

use of au.csiro.pathling.fhirpath.operator.PathTraversalInput in project pathling by aehrc.

the class InvocationVisitor method visitMemberInvocation.

/**
 * This method gets called when an element is on the right-hand side of the invocation expression,
 * or when an identifier is referred to as a term (e.g. "Encounter" or "type").
 *
 * @param ctx The {@link MemberInvocationContext}
 * @return A {@link FhirPath} expression
 */
@Override
@Nonnull
public FhirPath visitMemberInvocation(@Nullable final MemberInvocationContext ctx) {
    @Nullable final String fhirPath = checkNotNull(ctx).getText();
    checkNotNull(fhirPath);
    if (invoker != null) {
        // If there is an invoker, we treat this as a path traversal from the invoker.
        final PathTraversalInput pathTraversalInput = new PathTraversalInput(context, invoker, fhirPath);
        return new PathTraversalOperator().invoke(pathTraversalInput);
    } else {
        if (context.getThisContext().isEmpty()) {
            // See https://hl7.org/fhirpath/2018Sep/index.html#path-selection.
            if (fhirPath.equals(context.getInputContext().getExpression())) {
                return context.getInputContext();
            } else {
                // If the expression is not a reference to the subject resource, treat it as a path
                // traversal from the input context.
                final PathTraversalInput pathTraversalInput = new PathTraversalInput(context, context.getInputContext(), fhirPath);
                return new PathTraversalOperator().invoke(pathTraversalInput);
            }
        } else {
            // If we're in the context of a function's arguments, there are two valid things this
            // could be:
            // (1) a path traversal from the input context;
            // (2) a reference to a resource type.
            // Check if the expression is a reference to a known resource type.
            final ResourceType resourceType;
            try {
                resourceType = ResourceType.fromCode(fhirPath);
            } catch (final FHIRException e) {
                // If the expression is not a resource reference, treat it as a path traversal from the
                // input context.
                final PathTraversalInput pathTraversalInput = new PathTraversalInput(context, context.getThisContext().get(), fhirPath);
                return new PathTraversalOperator().invoke(pathTraversalInput);
            }
            // the current resource reference.
            return ResourcePath.build(context.getFhirContext(), context.getDatabase(), resourceType, fhirPath, true);
        }
    }
}
Also used : PathTraversalInput(au.csiro.pathling.fhirpath.operator.PathTraversalInput) PathTraversalOperator(au.csiro.pathling.fhirpath.operator.PathTraversalOperator) ResourceType(org.hl7.fhir.r4.model.Enumerations.ResourceType) FHIRException(org.hl7.fhir.exceptions.FHIRException) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Aggregations

PathTraversalInput (au.csiro.pathling.fhirpath.operator.PathTraversalInput)2 PathTraversalOperator (au.csiro.pathling.fhirpath.operator.PathTraversalOperator)2 Nonnull (javax.annotation.Nonnull)2 FhirPath (au.csiro.pathling.fhirpath.FhirPath)1 NonLiteralPath (au.csiro.pathling.fhirpath.NonLiteralPath)1 ElementPath (au.csiro.pathling.fhirpath.element.ElementPath)1 StringLiteralPath (au.csiro.pathling.fhirpath.literal.StringLiteralPath)1 ComparisonOperator (au.csiro.pathling.fhirpath.operator.ComparisonOperator)1 OperatorInput (au.csiro.pathling.fhirpath.operator.OperatorInput)1 ParserContext (au.csiro.pathling.fhirpath.parser.ParserContext)1 Nullable (javax.annotation.Nullable)1 FHIRException (org.hl7.fhir.exceptions.FHIRException)1 ResourceType (org.hl7.fhir.r4.model.Enumerations.ResourceType)1