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