Concepts to Know : Expression Language : Extending the Expression Language
 
Share this page                  
Extending the Expression Language
The function language can be extended to support any user-defined scalar valued functions or aggregations.
To create your own function, create a class containing methods that return your scalar valued functions or aggregations. Mark each of these methods with the @Function annotation.
You may optionally specify the following properties for the @Function annotation:
name
Specifies the identifier to use within the function language to identify this function. If not specified, the name of the method is used.
invoker
Specifies the FunctionInvoker class to use when invoking this method. If not specified, DefaultFunctionInvoker is used.
argumentCount
Specifies the number of arguments which the function language should expect when calling this function. If not specified, the number of method arguments is used.
description
Provides a description of the function, used in documentation.
argumentNames
Specifies an array of names for each argument the function takes. This only needs to be set if the number of function arguments does not match the number of method arguments; otherwise, specify this for each argument using the name property in @FunctionArgument.
In most cases, DefaultFunctionInvoker can be used to invoke a scalar valued function method. This invoker will expect the same number of arguments as the method takes.
ScalarValuedFunction method arguments are taken directly from the function call. If the method takes primitive or String arguments, the invoker will expect ConstantReference arguments of the appropriate type. For other argument types, you can specify a custom ArgumentConverter for each argument using the @FunctionArgument annotation.
@FunctionArgument optionally takes the following properties:
name
Specifies the name of the argument, used in documentation.
converter
Specifies the ArgumentConverter class, which DefaultFunctionInvoker should use to convert this argument.
description
Provides a description of the argument, used in documentation.
If your method takes a single List<ScalarValuedFunction> argument, you may use the ListFunctionInvoker invoker and specify an argumentCount of Function.VARIABLE_ARGUMENT_COUNT. This invoker will take any number of ScalarValuedFunction arguments and pass them as a single list to the method.
If your method requires more complex arguments, you may create your own subclass of FunctionInvoker.
It will require a single method, invoke, which takes two arguments, a Method to invoke, and an array of ScalarValuedFunction arguments. Process the arguments as required and pass them to the method using the Method.invoke() call.
Once your functions have been defined, you can create a subclass of SimpleFunctionProvider to register these method classes. Finally, add a file to META-INF/services called com.pervasive.dataflow.functions.FunctionProvider, containing the fully qualified name of your SimpleFunctionProvider subclass.
The same applies for aggregations, except you will create a subclass of SimpleAggregationProvider, and the file you add to META-INF/services will be called com.pervasive.dataflow.aggregations.AggregationProvider.
For more information about writing custom DataFlow functions, see Writing a Function.