Skip to content

Commit

Permalink
SONAR-6682 Merge DocumentationMeasuresStep into CommentMeasuresStep
Browse files Browse the repository at this point in the history
  • Loading branch information
julienlancelot committed Jul 16, 2015
1 parent a1ea8a8 commit 182186a
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 328 deletions.
Expand Up @@ -22,59 +22,78 @@


import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.TreeRootHolder; import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.formula.BiSumCounter; import org.sonar.server.computation.formula.Counter;
import org.sonar.server.computation.formula.CreateMeasureContext; import org.sonar.server.computation.formula.CreateMeasureContext;
import org.sonar.server.computation.formula.FileAggregateContext;
import org.sonar.server.computation.formula.Formula; import org.sonar.server.computation.formula.Formula;
import org.sonar.server.computation.formula.FormulaExecutorComponentVisitor; import org.sonar.server.computation.formula.FormulaExecutorComponentVisitor;
import org.sonar.server.computation.formula.SumCounter;
import org.sonar.server.computation.measure.Measure; import org.sonar.server.computation.measure.Measure;
import org.sonar.server.computation.measure.MeasureRepository; import org.sonar.server.computation.measure.MeasureRepository;
import org.sonar.server.computation.metric.Metric;
import org.sonar.server.computation.metric.MetricRepository; import org.sonar.server.computation.metric.MetricRepository;


import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_DENSITY_KEY; import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_DENSITY_KEY;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_KEY; import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY; import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_API_KEY;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_DOCUMENTED_API_DENSITY_KEY;
import static org.sonar.api.measures.CoreMetrics.PUBLIC_UNDOCUMENTED_API_KEY;


/** /**
* Computes comments measures on files and then aggregates them on higher components. * Computes comments measures on files and then aggregates them on higher components.
*/ */
public class CommentMeasuresStep implements ComputationStep { public class CommentMeasuresStep implements ComputationStep {


private static final ImmutableList<Formula> FORMULAS = ImmutableList.<Formula>of(
// TODO add this formula when {@link CoreMetrics.DUPLICATED_LINES_DENSITY} will be computed in CE
// new SumFormula(CoreMetrics.COMMENT_LINES_KEY),
new CommentDensityFormula()
);

private final TreeRootHolder treeRootHolder; private final TreeRootHolder treeRootHolder;
private final MetricRepository metricRepository; private final MetricRepository metricRepository;
private final MeasureRepository measureRepository; private final MeasureRepository measureRepository;
private final ImmutableList<Formula> formulas;


public CommentMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) { public CommentMeasuresStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository) {
this.treeRootHolder = treeRootHolder; this.treeRootHolder = treeRootHolder;
this.metricRepository = metricRepository; this.metricRepository = metricRepository;
this.measureRepository = measureRepository; this.measureRepository = measureRepository;
this.formulas = ImmutableList.<Formula>of(
new DocumentationFormula(),

// TODO replace EmptyCounter by a SumCounter fo compute comment_lines when {@link DUPLICATED_LINES_DENSITY} will be computed in CE
// new SumFormula(CoreMetrics.COMMENT_LINES_KEY),
new CommentDensityFormula()
);
} }


@Override @Override
public void execute() { public void execute() {
FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository) FormulaExecutorComponentVisitor.newBuilder(metricRepository, measureRepository)
.buildFor(FORMULAS) .buildFor(formulas)
.visit(treeRootHolder.getRoot()); .visit(treeRootHolder.getRoot());
} }


private static class CommentDensityFormula implements Formula<BiSumCounter> { private class CommentDensityFormula implements Formula<EmptyCounter> {

private final Metric nclocMetric;
private final Metric commentMetric;

public CommentDensityFormula() {
this.nclocMetric = metricRepository.getByKey(NCLOC_KEY);
this.commentMetric = metricRepository.getByKey(COMMENT_LINES_KEY);
}


@Override @Override
public BiSumCounter createNewCounter() { public EmptyCounter createNewCounter() {
return new BiSumCounter(NCLOC_KEY, COMMENT_LINES_KEY); return new EmptyCounter();
} }


@Override @Override
public Optional<Measure> createMeasure(BiSumCounter counter, CreateMeasureContext context) { public Optional<Measure> createMeasure(EmptyCounter counter, CreateMeasureContext context) {
if (counter.getValue1().isPresent() && counter.getValue2().isPresent()) { Optional<Measure> nclocsOpt = measureRepository.getRawMeasure(context.getComponent(), nclocMetric);
double nclocs = counter.getValue1().get(); Optional<Measure> commentsOpt = measureRepository.getRawMeasure(context.getComponent(), commentMetric);
double comments = counter.getValue2().get(); if (nclocsOpt.isPresent() && commentsOpt.isPresent()) {
double nclocs = nclocsOpt.get().getIntValue();
double comments = commentsOpt.get().getIntValue();
double divisor = nclocs + comments; double divisor = nclocs + comments;
if (divisor > 0d) { if (divisor > 0d) {
double value = 100d * (comments / divisor); double value = 100d * (comments / divisor);
Expand All @@ -90,6 +109,91 @@ public String[] getOutputMetricKeys() {
} }
} }


private static class EmptyCounter implements Counter<EmptyCounter> {

@Override
public void aggregate(EmptyCounter counter) {
// nothing to do
}

@Override
public void aggregate(FileAggregateContext context) {
// nothing to do
}
}

private static class DocumentationFormula implements Formula<DocumentationCounter> {

@Override
public DocumentationCounter createNewCounter() {
return new DocumentationCounter();
}

@Override
public Optional<Measure> createMeasure(DocumentationCounter counter, CreateMeasureContext context) {
return getMeasure(context, counter.getPublicApiValue(), PUBLIC_API_KEY)
.or(getMeasure(context, counter.getPublicUndocumentedApiValue(), PUBLIC_UNDOCUMENTED_API_KEY))
.or(getDensityMeasure(counter, context));
}

private static Optional<Measure> getMeasure(CreateMeasureContext context, Optional<Integer> metricValue, String metricKey) {
if (context.getMetric().getKey().equals(metricKey) && metricValue.isPresent() && context.getComponent().getType().isHigherThan(Component.Type.FILE)) {
return Optional.of(Measure.newMeasureBuilder().create(metricValue.get()));
}
return Optional.absent();
}

private static Optional<Measure> getDensityMeasure(DocumentationCounter counter, CreateMeasureContext context) {
if (context.getMetric().getKey().equals(PUBLIC_DOCUMENTED_API_DENSITY_KEY) && counter.getPublicApiValue().isPresent()
&& counter.getPublicUndocumentedApiValue().isPresent()) {
double publicApis = counter.getPublicApiValue().get();
double publicUndocumentedApis = counter.getPublicUndocumentedApiValue().get();
if (publicApis > 0d) {
double documentedAPI = publicApis - publicUndocumentedApis;
double value = 100d * (documentedAPI / publicApis);
return Optional.of(Measure.newMeasureBuilder().create(value));
}
}
return Optional.absent();
}

@Override
public String[] getOutputMetricKeys() {
return new String[] {PUBLIC_API_KEY, PUBLIC_UNDOCUMENTED_API_KEY, PUBLIC_DOCUMENTED_API_DENSITY_KEY};
}
}

private static class DocumentationCounter implements Counter<DocumentationCounter> {

private final SumCounter publicApiCounter;
private final SumCounter publicUndocumentedApiCounter;

public DocumentationCounter() {
this.publicApiCounter = new SumCounter(PUBLIC_API_KEY);
this.publicUndocumentedApiCounter = new SumCounter(PUBLIC_UNDOCUMENTED_API_KEY);
}

@Override
public void aggregate(DocumentationCounter counter) {
publicApiCounter.aggregate(counter.publicApiCounter);
publicUndocumentedApiCounter.aggregate(counter.publicUndocumentedApiCounter);
}

@Override
public void aggregate(FileAggregateContext context) {
publicApiCounter.aggregate(context);
publicUndocumentedApiCounter.aggregate(context);
}

public Optional<Integer> getPublicApiValue() {
return publicApiCounter.getValue();
}

public Optional<Integer> getPublicUndocumentedApiValue() {
return publicUndocumentedApiCounter.getValue();
}
}

@Override @Override
public String getDescription() { public String getDescription() {
return "Aggregation of comment measures"; return "Aggregation of comment measures";
Expand Down
Expand Up @@ -55,7 +55,6 @@ public List<Class<? extends ComputationStep>> orderedStepClasses() {
CoreMetricFormulaExecutorStep.class, CoreMetricFormulaExecutorStep.class,
CustomMeasuresCopyStep.class, CustomMeasuresCopyStep.class,
CommentMeasuresStep.class, CommentMeasuresStep.class,
DocumentationMeasuresStep.class,


// SQALE measures depend on issues // SQALE measures depend on issues
SqaleMeasuresStep.class, SqaleMeasuresStep.class,
Expand Down

This file was deleted.

0 comments on commit 182186a

Please sign in to comment.