Package com.orchestranetworks.addon.dpra.function
package com.orchestranetworks.addon.dpra.function
Provides classes and interfaces to create custom functions.
Sample code to create a custom function that queries data using SQL:
-
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);
Sample code to create a custom function with linked records:
-
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);
-
ClassDescriptionBaseFunctionDefinitionBuilder<T extends BaseFunctionDefinitionBuilder<T>>Base builder of
FunctionDefinition
instances.A function declaration.Builder ofFunctionDefinition
instances.Builder ofFunctionDefinition
instances at the dataset level.Builder ofFunctionDefinition
instances at the dataspace level.Builder ofFunctionDefinition
instances at the field level.Builder ofFunctionDefinition
instances at the table level.Builder ofFunctionDefinition
instances at both the table and the field levels.Builder ofFunctionDefinition
instances at the workflow level.Registers instances ofFunctionDefinition
.Specifies the input definition of a function.Specifies the output definition of a function.