/*
* Sonar, open source software quality management tool.
* Copyright (C) 2009 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar 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.
*
* Sonar 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 Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
package org.sonar.plugins.qi;
import com.google.common.collect.Lists;
import org.apache.commons.configuration.Configuration;
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.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasureUtils;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import java.util.Arrays;
import java.util.List;
/**
* An abstract class that all decorators decorating QI axes should extend
*/
public abstract class AbstractDecorator implements Decorator {
private Metric metric;
private String axisWeight;
private String defaultAxisWeight;
protected Configuration configuration;
/**
* Creates Abstract Decorator
*
* @param configuration the configuration
* @param metric the axis metric
* @param axisWeight the key to retrieve the axis weight
* @param defaultAxisWeight the key to retrieve the default axis weight
*/
public AbstractDecorator(Configuration configuration, Metric metric, String axisWeight, String defaultAxisWeight) {
this.metric = metric;
this.axisWeight = axisWeight;
this.defaultAxisWeight = defaultAxisWeight;
this.configuration = configuration;
}
/**
* @return the metric that is generated by the decorator
*/
@DependedUpon
public List<Metric> dependedUpon() {
return Arrays.asList(metric);
}
/**
* @return the aggregated list of metrics the decorator depends upon
*/
@DependsUpon
public List<Metric> aggregDependsUpon() {
List<Metric> list = Lists.newArrayList(CoreMetrics.DUPLICATED_LINES, CoreMetrics.NCLOC);
list.addAll(dependsUpon());
return list;
}
/**
* The method to implement to add specific metric dependency for the decorator
*
* @return the dependency metric
*/
public abstract List<Metric> dependsUpon();
/**
* @param context the context
* @return the valid lines of the component, i.e. the real number of lines
*/
protected double getValidLines(DecoratorContext context) {
double duplicatedLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.DUPLICATED_LINES), 0.0);
double totalLines = MeasureUtils.getValue(context.getMeasure(CoreMetrics.NCLOC), 0.0);
double validLines = totalLines - duplicatedLines;
return validLines > 0 ? validLines : 1.0;
}
/**
* Saves the calculated measure
*
* @param context the context
* @param value the value
*/
protected void saveMeasure(DecoratorContext context, double value) {
if (!Utils.shouldSaveMeasure(context.getResource())) {
return;
}
String qualifier = context.getResource().getQualifier();
// if < 0.05, we do not record at file level to avoid storing and displaying 0.0 values
if (value < 0.05
&& (qualifier.equals(Resource.QUALIFIER_FILE) || qualifier.equals(Resource.QUALIFIER_CLASS))) {
return;
}
if (value > 1) {
value = 1;
}
Measure measure = new Measure(metric, value * computeAxisWeight(), Double.toString(computeAxisWeight()));
context.saveMeasure(measure);
}
/**
* Retrieves weight for the axis
*
* @return the weight if exists, the default value otherwise
*/
protected double computeAxisWeight() {
return configuration.getDouble(axisWeight, Double.valueOf(defaultAxisWeight));
}
/**
* @param project the project
* @return whether to execute the decorator on the project
*/
public boolean shouldExecuteOnProject(Project project) {
return Utils.shouldExecuteOnProject(project);
}
}