diff options
50 files changed, 426 insertions, 1235 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 68275cb247a..fb1eb26c69d 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -52,7 +52,6 @@ import org.sonar.plugins.core.security.ApplyProjectRolesDecorator; import org.sonar.plugins.core.sensors.BranchCoverageDecorator; import org.sonar.plugins.core.sensors.CommentDensityDecorator; import org.sonar.plugins.core.sensors.CoverageDecorator; -import org.sonar.plugins.core.sensors.CoverageMeasurementFilter; import org.sonar.plugins.core.sensors.DirectoriesDecorator; import org.sonar.plugins.core.sensors.FileHashSensor; import org.sonar.plugins.core.sensors.FilesDecorator; @@ -369,7 +368,6 @@ public final class CorePlugin extends SonarPlugin { OverallLineCoverageDecorator.class, OverallCoverageDecorator.class, OverallBranchCoverageDecorator.class, - CoverageMeasurementFilter.class, ApplyProjectRolesDecorator.class, CommentDensityDecorator.class, DirectoriesDecorator.class, diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java index 951c1d383a1..529883fc749 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/BranchCoverageDecorator.java @@ -19,20 +19,19 @@ */ package org.sonar.plugins.core.sensors; -import com.google.common.collect.ImmutableList; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependsUpon; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.MeasureUtils; import org.sonar.api.measures.Metric; +import org.sonar.batch.sensor.coverage.CoverageConstants; -import java.util.List; +import java.util.Collection; public final class BranchCoverageDecorator extends AbstractCoverageDecorator { @DependsUpon - public List<Metric> dependsUponMetrics() { - return ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER, - CoreMetrics.NEW_UNCOVERED_CONDITIONS, CoreMetrics.NEW_CONDITIONS_TO_COVER); + public Collection<Metric> dependsUponMetrics() { + return CoverageConstants.BRANCH_COVERAGE_METRICS; } @Override diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java index 2d37d02dec9..46b02d4e0f8 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageDecorator.java @@ -19,21 +19,19 @@ */ package org.sonar.plugins.core.sensors; -import com.google.common.collect.ImmutableList; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependsUpon; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.MeasureUtils; import org.sonar.api.measures.Metric; +import org.sonar.batch.sensor.coverage.CoverageConstants; import java.util.Collection; public final class CoverageDecorator extends AbstractCoverageDecorator { @DependsUpon public Collection<Metric> usedMetrics() { - return ImmutableList.<Metric>of(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER, - CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS, - CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS); + return CoverageConstants.COVERAGE_METRICS; } @Override diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java index feaf04176cf..11ff93f0634 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/LineCoverageDecorator.java @@ -19,20 +19,19 @@ */ package org.sonar.plugins.core.sensors; -import com.google.common.collect.ImmutableList; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependsUpon; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.MeasureUtils; import org.sonar.api.measures.Metric; +import org.sonar.batch.sensor.coverage.CoverageConstants; -import java.util.List; +import java.util.Collection; public final class LineCoverageDecorator extends AbstractCoverageDecorator { @DependsUpon - public List<Metric> dependsUponMetrics() { - return ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, - CoreMetrics.NEW_LINES_TO_COVER); + public Collection<Metric> dependsUponMetrics() { + return CoverageConstants.LINE_COVERAGE_METRICS; } @Override diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java index 87dd7f9ae6d..e2956df1683 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/LineCoverageDecoratorTest.java @@ -24,15 +24,12 @@ import org.junit.Test; import org.sonar.api.batch.DecoratorContext; 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.Scopes; -import java.util.List; - import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.anyDouble; -import static org.mockito.Mockito.eq; +import static org.mockito.Matchers.anyDouble; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -49,9 +46,8 @@ public class LineCoverageDecoratorTest { @Test public void should_depend_on_coverage_metrics() { - List<Metric> metrics = decorator.dependsUponMetrics(); - - assertThat(metrics).containsOnly(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER); + assertThat(decorator.dependsUponMetrics()).containsOnly(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, + CoreMetrics.NEW_LINES_TO_COVER); } @Test diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java index 471a5835639..a890b63ac9d 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java @@ -28,8 +28,7 @@ import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; -import org.sonar.api.batch.sensor.measure.Measure; -import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.xoo.Xoo; import java.io.File; @@ -88,7 +87,7 @@ public class MeasureSensor implements Sensor { if (metric == null) { throw new IllegalStateException("Unknow metric with key: " + metricKey); } - Measure<Serializable> newMeasure = context.newMeasure() + NewMeasure<Serializable> newMeasure = context.newMeasure() .forMetric(metric) .onFile(xooFile); if (Boolean.class.equals(metric.valueType())) { @@ -111,9 +110,7 @@ public class MeasureSensor implements Sensor { public void describe(SensorDescriptor descriptor) { descriptor .name("Xoo Measure Sensor") - .provides(CoreMetrics.LINES) - .onlyOnLanguages(Xoo.KEY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .onlyOnLanguages(Xoo.KEY); } @Override diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java index fbff5f75641..8d14771bab4 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SymbolReferencesSensor.java @@ -87,8 +87,7 @@ public class SymbolReferencesSensor implements Sensor { public void describe(SensorDescriptor descriptor) { descriptor .name("Xoo Symbol Reference Sensor") - .onlyOnLanguages(Xoo.KEY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .onlyOnLanguages(Xoo.KEY); } @Override diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java index d72b50b4089..004c186b208 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/SyntaxHighlightingSensor.java @@ -85,8 +85,7 @@ public class SyntaxHighlightingSensor implements Sensor { public void describe(SensorDescriptor descriptor) { descriptor .name("Xoo Highlighting Sensor") - .onlyOnLanguages(Xoo.KEY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .onlyOnLanguages(Xoo.KEY); } @Override diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java index 04dc7be446f..886104c14a0 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java @@ -35,8 +35,7 @@ public class CreateIssueByInternalKeySensor implements Sensor { descriptor .name("CreateIssueByInternalKeySensor") .onlyOnLanguages(Xoo.KEY) - .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY); } @Override diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java index 548b596c300..66a31686e03 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java @@ -36,8 +36,7 @@ public class OneIssueOnDirPerFileSensor implements Sensor { descriptor .name("One Issue On Dir Per File") .onlyOnLanguages(Xoo.KEY) - .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY); } @Override diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java index 081bb1a0a2b..3e0b9f48ee5 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java @@ -24,7 +24,6 @@ import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.batch.sensor.issue.Issue.Severity; -import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.xoo.Xoo; @@ -38,10 +37,8 @@ public class OneIssuePerLineSensor implements Sensor { public void describe(SensorDescriptor descriptor) { descriptor .name("One Issue Per Line") - .dependsOn(CoreMetrics.LINES) .onlyOnLanguages(Xoo.KEY) - .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY) - .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST); + .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java index 1fa2a1b6450..3d18e06c5a9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java @@ -40,7 +40,7 @@ import org.sonar.api.utils.SonarException; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.duplication.DuplicationUtils; import org.sonar.batch.scan.measure.MeasureCache; -import org.sonar.core.measure.MeasurementFilters; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import java.util.Arrays; import java.util.Collection; @@ -54,7 +54,6 @@ public class DefaultDecoratorContext implements DecoratorContext { private static final String SAVE_MEASURE_METHOD = "saveMeasure"; private SonarIndex sonarIndex; private Resource resource; - private MeasurementFilters measurementFilters; private boolean readOnly = false; private List<DecoratorContext> childrenContexts; @@ -63,18 +62,19 @@ public class DefaultDecoratorContext implements DecoratorContext { private MeasureCache measureCache; private MetricFinder metricFinder; private final DuplicationCache duplicationCache; + private final CoverageExclusions coverageFilter; public DefaultDecoratorContext(Resource resource, SonarIndex index, List<DecoratorContext> childrenContexts, - MeasurementFilters measurementFilters, MeasureCache measureCache, MetricFinder metricFinder, DuplicationCache duplicationCache) { + MeasureCache measureCache, MetricFinder metricFinder, DuplicationCache duplicationCache, CoverageExclusions coverageFilter) { this.sonarIndex = index; this.resource = resource; this.childrenContexts = childrenContexts; - this.measurementFilters = measurementFilters; this.measureCache = measureCache; this.metricFinder = metricFinder; this.duplicationCache = duplicationCache; + this.coverageFilter = coverageFilter; } public void init() { @@ -178,7 +178,7 @@ public class DefaultDecoratorContext implements DecoratorContext { throw new SonarException("Unknown metric: " + measure.getMetricKey()); } measure.setMetric(metric); - if (measurementFilters.accept(resource, measure)) { + if (coverageFilter.accept(resource, measure)) { List<Measure> metricMeasures = measuresByMetric.get(measure.getMetricKey()); boolean add = true; diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java index eeecd48b8bd..35d329627f3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java @@ -25,9 +25,13 @@ import org.slf4j.LoggerFactory; import org.sonar.api.batch.Event; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.SonarIndex; +import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.sensor.SensorStorage; +import org.sonar.api.config.Settings; import org.sonar.api.design.Dependency; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; @@ -40,7 +44,11 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; -import org.sonar.core.measure.MeasurementFilters; +import org.sonar.batch.duplication.BlockCache; +import org.sonar.batch.duplication.DuplicationCache; +import org.sonar.batch.index.ComponentDataCache; +import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import java.io.Serializable; import java.util.Collection; @@ -48,18 +56,21 @@ import java.util.Date; import java.util.List; import java.util.Set; -public class DefaultSensorContext implements SensorContext { +public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext { - private static final Logger LOG = LoggerFactory.getLogger(DefaultSensorContext.class); + private static final Logger LOG = LoggerFactory.getLogger(DeprecatedSensorContext.class); - private SonarIndex index; - private Project project; - private MeasurementFilters filters; + private final SonarIndex index; + private final Project project; + private final CoverageExclusions coverageFilter; - public DefaultSensorContext(SonarIndex index, Project project, MeasurementFilters filters) { + public DeprecatedSensorContext(SonarIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules, + ComponentDataCache componentDataCache, CoverageExclusions coverageFilter, + BlockCache blockCache, DuplicationCache duplicationCache, SensorStorage sensorStorage) { + super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache, sensorStorage); this.index = index; this.project = project; - this.filters = filters; + this.coverageFilter = coverageFilter; } public Project getProject() { @@ -173,8 +184,9 @@ public class DefaultSensorContext implements SensorContext { @Override public Measure saveMeasure(Resource resource, Measure measure) { - if (filters.accept(resource, measure)) { - return index.addMeasure(resourceOrProject(resource), measure); + Resource resourceOrProject = resourceOrProject(resource); + if (coverageFilter.accept(resourceOrProject, measure)) { + return index.addMeasure(resourceOrProject, measure); } else { return measure; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index 32bebf6182e..e0a0e348514 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -29,6 +29,7 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.batch.scan.SensorWrapper; import org.sonar.batch.scan2.AnalyzerOptimizer; +import org.sonar.batch.sensor.DefaultSensorContext; import javax.annotation.Nullable; @@ -43,7 +44,7 @@ public class BatchExtensionDictionnary extends org.sonar.api.batch.BatchExtensio private SensorContext context; private AnalyzerOptimizer analyzerOptimizer; - public BatchExtensionDictionnary(ComponentContainer componentContainer, SensorContext context, AnalyzerOptimizer analyzerOptimizer) { + public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext context, AnalyzerOptimizer analyzerOptimizer) { super(componentContainer); this.context = context; this.analyzerOptimizer = analyzerOptimizer; diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index 9e3a3d1b133..64886cc1529 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -31,8 +31,10 @@ import org.slf4j.LoggerFactory; import org.sonar.api.batch.Event; import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.design.Dependency; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.measures.MeasuresFilters; @@ -51,7 +53,6 @@ import org.sonar.api.utils.SonarException; import org.sonar.batch.ProjectTree; import org.sonar.batch.issue.ModuleIssues; import org.sonar.batch.scan.measure.MeasureCache; -import org.sonar.batch.scan2.DefaultSensorContext; import org.sonar.core.component.ComponentKeys; import javax.annotation.CheckForNull; @@ -59,6 +60,7 @@ import javax.annotation.Nullable; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -72,6 +74,31 @@ public class DefaultIndex extends SonarIndex { private static final Logger LOG = LoggerFactory.getLogger(DefaultIndex.class); + private static final List<Metric> INTERNAL_METRICS = Arrays.<Metric>asList( + // Computed by DsmDecorator + CoreMetrics.DEPENDENCY_MATRIX, + CoreMetrics.DIRECTORY_CYCLES, + CoreMetrics.DIRECTORY_EDGES_WEIGHT, + CoreMetrics.DIRECTORY_FEEDBACK_EDGES, + CoreMetrics.DIRECTORY_TANGLE_INDEX, + CoreMetrics.DIRECTORY_TANGLES, + CoreMetrics.FILE_CYCLES, + CoreMetrics.FILE_EDGES_WEIGHT, + CoreMetrics.FILE_FEEDBACK_EDGES, + CoreMetrics.FILE_TANGLE_INDEX, + CoreMetrics.FILE_TANGLES, + // Computed by ScmActivitySensor + CoreMetrics.SCM_AUTHORS_BY_LINE, + CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, + CoreMetrics.SCM_REVISIONS_BY_LINE, + // Computed by core duplication plugin + CoreMetrics.DUPLICATIONS_DATA, + CoreMetrics.DUPLICATION_LINES_DATA, + CoreMetrics.DUPLICATED_FILES, + CoreMetrics.DUPLICATED_LINES, + CoreMetrics.DUPLICATED_BLOCKS + ); + private final ResourceCache resourceCache; private final MetricFinder metricFinder; @@ -228,7 +255,7 @@ public class DefaultIndex extends SonarIndex { if (metric == null) { throw new SonarException("Unknown metric: " + measure.getMetricKey()); } - if (!isTechnicalProjectCopy(resource) && !measure.isFromCore() && DefaultSensorContext.INTERNAL_METRICS.contains(metric)) { + if (!isTechnicalProjectCopy(resource) && !measure.isFromCore() && INTERNAL_METRICS.contains(metric)) { LOG.debug("Metric " + metric.key() + " is an internal metric computed by SonarQube. Please update your plugin."); return measure; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java index b9216a859f7..7bc120b37d6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.mediumtest; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.InputDir; @@ -28,6 +29,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.dependency.Dependency; import org.sonar.api.batch.sensor.duplication.DuplicationGroup; import org.sonar.api.batch.sensor.highlighting.TypeOfText; +import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.Symbol; import org.sonar.api.batch.sensor.test.TestCaseCoverage; import org.sonar.api.batch.sensor.test.TestCaseExecution; @@ -51,6 +53,7 @@ import org.sonar.core.source.SnapshotDataTypes; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -64,7 +67,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { private static final Logger LOG = LoggerFactory.getLogger(TaskResult.class); private List<Issue> issues = new ArrayList<>(); - private List<Measure> measures = new ArrayList<>(); + private List<org.sonar.api.batch.sensor.measure.Measure> measures = new ArrayList<>(); private Map<String, List<DuplicationGroup>> duplications = new HashMap<>(); private Map<String, InputFile> inputFiles = new HashMap<>(); private Map<String, InputDir> inputDirs = new HashMap<>(); @@ -81,11 +84,10 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { issues.add(issue); } - for (Measure measure : container.getComponentByType(MeasureCache.class).all()) { - measures.add(measure); - } - storeFs(container); + + storeMeasures(container); + storeComponentData(container); storeDuplication(container); // storeTestCases(container); @@ -94,6 +96,24 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { } + private void storeMeasures(ProjectScanContainer container) { + InputPathCache inputFileCache = container.getComponentByType(InputPathCache.class); + for (Entry<Measure> measureEntry : container.getComponentByType(MeasureCache.class).entries()) { + String componentKey = measureEntry.key()[0].toString(); + InputFile file = inputFileCache.getFile(StringUtils.substringBeforeLast(componentKey, ":"), StringUtils.substringAfterLast(componentKey, ":")); + Measure oldMeasure = measureEntry.value(); + DefaultMeasure<Serializable> newMeasure = new DefaultMeasure<>() + .forMetric(oldMeasure.getMetric()); + if (file != null) { + newMeasure.onFile(file); + } else { + newMeasure.onProject(); + } + newMeasure.withValue(oldMeasure.value()); + measures.add(newMeasure); + } + } + private void storeCoveragePerTest(ProjectScanContainer container) { TestCaseCoverageCache testCaseCoverageCache = container.getComponentByType(TestCaseCoverageCache.class); for (Entry<TestCaseCoverage> entry : testCaseCoverageCache.entries()) { @@ -170,7 +190,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver { return issues; } - public List<Measure> measures() { + public List<org.sonar.api.batch.sensor.measure.Measure> measures() { return measures; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java index b867e0fc010..01ae1e452d8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DecoratorsExecutor.java @@ -35,7 +35,7 @@ import org.sonar.batch.DefaultDecoratorContext; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.events.EventBus; import org.sonar.batch.scan.measure.MeasureCache; -import org.sonar.core.measure.MeasurementFilters; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import java.util.Collection; import java.util.List; @@ -46,13 +46,13 @@ public class DecoratorsExecutor implements BatchComponent { private SonarIndex index; private EventBus eventBus; private Project project; - private MeasurementFilters measurementFilters; + private CoverageExclusions coverageFilter; private MeasureCache measureCache; private MetricFinder metricFinder; private final DuplicationCache duplicationCache; public DecoratorsExecutor(BatchExtensionDictionnary batchExtDictionnary, - Project project, SonarIndex index, EventBus eventBus, MeasurementFilters measurementFilters, MeasureCache measureCache, MetricFinder metricFinder, + Project project, SonarIndex index, EventBus eventBus, CoverageExclusions coverageFilter, MeasureCache measureCache, MetricFinder metricFinder, DuplicationCache duplicationCache) { this.measureCache = measureCache; this.metricFinder = metricFinder; @@ -61,7 +61,7 @@ public class DecoratorsExecutor implements BatchComponent { this.index = index; this.eventBus = eventBus; this.project = project; - this.measurementFilters = measurementFilters; + this.coverageFilter = coverageFilter; } public void execute() { @@ -79,7 +79,7 @@ public class DecoratorsExecutor implements BatchComponent { childrenContexts.add(childContext.end()); } - DefaultDecoratorContext context = new DefaultDecoratorContext(resource, index, childrenContexts, measurementFilters, measureCache, metricFinder, duplicationCache); + DefaultDecoratorContext context = new DefaultDecoratorContext(resource, index, childrenContexts, measureCache, metricFinder, duplicationCache, coverageFilter); context.init(); if (executeDecorators) { for (Decorator decorator : decorators) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index af680789d80..98598f57f33 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -31,8 +31,8 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.scan.filesystem.FileExclusions; import org.sonar.batch.DefaultProjectClasspath; -import org.sonar.batch.DefaultSensorContext; import org.sonar.batch.DefaultTimeMachine; +import org.sonar.batch.DeprecatedSensorContext; import org.sonar.batch.ProjectTree; import org.sonar.batch.ResourceFilters; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; @@ -97,8 +97,10 @@ import org.sonar.batch.scan.filesystem.StatusDetectionFactory; import org.sonar.batch.scan.maven.MavenPluginsConfigurator; import org.sonar.batch.scan.report.JsonReport; import org.sonar.batch.scan2.AnalyzerOptimizer; +import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.DefaultSensorStorage; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import org.sonar.core.component.ScanPerspectives; -import org.sonar.core.measure.MeasurementFilters; public class ModuleScanContainer extends ComponentContainer { private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class); @@ -174,11 +176,12 @@ public class ModuleScanContainer extends ComponentContainer { AnalyzerOptimizer.class, DefaultSensorContext.class, - SensorContextAdapter.class, + DefaultSensorStorage.class, + DeprecatedSensorContext.class, BatchExtensionDictionnary.class, DefaultTimeMachine.class, IssueFilters.class, - MeasurementFilters.class, + CoverageExclusions.class, ResourceFilters.class, // rules diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java deleted file mode 100644 index 621668853d3..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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.scan2; - -import org.apache.commons.io.Charsets; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputPath; -import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.Issue.Severity; -import org.sonar.api.batch.sensor.measure.Measure; -import org.sonar.api.config.Settings; -import org.sonar.api.utils.ZipUtils; -import org.sonar.api.utils.text.JsonWriter; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.util.Properties; - -public final class AnalysisPublisher { - - private static final Logger LOG = LoggerFactory.getLogger(AnalysisPublisher.class); - private final Settings settings; - private final FileSystem fs; - private final MeasureCache measureCache; - private final ProjectDefinition def; - private final IssueCache issueCache; - - public AnalysisPublisher(ProjectDefinition def, Settings settings, FileSystem fs, - MeasureCache measureCache, - IssueCache analyzerIssueCache) { - this.def = def; - this.settings = settings; - this.fs = fs; - this.measureCache = measureCache; - this.issueCache = analyzerIssueCache; - } - - public void execute() { - if (settings.getBoolean("sonar.skipPublish")) { - LOG.debug("Publishing of results is skipped"); - return; - } - File exportDir = prepareExportDir(); - - exportAnalysisProperties(exportDir); - - exportSourceFiles(exportDir); - - exportMeasures(exportDir); - - exportIssues(exportDir); - - createZip(exportDir); - - } - - private void createZip(File exportDir) { - File exportZip = new File(fs.workDir(), def.getKey() + "-export.zip"); - try { - ZipUtils.zipDir(exportDir, exportZip); - FileUtils.deleteDirectory(exportDir); - } catch (IOException e) { - throw unableToExport(e); - } - LOG.info("Results packaged in " + exportZip); - } - - private IllegalStateException unableToExport(IOException e) { - return new IllegalStateException("Unable to export result of analyzis", e); - } - - private void exportIssues(File exportDir) { - File issuesFile = new File(exportDir, "issues.json"); - try (Writer issueWriter = new OutputStreamWriter(new FileOutputStream(issuesFile), Charsets.UTF_8)) { - JsonWriter jsonWriter = JsonWriter.of(issueWriter); - jsonWriter - .beginObject().name("issues") - .beginArray(); - for (Issue issue : issueCache.byModule(def.getKey())) { - jsonWriter.beginObject() - .prop("repository", issue.ruleKey().repository()) - .prop("rule", issue.ruleKey().rule()); - InputPath inputPath = issue.inputPath(); - if (inputPath != null) { - jsonWriter.prop("path", inputPath.relativePath()); - } - jsonWriter.prop("message", issue.message()) - .prop("effortToFix", issue.effortToFix()) - .prop("line", issue.line()); - Severity overridenSeverity = issue.overridenSeverity(); - if (overridenSeverity != null) { - jsonWriter.prop("severity", overridenSeverity.name()); - } - jsonWriter.endObject(); - } - jsonWriter.endArray() - .endObject() - .close(); - } catch (IOException e) { - throw unableToExport(e); - } - } - - private void exportMeasures(File exportDir) { - File measuresFile = new File(exportDir, "measures.json"); - try (Writer measureWriter = new OutputStreamWriter(new FileOutputStream(measuresFile), Charsets.UTF_8)) { - JsonWriter jsonWriter = JsonWriter.of(measureWriter); - jsonWriter - .beginObject().name("measures") - .beginArray(); - for (Measure<?> measure : measureCache.byModule(def.getKey())) { - jsonWriter.beginObject() - .prop("metricKey", measure.metric().key()); - InputFile inputFile = measure.inputFile(); - if (inputFile != null) { - jsonWriter.prop("filePath", inputFile.relativePath()); - } - jsonWriter.prop("value", String.valueOf(measure.value())) - .endObject(); - } - jsonWriter.endArray() - .endObject() - .close(); - } catch (IOException e) { - throw unableToExport(e); - } - } - - private void exportSourceFiles(File exportDir) { - File sourceDir = new File(exportDir, "sources"); - for (InputFile inputFile : fs.inputFiles(fs.predicates().all())) { - File dest = new File(sourceDir, inputFile.relativePath()); - try { - FileUtils.copyFile(inputFile.file(), dest); - } catch (IOException e) { - throw unableToExport(e); - } - } - } - - private void exportAnalysisProperties(File exportDir) { - File propsFile = new File(exportDir, "analysis.properties"); - Properties props = new Properties(); - props.putAll(settings.getProperties()); - try (Writer writer = new OutputStreamWriter(new FileOutputStream(propsFile), Charsets.UTF_8)) { - props.store(writer, "SonarQube batch"); - } catch (IOException e) { - throw unableToExport(e); - } - } - - private File prepareExportDir() { - File exportDir = new File(fs.workDir(), "export"); - try { - if (exportDir.exists()) { - FileUtils.forceDelete(exportDir); - } - FileUtils.forceMkdir(exportDir); - } catch (IOException e) { - throw unableToExport(e); - } - return exportDir; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java deleted file mode 100644 index cb70fa25b6a..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.scan2; - -import com.google.common.base.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputPath; -import org.sonar.api.batch.measure.Metric; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.DefaultActiveRule; -import org.sonar.api.batch.sensor.dependency.Dependency; -import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; -import org.sonar.api.batch.sensor.measure.Measure; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.api.batch.sensor.test.TestCaseCoverage; -import org.sonar.api.batch.sensor.test.TestCaseExecution; -import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution; -import org.sonar.api.config.Settings; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.MessageException; -import org.sonar.batch.dependency.DependencyCache; -import org.sonar.batch.duplication.BlockCache; -import org.sonar.batch.duplication.DuplicationCache; -import org.sonar.batch.index.ComponentDataCache; -import org.sonar.batch.issue.IssueFilters; -import org.sonar.batch.scan.SensorContextAdapter; -import org.sonar.batch.test.TestCaseCoverageCache; -import org.sonar.batch.test.TestCaseExecutionCache; -import org.sonar.core.component.ComponentKeys; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.List; - -public class DefaultSensorContext extends BaseSensorContext { - - private static final Logger LOG = LoggerFactory.getLogger(DefaultSensorContext.class); - - public static final List<Metric> INTERNAL_METRICS = Arrays.<Metric>asList( - // Computed by DsmDecorator - CoreMetrics.DEPENDENCY_MATRIX, - CoreMetrics.DIRECTORY_CYCLES, - CoreMetrics.DIRECTORY_EDGES_WEIGHT, - CoreMetrics.DIRECTORY_FEEDBACK_EDGES, - CoreMetrics.DIRECTORY_TANGLE_INDEX, - CoreMetrics.DIRECTORY_TANGLES, - CoreMetrics.FILE_CYCLES, - CoreMetrics.FILE_EDGES_WEIGHT, - CoreMetrics.FILE_FEEDBACK_EDGES, - CoreMetrics.FILE_TANGLE_INDEX, - CoreMetrics.FILE_TANGLES, - // Computed by ScmActivitySensor - CoreMetrics.SCM_AUTHORS_BY_LINE, - CoreMetrics.SCM_LAST_COMMIT_DATETIMES_BY_LINE, - CoreMetrics.SCM_REVISIONS_BY_LINE, - // Computed by core duplication plugin - CoreMetrics.DUPLICATIONS_DATA, - CoreMetrics.DUPLICATION_LINES_DATA, - CoreMetrics.DUPLICATED_FILES, - CoreMetrics.DUPLICATED_LINES, - CoreMetrics.DUPLICATED_BLOCKS - ); - private final MeasureCache measureCache; - private final IssueCache issueCache; - private final ProjectDefinition def; - private final ActiveRules activeRules; - private final IssueFilters issueFilters; - private final TestCaseExecutionCache testCaseExecutionCache; - private final TestCaseCoverageCache coveragePerTestCache; - private final DependencyCache dependencyCache; - - public DefaultSensorContext(ProjectDefinition def, MeasureCache measureCache, IssueCache issueCache, - Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache, - BlockCache blockCache, DuplicationCache duplicationCache, TestCaseExecutionCache testCaseCache, TestCaseCoverageCache coveragePerTestCache, DependencyCache dependencyCache) { - super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache); - this.def = def; - this.measureCache = measureCache; - this.issueCache = issueCache; - this.activeRules = activeRules; - this.issueFilters = issueFilters; - this.testCaseExecutionCache = testCaseCache; - this.coveragePerTestCache = coveragePerTestCache; - this.dependencyCache = dependencyCache; - } - - @Override - public void store(Measure newMeasure) { - DefaultMeasure<Serializable> measure = (DefaultMeasure<Serializable>) newMeasure; - if (!measure.isFromCore() && INTERNAL_METRICS.contains(measure.metric())) { - throw new IllegalArgumentException("Metric " + measure.metric().key() + " is an internal metric computed by SonarQube. Please remove or update offending plugin."); - } - InputFile inputFile = measure.inputFile(); - if (inputFile != null) { - measureCache.put(def.getKey(), ComponentKeys.createEffectiveKey(def.getKey(), inputFile), measure); - } else { - measureCache.put(def.getKey(), def.getKey(), measure); - } - } - - @Override - public void store(Issue issue) { - String resourceKey; - InputPath inputPath = issue.inputPath(); - if (inputPath != null) { - resourceKey = ComponentKeys.createEffectiveKey(def.getKey(), inputPath); - } else { - resourceKey = def.getKey(); - } - RuleKey ruleKey = issue.ruleKey(); - DefaultActiveRule activeRule = (DefaultActiveRule) activeRules.find(ruleKey); - if (activeRule == null) { - // rule does not exist or is not enabled -> ignore the issue - LOG.debug("Rule {} does not exists or is not enabled. Issue {} is ignored.", issue.ruleKey(), issue); - return; - } - if (Strings.isNullOrEmpty(activeRule.name()) && Strings.isNullOrEmpty(issue.message())) { - throw MessageException.of(String.format("The rule '%s' has no name and the related issue has no message.", ruleKey)); - } - - updateIssue((DefaultIssue) issue, activeRule); - - if (!issueFilters.accept(SensorContextAdapter.toDefaultIssue(def.getKey(), resourceKey, issue))) { - LOG.debug("Issue {} was excluded by some filters.", issue); - return; - } - issueCache.put(def.getKey(), resourceKey, (DefaultIssue) issue); - } - - private void updateIssue(DefaultIssue issue, DefaultActiveRule activeRule) { - if (Strings.isNullOrEmpty(issue.message())) { - issue.message(activeRule.name()); - } - } - - @Override - public void store(TestCaseExecution testCaseExecution) { - if (testCaseExecutionCache.contains(((DefaultTestCaseExecution) testCaseExecution).testFile(), testCaseExecution.name())) { - throw new IllegalArgumentException("There is already a test case with the same name: " + testCaseExecution.name()); - } - testCaseExecutionCache.put(((DefaultTestCaseExecution) testCaseExecution).testFile(), testCaseExecution); - } - - @Override - public void store(TestCaseCoverage testCaseCoverage) { - if (coveragePerTestCache.getCoverage(testCaseCoverage.testFile(), testCaseCoverage.testName(), testCaseCoverage.coveredFile()) != null) { - throw new IllegalArgumentException("Test coverage already registered for this combination of test file, test name and main file: " + testCaseCoverage); - } - coveragePerTestCache.put(testCaseCoverage); - } - - @Override - public void store(Dependency dep) { - if (dependencyCache.get(def.getKey(), dep.from(), dep.to()) != null) { - throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved."); - } - dependencyCache.put(def.getKey(), dep); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java deleted file mode 100644 index e0c9d5a6db5..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.scan2; - -import com.google.common.base.Preconditions; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.batch.index.Cache; -import org.sonar.batch.index.Cache.Entry; -import org.sonar.batch.index.Caches; -import org.sonar.batch.scan.filesystem.InputPathCache; - -/** - * Cache of all measures. This cache is shared amongst all project modules. - */ -public class MeasureCache implements BatchComponent { - - // project key -> component key -> metric key -> measure - private final Cache<DefaultMeasure> cache; - - public MeasureCache(Caches caches, MetricFinder metricFinder, InputPathCache inputPathCache) { - caches.registerValueCoder(DefaultMeasure.class, new DefaultMeasureValueCoder(metricFinder, inputPathCache)); - cache = caches.createCache("measures"); - } - - public Iterable<Entry<DefaultMeasure>> entries() { - return cache.entries(); - } - - public Iterable<DefaultMeasure> byModule(String projectKey) { - return cache.values(projectKey); - } - - public DefaultMeasure byMetric(String projectKey, String resourceKey, String metricKey) { - return cache.get(projectKey, resourceKey, metricKey); - } - - public MeasureCache put(String projectKey, String resourceKey, DefaultMeasure<?> measure) { - Preconditions.checkNotNull(projectKey); - Preconditions.checkNotNull(resourceKey); - Preconditions.checkNotNull(measure); - cache.put(projectKey, resourceKey, measure.metric().key(), measure); - return this; - } - - public boolean contains(String projectKey, String resourceKey, DefaultMeasure<?> measure) { - Preconditions.checkNotNull(projectKey); - Preconditions.checkNotNull(resourceKey); - Preconditions.checkNotNull(measure); - return cache.containsKey(projectKey, resourceKey, measure.metric().key()); - } - - public Iterable<DefaultMeasure> all() { - return cache.values(); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java deleted file mode 100644 index 5d3cb485f47..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanContainer.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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.scan2; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.InstantiationStrategy; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.rule.CheckFactory; -import org.sonar.api.platform.ComponentContainer; -import org.sonar.api.scan.filesystem.FileExclusions; -import org.sonar.batch.bootstrap.BatchExtensionDictionnary; -import org.sonar.batch.bootstrap.ExtensionInstaller; -import org.sonar.batch.bootstrap.ExtensionMatcher; -import org.sonar.batch.bootstrap.ExtensionUtils; -import org.sonar.batch.events.EventBus; -import org.sonar.batch.issue.IssuableFactory; -import org.sonar.batch.issue.IssueFilters; -import org.sonar.batch.issue.ModuleIssues; -import org.sonar.batch.issue.ignore.EnforceIssuesFilter; -import org.sonar.batch.issue.ignore.IgnoreIssuesFilter; -import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer; -import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer; -import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; -import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner; -import org.sonar.batch.rule.ActiveRulesProvider; -import org.sonar.batch.rule.ModuleQProfiles; -import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.scan.LanguageVerifier; -import org.sonar.batch.scan.ModuleSettings; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.batch.scan.filesystem.DeprecatedFileFilters; -import org.sonar.batch.scan.filesystem.ExclusionFilters; -import org.sonar.batch.scan.filesystem.FileIndexer; -import org.sonar.batch.scan.filesystem.FileSystemLogger; -import org.sonar.batch.scan.filesystem.InputFileBuilderFactory; -import org.sonar.batch.scan.filesystem.LanguageDetectionFactory; -import org.sonar.batch.scan.filesystem.ModuleFileSystemInitializer; -import org.sonar.batch.scan.filesystem.ModuleInputFileCache; -import org.sonar.batch.scan.filesystem.StatusDetectionFactory; - -public class ModuleScanContainer extends ComponentContainer { - private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class); - private final ProjectDefinition moduleDefinition; - - public ModuleScanContainer(ProjectScanContainer parent, ProjectDefinition moduleDefinition) { - super(parent); - this.moduleDefinition = moduleDefinition; - } - - @Override - protected void doBeforeStart() { - LOG.info("------------- Scan {}", moduleDefinition.getName()); - addCoreComponents(); - addExtensions(); - } - - private void addCoreComponents() { - add( - moduleDefinition, - ModuleSettings.class, - - EventBus.class, - ModuleScanExecutor.class, - ModuleScanExecutor.getPhaseClasses(), - moduleDefinition.getContainerExtensions(), - - // file system - ModuleInputFileCache.class, - FileExclusions.class, - ExclusionFilters.class, - DeprecatedFileFilters.class, - InputFileBuilderFactory.class, - StatusDetectionFactory.class, - LanguageDetectionFactory.class, - FileIndexer.class, - LanguageVerifier.class, - FileSystemLogger.class, - DefaultModuleFileSystem.class, - ModuleFileSystemInitializer.class, - QProfileVerifier.class, - - AnalyzerOptimizer.class, - - DefaultSensorContext.class, - BatchExtensionDictionnary.class, - IssueFilters.class, - - // rules - ModuleQProfiles.class, - new ActiveRulesProvider(), - CheckFactory.class, - - // issues - IssuableFactory.class, - ModuleIssues.class, - - // Measures - DefaultFileLinesContextFactory.class, - - // issue exclusions - IssueInclusionPatternInitializer.class, - IssueExclusionPatternInitializer.class, - IssueExclusionsRegexpScanner.class, - IssueExclusionsLoader.class, - EnforceIssuesFilter.class, - IgnoreIssuesFilter.class, - - AnalysisPublisher.class); - } - - private void addExtensions() { - ExtensionInstaller installer = getComponentByType(ExtensionInstaller.class); - installer.install(this, new ExtensionMatcher() { - @Override - public boolean accept(Object extension) { - return ExtensionUtils.isType(extension, BatchComponent.class) - && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_PROJECT); - } - }); - } - - @Override - protected void doAfterStart() { - getComponentByType(ModuleScanExecutor.class).execute(); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java index 088125818df..943f93e1db0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java @@ -37,19 +37,16 @@ public final class ModuleScanExecutor { private final QProfileVerifier profileVerifier; private final IssueExclusionsLoader issueExclusionsLoader; - private AnalysisPublisher analyzisPublisher; - public ModuleScanExecutor(SensorsExecutor analyzersExecutor, SensorContext analyzerContext, FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, - IssueExclusionsLoader issueExclusionsLoader, AnalysisPublisher analyzisPublisher) { + IssueExclusionsLoader issueExclusionsLoader) { this.analyzersExecutor = analyzersExecutor; this.analyzerContext = analyzerContext; this.fsLogger = fsLogger; this.fs = fs; this.profileVerifier = profileVerifier; this.issueExclusionsLoader = issueExclusionsLoader; - this.analyzisPublisher = analyzisPublisher; } public static Collection<Class> getPhaseClasses() { @@ -73,8 +70,5 @@ public final class ModuleScanExecutor { analyzersExecutor.execute(analyzerContext); - // Export results - analyzisPublisher.execute(); - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java deleted file mode 100644 index 5f796661473..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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.scan2; - -import com.google.common.annotations.VisibleForTesting; -import org.sonar.api.BatchComponent; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.InstantiationStrategy; -import org.sonar.api.batch.bootstrap.ProjectBootstrapper; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.config.Settings; -import org.sonar.api.platform.ComponentContainer; -import org.sonar.api.resources.Languages; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.batch.bootstrap.ExtensionInstaller; -import org.sonar.batch.bootstrap.ExtensionMatcher; -import org.sonar.batch.bootstrap.ExtensionUtils; -import org.sonar.batch.dependency.DependencyCache; -import org.sonar.batch.duplication.BlockCache; -import org.sonar.batch.duplication.DuplicationCache; -import org.sonar.batch.index.Caches; -import org.sonar.batch.index.ComponentDataCache; -import org.sonar.batch.index.ResourceCache; -import org.sonar.batch.languages.DefaultLanguagesReferential; -import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; -import org.sonar.batch.referential.DefaultProjectReferentialsLoader; -import org.sonar.batch.referential.ProjectReferentialsLoader; -import org.sonar.batch.referential.ProjectReferentialsProvider; -import org.sonar.batch.scan.ProjectReactorBuilder; -import org.sonar.batch.scan.ProjectSettings; -import org.sonar.batch.scan.filesystem.InputPathCache; -import org.sonar.batch.scan.maven.FakeMavenPluginExecutor; -import org.sonar.batch.scan.maven.MavenPluginExecutor; -import org.sonar.batch.test.TestCaseCoverageCache; -import org.sonar.batch.test.TestCaseExecutionCache; - -public class ProjectScanContainer extends ComponentContainer { - public ProjectScanContainer(ComponentContainer taskContainer) { - super(taskContainer); - } - - @Override - protected void doBeforeStart() { - projectBootstrap(); - addBatchComponents(); - fixMavenExecutor(); - addBatchExtensions(); - Settings settings = getComponentByType(Settings.class); - if (settings != null && settings.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY)) { - add(PhasesSumUpTimeProfiler.class); - } - } - - private void projectBootstrap() { - ProjectReactor reactor; - ProjectBootstrapper bootstrapper = getComponentByType(ProjectBootstrapper.class); - Settings settings = getComponentByType(Settings.class); - if (bootstrapper == null - // Starting from Maven plugin 2.3 then only DefaultProjectBootstrapper should be used. - || "true".equals(settings.getString("sonar.mojoUseRunner"))) { - // Use default SonarRunner project bootstrapper - ProjectReactorBuilder builder = getComponentByType(ProjectReactorBuilder.class); - reactor = builder.execute(); - } else { - reactor = bootstrapper.bootstrap(); - } - if (reactor == null) { - throw new IllegalStateException(bootstrapper + " has returned null as ProjectReactor"); - } - add(reactor); - if (getComponentByType(ProjectReferentialsLoader.class) == null) { - add(DefaultProjectReferentialsLoader.class); - } - } - - private void addBatchComponents() { - add( - new ProjectReferentialsProvider(), - ProjectSettings.class, - Caches.class, - ResourceCache.class, - - // lang - Languages.class, - DefaultLanguagesReferential.class, - - // Measures - MeasureCache.class, - - // file system - InputPathCache.class, - PathResolver.class, - - // issues - IssueCache.class, - - // Syntax highlighting and symbols - ComponentDataCache.class, - - // Duplications - BlockCache.class, - DuplicationCache.class, - - // Tests - TestCaseExecutionCache.class, - TestCaseCoverageCache.class, - - // Dependencies - DependencyCache.class, - - ScanTaskObservers.class); - } - - private void fixMavenExecutor() { - if (getComponentByType(MavenPluginExecutor.class) == null) { - add(FakeMavenPluginExecutor.class); - } - } - - private void addBatchExtensions() { - getComponentByType(ExtensionInstaller.class).install(this, new BatchExtensionFilter()); - } - - @Override - protected void doAfterStart() { - ProjectReactor tree = getComponentByType(ProjectReactor.class); - scanRecursively(tree.getRoot()); - - getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask(); - } - - private void scanRecursively(ProjectDefinition module) { - for (ProjectDefinition subModules : module.getSubProjects()) { - scanRecursively(subModules); - } - scan(module); - } - - @VisibleForTesting - void scan(ProjectDefinition module) { - new ModuleScanContainer(this, module).execute(); - } - - static class BatchExtensionFilter implements ExtensionMatcher { - @Override - public boolean accept(Object extension) { - return ExtensionUtils.isType(extension, BatchComponent.class) - && ExtensionUtils.isInstantiationStrategy(extension, InstantiationStrategy.PER_BATCH); - } - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java deleted file mode 100644 index 636ed9f34ed..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObserver.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.scan2; - -import org.sonar.api.BatchExtension; - -public interface ScanTaskObserver extends BatchExtension { - - void scanTaskCompleted(ProjectScanContainer container); - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java deleted file mode 100644 index 6dc8fa6fd40..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ScanTaskObservers.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.scan2; - -public class ScanTaskObservers { - - private ScanTaskObserver[] observers; - private ProjectScanContainer projectScanContainer; - - public ScanTaskObservers(ProjectScanContainer projectScanContainer, ScanTaskObserver... observers) { - this.projectScanContainer = projectScanContainer; - this.observers = observers; - } - - public ScanTaskObservers(ProjectScanContainer projectScanContainer) { - this(projectScanContainer, new ScanTaskObserver[0]); - } - - public void notifyEndOfScanTask() { - for (ScanTaskObserver scanTaskObserver : observers) { - scanTaskObserver.scanTaskCompleted(projectScanContainer); - } - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java index 09b9e5b5f3e..e02fe9e1f90 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java @@ -17,7 +17,7 @@ * 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.scan2; +package org.sonar.batch.sensor; import com.google.common.base.Preconditions; import org.sonar.api.batch.fs.FileSystem; @@ -35,7 +35,7 @@ import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; -import org.sonar.api.batch.sensor.measure.Measure; +import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder; import org.sonar.api.batch.sensor.test.Coverage; @@ -50,7 +50,6 @@ import org.sonar.batch.duplication.DefaultTokenBuilder; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.highlighting.DefaultHighlightingBuilder; import org.sonar.batch.index.ComponentDataCache; -import org.sonar.batch.scan.SensorContextAdapter; import org.sonar.batch.symbol.DefaultSymbolTableBuilder; import org.sonar.duplications.internal.pmd.PmdBlockChunker; @@ -58,11 +57,11 @@ import java.io.Serializable; import java.util.List; /** - * Common bits between {@link DefaultSensorContext} and {@link SensorContextAdapter} + * Common bits between {@link ExperimentalSensorStorage} and {@link SensorContextAdapter} * @author julien * */ -public abstract class BaseSensorContext implements SensorContext, SensorStorage { +public class DefaultSensorContext implements SensorContext { private final Settings settings; private final FileSystem fs; @@ -70,15 +69,17 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage private final ComponentDataCache componentDataCache; private final BlockCache blockCache; private final DuplicationCache duplicationCache; + private final SensorStorage sensorStorage; - protected BaseSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, - BlockCache blockCache, DuplicationCache duplicationCache) { + public DefaultSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, + BlockCache blockCache, DuplicationCache duplicationCache, SensorStorage sensorStorage) { this.settings = settings; this.fs = fs; this.activeRules = activeRules; this.componentDataCache = componentDataCache; this.blockCache = blockCache; this.duplicationCache = duplicationCache; + this.sensorStorage = sensorStorage; } @Override @@ -97,13 +98,13 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage } @Override - public <G extends Serializable> Measure<G> newMeasure() { - return (Measure<G>) new DefaultMeasure(this); + public <G extends Serializable> NewMeasure<G> newMeasure() { + return new DefaultMeasure(sensorStorage); } @Override public Issue newIssue() { - return new DefaultIssue(this); + return new DefaultIssue(sensorStorage); } @Override @@ -158,22 +159,22 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage @Override public Coverage newCoverage() { - return new DefaultCoverage(this); + return new DefaultCoverage(sensorStorage); } @Override public TestCaseExecution newTestCaseExecution() { - return new DefaultTestCaseExecution(this); + return new DefaultTestCaseExecution(sensorStorage); } @Override public TestCaseCoverage newTestCaseCoverage() { - return new DefaultTestCaseCoverage(this); + return new DefaultTestCaseCoverage(sensorStorage); } @Override public Dependency newDependency() { - return new DefaultDependency(this); + return new DefaultDependency(sensorStorage); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java index a8d57e8088f..c1c3e2ba384 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java @@ -17,17 +17,15 @@ * 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.scan; +package org.sonar.batch.sensor; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.measure.Measure; @@ -58,33 +56,28 @@ import org.sonar.api.test.Testable; import org.sonar.batch.duplication.BlockCache; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; -import org.sonar.batch.scan2.BaseSensorContext; +import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import org.sonar.core.component.ComponentKeys; -/** - * Implements {@link SensorContext} but forward everything to {@link org.sonar.api.batch.SensorContext} for backward compatibility. - * Will be dropped once old {@link Sensor} API is dropped. - * - */ -public class SensorContextAdapter extends BaseSensorContext { +public class DefaultSensorStorage implements SensorStorage { private static final String USES = "USES"; - private final org.sonar.api.batch.SensorContext sensorContext; private final MetricFinder metricFinder; private final Project project; private final ResourcePerspectives perspectives; - private final SonarIndex sonarIndex; + private final DefaultIndex sonarIndex; + private final CoverageExclusions coverageExclusions; - public SensorContextAdapter(org.sonar.api.batch.SensorContext sensorContext, MetricFinder metricFinder, Project project, + public DefaultSensorStorage(MetricFinder metricFinder, Project project, ResourcePerspectives perspectives, Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, BlockCache blockCache, - DuplicationCache duplicationCache, SonarIndex sonarIndex) { - super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache); - this.sensorContext = sensorContext; + DuplicationCache duplicationCache, DefaultIndex sonarIndex, CoverageExclusions coverageExclusions) { this.metricFinder = metricFinder; this.project = project; this.perspectives = perspectives; this.sonarIndex = sonarIndex; + this.coverageExclusions = coverageExclusions; } private Metric findMetricOrFail(String metricKey) { @@ -109,9 +102,12 @@ public class SensorContextAdapter extends BaseSensorContext { && !Scopes.isHigherThanOrEquals(Scopes.FILE, ((SumChildDistributionFormula) formula).getMinimumScopeToPersist())) { measureToSave.setPersistenceMode(PersistenceMode.MEMORY); } - sensorContext.saveMeasure(newMeasure.inputFile(), measureToSave); + File sonarFile = getFile(newMeasure.inputFile()); + if (coverageExclusions.accept(sonarFile, measureToSave)) { + sonarIndex.addMeasure(sonarFile, measureToSave); + } } else { - sensorContext.saveMeasure(measureToSave); + sonarIndex.addMeasure(project, measureToSave); } } @@ -214,7 +210,7 @@ public class SensorContextAdapter extends BaseSensorContext { File testRes = File.create(testFile.relativePath()); testRes.setQualifier(Qualifiers.UNIT_TEST_FILE); // Reload - testRes = sensorContext.getResource(testRes); + testRes = sonarIndex.getResource(testRes); if (testRes == null) { throw new IllegalArgumentException("Provided input file is not indexed or not a test file: " + testFile); } @@ -224,7 +220,7 @@ public class SensorContextAdapter extends BaseSensorContext { private File getMainResource(InputFile mainFile) { File mainRes = File.create(mainFile.relativePath()); // Reload - mainRes = sensorContext.getResource(mainRes); + mainRes = sonarIndex.getResource(mainRes); if (mainRes == null) { throw new IllegalArgumentException("Provided input file is not indexed or not a main file: " + mainRes); } @@ -255,13 +251,12 @@ public class SensorContextAdapter extends BaseSensorContext { parentDep.setWeight(parentDep.getWeight() + 1); } else { parentDep = new Dependency(fromParent, toParent).setUsage(USES).setWeight(1); - parentDep = sensorContext.saveDependency(parentDep); + parentDep = sonarIndex.addDependency(parentDep); } } - sensorContext.saveDependency(new Dependency(fromResource, toResource) + sonarIndex.addDependency(new Dependency(fromResource, toResource) .setUsage(USES) .setWeight(dep.weight()) .setParent(parentDep)); } - } diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageConstants.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageConstants.java new file mode 100644 index 00000000000..46aa7173716 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageConstants.java @@ -0,0 +1,39 @@ +/* + * 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.sensor.coverage; + +import com.google.common.collect.ImmutableList; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; + +import java.util.Collection; + +public class CoverageConstants { + + public static final Collection<Metric> COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.LINES_TO_COVER, CoreMetrics.UNCOVERED_LINES, CoreMetrics.NEW_LINES_TO_COVER, + CoreMetrics.NEW_UNCOVERED_LINES, CoreMetrics.CONDITIONS_TO_COVER, CoreMetrics.UNCOVERED_CONDITIONS, + CoreMetrics.NEW_CONDITIONS_TO_COVER, CoreMetrics.NEW_UNCOVERED_CONDITIONS); + + public static final Collection<Metric> LINE_COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_LINES, CoreMetrics.LINES_TO_COVER, CoreMetrics.NEW_UNCOVERED_LINES, + CoreMetrics.NEW_LINES_TO_COVER); + + public static final Collection<Metric> BRANCH_COVERAGE_METRICS = ImmutableList.<Metric>of(CoreMetrics.UNCOVERED_CONDITIONS, CoreMetrics.CONDITIONS_TO_COVER, + CoreMetrics.NEW_UNCOVERED_CONDITIONS, CoreMetrics.NEW_CONDITIONS_TO_COVER); +} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageExclusions.java index e236c6298ed..1545c060d07 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/coverage/CoverageExclusions.java @@ -17,7 +17,7 @@ * 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.plugins.core.sensors; +package org.sonar.batch.sensor.coverage; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; @@ -27,41 +27,37 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Measure; import org.sonar.api.measures.Metric; import org.sonar.api.resources.Resource; import org.sonar.api.utils.WildcardPattern; -import org.sonar.core.measure.MeasurementFilter; import java.util.Collection; import java.util.Iterator; -public class CoverageMeasurementFilter implements MeasurementFilter { +public class CoverageExclusions { - private static final Logger LOG = LoggerFactory.getLogger(CoverageMeasurementFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(CoverageExclusions.class); private final Settings settings; private final ImmutableSet<Metric> coverageMetrics; private Collection<WildcardPattern> resourcePatterns; - public CoverageMeasurementFilter(Settings settings, - CoverageDecorator coverageDecorator, - LineCoverageDecorator lineCoverageDecorator, - BranchCoverageDecorator branchCoverageDecorator) { + public CoverageExclusions(Settings settings) { this.settings = settings; this.coverageMetrics = ImmutableSet.<Metric>builder() - .addAll(coverageDecorator.generatedMetrics()) - .addAll(coverageDecorator.usedMetrics()) - .addAll(lineCoverageDecorator.generatedMetrics()) - .addAll(lineCoverageDecorator.dependsUponMetrics()) - .addAll(branchCoverageDecorator.generatedMetrics()) - .addAll(branchCoverageDecorator.dependsUponMetrics()) + .add(CoreMetrics.COVERAGE) + .addAll(CoverageConstants.COVERAGE_METRICS) + .add(CoreMetrics.LINE_COVERAGE) + .addAll(CoverageConstants.LINE_COVERAGE_METRICS) + .add(CoreMetrics.BRANCH_COVERAGE) + .addAll(CoverageConstants.BRANCH_COVERAGE_METRICS) .build(); initPatterns(); } - @Override public boolean accept(Resource resource, Measure measure) { if (isCoverageMetric(measure.getMetric())) { return !hasMatchingPattern(resource); diff --git a/sonar-core/src/main/java/org/sonar/core/measure/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/package-info.java index 036a513e710..de8138fcecd 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/package-info.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/package-info.java @@ -17,8 +17,5 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -@ParametersAreNonnullByDefault -package org.sonar.core.measure; - -import javax.annotation.ParametersAreNonnullByDefault; - +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.sensor; diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java index b0c2e3076d6..1509a65ffea 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java @@ -22,10 +22,10 @@ package org.sonar.batch.bootstrap; import org.junit.Test; import org.sonar.api.BatchExtension; import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.batch.scan2.AnalyzerOptimizer; +import org.sonar.batch.sensor.DefaultSensorContext; import java.util.Collection; @@ -41,7 +41,7 @@ public class BatchExtensionDictionnaryTest { for (BatchExtension extension : extensions) { iocContainer.addSingleton(extension); } - return new BatchExtensionDictionnary(iocContainer, mock(SensorContext.class), mock(AnalyzerOptimizer.class)); + return new BatchExtensionDictionnary(iocContainer, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class)); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java index 6787ae5710f..f11c843c541 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java @@ -25,6 +25,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; +import org.sonar.api.measures.CoreMetrics; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.xoo.XooPlugin; @@ -92,10 +95,10 @@ public class MeasuresMediumTest { assertThat(result.measures()).hasSize(2); - // assertThat(result.measures()).contains(new DefaultMeasure<Integer>() - // .forMetric(CoreMetrics.LINES) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue(20)); + assertThat(result.measures()).contains(new DefaultMeasure<Integer>() + .forMetric(CoreMetrics.LINES) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue(20)); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java index b7aacbcd2d1..4a6e1a79cef 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java @@ -27,6 +27,9 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; +import org.sonar.api.measures.CoreMetrics; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.xoo.XooPlugin; @@ -80,15 +83,15 @@ public class ScmMediumTest { assertThat(result.measures()).hasSize(5); - // assertThat(result.measures()).contains(new DefaultMeasure<Integer>() - // .forMetric(CoreMetrics.LINES) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue(5)); - // - // assertThat(result.measures()).contains(new DefaultMeasure<String>() - // .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue("1=;2=julien;3=julien;4=julien;5=simon")); + assertThat(result.measures()).contains(new DefaultMeasure<Integer>() + .forMetric(CoreMetrics.LINES) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue(5)); + + assertThat(result.measures()).contains(new DefaultMeasure<String>() + .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue("1=;2=julien;3=julien;4=julien;5=simon")); } @Test @@ -136,15 +139,15 @@ public class ScmMediumTest { assertThat(result.measures()).hasSize(5); - // assertThat(result.measures()).contains(new DefaultMeasure<Integer>() - // .forMetric(CoreMetrics.LINES) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue(5)); - // - // assertThat(result.measures()).contains(new DefaultMeasure<String>() - // .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue("1=;2=julien;3=julien;4=julien;5=simon")); + assertThat(result.measures()).contains(new DefaultMeasure<Integer>() + .forMetric(CoreMetrics.LINES) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue(5)); + + assertThat(result.measures()).contains(new DefaultMeasure<String>() + .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue("1=;2=julien;3=julien;4=julien;5=simon")); } @Test @@ -167,15 +170,15 @@ public class ScmMediumTest { assertThat(result.measures()).hasSize(5); - // assertThat(result.measures()).contains(new DefaultMeasure<Integer>() - // .forMetric(CoreMetrics.LINES) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue(5)); - // - // assertThat(result.measures()).contains(new DefaultMeasure<String>() - // .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) - // .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) - // .withValue("1=;2=julien;3=julien;4=julien;5=simon")); + assertThat(result.measures()).contains(new DefaultMeasure<Integer>() + .forMetric(CoreMetrics.LINES) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue(5)); + + assertThat(result.measures()).contains(new DefaultMeasure<String>() + .forMetric(CoreMetrics.SCM_AUTHORS_BY_LINE) + .onFile(new DefaultInputFile("com.foo.project", "src/sample.xoo")) + .withValue("1=;2=julien;3=julien;4=julien;5=simon")); } private File prepareProject() throws IOException { diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java index 1fd1c4e081c..3f471711146 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/DecoratorsExecutorTest.java @@ -33,7 +33,7 @@ import org.sonar.batch.DefaultDecoratorContext; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.events.EventBus; import org.sonar.batch.scan.measure.MeasureCache; -import org.sonar.core.measure.MeasurementFilters; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -67,7 +67,7 @@ public class DecoratorsExecutorTest { doThrow(new SonarException()).when(decorator).decorate(any(Resource.class), any(DecoratorContext.class)); DecoratorsExecutor executor = new DecoratorsExecutor(mock(BatchExtensionDictionnary.class), new Project("key"), mock(SonarIndex.class), - mock(EventBus.class), mock(MeasurementFilters.class), mock(MeasureCache.class), mock(MetricFinder.class), mock(DuplicationCache.class)); + mock(EventBus.class), mock(CoverageExclusions.class), mock(MeasureCache.class), mock(MetricFinder.class), mock(DuplicationCache.class)); try { executor.executeDecorator(decorator, mock(DefaultDecoratorContext.class), File.create("src/org/foo/Bar.java", "org/foo/Bar.java", null, false)); fail("Exception has not been thrown"); diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java new file mode 100644 index 00000000000..b51dccd8f05 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java @@ -0,0 +1,76 @@ +/* + * 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.sensor; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.measure.MetricFinder; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.sensor.SensorStorage; +import org.sonar.api.config.Settings; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.batch.duplication.BlockCache; +import org.sonar.batch.duplication.DuplicationCache; +import org.sonar.batch.index.ComponentDataCache; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultSensorContextTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private ActiveRules activeRules; + private DefaultFileSystem fs; + private DefaultSensorContext adaptor; + private Settings settings; + private SensorStorage sensorStorage; + + @Before + public void prepare() { + activeRules = new ActiveRulesBuilder().build(); + fs = new DefaultFileSystem(); + MetricFinder metricFinder = mock(MetricFinder.class); + when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC); + when(metricFinder.findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION); + settings = new Settings(); + ComponentDataCache componentDataCache = mock(ComponentDataCache.class); + BlockCache blockCache = mock(BlockCache.class); + sensorStorage = mock(SensorStorage.class); + adaptor = new DefaultSensorContext(settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), sensorStorage); + } + + @Test + public void shouldProvideComponents() { + assertThat(adaptor.activeRules()).isEqualTo(activeRules); + assertThat(adaptor.fileSystem()).isEqualTo(fs); + assertThat(adaptor.settings()).isEqualTo(settings); + + assertThat(adaptor.newIssue()).isNotNull(); + assertThat(adaptor.newMeasure()).isNotNull(); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java index a5610c66aa2..c977124e861 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java @@ -17,15 +17,13 @@ * 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.scan; +package org.sonar.batch.sensor; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.fs.InputDir; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; @@ -45,6 +43,7 @@ import org.sonar.api.design.Dependency; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; import org.sonar.api.measures.PersistenceMode; import org.sonar.api.resources.Directory; import org.sonar.api.resources.File; @@ -54,27 +53,29 @@ import org.sonar.api.rule.RuleKey; import org.sonar.batch.duplication.BlockCache; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.index.ComponentDataCache; +import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.sensor.coverage.CoverageExclusions; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -public class SensorContextAdapterTest { +public class DefaultSensorStorageTest { @Rule public ExpectedException thrown = ExpectedException.none(); private ActiveRules activeRules; private DefaultFileSystem fs; - private SensorContextAdapter adaptor; - private SensorContext sensorContext; + private DefaultSensorStorage sensorStorage; private Settings settings; private ResourcePerspectives resourcePerspectives; private Project project; - private SonarIndex sonarIndex; + private DefaultIndex sonarIndex; @Before public void prepare() { @@ -83,25 +84,16 @@ public class SensorContextAdapterTest { MetricFinder metricFinder = mock(MetricFinder.class); when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC); when(metricFinder.findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION); - sensorContext = mock(SensorContext.class); settings = new Settings(); resourcePerspectives = mock(ResourcePerspectives.class); ComponentDataCache componentDataCache = mock(ComponentDataCache.class); BlockCache blockCache = mock(BlockCache.class); project = new Project("myProject"); - sonarIndex = mock(SonarIndex.class); - adaptor = new SensorContextAdapter(sensorContext, metricFinder, project, - resourcePerspectives, settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), sonarIndex); - } - - @Test - public void shouldProvideComponents() { - assertThat(adaptor.activeRules()).isEqualTo(activeRules); - assertThat(adaptor.fileSystem()).isEqualTo(fs); - assertThat(adaptor.settings()).isEqualTo(settings); - - assertThat(adaptor.newIssue()).isNotNull(); - assertThat(adaptor.newMeasure()).isNotNull(); + sonarIndex = mock(DefaultIndex.class); + CoverageExclusions coverageExclusions = mock(CoverageExclusions.class); + when(coverageExclusions.accept(any(Resource.class), any(Measure.class))).thenReturn(true); + sensorStorage = new DefaultSensorStorage(metricFinder, project, + resourcePerspectives, settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), sonarIndex, coverageExclusions); } @Test @@ -111,7 +103,7 @@ public class SensorContextAdapterTest { thrown.expect(IllegalStateException.class); thrown.expectMessage("Unknow metric with key: lines"); - adaptor.store(new DefaultMeasure() + sensorStorage.store(new DefaultMeasure() .onFile(file) .forMetric(CoreMetrics.LINES) .withValue(10)); @@ -122,9 +114,10 @@ public class SensorContextAdapterTest { InputFile file = new DefaultInputFile("foo", "src/Foo.php"); ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class); - when(sensorContext.saveMeasure(eq(file), argumentCaptor.capture())).thenReturn(null); - - adaptor.store(new DefaultMeasure() + File sonarFile = File.create("src/Foo.php"); + when(sonarIndex.addMeasure(eq(sonarFile), argumentCaptor.capture())).thenReturn(null); + when(sonarIndex.getResource(sonarFile)).thenReturn(sonarFile); + sensorStorage.store(new DefaultMeasure() .onFile(file) .forMetric(CoreMetrics.NCLOC) .withValue(10)); @@ -141,9 +134,13 @@ public class SensorContextAdapterTest { InputFile file = new DefaultInputFile("foo", "src/Foo.php"); ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class); - when(sensorContext.saveMeasure(eq(file), argumentCaptor.capture())).thenReturn(null); + File sonarFile = File.create("src/Foo.php"); + + when(sonarIndex.addMeasure(eq(sonarFile), argumentCaptor.capture())).thenReturn(null); + + when(sonarIndex.getResource(sonarFile)).thenReturn(sonarFile); - adaptor.store(new DefaultMeasure() + sensorStorage.store(new DefaultMeasure() .onFile(file) .forMetric(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION) .withValue("foo")); @@ -159,9 +156,9 @@ public class SensorContextAdapterTest { public void shouldSaveProjectMeasureToSensorContext() { ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class); - when(sensorContext.saveMeasure(argumentCaptor.capture())).thenReturn(null); + when(sonarIndex.addMeasure(eq(project), argumentCaptor.capture())).thenReturn(null); - adaptor.store(new DefaultMeasure() + sensorStorage.store(new DefaultMeasure() .onProject() .forMetric(CoreMetrics.NCLOC) .withValue(10)); @@ -182,7 +179,7 @@ public class SensorContextAdapterTest { when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true); - adaptor.store(new DefaultIssue() + sensorStorage.store(new DefaultIssue() .onFile(file) .ruleKey(RuleKey.of("foo", "bar")) .message("Foo") @@ -208,7 +205,7 @@ public class SensorContextAdapterTest { when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true); - adaptor.store(new DefaultIssue() + sensorStorage.store(new DefaultIssue() .onDir(dir) .ruleKey(RuleKey.of("foo", "bar")) .message("Foo") @@ -231,7 +228,7 @@ public class SensorContextAdapterTest { when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true); - adaptor.store(new DefaultIssue() + sensorStorage.store(new DefaultIssue() .onProject() .ruleKey(RuleKey.of("foo", "bar")) .message("Foo") @@ -251,17 +248,17 @@ public class SensorContextAdapterTest { File foo = File.create("src/Foo.java"); File bar = File.create("src/Bar.java"); - when(sensorContext.getResource(foo)).thenReturn(foo); - when(sensorContext.getResource(bar)).thenReturn(bar); + when(sonarIndex.getResource(foo)).thenReturn(foo); + when(sonarIndex.getResource(bar)).thenReturn(bar); - adaptor.store(new DefaultDependency() + sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) .to(new DefaultInputFile("foo", "src/Bar.java").setType(Type.MAIN)) .weight(3)); ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); - verify(sensorContext).saveDependency(argumentCaptor.capture()); + verify(sonarIndex).addDependency(argumentCaptor.capture()); assertThat(argumentCaptor.getValue().getFrom()).isEqualTo(foo); assertThat(argumentCaptor.getValue().getTo()).isEqualTo(bar); assertThat(argumentCaptor.getValue().getWeight()).isEqualTo(3); @@ -273,14 +270,14 @@ public class SensorContextAdapterTest { File foo = File.create("src/Foo.java"); File bar = File.create("src/Bar.java"); - when(sensorContext.getResource(foo)).thenReturn(foo); - when(sensorContext.getResource(bar)).thenReturn(bar); + when(sonarIndex.getResource(foo)).thenReturn(foo); + when(sonarIndex.getResource(bar)).thenReturn(bar); when(sonarIndex.getEdge(foo, bar)).thenReturn(new Dependency(foo, bar)); thrown.expect(IllegalStateException.class); thrown.expectMessage("Dependency between [moduleKey=foo, relative=src/Foo.java, abs=null] and [moduleKey=foo, relative=src/Bar.java, abs=null] was already saved."); - adaptor.store(new DefaultDependency() + sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN)) .to(new DefaultInputFile("foo", "src/Bar.java").setType(Type.MAIN)) .weight(3)); @@ -291,17 +288,17 @@ public class SensorContextAdapterTest { File foo = File.create("src1/Foo.java"); File bar = File.create("src2/Bar.java"); - when(sensorContext.getResource(foo)).thenReturn(foo); - when(sensorContext.getResource(bar)).thenReturn(bar); + when(sonarIndex.getResource(foo)).thenReturn(foo); + when(sonarIndex.getResource(bar)).thenReturn(bar); - adaptor.store(new DefaultDependency() + sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src1/Foo.java").setType(Type.MAIN)) .to(new DefaultInputFile("foo", "src2/Bar.java").setType(Type.MAIN)) .weight(3)); ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); - verify(sensorContext, times(2)).saveDependency(argumentCaptor.capture()); + verify(sonarIndex, times(2)).addDependency(argumentCaptor.capture()); assertThat(argumentCaptor.getAllValues()).hasSize(2); Dependency value1 = argumentCaptor.getAllValues().get(0); assertThat(value1.getFrom()).isEqualTo(Directory.create("src1")); @@ -323,19 +320,19 @@ public class SensorContextAdapterTest { File bar = File.create("src2/Bar.java"); Directory src1 = Directory.create("src1"); Directory src2 = Directory.create("src2"); - when(sensorContext.getResource(foo)).thenReturn(foo); - when(sensorContext.getResource(bar)).thenReturn(bar); + when(sonarIndex.getResource(foo)).thenReturn(foo); + when(sonarIndex.getResource(bar)).thenReturn(bar); Dependency parentDep = new Dependency(src1, src2).setWeight(4); when(sonarIndex.getEdge(src1, src2)).thenReturn(parentDep); - adaptor.store(new DefaultDependency() + sensorStorage.store(new DefaultDependency() .from(new DefaultInputFile("foo", "src1/Foo.java").setType(Type.MAIN)) .to(new DefaultInputFile("foo", "src2/Bar.java").setType(Type.MAIN)) .weight(3)); ArgumentCaptor<Dependency> argumentCaptor = ArgumentCaptor.forClass(Dependency.class); - verify(sensorContext).saveDependency(argumentCaptor.capture()); + verify(sonarIndex).addDependency(argumentCaptor.capture()); assertThat(parentDep.getWeight()).isEqualTo(5); diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/coverage/CoverageExclusionsTest.java index 85ca73d04bf..ec592a7962e 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/CoverageMeasurementFilterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/coverage/CoverageExclusionsTest.java @@ -17,7 +17,7 @@ * 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.plugins.core.sensors; +package org.sonar.batch.sensor.coverage; import org.junit.Before; import org.junit.Test; @@ -33,16 +33,16 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class CoverageMeasurementFilterTest { +public class CoverageExclusionsTest { private Settings settings; - private CoverageMeasurementFilter filter; + private CoverageExclusions filter; @Before public void createFilter() { settings = new Settings(new PropertyDefinitions(ExclusionProperties.all())); - filter = new CoverageMeasurementFilter(settings, new CoverageDecorator(), new LineCoverageDecorator(), new BranchCoverageDecorator()); + filter = new CoverageExclusions(settings); } @Test diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasurementFilters.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasurementFilters.java deleted file mode 100644 index fa69974571d..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasurementFilters.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.core.measure; - -import com.google.common.collect.ImmutableList; -import org.sonar.api.BatchExtension; -import org.sonar.api.measures.Measure; -import org.sonar.api.resources.Resource; - -import java.util.Iterator; -import java.util.List; - -/** - * - * @since 4.0 - * - */ -public class MeasurementFilters implements BatchExtension { - - private List<MeasurementFilter> filters; - - public MeasurementFilters() { - this.filters = ImmutableList.of(); - } - - public MeasurementFilters(MeasurementFilter[] filters) { - this.filters = ImmutableList.copyOf(filters); - } - - public boolean accept(Resource resource, Measure measure) { - boolean accept = true; - Iterator<MeasurementFilter> iteratorFilter = filters.iterator(); - while(accept && iteratorFilter.hasNext()) { - accept &= iteratorFilter.next().accept(resource, measure); - } - return accept; - } -} diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasurementFiltersTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasurementFiltersTest.java deleted file mode 100644 index cc0f1022f84..00000000000 --- a/sonar-core/src/test/java/org/sonar/core/measure/MeasurementFiltersTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.core.measure; - -import org.assertj.core.util.Arrays; -import org.junit.Test; -import org.sonar.api.measures.Measure; -import org.sonar.api.resources.Resource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.*; - -public class MeasurementFiltersTest { - - private MeasurementFilters filters; - - @Test - public void shouldAcceptEverythingWithEmptyFilters() { - filters = new MeasurementFilters(); - Resource resource = mock(Resource.class); - Measure measure = mock(Measure.class); - assertThat(filters.accept(resource, measure)).isTrue(); - } - - @Test - public void shouldAcceptIfAllFiltersAccept() { - Resource resource = mock(Resource.class); - Measure measure = mock(Measure.class); - MeasurementFilter filter1 = mock(MeasurementFilter.class); - when(filter1.accept(resource, measure)).thenReturn(true); - MeasurementFilter filter2 = mock(MeasurementFilter.class); - when(filter2.accept(resource, measure)).thenReturn(true); - - filters = new MeasurementFilters(Arrays.array(filter1, filter2)); - assertThat(filters.accept(resource, measure)).isTrue(); - } - - @Test - public void shouldNnotAcceptIfOneFilterDoesntAccept() { - Resource resource = mock(Resource.class); - Measure measure = mock(Measure.class); - MeasurementFilter filter1 = mock(MeasurementFilter.class); - when(filter1.accept(resource, measure)).thenReturn(false); - MeasurementFilter filter2 = mock(MeasurementFilter.class); - - filters = new MeasurementFilters(Arrays.array(filter1, filter2)); - assertThat(filters.accept(resource, measure)).isFalse(); - verifyZeroInteractions(filter2); - } -} diff --git a/sonar-deprecated/src/main/java/org/sonar/api/checks/NoSonarFilter.java b/sonar-deprecated/src/main/java/org/sonar/api/checks/NoSonarFilter.java index 7626ce1e018..16aa183e3a5 100644 --- a/sonar-deprecated/src/main/java/org/sonar/api/checks/NoSonarFilter.java +++ b/sonar-deprecated/src/main/java/org/sonar/api/checks/NoSonarFilter.java @@ -21,7 +21,7 @@ package org.sonar.api.checks; import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; -import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.SonarIndex; import org.sonar.api.issue.Issue; import org.sonar.api.issue.batch.IssueFilterChain; import org.sonar.api.resources.Resource; @@ -37,16 +37,16 @@ import java.util.Set; public class NoSonarFilter implements org.sonar.api.issue.batch.IssueFilter { private final Map<String, Set<Integer>> noSonarLinesByKey = Maps.newHashMap(); - private SensorContext context; + private SonarIndex sonarIndex; - public NoSonarFilter(SensorContext context) { - this.context = context; + public NoSonarFilter(SonarIndex sonarIndex) { + this.sonarIndex = sonarIndex; } public void addResource(Resource model, Set<Integer> noSonarLines) { if (model != null && noSonarLines != null) { // Reload resource to handle backward compatibility of resource keys - Resource resource = context.getResource(model); + Resource resource = sonarIndex.getResource(model); if (resource != null) { noSonarLinesByKey.put(resource.getEffectiveKey(), noSonarLines); } diff --git a/sonar-deprecated/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java b/sonar-deprecated/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java index 5be33366643..1521ca67b52 100644 --- a/sonar-deprecated/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java +++ b/sonar-deprecated/src/test/java/org/sonar/api/checks/NoSonarFilterTest.java @@ -21,7 +21,7 @@ package org.sonar.api.checks; import org.junit.Before; import org.junit.Test; -import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.SonarIndex; import org.sonar.api.issue.Issue; import org.sonar.api.issue.batch.IssueFilterChain; import org.sonar.api.resources.File; @@ -37,8 +37,8 @@ import static org.mockito.Mockito.when; public class NoSonarFilterTest { - private SensorContext sensorContext = mock(SensorContext.class); - NoSonarFilter filter = new NoSonarFilter(sensorContext); + private SonarIndex sonarIndex = mock(SonarIndex.class); + NoSonarFilter filter = new NoSonarFilter(sonarIndex); private File javaFile; IssueFilterChain chain = mock(IssueFilterChain.class); @@ -47,7 +47,7 @@ public class NoSonarFilterTest { when(chain.accept(isA(Issue.class))).thenReturn(true); javaFile = new File("org.foo.Bar"); javaFile.setEffectiveKey("struts:org.apache.Action"); - when(sensorContext.getResource(javaFile)).thenReturn(javaFile); + when(sonarIndex.getResource(javaFile)).thenReturn(javaFile); } @Test diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java index a21d421e6ac..b75209e1538 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/SensorContext.java @@ -40,7 +40,7 @@ import java.util.Set; /** * @since 1.10 */ -public interface SensorContext { +public interface SensorContext extends org.sonar.api.batch.sensor.SensorContext { /** * Indexes a resource as a direct child of project. This method does nothing and returns true if the resource already indexed. diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/DependsUponMavenPlugin.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/DependsUponMavenPlugin.java index 0e590c84593..e83df0c84e6 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/DependsUponMavenPlugin.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/maven/DependsUponMavenPlugin.java @@ -33,7 +33,9 @@ import org.sonar.api.resources.Project; * </p> * * @since 1.10 + * @deprecated since 5.1 SQ platform don't want any dependency on Maven */ +@Deprecated @SupportedEnvironment("maven") public interface DependsUponMavenPlugin extends BatchExtension { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java index a0be6e447ab..01f0e109e53 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java @@ -31,7 +31,7 @@ import org.sonar.api.BatchExtension; * For example the Cobertura Sensor parses Cobertura report and saves the first-level of measures on files. * </p> * - * @since 5.0 + * @since 5.1 */ public interface Sensor extends BatchExtension { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index 805d9db2417..b32be9c7ab0 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -29,6 +29,7 @@ import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder; import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder; import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.measure.Measure; +import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder; import org.sonar.api.batch.sensor.test.Coverage; import org.sonar.api.batch.sensor.test.TestCaseCoverage; @@ -40,7 +41,7 @@ import java.util.List; /** * See {@link Sensor#execute(SensorContext)} - * @since 5.0 + * @since 5.1 */ public interface SensorContext { @@ -62,9 +63,9 @@ public interface SensorContext { // ----------- MEASURES -------------- /** - * Fluent builder to create a new {@link Measure}. Don't forget to call {@link Measure#save()} once all parameters are provided. + * Fluent builder to create a new {@link Measure}. Don't forget to call {@link NewMeasure#save()} once all parameters are provided. */ - <G extends Serializable> Measure<G> newMeasure(); + <G extends Serializable> NewMeasure<G> newMeasure(); // ----------- ISSUES -------------- diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java index 86a0abdffad..c59f7a7be76 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java @@ -27,22 +27,13 @@ import javax.annotation.CheckForNull; import java.io.Serializable; /** - * Builder to create new Measure. - * @since 5.0 + * Measure on File, Directory or Project. + * Should not be implemented by client. + * @since 5.1 */ public interface Measure<G extends Serializable> { /** - * The file the measure belongs to. - */ - Measure<G> onFile(InputFile file); - - /** - * Tell that the measure is global to the project. - */ - Measure<G> onProject(); - - /** * The file the measure belong to. * @return null if measure is on project */ @@ -50,11 +41,6 @@ public interface Measure<G extends Serializable> { InputFile inputFile(); /** - * Set the metric this measure belong to. - */ - Measure<G> forMetric(Metric<G> metric); - - /** * The metric this measure belong to. */ Metric<G> metric(); @@ -62,16 +48,6 @@ public interface Measure<G extends Serializable> { /** * Value of the measure. */ - Measure<G> withValue(G value); - - /** - * Value of the measure. - */ G value(); - /** - * Save the measure. It is not permitted so save several measures of the same metric on the same file/project. - */ - void save(); - } diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasurementFilter.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/NewMeasure.java index 324c7e4c1ca..cf8bccba48b 100644 --- a/sonar-core/src/main/java/org/sonar/core/measure/MeasurementFilter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/NewMeasure.java @@ -17,25 +17,43 @@ * 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.core.measure; +package org.sonar.api.batch.sensor.measure; -import org.sonar.api.BatchExtension; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.measure.Metric; -import org.sonar.api.resources.Resource; -import org.sonar.api.measures.Measure; +import java.io.Serializable; /** - * Allows to define filter {@link Measure}s when they are saved on {@link Resource}s - * @since 4.0 - * + * Builder to create new Measure. + * Should not be implemented by client. + * @since 5.1 */ -public interface MeasurementFilter extends BatchExtension { +public interface NewMeasure<G extends Serializable> { + + /** + * The file the measure belongs to. + */ + NewMeasure<G> onFile(InputFile file); + + /** + * Tell that the measure is global to the project. + */ + NewMeasure<G> onProject(); /** - * - * @param resource - * @param measure - * @return <code>true</code> if the given measure can be saved for the given resource + * Set the metric this measure belong to. */ - boolean accept(Resource resource, Measure measure); + NewMeasure<G> forMetric(Metric<G> metric); + + /** + * Value of the measure. + */ + NewMeasure<G> withValue(G value); + + /** + * Save the measure. It is not permitted so save several measures of the same metric on the same file/project. + */ + void save(); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java index 167f9e6af98..a6e4a0021fa 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java @@ -27,13 +27,14 @@ import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.sensor.SensorStorage; import org.sonar.api.batch.sensor.internal.DefaultStorable; import org.sonar.api.batch.sensor.measure.Measure; +import org.sonar.api.batch.sensor.measure.NewMeasure; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import java.io.Serializable; -public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G> { +public class DefaultMeasure<G extends Serializable> extends DefaultStorable implements Measure<G>, NewMeasure<G> { private boolean onProject = false; private InputFile file; @@ -102,7 +103,7 @@ public class DefaultMeasure<G extends Serializable> extends DefaultStorable impl Preconditions.checkNotNull(this.value, "Measure value can't be null"); Preconditions.checkNotNull(this.metric, "Measure metric can't be null"); Preconditions.checkState(this.metric.valueType().equals(this.value.getClass()), "Measure value should be of type " + this.metric.valueType()); - storage.store((Measure<Serializable>) this); + storage.store(this); } @Override diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MetricFinder.java b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MetricFinder.java index c6f68aaedce..bb89c172a07 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/measures/MetricFinder.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/measures/MetricFinder.java @@ -29,7 +29,9 @@ import java.util.List; /** * @since 2.5 + * @deprecated since 5.1 use {@link org.sonar.api.batch.measure.MetricFinder} on batch side */ +@Deprecated public interface MetricFinder extends TaskComponent, ServerComponent { @CheckForNull |