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