Package org.sonar.batch.debt

Source Code of org.sonar.batch.debt.SqaleRatingDecorator

/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* SonarQube is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

package org.sonar.batch.debt;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.DecoratorContext;
import org.sonar.api.batch.DependedUpon;
import org.sonar.api.batch.DependsUpon;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;

import javax.annotation.Nullable;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
* Decorator that computes Sqale Rating metric
*/
public final class SqaleRatingDecorator implements Decorator {

  private final SqaleRatingSettings sqaleRatingSettings;
  private final Metric[] metrics;
  private final FileSystem fs;

  public SqaleRatingDecorator(SqaleRatingSettings sqaleRatingSettings, Metric[] metrics, FileSystem fs) {
    this.sqaleRatingSettings = sqaleRatingSettings;
    this.metrics = Arrays.copyOf(metrics, metrics.length);
    this.fs = fs;
  }

  @VisibleForTesting
  SqaleRatingDecorator() {
    this.sqaleRatingSettings = null;
    this.metrics = null;
    this.fs = null;
  }

  @Override
  public boolean shouldExecuteOnProject(Project project) {
    return true;
  }

  @DependsUpon
  public List<Metric> dependsOnMetrics() {
    return Lists.<Metric>newArrayList(CoreMetrics.TECHNICAL_DEBT,
      // ncloc and complexity are the two possible metrics to be used to calculate the development cost
      CoreMetrics.NCLOC, CoreMetrics.COMPLEXITY);
  }

  @DependedUpon
  public List<Metric> generatesMetrics() {
    return Lists.<Metric>newArrayList(CoreMetrics.SQALE_RATING, CoreMetrics.DEVELOPMENT_COST, CoreMetrics.SQALE_DEBT_RATIO);
  }

  @Override
  public void decorate(Resource resource, DecoratorContext context) {
    if (ResourceUtils.isPersistable(resource) && !ResourceUtils.isUnitTestClass(resource)) {
      Long developmentCost = getDevelopmentCost(context);
      context.saveMeasure(new Measure(CoreMetrics.DEVELOPMENT_COST, Long.toString(developmentCost)));

      long debt = getMeasureValue(context, CoreMetrics.TECHNICAL_DEBT);
      double density = computeDensity(debt, developmentCost);
      context.saveMeasure(CoreMetrics.SQALE_DEBT_RATIO, 100.0 * density);

      SqaleRatingGrid ratingGrid = new SqaleRatingGrid(sqaleRatingSettings.getRatingGrid());
      context.saveMeasure(createRatingMeasure(ratingGrid.getRatingForDensity(density)));
    }
  }

  private Measure createRatingMeasure(int rating) {
    return new Measure(CoreMetrics.SQALE_RATING).setIntValue(rating).setData(toRatingLetter(rating));
  }

  static String toRatingLetter(@Nullable Integer rating) {
    if (rating != null) {
      return SqaleRatingGrid.SqaleRating.createForIndex(rating).name();
    }
    return null;
  }

  private long getDevelopmentCost(DecoratorContext context) {
    InputFile file = fs.inputFile(fs.predicates().hasRelativePath(context.getResource().getKey()));
    if (file != null) {
      String language = file.language();
      return getMeasureValue(context, sqaleRatingSettings.getSizeMetric(language, metrics)) * sqaleRatingSettings.getDevCost(language);
    } else {
      Collection<Measure> childrenMeasures = context.getChildrenMeasures(CoreMetrics.DEVELOPMENT_COST);
      Double sum = sum(childrenMeasures);
      return sum.longValue();
    }
  }

  private static Double sum(@Nullable Collection<Measure> measures) {
    if (measures == null) {
      return 0d;
    }
    double sum = 0d;
    for (Measure measure : measures) {
      String data = measure.getData();
      if (data != null) {
        sum += Double.parseDouble(data);
      }
    }
    return sum;
  }

  private long getMeasureValue(DecoratorContext context, Metric metric) {
    Measure measure = context.getMeasure(metric);
    if (measure != null) {
      return measure.getValue().longValue();
    }
    return 0L;
  }

  protected double computeDensity(double debt, double developmentCost) {
    if (Double.doubleToRawLongBits(developmentCost) != 0L) {
      return debt / developmentCost;
    }
    return 0d;
  }

}
TOP

Related Classes of org.sonar.batch.debt.SqaleRatingDecorator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.