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));
}
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);
}
}
}
Aggregations