/* * 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); } }