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);
-
Interface Summary Interface Description FunctionDefinition A function declaration.FunctionDefinitionBuilder Builder ofFunctionDefinitioninstances. -
Class Summary Class Description BaseFunctionDefinitionBuilder<T extends BaseFunctionDefinitionBuilder<T>> Base builder ofFunctionDefinitioninstances.FunctionDefinitionOnDatasetBuilder Builder ofFunctionDefinitioninstances at the dataset level.FunctionDefinitionOnDataspaceBuilder Builder ofFunctionDefinitioninstances at the dataspace level.FunctionDefinitionOnFieldBuilder Builder ofFunctionDefinitioninstances at the field level.FunctionDefinitionOnTableBuilder Builder ofFunctionDefinitioninstances at the table level.FunctionDefinitionOnTableLevelBuilder<T extends BaseFunctionDefinitionBuilder<T>> Builder ofFunctionDefinitioninstances at both the table and the field levels.FunctionDefinitionOnWorkflowBuilder Builder ofFunctionDefinitioninstances at the workflow level.FunctionDefinitionRegistry Registers instances ofFunctionDefinition.InputDefinition Specifies the input definition of a function.OutputDefinition Specifies the output definition of a function.