Contents > 9 Extending the Metrics and Rule Engine > 9.5 Scalar Functions

9.5 Scalar Functions

A scalar function is used in metric expressions (see Section 8.5 "Expression Terms") and yields a numerical value, a string value, or a model element. In the following example, we will implement a function that yields the maximum value from a list of numerical values, e.g., in a metric expression like this:
  max(NumClasses, NumInterfaces, NumUseCases) 
The following implementation of the MAX function calculates the value of each argument provided to the function, and returns the maximum value:
   packacke com.acme;
   import com.sdmetrics.math.ExpressionNode;
   import com.sdmetrics.metrics.MetricTools;
   import com.sdmetrics.metrics.SDMetricsException;
   import com.sdmetrics.metrics.ScalarOperation;
   import com.sdmetrics.metrics.Variables;
   import com.sdmetrics.model.ModelElement;

01 public class ScalarOperationMax extends ScalarOperation {

02 public Number calculateValue(ModelElement element, ExpressionNode node,
			Variables vars) throws SDMetricsException {
03    float result = Float.NEGATIVE_INFINITY;
04    for (int index = 0; index < node.getOperandCount(); index++) {
05      float value = ((Number) evalExpression(element,
          node.getOperand(index), vars)).floatValue();
06      result = Math.max(result, value);
07    return MetricTools.getNumber(result);
Again, we discuss the implementation line by line: To use the scalar function, we register it with the metrics engine as follows:
<scalaroperationdefinition name="max" 
   class="com.acme.ScalarOperationMax" />
As with Boolean functions, we deploy the class file of the class in the "bin" folder of our SDMetrics installation (path com/acme/ScalarOperationMax.class). After that, we can write metric expressions using the new function. For example:
<metric name="DominantElementTypeSize" domain="package">
<description>Size of the package in terms of the number elements
  of the most dominant type in the package.</description>
  term="max(NumClasses, NumInterfaces, NumDataTypes, NumUseCases)" />