See: Description
Interface | Description |
---|---|
DataElementConcept |
Represents a Data Element Concept.
|
IndicatorDefinition |
Defines an indicator.
Guides and inputs the indicator declaration in the user interface. |
IndicatorDefinitionContext |
Represents the configuration of an
IndicatorDefinition . |
IndicatorExecutionEnvironment |
Execution environment of the indicator.
|
IndicatorsExecutionResult |
Global execution result of all indicators.
|
IndicatorStorage |
Defines the storage of results.
|
LinkedRecordInformation |
Retrieves the rule that defines what kinds of records affecting an indicator result.
|
Class | Description |
---|---|
BigDataDefinition |
Defines fields in the
Big data report table - Insight - Reporting data set. |
BigDataValue | Deprecated |
BigDecimalValue |
Represents a decimal outcome of
IndicatorReport . |
BooleanValue |
Represents a boolean outcome of
IndicatorReport . |
DateValue |
Represents a date outcome of
IndicatorReport . |
DECIndicator |
This abstract class must be extended to define the behavior of an indicator running on a
Data Element Concept . |
DECIndicatorExecutionContext |
Execution context for a Data Element Concept.
|
DECIndicatorExecutionContextOnDemand |
The on-demand context for a data element concept.
|
DECIndicatorExecutionContextOnProbe |
The on-probe context for a data element concept.
|
DECIndicatorExecutionEnvironment |
The execution environment for a Data Element Concept.
|
DefaultDECIndicator |
Provides default implementations for optional properties of an
IndicatorDefinition , and allows users to define the behavior of a DECIndicator . |
DefaultWorkflowIndicator |
Provides default implementations for optional properties of an
IndicatorDefinition , and offers the ability to define the behavior of a WorkflowIndicator . |
FlatDataAccessor |
Retrieves specific data in the
Flat data table or the Big data table from IndicatorExecutionContext . |
FlatDataDefinition |
Contains definitions of the fields in the
Flat data report table - Insight - Reporting data set. |
FlatDataValue |
Defines a value set in either the
Big data table or the Flat data table. |
GraphicalOptions |
Provides additional information for a
ParameterDefinition , which is used for chart generation. |
Indicator |
This abstract class must be extended to define the behavior of an indicator.
|
IndicatorConfiguration |
Offers accessors to the configuration.
|
IndicatorDefinitionCatalog |
Provides a catalog to register indicators.
|
IndicatorExecutionContext |
The execution context of the indicator.
|
IndicatorReport |
The Java Bean container an
Indicator 's outcomes. |
IndicatorReportAccessor |
Retrieves specific data in the
Indicator report table and the Indicator value table from IndicatorExecutionContext . |
IndicatorReportDefinition |
The definitions of the fields in the
Indicator report table - Insight - Reporting data set. |
IndicatorStorageFactory |
The factory class of
IndicatorStorage . |
IndicatorValue |
Defines an atomic outcome of
IndicatorReport . |
IndicatorValueDefinition |
The definitions of the fields in the
Indicator value table - Insight - Reporting data set. |
IntegerValue |
Represents an integer outcome of
IndicatorReport . |
IntervalValue |
Represents an interval outcome of indicator execution.
|
LinkedRecord |
The relevant records that affect an indicator result.
|
LinkedRecordDefinition |
Declares the rule that defines what kind of records affecting an indicator result.
|
ListConstraint |
Definition of a constraint for a multiple occurred parameter or enumeration.
|
ParameterConstraint |
The definition of a constraint for the value of a parameter.
|
ParameterDefinition |
The definition of an
Indicator input or output parameter. |
PercentageValue |
Represents a percentage outcome of indicator execution.
|
PredefinedValue |
To define a value with a string label or a localized label.
|
ReportingDefinition |
Declares associations between output parameters and reporting fields in the
Flat data report table or the Big data report table of Insight - Reporting data sets. |
ReportingUtilities |
Offers accessors to the reporting.
|
StringValue |
Represents a string outcome of
IndicatorReport . |
Watchdog |
Represents the configured Watchdog for the
Indicator . |
WatchdogInformation |
The definition of a watchdog for an
Indicator . |
WorkflowIndicator |
This abstract class must be extended to define the behavior of an indicator run on a workflow.
|
WorkflowIndicatorExecutionContext |
The on-demand context for a workflow.
|
WorkflowIndicatorExecutionEnvironment |
The execution environment for a workflow.
|
Provides classes and interfaces to define, publish and execute indicators.
To add a custom indicator, its definition must first be created. Since {addon.label} v1.5.2, you can declare an indicator definition and its execution in the same class by extending the DefaultDECIndicator or DefaultWorkflowIndicator class. For example:
public final class TestDefaultDECIndicator extends DefaultDECIndicator { private static final String NUMBER_OF_RECORDS_PARAM ="numberOfRecords"
; private static final String LAST_MODIFICATION_TIME_PARAM ="lastModificationTime"
; public String getCode() { return"TestDefaultDECIndicator"
;// the code must be unique
} public DECType getDECType() { return DECType.TABLE; } public Set<FrequencyType> getPossibleComputationFrequencies() { Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>(); frequencyTypes.add(FrequencyType.ON_DEMAND); return frequencyTypes; } public List<ParameterDefinition> getOutputParametersDefinition() { List<ParameterDefinition> outputs = new ArrayList<ParameterDefinition>(); UserMessageString nbOfRecordsMsg = UserMessage.createInfo("Number of records"
); outputs.add(new ParameterDefinition(NUMBER_OF_RECORDS_PARAM, SchemaTypeName.XS_INT, nbOfRecordsMsg, nbOfRecordsMsg)); UserMessageString lastModificationTimeMsg = UserMessage.createInfo("Last modification time"
); outputs.add(new ParameterDefinition(LAST_MODIFICATION_TIME_PARAM, SchemaTypeName.XS_DATETIME, lastModificationTimeMsg, lastModificationTimeMsg)); return outputs; } public BigDataDefinition getBigDataDefinition() { BigDataDefinition bigDataDefinition = new BigDataDefinition(); bigDataDefinition.addPathAssociation(BigDataDefinition.NbRecordsTable, NUMBER_OF_RECORDS_PARAM); bigDataDefinition.addPathAssociation(BigDataDefinition.LastUpdateDate, LAST_MODIFICATION_TIME_PARAM); return bigDataDefinition; }// since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
public FlatDataDefinition getFlatDataDefinition() { FlatDataDefinition flatDataDefinition = new FlatDataDefinition(); flatDataDefinition.addPathAssociation(FlatDataDefinition.Integer1, NUMBER_OF_RECORDS_PARAM); flatDataDefinition.addPathAssociation(FlatDataDefinition.Datetime1, LAST_MODIFICATION_TIME_PARAM); return flatDataDefinition; } public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException { IndicatorReport report = new IndicatorReport();// sequence: 1, order: 1
Integer number = Integer.valueOf(100); IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1); // built-in IndicatorValue// deprecated since v2.0.0
// numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number); report.addValue(numberOfRecordsValue);// sequence: 1, order: 2
Date date = new Date(); IndicatorValue modificationTimeValue = new IndicatorTestValue(date, 1, 2); // custom IndicatorValue// deprecated since v2.0.0
// modificationTimeValue.setBigDataReportField(BigDataDefinition.LastUpdateDate, date);
modificationTimeValue.setFlatDataFieldValue(FlatDataDefinition.Datetime1, date); report.addValue(modificationTimeValue); return report; } }
Next, you can create a custom indicator value to store execution results if necessary. For example:
public final class IndicatorTestValue extends IndicatorValue
{
private final Date date;
public IndicatorTestValue(Date date, int sequence, int order)
{
super(sequence, order);
this.date = date;
}
public String formatDataType()
{
return Date.class.getSimpleName();
}
public String formatValue()
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"
);
return df.format(this.date);
}
public Object getValue()
{
return this.date;
}
}
Finally, the indicator must be registered with the add-on in order to be available in the configuration:
IndicatorDefinitionCatalog.add(new TestDefaultDECIndicator());
By extending the default indicator classes, you can also apply multiple implementations on the same definition. For example, declare an abstract indicator definition as the following:
public abstract class AbstractNumberOfRecordsIndicator extends DefaultDECIndicator { protected static final String NUMBER_OF_RECORDS_OUTPUT_PARAM ="numberOfRecords"
; public DECType getDECType() { return DECType.TABLE; } public Set<FrequencyType> getPossibleComputationFrequencies() { Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>(); frequencyTypes.add(FrequencyType.ON_DEMAND); return frequencyTypes; } public List<ParameterDefinition> getOutputParametersDefinition() { List<ParameterDefinition> outputs = new ArrayList<ParameterDefinition>(); UserMessageString nbOfRecordsMsg = UserMessage.createInfo("Number of records"
); outputs.add(new ParameterDefinition(NUMBER_OF_RECORDS_OUTPUT_PARAM, SchemaTypeName.XS_INT, nbOfRecordsMsg, nbOfRecordsMsg)); return outputs; } public BigDataDefinition getBigDataDefinition() { BigDataDefinition bigDataDefinition = new BigDataDefinition(); bigDataDefinition.addPathAssociation(BigDataDefinition.NbRecordsTable, NUMBER_OF_RECORDS_OUTPUT_PARAM); return bigDataDefinition; }// since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
public FlatDataDefinition getFlatDataDefinition() { FlatDataDefinition flatDataDefinition = new FlatDataDefinition(); flatDataDefinition.addPathAssociation(FlatDataDefinition.Integer1, NUMBER_OF_RECORDS_OUTPUT_PARAM); return flatDataDefinition; } }
Then extend the above class to handle the business in different scenarios:
public final class NumberOfRecordsWithErrorsIndicator extends AbstractNumberOfRecordsIndicator { public String getCode() { return"NumberOfRecordsWithErrors"
; } public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException { IndicatorReport report = new IndicatorReport(); Integer number = Integer.valueOf(50); IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1);// deprecated since v2.0.0
// numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number); report.addValue(numberOfRecordsValue); return report; } } public final class NumberOfRecordsWithWarningsIndicator extends AbstractNumberOfRecordsIndicator { public String getCode() { return"NumberOfRecordsWithWarnings"
; } public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException { IndicatorReport report = new IndicatorReport(); Integer number = Integer.valueOf(80); IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1);// deprecated since v2.0.0
// numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number); report.addValue(numberOfRecordsValue); return report; } }
The following example covers in-depth all properties of an IndicatorDefinition instance:
public final class IndicatorDurationDefinition implements IndicatorDefinition { private static final String TIME_PARAM ="TimeOutput"
; private static final String DURATION_PARAM ="DurationOutput"
; public IndicatorDurationDefinition() { } public String getCode() { return"Indicator-Duration"
; } public UserMessage getLabel() { return UserMessage.createInfo("Time duration in interval format"
); } public UserMessage getDashboardLabel() { return UserMessage.createInfo("Time duration"
); } public UserMessage getDescription() { return UserMessage.createInfo("This indicator checks if the value of a Datetime field is within a specified time range " + "and displays the time range from that time to the execution time in interval format."); } public Indicator getImplementation() { return new IndicatorDurationImpl();// this implementation class is defined below
} public DECType getDECType() { return DECType.FIELD; } public DECSubType getDECSubType() {// return null if the indicator doesn't have any D.E.C. sub-types
return FieldDECSubType.DATE;// this indicator can only be configured and executed on fields with the Date type
} public List<ParameterDefinition> getInputParametersDefinition() {// return null if the indicator doesn't have any input parameters
List<ParameterDefinition> inputs = new ArrayList<ParameterDefinition>();// numeric input
UserMessage maxNbOfOutcomesLabel = UserMessage.createInfo("Maximum number of outcomes"); UserMessage maxNbOfOutcomesDescription = UserMessage.createInfo("The maximum of outcomes (also the Big data records) for an execution."); ParameterDefinition maxNumberOfOutputs = new ParameterDefinition( "maxNumberOfOutcomesInput", SchemaTypeName.XS_INTEGER, maxNbOfOutcomesLabel, maxNbOfOutcomesDescription, String.valueOf(1));// optional constraint for an input parameter
ParameterConstraint parameterConstraint = new ParameterConstraint(); parameterConstraint.setUnboundedSupported(true); maxNumberOfOutputs.setParameterConstraint(parameterConstraint); inputs.add(maxNumberOfOutputs);// datetime inputs
UserMessage fromTimeLabel = UserMessage.createInfo("From"); UserMessage fromTimeDescription = UserMessage.createInfo("The start time of the time range. Only considered if the configured periodicity is 'None'."); ParameterDefinition fromDate = new ParameterDefinition( "fromTimeInput", SchemaTypeName.XS_DATETIME, fromTimeLabel, fromTimeDescription); inputs.add(fromDate); UserMessage toDateLabel = UserMessage.createInfo("To"); UserMessage toDateDescription = UserMessage.createInfo("The end time of the time range. Only considered if the configured periodicity is 'None'."); ParameterDefinition toDate = new ParameterDefinition( "toTimeInput", SchemaTypeName.XS_DATETIME, toDateLabel, toDateDescription); inputs.add(toDate);// enumeration input with interval formats
UserMessage intervalFormatLabel = UserMessage.createInfo("Interval format"); UserMessage intervalFormatDescription = UserMessage.createInfo("The interval format for the 'Duration' output."); Set<PredefinedValue> formats = new HashSet<PredefinedValue>(); formats.add(new PredefinedValue(IntervalType.DAY_HOUR.getCode(), IntervalType.DAY_HOUR.getLabel())); formats.add(new PredefinedValue(IntervalType.DAY_HOUR_MINUTE.getCode(), IntervalType.DAY_HOUR_MINUTE.getLabel())); PredefinedValue defaultFormat = new PredefinedValue(IntervalType.DAY_HOUR.getCode()); // default selected option of the list ListConstraint listConstraint = new ListConstraint(formats, Collections.singleton(defaultFormat)); ParameterDefinition intervalFormat = new ParameterDefinition( "intervalFormatInput", SchemaTypeName.XS_STRING, intervalFormatLabel, intervalFormatDescription, listConstraint, HTMLComponent.DROPDOWNBOX_COMPONENT);// HTML type for the input
inputs.add(intervalFormat); return Collections.unmodifiableList(inputs); } public List<ParameterDefinition> getOutputParametersDefinition() { List<ParameterDefinition> parameterDefinitions = new ArrayList<ParameterDefinition>(); UserMessage timeLabel = UserMessage.createInfo("Time in range"); UserMessage timeDescription = UserMessage.createInfo("Displays the datetime value within the time range."); ParameterDefinition timeOutput = new ParameterDefinition( IndicatorDurationDefinition.TIME_PARAM, SchemaTypeName.XS_DATETIME, timeLabel, timeDescription); parameterDefinitions.add(timeOutput); UserMessage durationLabel = UserMessage.createInfo("Time duration in interval"); UserMessage durationDescription = UserMessage.createInfo("Displays the time range from a certain time to the execution time in interval format."); ParameterDefinition durationOutput = new ParameterDefinition( IndicatorDurationDefinition.DURATION_PARAM, SchemaTypeNameExtension.INTERVAL, durationLabel, durationDescription); parameterDefinitions.add(durationOutput); return parameterDefinitions; } public BigDataDefinition getBigDataDefinition() { BigDataDefinition bigDataDefinition = new BigDataDefinition(); bigDataDefinition.addPathAssociation(BigDataDefinition.OverseeDateValue, IndicatorDurationDefinition.TIME_PARAM); bigDataDefinition.addPathAssociation(BigDataDefinition.LifeTimeOfDataspace, IndicatorDurationDefinition.DURATION_PARAM); return bigDataDefinition; }// since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
public FlatDataDefinition getFlatDataDefinition() { FlatDataDefinition flatDataDefinition = new FlatDataDefinition(); flatDataDefinition.addPathAssociation(FlatDataDefinition.Datetime1, IndicatorDurationDefinition.TIME_PARAM); flatDataDefinition.addPathAssociation(FlatDataDefinition.Interval1, IndicatorDurationDefinition.DURATION_PARAM); return flatDataDefinition; } public Set<FrequencyType> getPossibleComputationFrequencies() {// supports both the on-demand and the real-time computations
Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>(); frequencyTypes.add(FrequencyType.ON_DEMAND); frequencyTypes.add(FrequencyType.REAL_TIME); return frequencyTypes; } public Set<ProbeType> getPossibleProbes() {// returns null if the indicator runs on-demand
return Collections.singleton(ProbeType.TRIGGER); // supports probes for a real-time indicator } public WatchdogInformation getWatchdogInformation() {// return null if the indicator doesn't have any periodicities or thresholds
WatchdogInformation information = new WatchdogInformation(); Set<PeriodicityType> possiblePeriodicities = new HashSet<PeriodicityType>(); possiblePeriodicities.add(PeriodicityType.DAILY); possiblePeriodicities.add(PeriodicityType.TOLERANCE); // TOLERANCE or 'None' means using the configured time range information.setPossiblePeriodicityOfControl(Collections.unmodifiableSet(possiblePeriodicities)); return information; } public UserMessage getStorageProcedureInformation() { return UserMessage.createInfo("Any results are stored."
); }// deprecated since v2.0.0
public boolean hasManyOutcomesStoredInBigDataTable() { return true;// has multiple outcomes because there may be many datetime values within a time ranges
} public boolean hasManyOutcomesStoredInReportingTable() { return true;// has multiple outcomes because there may be many datetime values within a time ranges
} public LinkedRecordDefinition getLinkedRecordDefinition() {// return null if the indicator doesn't store any records
LinkedRecordDefinition linkedRecordDefinition = new LinkedRecordDefinition(UserMessage.createInfo("Records with time duration greater than one day will be stored"
)); UserMessage label = UserMessage.createInfo("Duration greater than one day."
); UserMessage description = UserMessage.createInfo("Records with time duration greater than one day will be stored."
); linkedRecordDefinition.addOption(new ParameterDefinition("DurationLinkedRecordOption"
, SchemaTypeName.XS_BOOLEAN, label, description, Boolean.TRUE.toString())); return linkedRecordDefinition; } }
Next, the definition of the indicator value to be stored must be created. For example:
public final class IndicatorTestValue extends IndicatorValue
{
private final Date date;
public IndicatorTestValue(Date date, int sequence, int order)
{
super(sequence, order);
this.date = date;
}
public String formatDataType()
{
return Date.class.getSimpleName();
}
public String formatValue()
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"
);
return df.format(this.date);
}
public Object getValue()
{
return this.date;
}
}
To execute the indicator, the definition of the implementation must first be created. The following example illustrates how to get and handle indicator configuration properties:
public class IndicatorDurationImpl extends DECIndicator { private static final int TIME_OF_A_DAY = 1000 * 60 * 60 * 24; public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException { IndicatorDefinitionContext definitionContext = this.getIndicatorDefinitionContext();// input parameter values
String maxNbOfOutcomeValue = definitionContext.getBespokeParameterValue("maxNumberOfOutcomesInput"
); String fromTimeValue = definitionContext.getBespokeParameterValue("fromTimeInput"
); String toTimeValue = definitionContext.getBespokeParameterValue("toTimeInput"
); String intervalFormatValue = definitionContext.getBespokeParameterValue("intervalFormatInput"
); String linkedRecordOption = definitionContext.getLinkedRecordInformation().getOption("DurationLinkedRecordOption"
); int maxNbOfOutcomes; try { maxNbOfOutcomes = Integer.parseInt(maxNbOfOutcomeValue); } catch (NumberFormatException ex) { throw new DQIdException(UserMessage.createError("Invalid maximum number of outcomes."
)); }// periodicity
Watchdog watchdog = definitionContext.getWatchdog(); PeriodicityType periodicityType = watchdog == null ? null : watchdog.getPeriodicityOfControl(); Date fromTime = null; Date toTime = null;// if the periodicity is 'None'
if (periodicityType.isTolerance()) { if (fromTimeValue == null || toTimeValue == null) { throw new DQIdException(UserMessage.createError("Invalid time."
)); } fromTime = FormatDataPolicy.parseDate(SchemaTypeName.XS_DATETIME, fromTimeValue); toTime = FormatDataPolicy.parseDate(SchemaTypeName.XS_DATETIME, toTimeValue); } else {// other cases to check if a date value is within the periodicity
} if (fromTime == null || toTime == null) { throw new DQIdException(UserMessage.createError("Invalid time."
)); } if (toTime.before(fromTime)) { throw new DQIdException(UserMessage.createError("From time cannot be before to time.")); } AdaptationTable table = executionContext.getExecutionEnvironment().getTable(); Path fieldPath = definitionContext.getField(); Date executionTime = new Date(); IntervalType intervalType = IntervalType.DAY_HOUR_MINUTE.getCode().equals(intervalFormatValue) ? IntervalType.DAY_HOUR_MINUTE : IntervalType.DAY_HOUR; boolean saveLastValueOnlyInReporting = definitionContext.saveLastValueOnlyInFlatDataTable(); boolean storeAll = !Boolean.getBoolean(linkedRecordOption); IndicatorReport indicatorReport; if (executionContext.isOnDemand())// on-demand execution
{ indicatorReport = this.executeOnDemand( executionContext, table, fieldPath, fromTime, toTime, executionTime, intervalType, maxNbOfOutcomes, saveLastValueOnlyInReporting, storeAll); } else// real-time execution
{ String currentRecordXPath = executionContext.getCurrentRecordXPathPredicate(); indicatorReport = this.executeRealtime( executionContext, table, fieldPath, currentRecordXPath, fromTime, toTime, executionTime, intervalType, maxNbOfOutcomes, saveLastValueOnlyInReporting, storeAll); } if (indicatorReport == null) { return null; }// indicates that the watchdog is used as an alert to save the indicator report
indicatorReport.setAlertRaisedByWatchdog(true); return indicatorReport; } private IndicatorReport executeOnDemand( DECIndicatorExecutionContext executionContext, AdaptationTable table, Path fieldPath, Date fromTime, Date toTime, Date executionTime, IntervalType intervalType, int maxNbOfOutcomes, boolean saveLastValueOnlyInReporting, boolean storeAll) throws DQIdException { IndicatorReport indicatorReport = new IndicatorReport(); int sequence = 1;// sequence always starts with 1
RequestResult requestResult = table.createRequest().execute(); try { Adaptation record = null; while ((record = requestResult.nextAdaptation()) != null) { Date datetime = record.getDate(fieldPath); if (datetime.before(fromTime) || datetime.after(toTime) || datetime.after(executionTime)) { continue; } if (sequence > maxNbOfOutcomes) { break; } this.addIndicatorValues( executionContext, indicatorReport, datetime, executionTime, intervalType, sequence, saveLastValueOnlyInReporting, record.toXPathPredicateString(), storeAll); sequence++; } } finally { requestResult.close(); } return indicatorReport; } private IndicatorReport executeRealtime( DECIndicatorExecutionContext executionContext, AdaptationTable table, Path fieldPath, String currentRecordXPath, Date fromTime, Date toTime, Date executionTime, IntervalType intervalType, int maxNbOfOutcomes, boolean saveLastValueOnlyInReporting, boolean storeAll) throws DQIdException { if (maxNbOfOutcomes <= 0 || AddonStringUtils.isEmpty(currentRecordXPath)) { return null; } RequestResult requestResult = table.createRequestResult(currentRecordXPath); try { Adaptation record = requestResult.nextAdaptation(); if (record == null) { return null; } Date datetime = record.getDate(fieldPath); if (datetime.before(fromTime) || datetime.after(toTime) || datetime.after(executionTime)) { return null; } IndicatorReport indicatorReport = new IndicatorReport(); this.addIndicatorValues( executionContext, indicatorReport, datetime, executionTime, intervalType, 1, saveLastValueOnlyInReporting, record.toXPathPredicateString(), storeAll); return indicatorReport; } finally { requestResult.close(); } } private void addIndicatorValues( DECIndicatorExecutionContext executionContext, IndicatorReport indicatorReport, Date datetime, Date executionTime, IntervalType intervalType, int sequence, boolean saveLastValueOnlyInReporting, String recordPredicate, boolean storeAll) throws DQIdException {// indicator values
IndicatorValue datetimeValue = new IndicatorTestValue(datetime, sequence, 1);// IndicatorTestValue was defined before
// deprecated since v2.0.0
// datetimeValue.setBigDataReportField(BigDataDefinition.OverseeDateValue, datetimeValue);
datetimeValue.setFlatDataFieldValue(FlatDataDefinition.Datetime1, datetimeValue); indicatorReport.addValue(datetimeValue); long duration = executionTime.getTime() - datetime.getTime();// IntervalValue is an available implementation class of IndicatorValue
IndicatorValue intervalValue = new IntervalValue(BigDecimal.valueOf(duration), sequence, 2, intervalType);// deprecated since v2.0.0
// datetimeValue.setBigDataReportField(BigDataDefinition.LifeTimeOfDataspace, BigDecimal.valueOf(duration));
datetimeValue.setFlatDataFieldValue(FlatDataDefinition.Interval1, BigDecimal.valueOf(duration)); indicatorReport.addValue(intervalValue);// handle saving last value in the Flat data table
if (saveLastValueOnlyInReporting) {// deprecated since v2.0.0
// indicatorReport.setPrimaryKeyOfPreviousBigDataReportBySequence(sequence, this.getPrimaryKeyOrNullOfExistingIndicatorReportInBigDataTable(executionContext, sequence));
indicatorReport.setPrimaryKeyOfPreviousReportingRecordBySequence(sequence, this.getFlatDataAccessor().getPrimaryKeyOrNullOfLatestRecord(executionContext, sequence)); }// linked record - check if duration is greater than a day
if (!storeAll && duration <= TIME_OF_A_DAY) { return; } LinkedRecord linkedRecord = new LinkedRecord(); linkedRecord.addRelevantRecordPredicate(recordPredicate); indicatorReport.addLinkedRecord(sequence, linkedRecord); } }
Finally, the indicator must be registered with the add-on in order to be available in the configuration:
IndicatorDefinitionCatalog.add(new IndicatorDurationDefinition());