Interface FunctionExtension
A read-only function extension (RFC 9535, Section 2.4). It runs with each JsonModel, also
with a read-only model such as a model over a memory-mapped file.
A function extension adds a function to filter expressions. It has two parts:
- A
FunctionSignaturefor the parser, which checks that each call is well-typed. - This implementation for the evaluator, which applies the function.
Example
// first(NodesType): ValueType. The first node of a nodelist, or Nothing.
// A read-only extension: it runs with each JsonModel, also with a read-only model.
static final class First implements FunctionExtension {
static final FunctionSignature SIGNATURE =
new FunctionSignature("first", FunctionType.VALUE, List.of(FunctionType.NODES));
@Override
public FunctionSignature signature() {
return SIGNATURE;
}
@Override
public <N> Instance<N> apply(List<Instance<N>> arguments, JsonModel<N> model) {
// The evaluator gives one instance for each parameter, of the declared type.
List<Node<N>> nodes = ((Instance.NodesInstance<N>) arguments.getFirst()).nodes();
// A ValueType result is an existing node, or Nothing.
return new Instance.ValueInstance<>(nodes.isEmpty() ? Maybe.none() : Maybe.some(nodes.getFirst().value()));
}
}
Give the signature to the parser and the implementation to the evaluator:
// The parser needs the signature, to check that queries are well-typed.
Result<JsonPathParser, FunctionRegistrationError> parser =
JsonPathParser.withFunctions(List.of(First.SIGNATURE));
// The evaluator needs the implementation.
Result<JsonPathEvaluator, ExtensionError> evaluator =
JsonPathEvaluator.withFunctions(List.of(new First()));
JsonPathQuery query = parser.orElse(JsonPathParser.standard())
.parse("$[?first(@.*) > 4]")
.orElse(null);
List<Node<JsonNode>> nodes = evaluator.orElse(JsonPathEvaluator.standard())
.evaluate(query, root, JacksonJsonModel.INSTANCE)
.orElse(List.of());
// nodes: the path $[1]
Arguments and results
A read-only extension cannot make new JSON values, because a read-only model cannot build nodes. So its signature has these limits:
| Permitted | |
|---|---|
| Parameters | NodesType (Instance.NodesInstance) and LogicalType (Instance.LogicalInstance) |
| Result | LogicalType, NodesType, or ValueType (Instance.ValueInstance) |
A ValueType result must be a node of the query argument, for example a node of an argument nodelist, or Nothing. A NodesType result must have nodes of the query argument with their paths.
JsonPathEvaluator.withFunctions(List) rejects a read-only extension with a ValueType
parameter: a ValueType argument can be a literal, which is not a node of the query argument.
For such functions, use a BuildingFunctionExtension.
A result of the wrong type gives EvaluationError.ExtensionResultMismatch.
Rules
An implementation must have no side effects: the same arguments must always give the same
result. It must not throw an exception. It reads node values only through the JsonModel that
it receives.
-
Method Summary
-
Method Details
-
signature
FunctionSignature signature()Returns the signature. The parser that makes the queries must know the same signature.- Returns:
- the signature
-
apply
Applies the function.- Type Parameters:
N- the node type of the JSON model- Parameters:
arguments- one instance for each parameter, of the declared type of the parametermodel- the model of the query argument, to read node values- Returns:
- the result, an instance of the declared result type
-