Contents > 9 Extending the Metrics and Rule Engine > 9.1 Metric Procedures > 9.1.2 Implementation of the Metric Procedure

9.1.2 Implementation of the Metric Procedure

The following listing shows the complete implementation of the new metric procedure outlined in the previous section. Because we heavily utilize the API of the metrics engine, which already provides much of the functionality, the implementation of the procedure is quite compact, and essentially contains a nested loop to generate the element pairs.
   packacke com.acme;
   import java.util.Collection;
   import java.util.Comparator;
   import com.sdmetrics.math.ExpressionNode;
   import com.sdmetrics.metrics.*;
   import com.sdmetrics.model.ModelElement;
 
01 public class MetricProcedurePairwise extends MetricProcedure {

   @Override
02 public Object calculate(ModelElement element, Metric metric)
         throws SDMetricsException {
03    ProcedureAttributes attributes = metric.getAttributes();

04    Variables vars = new Variables(element);
05    Collection<ModelElement> set = 
         getRelationOrSet(element, attributes, vars);
06    if (set == null)
07       return Integer.valueOf(0);

08    ExpressionNode pairCondition = attributes.getExpression("paircondition");
09    boolean allTuples = attributes.getBooleanValue("tuples", false);
10    boolean withSelf = attributes.getBooleanValue("withself", allTuples);

11    FilterAttributeProcessor fap = getFilterAttributeProcessor(attributes);
12    SummationHelper sum = new SummationHelper(getMetricsEngine(), attributes);
13    Comparator<ModelElement> comparator = ModelElement.getComparator();

14    for (ModelElement first : fap.validIteration(set, vars)) {
15       vars.setVariable("_first", first);
16       for (ModelElement second : fap.validIteration(set, vars)) {
17          int comp = comparator.compare(first, second);
18          if (comp == 0 && !withSelf)
19             continue;
20          if (comp > 0 && !allTuples)
21             continue;

22          vars.setVariable("_second", second);
23          if (pairCondition == null
                || evalBooleanExpression(element, pairCondition, vars)) {
24             sum.add(second, vars);
            }
         }
      }
25    return sum.getTotal();
   }
}

Let's go through the salient points of this implementation line by line: