Skip to content

How to add a new Code Metric

Felipe Gustavo de Souza Gomes edited this page Oct 20, 2017 · 1 revision

First of all, we recommend that the new metrics should be added in the rm-core project at package org.repositoryminer.metric. In this example we will implment the metric WMC (Weighted Methods per Class).

The first thing to do is to register your metric identifier in the enum org.repositoryminer.metric.MetricID. Below follows an example.

public enum MetricID { NOM, CYCLO, WMC; }

After created an identifier for our metric we need to implement it. We recommend that you put your implementation class at package org.repositoryminer.metric alongside IMetric interface. Below you can see our implementation of WMC.

public class AMW implements IMetric {
  private static final MetricID[] REQUIRED_METRICS = {MetricID.WMC, MetricID.NOM};

  @Override
  public void calculate(AST ast) {
    for (AbstractType type : ast.getTypes()) {
	    int wmc = (Integer) type.getMetrics().get(MetricID.WMC);
	    int nom = (Integer) type.getMetrics().get(MetricID.NOM);
	    type.getMetrics().put(MetricID.AMW, calculate(wmc, nom));
    }
  }

  public float calculate(int wmc, int nom) {
    if (nom == 0)
	    return 0l;
    return new BigDecimal(wmc * 1f / nom).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
  }

  @Override
  public MetricID getId() {
    return MetricID.AMW;
  }

  @Override
  public MetricID[] getRequiredMetrics() {
    return REQUIRED_METRICS;
  }
}

First we need to implement the IMetric interface, this interface defines how you must implement your metric. In the method getId() you must return the metric identifier registered in MetricID before.

In the method getRequiredMetrics() you must return an array with all the metrics identifier that your metric depends on. If the metric does not need others to be calculated then this method should returns null or an empty array.

In the method calculate(AST ast) is where you should implement the metric. The metric result should be put inside the AST in the correspondent element and you can access the values of others metrics too from the AST. The elements that we allow you to save metrics values has a map called metrics, they are: Files, Classes and Methods. Inside this map use the metric identifier as key and as value you can use any Object.

Other important point is, to ensure that the metrics values you need will be in the AST, you must return theses metrics identifers in getRequiredMetrics(). To know more about the supported metrics check the page Available Metrics.

For last, after implmented the metric we need to add it to the metric factory. Access the class org.repositoryminer.metric.MetricFactory, then add the new metric to the switch-case in the method getMetric(MetricID id). Check the example below.

public class MetricFactory {
  public static IMetric getMetric(MetricID id) {
    switch (id) {
    case WMC: return new WMC(); // our metric
    case CYCLO: return new CYCLO();
    case NOM: return new NOM();
    /*** Others metrics goes here ***/
    }
  }
}