diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-28 13:17:57 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-01-28 13:18:46 +0100 |
commit | b8eecc041ad4aa23a3bf5cf7c8847573b125d187 (patch) | |
tree | d0b719f881f8f324d574fa699bd6befb7608c058 /sonar-plugin-api | |
parent | 220dd330306d76b7ff13baa07abf461688c92fc1 (diff) | |
download | sonarqube-b8eecc041ad4aa23a3bf5cf7c8847573b125d187.tar.gz sonarqube-b8eecc041ad4aa23a3bf5cf7c8847573b125d187.zip |
SONAR-2149 Resource filters are ignored in complexity distributions of Java projects
This issue implies SONAR-2153 : API: A decorator should override formulas
Diffstat (limited to 'sonar-plugin-api')
6 files changed, 134 insertions, 219 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/FormulaDecorator.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/FormulaDecorator.java deleted file mode 100644 index a082bffc578..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/FormulaDecorator.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * 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.api.batch; - -import org.sonar.api.measures.FormulaData; -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 java.util.List; - -/** - * A pre-implementation of a decorator using a simple calculation formula - * @since 1.11 - */ -public class FormulaDecorator implements Decorator { - - private Metric metric; - private DefaultFormulaContext formulaContext; - - /** - * Creates a FormulaDecorator - * - * @param metric the metric should have an associated formula - * - * @throws IllegalArgumentException if no formula is associated to the metric - */ - public FormulaDecorator(Metric metric) { - if (metric.getFormula() == null) { - throw new IllegalArgumentException("No formula defined on metric"); - } - this.metric = metric; - this.formulaContext = new DefaultFormulaContext(metric); - } - - /** - * {@inheritDoc} - */ - public boolean shouldExecuteOnProject(Project project) { - return true; - } - - /** - * @return metric generated by the decorator - */ - @DependedUpon - public Metric generatesMetric() { - return metric; - } - - /** - * @return metric the decorator depends upon - */ - @DependsUpon - public List<Metric> dependsUponMetrics() { - return metric.getFormula().dependsUponMetrics(); - } - - /** - * {@inheritDoc} - */ - public void decorate(Resource resource, DecoratorContext context) { - if (context.getMeasure(metric) != null) { - return; - } - - formulaContext.setDecoratorContext(context); - FormulaData data = new DefaultFormulaData(context); - Measure measure = metric.getFormula().calculate(data, formulaContext); - if (measure != null) { - context.saveMeasure(measure); - } - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - FormulaDecorator that = (FormulaDecorator) o; - - if (metric != null ? !metric.equals(that.metric) : that.metric != null) { - return false; - } - return true; - } - - @Override - public int hashCode() { - return metric != null ? metric.hashCode() : 0; - } - - @Override - public String toString() { - return new StringBuilder().append("f(").append(metric.getKey()).append(")").toString(); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java index 35f270d3c4d..ab1c36d8c0a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/CoreMetrics.java @@ -20,6 +20,7 @@ package org.sonar.api.measures; import org.apache.commons.lang.StringUtils; +import org.sonar.api.resources.Scopes; import org.sonar.api.utils.SonarException; import java.lang.reflect.Field; @@ -133,22 +134,22 @@ public final class CoreMetrics { public static final String CLASS_COMPLEXITY_DISTRIBUTION_KEY = "class_complexity_distribution"; public static final Metric CLASS_COMPLEXITY_DISTRIBUTION = new Metric(CLASS_COMPLEXITY_DISTRIBUTION_KEY, "Classes distribution /complexity", "Classes distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, - DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula()); + DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String FUNCTION_COMPLEXITY_DISTRIBUTION_KEY = "function_complexity_distribution"; public static final Metric FUNCTION_COMPLEXITY_DISTRIBUTION = new Metric(FUNCTION_COMPLEXITY_DISTRIBUTION_KEY, "Functions distribution /complexity", "Functions distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, - DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula()); + DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String FILE_COMPLEXITY_DISTRIBUTION_KEY = "file_complexity_distribution"; public static final Metric FILE_COMPLEXITY_DISTRIBUTION = new Metric(FILE_COMPLEXITY_DISTRIBUTION_KEY, "Files distribution /complexity", "Files distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_COMPLEXITY) - .setFormula(new SumChildDistributionFormula()); + .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY = "paragraph_complexity_distribution"; public static final Metric PARAGRAPH_COMPLEXITY_DISTRIBUTION = new Metric(PARAGRAPH_COMPLEXITY_DISTRIBUTION_KEY, "Paragraph distribution /complexity", "Paragraph distribution /complexity", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, - DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula()); + DOMAIN_COMPLEXITY).setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String COMMENT_LINES_KEY = "comment_lines"; public static final Metric COMMENT_LINES = new Metric(COMMENT_LINES_KEY, "Comment lines", "Number of comment lines", @@ -423,7 +424,8 @@ public final class CoreMetrics { public static final String RFC_DISTRIBUTION_KEY = "rfc_distribution"; public static final Metric RFC_DISTRIBUTION = new Metric(RFC_DISTRIBUTION_KEY, "Class distribution /RFC", "Class distribution /RFC", - Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_DESIGN).setFormula(new SumChildDistributionFormula()); + Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_DESIGN) + .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String LCOM4_KEY = "lcom4"; public static final Metric LCOM4 = new Metric(LCOM4_KEY, "LCOM4", "Lack of Cohesion of Methods", Metric.ValueType.FLOAT, @@ -436,7 +438,7 @@ public final class CoreMetrics { public static final String LCOM4_DISTRIBUTION_KEY = "lcom4_distribution"; public static final Metric LCOM4_DISTRIBUTION = new Metric(LCOM4_DISTRIBUTION_KEY, "Class distribution /LCOM4", "Class distribution /LCOM4", Metric.ValueType.DISTRIB, Metric.DIRECTION_NONE, true, DOMAIN_DESIGN) - .setFormula(new SumChildDistributionFormula()); + .setFormula(new SumChildDistributionFormula().setMinimumScopeToPersist(Scopes.DIRECTORY)); public static final String SUSPECT_LCOM4_DENSITY_KEY = "suspect_lcom4_density"; public static final Metric SUSPECT_LCOM4_DENSITY = new Metric(SUSPECT_LCOM4_DENSITY_KEY, "Suspect LCOM4 density", diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java index 423d2df83e9..d80b78ddc12 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/SumChildDistributionFormula.java @@ -19,9 +19,11 @@ */
package org.sonar.api.measures;
-import java.util.List;
-import java.util.Collections;
+import org.sonar.api.resources.Scopes;
+
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
/**
* @since 2.0
@@ -30,10 +32,21 @@ import java.util.Collection; */
public class SumChildDistributionFormula implements Formula {
+ private String minimumScopeToPersist= Scopes.FILE;
+
public List<Metric> dependsUponMetrics() {
return Collections.emptyList();
}
+ public String getMinimumScopeToPersist() {
+ return minimumScopeToPersist;
+ }
+
+ public SumChildDistributionFormula setMinimumScopeToPersist(String s) {
+ this.minimumScopeToPersist = s;
+ return this;
+ }
+
public Measure calculate(FormulaData data, FormulaContext context) {
Collection<Measure> measures = data.getChildrenMeasures(context.getTargetMetric());
if (measures == null || measures.isEmpty()) {
@@ -44,7 +57,11 @@ public class SumChildDistributionFormula implements Formula { for (Measure measure : measures) {
distribution.add(measure);
}
- return distribution.build();
+ Measure measure = distribution.build();
+ if (!Scopes.isHigherThanOrEquals(context.getResource().getScope(), minimumScopeToPersist)) {
+ measure.setPersistenceMode(PersistenceMode.MEMORY);
+ }
+ return measure;
}
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/BlockUnit.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/BlockUnit.java new file mode 100644 index 00000000000..ee6bbe1ac03 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/BlockUnit.java @@ -0,0 +1,104 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * 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.api.resources; + +public class BlockUnit extends Resource { + + public static final String SCOPE = Scopes.BLOCK_UNIT; + + protected String qualifier; + protected Language language; + + protected BlockUnit(String key, String qualifier, Language language) { + setKey(key); + this.qualifier = qualifier; + this.language = language; + } + + @Override + public String getName() { + return getKey(); + } + + @Override + public String getLongName() { + return getKey(); + } + + @Override + public String getDescription() { + return null; + } + + @Override + public final Language getLanguage() { + return language; + } + + @Override + public final String getScope() { + return SCOPE; + } + + @Override + public final String getQualifier() { + return qualifier; + } + + @Override + public Resource getParent() { + return null; + } + + @Override + public final boolean matchFilePattern(String antPattern) { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + BlockUnit blockUnit = (BlockUnit) o; + if (!qualifier.equals(blockUnit.qualifier)) { + return false; + } + return getKey().equals(blockUnit.getKey()); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + getKey().hashCode(); + result = 31 * result + qualifier.hashCode(); + return result; + } + + public static BlockUnit createMethod(String key, Language language) { + return new BlockUnit(key, Qualifiers.METHOD, language); + } +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/FormulaDecoratorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/FormulaDecoratorTest.java deleted file mode 100644 index 50865b26ae0..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/FormulaDecoratorTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2009 SonarSource SA - * 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.api.batch; - -import static org.hamcrest.core.Is.is; -import static org.junit.Assert.assertThat; -import org.junit.Test; -import static org.junit.internal.matchers.IsCollectionContaining.hasItem; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.*; -import org.sonar.api.measures.*; -import org.sonar.api.test.IsMeasure; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class FormulaDecoratorTest { - - @Test - public void doAlwaysExecute() { - assertThat(new FormulaDecorator(CoreMetrics.LINES).shouldExecuteOnProject(null), is(true)); - } - - @Test - public void declareDependencies() { - Formula formula = new Formula() { - public List<Metric> dependsUponMetrics() { - return Arrays.asList(CoreMetrics.COMPLEXITY, CoreMetrics.COVERAGE); - } - - public Measure calculate(FormulaData data, FormulaContext context) { - return null; - } - }; - Metric metric = new Metric().setFormula(formula); - List<Metric> dependencies = new FormulaDecorator(metric).dependsUponMetrics(); - assertThat(dependencies, hasItem(CoreMetrics.COMPLEXITY)); - assertThat(dependencies, hasItem(CoreMetrics.COVERAGE)); - } - - @Test - public void saveMeasure() { - FormulaDecorator decorator = new FormulaDecorator(new Metric("fake").setFormula(new FakeFormula())); - - DecoratorContext context = mock(DecoratorContext.class); - decorator.decorate(null, context); - - verify(context).saveMeasure(argThat(new IsMeasure(new Metric("fake"), 50.0))); - } - - @Test - public void doNotExecuteIfExistingResult() { - Metric fake = new Metric("fake"); - FormulaDecorator decorator = new FormulaDecorator(fake.setFormula(new FakeFormula())); - - DecoratorContext context = mock(DecoratorContext.class); - when(context.getMeasure(fake)).thenReturn(new Measure(fake, 10.0)); - decorator.decorate(null, context); - - verify(context, never()).saveMeasure((Measure) anyObject()); - } - - class FakeFormula implements Formula { - - public List<Metric> dependsUponMetrics() { - return Collections.emptyList(); - } - - public Measure calculate(FormulaData data, FormulaContext context) { - return new Measure(new Metric("fake")).setValue(50.0); - } - } -} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java index 9849c28d035..93d89b98abb 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/measures/SumChildDistributionFormulaTest.java @@ -22,6 +22,7 @@ package org.sonar.api.measures; import com.google.common.collect.Lists;
import org.junit.Before;
import org.junit.Test;
+import org.sonar.api.resources.File;
import java.util.Collections;
import java.util.List;
@@ -42,6 +43,7 @@ public class SumChildDistributionFormulaTest { public void init() {
formula = new SumChildDistributionFormula();
context = mock(FormulaContext.class);
+ when(context.getResource()).thenReturn(new File("foo"));
data = mock(FormulaData.class);
}
|