use of au.csiro.pathling.fhirpath.literal.StringLiteralPath in project pathling by aehrc.
the class MemberOfFunction method validateInput.
private void validateInput(@Nonnull final NamedFunctionInput input) {
final ParserContext context = input.getContext();
checkUserInput(context.getTerminologyServiceFactory().isPresent(), "Attempt to call terminology function " + NAME + " when terminology service has not been configured");
final FhirPath inputPath = input.getInput();
checkUserInput(inputPath instanceof ElementPath && (((ElementPath) inputPath).getFhirType().equals(FHIRDefinedType.CODING) || ((ElementPath) inputPath).getFhirType().equals(FHIRDefinedType.CODEABLECONCEPT)), "Input to memberOf function is of unsupported type: " + inputPath.getExpression());
checkUserInput(input.getArguments().size() == 1, "memberOf function accepts one argument of type String");
final FhirPath argument = input.getArguments().get(0);
checkUserInput(argument instanceof StringLiteralPath, "memberOf function accepts one argument of type String literal");
}
use of au.csiro.pathling.fhirpath.literal.StringLiteralPath in project pathling by aehrc.
the class TranslateFunction method validateInput.
private void validateInput(@Nonnull final NamedFunctionInput input) {
final ParserContext context = input.getContext();
checkUserInput(context.getTerminologyServiceFactory().isPresent(), "Attempt to call terminology function " + NAME + " when terminology service has not been configured");
final FhirPath inputPath = input.getInput();
checkUserInput(TerminologyUtils.isCodingOrCodeableConcept(inputPath), String.format("Input to %s function is of unsupported type: %s", NAME, inputPath.getExpression()));
final List<FhirPath> arguments = input.getArguments();
checkUserInput(arguments.size() >= 1 && arguments.size() <= 3, NAME + " function accepts one required and two optional arguments");
checkUserInput(arguments.get(0) instanceof StringLiteralPath, String.format("Function `%s` expects `%s` as argument %s", NAME, "String literal", 1));
checkUserInput(arguments.size() <= 1 || arguments.get(1) instanceof BooleanLiteralPath, String.format("Function `%s` expects `%s` as argument %s", NAME, "Boolean literal", 2));
checkUserInput(arguments.size() <= 2 || arguments.get(2) instanceof StringLiteralPath, String.format("Function `%s` expects `%s` as argument %s", NAME, "String literal", 3));
}
use of au.csiro.pathling.fhirpath.literal.StringLiteralPath 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.literal.StringLiteralPath in project pathling by aehrc.
the class ExtensionFunctionTest method testExtensionOnElements.
@Test
public void testExtensionOnElements() {
final ParserContext parserContext = new ParserContextBuilder(spark, fhirContext).build();
// Construct element dataset from the resource dataset so that the resource path
// can be used as the current resource for this element path
// Note: this resource path is not singular as this will be a base for elements.
final Dataset<Row> resourceLikeDataset = new ResourceDatasetBuilder(spark).withIdColumn().withEidColumn().withStructColumn("name", DataTypes.StringType).withStructColumn("_fid", DataTypes.IntegerType).withStructValueColumn().withExtensionColumn().withRow("observation-1", makeEid(0), RowFactory.create("name1", 0), oneEntryMap(0, MANY_MY_EXTENSIONS)).withRow("observation-2", makeEid(0), RowFactory.create("name2", 1), oneEntryMap(1, ONE_MY_EXTENSION)).withRow("observation-3", makeEid(0), RowFactory.create("name3", 2), oneEntryMap(2, NO_MY_EXTENSIONS)).withRow("observation-4", makeEid(0), RowFactory.create("name4", 3), oneEntryMap(3, ONE_MY_EXTENSION)).withRow("observation-4", makeEid(1), RowFactory.create("name5", 4), oneEntryMap(3, ONE_MY_EXTENSION)).withRow("observation-5", makeEid(0), null, null).withRow("observation-5", makeEid(1), null, null).build();
when(database.read(ResourceType.OBSERVATION)).thenReturn(resourceLikeDataset);
final ResourcePath baseResourcePath = ResourcePath.build(fhirContext, database, ResourceType.OBSERVATION, "Observation", false);
final Dataset<Row> elementDataset = toElementDataset(resourceLikeDataset, baseResourcePath);
final ElementDefinition codeDefinition = checkPresent(FhirHelpers.getChildOfResource(fhirContext, "Observation", "code"));
final ElementPath inputPath = new ElementPathBuilder(spark).fhirType(FHIRDefinedType.CODEABLECONCEPT).definition(codeDefinition).dataset(elementDataset).idAndEidAndValueColumns().expression("code").singular(false).currentResource(baseResourcePath).buildDefined();
final StringLiteralPath argumentExpression = StringLiteralPath.fromString("'" + "uuid:myExtension" + "'", inputPath);
final NamedFunctionInput extensionInput = new NamedFunctionInput(parserContext, inputPath, Collections.singletonList(argumentExpression));
final NamedFunction extension = NamedFunction.getInstance("extension");
final FhirPath result = extension.invoke(extensionInput);
final Dataset<Row> expectedResult = new DatasetBuilder(spark).withIdColumn().withEidColumn().withStructTypeColumns(DatasetBuilder.SIMPLE_EXTENSION_TYPE).withRow("observation-1", makeEid(0, 0), null).withRow("observation-1", makeEid(0, 1), null).withRow("observation-1", makeEid(0, 2), MANY_EXT_ROW_1).withRow("observation-1", makeEid(0, 3), MANY_EXT_ROW_2).withRow("observation-2", makeEid(0, 0), null).withRow("observation-2", makeEid(0, 1), ONE_EXT_ROW_1).withRow("observation-3", makeEid(0, 0), null).withRow("observation-3", makeEid(0, 1), null).withRow("observation-4", makeEid(0, 0), null).withRow("observation-4", makeEid(0, 1), ONE_EXT_ROW_1).withRow("observation-4", makeEid(1, 0), null).withRow("observation-5", makeEid(0, 0), null).withRow("observation-5", makeEid(1, 0), null).buildWithStructValue();
assertThat(result).hasExpression("code.extension('uuid:myExtension')").isNotSingular().isElementPath(ElementPath.class).hasFhirType(FHIRDefinedType.EXTENSION).selectOrderedResultWithEid().hasRows(expectedResult);
}
use of au.csiro.pathling.fhirpath.literal.StringLiteralPath in project pathling by aehrc.
the class IifFunctionTest method throwsErrorIfConditionNotBoolean.
@Test
void throwsErrorIfConditionNotBoolean() {
final ElementPath condition = new ElementPathBuilder(spark).fhirType(FHIRDefinedType.INTEGER).expression("valueInteger").singular(true).build();
final StringLiteralPath ifTrue = StringLiteralPath.fromString("foo", condition);
final StringLiteralPath otherwise = StringLiteralPath.fromString("bar", condition);
final NamedFunctionInput iifInput = new NamedFunctionInput(parserContext, condition, Arrays.asList(condition, ifTrue, otherwise));
final NamedFunction notFunction = NamedFunction.getInstance("iif");
final InvalidUserInputError error = assertThrows(InvalidUserInputError.class, () -> notFunction.invoke(iifInput));
assertEquals("Condition argument to iif must be Boolean: valueInteger", error.getMessage());
}
Aggregations