See: Description
| Interface | Description |
|---|---|
| FunctionDefinition |
A function declaration.
|
| FunctionDefinitionBuilder |
Builder of
FunctionDefinition instances. |
| Class | Description |
|---|---|
| BaseFunctionDefinitionBuilder<T extends BaseFunctionDefinitionBuilder<T>> |
Base builder of
FunctionDefinition instances. |
| FunctionDefinitionOnDatasetBuilder |
Builder of
FunctionDefinition instances at the dataset level. |
| FunctionDefinitionOnDataspaceBuilder |
Builder of
FunctionDefinition instances at the dataspace level. |
| FunctionDefinitionOnFieldBuilder |
Builder of
FunctionDefinition instances at the field level. |
| FunctionDefinitionOnTableBuilder |
Builder of
FunctionDefinition instances at the table level. |
| FunctionDefinitionOnTableLevelBuilder<T extends BaseFunctionDefinitionBuilder<T>> |
Builder of
FunctionDefinition instances at both the table and the field levels. |
| FunctionDefinitionOnWorkflowBuilder |
Builder of
FunctionDefinition instances at the workflow level. |
| FunctionDefinitionRegistry |
Registers instances of
FunctionDefinition. |
| InputDefinition |
Specifies the input definition of a function.
|
| OutputDefinition |
Specifies the output definition of a function.
|
Provides classes and interfaces to create custom functions.
Define function:
public final class CustomLowestValueFunction
{
private static final String OUTPUT_LOWEST_VALUE = "lowestValue";
private static final OutputDefinition LOWEST_VALUE_OUTPUT_DEF = OutputDefinition
.forDecimal(OUTPUT_LOWEST_VALUE, UserMessage.createInfo("Lowest value"), null);
public static final FunctionDefinition DEFINITION = FunctionDefinition
.onField("CustomLowestValueFunction")
.withLabel("Lowest value function")
.withDescription("This function finds the lowest value for a numeric field.")
.withOutputs(LOWEST_VALUE_OUTPUT_DEF)
.onValidation(CustomLowestValueFunction::validate)
.onExecution(CustomLowestValueFunction::execute)
.build();
public static final ChartConfigForFunction CHART_CONFIG = ChartConfigForFunction
.newBuilder(AxisConfig.outputLabelAsCategory(OUTPUT_LOWEST_VALUE))
.setDefaultChartType(ChartType.CARD)
.addOtherChartTypes(ChartType.COLUMN)
.build();
private static void validate(ValidationContextOnField context) throws InvalidFunctionException
{
final SchemaTypeName dataType = context.getCurrentField().getXsTypeName();
if (SchemaTypeName.XS_DECIMAL.equals(dataType) || SchemaTypeName.XS_INT.equals(dataType)
|| SchemaTypeName.XS_INTEGER.equals(dataType))
{
return;
}
throw new InvalidFunctionException(
UserMessage.createError("This function only applies for numeric fields."));
}
private static FunctionResult execute(ExecutionContextOnField context) throws DPRAException
{
final SchemaNode field = context.getCurrentField();
final AdaptationTable table = context.getCurrentTable();
final String fieldName = getFieldNameForSql(field);
final String tableName = getTableNameForSql(table);
final String sql = "SELECT " + fieldName + " FROM " + tableName + " ORDER BY " + fieldName
+ " LIMIT 1";
final Query<Number> query = context.getCurrentDataset()
.createQueryBuilder()
.build(sql, Number.class);
try (QueryResult<Number> result = query.getResult())
{
final Iterator<Number> iterator = result.iterator();
// table has no records or all field values are null
if (!iterator.hasNext())
{
return FunctionResult.newInstance();
}
final Number value = iterator.next();
if (value == null)
{
return FunctionResult.newInstance();
}
final ValueSequence sequence = context.newValueSequence()
.set(OUTPUT_LOWEST_VALUE, BigDecimal.valueOf(value.doubleValue()));
return FunctionResult.of(sequence);
}
}
private static String getFieldNameForSql(SchemaNode field)
{
return "\"" + field.getPathInAdaptation().getLastStep().format() + "\"";
}
private static String getTableNameForSql(AdaptationTable table)
{
return "\"" + table.getTablePath().format() + "\"";
}
private CustomLowestValueFunction()
{
}
}
Register function:
FunctionDefinitionRegistry.register(CustomLowestValueFunction.DEFINITION, CustomLowestValueFunction.CHART_CONFIG);
Define function:
public final class CustomRecordCountFunction
{
private static final String OUTPUT_COUNT = "recordCount";
private static final OutputDefinition COUNT_OUTPUT_DEF = OutputDefinition
.forInteger(OUTPUT_COUNT, UserMessage.createInfo("Record count"), null);
public static final FunctionDefinition DEFINITION = FunctionDefinition.onTable("CustomRecordCountFunction")
.withLabel("Record count")
.withDescription("This function counts the number of records in a table.")
.withOutputs(COUNT_OUTPUT_DEF)
.withLinkedRecord()
.onExecution(CustomRecordCountFunction::execute)
.build();
public static final ChartConfigForFunction CHART_CONFIG = ChartConfigForFunction
.newBuilder(AxisConfig.outputLabelAsCategory(OUTPUT_COUNT))
.setDefaultChartType(ChartType.CARD)
.addOtherChartTypes(ChartType.COLUMN)
.build();
private static FunctionResult execute(ExecutionContextOnTable context) throws DPRAException
{
final AdaptationTable table = context.getCurrentTable();
final String xpathPredicate = context.getXpathFilterPredicate();
final boolean hasFilter = xpathPredicate != null && xpathPredicate.trim().length() > 0;
try (RequestResult requestResult = hasFilter
? table.createRequestResult(xpathPredicate)
: table.createRequest().execute())
{
final int tableCount = requestResult.getSize();
final ValueSequence sequence = context.newValueSequence()
.set(OUTPUT_COUNT, Integer.valueOf(tableCount));
if (context.isLinkedRecordEnabled())
{
if (hasFilter)
{
sequence.linkWithRecords(xpathPredicate);
}
else
{
sequence.linkWithRecords(buildLinkedRecordXPathFilter(requestResult));
}
}
return FunctionResult.of(sequence);
}
}
private static XPathFilter buildLinkedRecordXPathFilter(RequestResult requestResult)
{
final StringBuilder builder = new StringBuilder();
for (Adaptation record; (record = requestResult.nextAdaptation()) != null;)
{
if (builder.length() > 0)
{
builder.append(" or ");
}
builder.append(record.toXPathPredicateString());
}
return XPathFilter.newFilter(builder.toString());
}
private CustomRecordCountFunction()
{
}
}
Register function:
FunctionDefinitionRegistry.register(CustomRecordCountFunction.DEFINITION, CustomRecordCountFunction.CHART_CONFIG);