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;
OverallLineCoverageDecorator.class,
OverallCoverageDecorator.class,
OverallBranchCoverageDecorator.class,
- CoverageMeasurementFilter.class,
ApplyProjectRolesDecorator.class,
CommentDensityDecorator.class,
DirectoriesDecorator.class,
*/
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
*/
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
+++ /dev/null
-/*
- * 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.plugins.core.sensors;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import com.google.common.collect.ImmutableSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Settings;
-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 {
-
- private static final Logger LOG = LoggerFactory.getLogger(CoverageMeasurementFilter.class);
-
- private final Settings settings;
- private final ImmutableSet<Metric> coverageMetrics;
- private Collection<WildcardPattern> resourcePatterns;
-
- public CoverageMeasurementFilter(Settings settings,
- CoverageDecorator coverageDecorator,
- LineCoverageDecorator lineCoverageDecorator,
- BranchCoverageDecorator branchCoverageDecorator) {
- 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())
- .build();
-
- initPatterns();
- }
-
- @Override
- public boolean accept(Resource resource, Measure measure) {
- if (isCoverageMetric(measure.getMetric())) {
- return !hasMatchingPattern(resource);
- } else {
- return true;
- }
- }
-
- private boolean isCoverageMetric(Metric metric) {
- return this.coverageMetrics.contains(metric);
- }
-
- private boolean hasMatchingPattern(Resource resource) {
- boolean found = false;
- Iterator<WildcardPattern> iterator = resourcePatterns.iterator();
- while (!found && iterator.hasNext()) {
- found = resource.matchFilePattern(iterator.next().toString());
- }
- return found;
- }
-
- @VisibleForTesting
- final void initPatterns() {
- Builder<WildcardPattern> builder = ImmutableList.builder();
- for (String pattern : settings.getStringArray(CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY)) {
- builder.add(WildcardPattern.create(pattern));
- }
- resourcePatterns = builder.build();
- log("Excluded sources for coverage: ", resourcePatterns);
- }
-
- private void log(String title, Collection<WildcardPattern> patterns) {
- if (!patterns.isEmpty()) {
- LOG.info(title);
- for (WildcardPattern pattern : patterns) {
- LOG.info(" " + pattern);
- }
- }
- }
-}
*/
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
+++ /dev/null
-/*
- * 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.plugins.core.sensors;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Resource;
-import org.sonar.core.config.ExclusionProperties;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class CoverageMeasurementFilterTest {
-
- private Settings settings;
-
- private CoverageMeasurementFilter filter;
-
- @Before
- public void createFilter() {
- settings = new Settings(new PropertyDefinitions(ExclusionProperties.all()));
- filter = new CoverageMeasurementFilter(settings, new CoverageDecorator(), new LineCoverageDecorator(), new BranchCoverageDecorator());
- }
-
- @Test
- public void shouldNotFilterNonCoverageMetrics() {
- Measure otherMeasure = mock(Measure.class);
- when(otherMeasure.getMetric()).thenReturn(CoreMetrics.LINES);
- assertThat(filter.accept(mock(Resource.class), otherMeasure)).isTrue();
- }
-
- @Test
- public void shouldFilterFileBasedOnPattern() {
- Resource resource = File.create("src/org/polop/File.php", "org/polop/File.php", null, false);
- Measure coverageMeasure = mock(Measure.class);
- when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.LINES_TO_COVER);
-
- settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*");
- filter.initPatterns();
- assertThat(filter.accept(resource, coverageMeasure)).isFalse();
- }
-
- @Test
- public void shouldNotFilterFileBasedOnPattern() {
- Resource resource = File.create("src/org/polop/File.php", "org/polop/File.php", null, false);
- Measure coverageMeasure = mock(Measure.class);
- when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.COVERAGE);
-
- settings.setProperty("sonar.coverage.exclusions", "src/org/other/*");
- filter.initPatterns();
- assertThat(filter.accept(resource, coverageMeasure)).isTrue();
- }
-}
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;
@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
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;
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())) {
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
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
public void describe(SensorDescriptor descriptor) {
descriptor
.name("Xoo Highlighting Sensor")
- .onlyOnLanguages(Xoo.KEY)
- .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST);
+ .onlyOnLanguages(Xoo.KEY);
}
@Override
descriptor
.name("CreateIssueByInternalKeySensor")
.onlyOnLanguages(Xoo.KEY)
- .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY)
- .onOnFileType(InputFile.Type.MAIN, InputFile.Type.TEST);
+ .createIssuesForRuleRepositories(XooRulesDefinition.XOO_REPOSITORY);
}
@Override
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
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;
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
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;
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;
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() {
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;
+++ /dev/null
-/*
- * 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;
-
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-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.InputDir;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.InputPath;
-import org.sonar.api.design.Dependency;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilter;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.ProjectLink;
-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 java.io.Serializable;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-public class DefaultSensorContext implements SensorContext {
-
- private static final Logger LOG = LoggerFactory.getLogger(DefaultSensorContext.class);
-
- private SonarIndex index;
- private Project project;
- private MeasurementFilters filters;
-
- public DefaultSensorContext(SonarIndex index, Project project, MeasurementFilters filters) {
- this.index = index;
- this.project = project;
- this.filters = filters;
- }
-
- public Project getProject() {
- return project;
- }
-
- @Override
- public boolean index(Resource resource) {
- // SONAR-5006
- if (indexedByCore(resource)) {
- logWarning();
- return true;
- }
- return index.index(resource);
- }
-
- private boolean indexedByCore(Resource resource) {
- return StringUtils.equals(Qualifiers.DIRECTORY, resource.getQualifier()) ||
- StringUtils.equals(Qualifiers.FILE, resource.getQualifier());
- }
-
- @Override
- public boolean index(Resource resource, Resource parentReference) {
- // SONAR-5006
- if (indexedByCore(resource)) {
- logWarning();
- return true;
- }
- return index.index(resource, parentReference);
- }
-
- private void logWarning() {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Plugins are no more responsible for indexing physical resources like directories and files. This is now handled by the platform.", new SonarException(
- "Plugin should not index physical resources"));
- }
- }
-
- @Override
- public boolean isExcluded(Resource reference) {
- return index.isExcluded(reference);
- }
-
- @Override
- public boolean isIndexed(Resource reference, boolean acceptExcluded) {
- return index.isIndexed(reference, acceptExcluded);
- }
-
- @Override
- public Resource getParent(Resource reference) {
- return index.getParent(reference);
- }
-
- @Override
- public Collection<Resource> getChildren(Resource reference) {
- return index.getChildren(reference);
- }
-
- @Override
- public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) {
- return index.getMeasure(project, metric);
- }
-
- @Override
- public <M> M getMeasures(MeasuresFilter<M> filter) {
- return index.getMeasures(project, filter);
- }
-
- @Override
- public Measure saveMeasure(Measure measure) {
- return index.addMeasure(project, measure);
- }
-
- @Override
- public Measure saveMeasure(Metric metric, Double value) {
- return index.addMeasure(project, new Measure(metric, value));
- }
-
- @Override
- public <G extends Serializable> Measure<G> getMeasure(Resource resource, Metric<G> metric) {
- return index.getMeasure(resource, metric);
- }
-
- @Override
- public String saveResource(Resource resource) {
- Resource persistedResource = index.addResource(resource);
- if (persistedResource != null) {
- return persistedResource.getEffectiveKey();
- }
- return null;
- }
-
- public boolean saveResource(Resource resource, Resource parentReference) {
- return index.index(resource, parentReference);
- }
-
- @Override
- public Resource getResource(Resource resource) {
- return index.getResource(resource);
- }
-
- @Override
- public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
- return index.getMeasures(resource, filter);
- }
-
- @Override
- public Measure saveMeasure(Resource resource, Metric metric, Double value) {
- return saveMeasure(resource, new Measure(metric, value));
- }
-
- @Override
- public Measure saveMeasure(Resource resource, Measure measure) {
- if (filters.accept(resource, measure)) {
- return index.addMeasure(resourceOrProject(resource), measure);
- } else {
- return measure;
- }
- }
-
- @Override
- public void saveViolation(Violation violation, boolean force) {
- if (violation.getResource() == null) {
- violation.setResource(resourceOrProject(violation.getResource()));
- }
- index.addViolation(violation, force);
- }
-
- @Override
- public void saveViolation(Violation violation) {
- saveViolation(violation, false);
- }
-
- @Override
- public void saveViolations(Collection<Violation> violations) {
- if (violations != null) {
- for (Violation violation : violations) {
- saveViolation(violation);
- }
- }
- }
-
- @Override
- public Dependency saveDependency(Dependency dependency) {
- return index.addDependency(dependency);
- }
-
- @Override
- public Set<Dependency> getDependencies() {
- return index.getDependencies();
- }
-
- @Override
- public Collection<Dependency> getIncomingDependencies(Resource to) {
- return index.getIncomingEdges(resourceOrProject(to));
- }
-
- @Override
- public Collection<Dependency> getOutgoingDependencies(Resource from) {
- return index.getOutgoingEdges(resourceOrProject(from));
- }
-
- @Override
- public void saveSource(Resource reference, String source) {
- // useless since 4.2.
- }
-
- @Override
- public void saveLink(ProjectLink link) {
- index.addLink(link);
- }
-
- @Override
- public void deleteLink(String key) {
- index.deleteLink(key);
- }
-
- @Override
- public List<Event> getEvents(Resource resource) {
- return index.getEvents(resource);
- }
-
- @Override
- public Event createEvent(Resource resource, String name, String description, String category, Date date) {
- return index.addEvent(resource, name, description, category, date);
- }
-
- @Override
- public void deleteEvent(Event event) {
- index.deleteEvent(event);
- }
-
- private Resource resourceOrProject(Resource resource) {
- if (resource == null) {
- return project;
- }
- Resource indexedResource = getResource(resource);
- return indexedResource != null ? indexedResource : resource;
- }
-
- @Override
- public Measure saveMeasure(InputFile inputFile, Metric metric, Double value) {
- return saveMeasure(getResource(inputFile), metric, value);
- }
-
- @Override
- public Measure saveMeasure(InputFile inputFile, Measure measure) {
- return saveMeasure(getResource(inputFile), measure);
- }
-
- @Override
- public Resource getResource(InputPath inputPath) {
- Resource r;
- if (inputPath instanceof InputDir) {
- r = Directory.create(((InputDir) inputPath).relativePath());
- } else if (inputPath instanceof InputFile) {
- r = File.create(((InputFile) inputPath).relativePath());
- } else {
- throw new IllegalArgumentException("Unknow input path type: " + inputPath);
- }
- return getResource(r);
- }
-}
--- /dev/null
+/*
+ * 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;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+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;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ProjectLink;
+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.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;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeprecatedSensorContext.class);
+
+ private final SonarIndex index;
+ private final Project project;
+ private final CoverageExclusions coverageFilter;
+
+ 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.coverageFilter = coverageFilter;
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ @Override
+ public boolean index(Resource resource) {
+ // SONAR-5006
+ if (indexedByCore(resource)) {
+ logWarning();
+ return true;
+ }
+ return index.index(resource);
+ }
+
+ private boolean indexedByCore(Resource resource) {
+ return StringUtils.equals(Qualifiers.DIRECTORY, resource.getQualifier()) ||
+ StringUtils.equals(Qualifiers.FILE, resource.getQualifier());
+ }
+
+ @Override
+ public boolean index(Resource resource, Resource parentReference) {
+ // SONAR-5006
+ if (indexedByCore(resource)) {
+ logWarning();
+ return true;
+ }
+ return index.index(resource, parentReference);
+ }
+
+ private void logWarning() {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Plugins are no more responsible for indexing physical resources like directories and files. This is now handled by the platform.", new SonarException(
+ "Plugin should not index physical resources"));
+ }
+ }
+
+ @Override
+ public boolean isExcluded(Resource reference) {
+ return index.isExcluded(reference);
+ }
+
+ @Override
+ public boolean isIndexed(Resource reference, boolean acceptExcluded) {
+ return index.isIndexed(reference, acceptExcluded);
+ }
+
+ @Override
+ public Resource getParent(Resource reference) {
+ return index.getParent(reference);
+ }
+
+ @Override
+ public Collection<Resource> getChildren(Resource reference) {
+ return index.getChildren(reference);
+ }
+
+ @Override
+ public <G extends Serializable> Measure<G> getMeasure(Metric<G> metric) {
+ return index.getMeasure(project, metric);
+ }
+
+ @Override
+ public <M> M getMeasures(MeasuresFilter<M> filter) {
+ return index.getMeasures(project, filter);
+ }
+
+ @Override
+ public Measure saveMeasure(Measure measure) {
+ return index.addMeasure(project, measure);
+ }
+
+ @Override
+ public Measure saveMeasure(Metric metric, Double value) {
+ return index.addMeasure(project, new Measure(metric, value));
+ }
+
+ @Override
+ public <G extends Serializable> Measure<G> getMeasure(Resource resource, Metric<G> metric) {
+ return index.getMeasure(resource, metric);
+ }
+
+ @Override
+ public String saveResource(Resource resource) {
+ Resource persistedResource = index.addResource(resource);
+ if (persistedResource != null) {
+ return persistedResource.getEffectiveKey();
+ }
+ return null;
+ }
+
+ public boolean saveResource(Resource resource, Resource parentReference) {
+ return index.index(resource, parentReference);
+ }
+
+ @Override
+ public Resource getResource(Resource resource) {
+ return index.getResource(resource);
+ }
+
+ @Override
+ public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
+ return index.getMeasures(resource, filter);
+ }
+
+ @Override
+ public Measure saveMeasure(Resource resource, Metric metric, Double value) {
+ return saveMeasure(resource, new Measure(metric, value));
+ }
+
+ @Override
+ public Measure saveMeasure(Resource resource, Measure measure) {
+ Resource resourceOrProject = resourceOrProject(resource);
+ if (coverageFilter.accept(resourceOrProject, measure)) {
+ return index.addMeasure(resourceOrProject, measure);
+ } else {
+ return measure;
+ }
+ }
+
+ @Override
+ public void saveViolation(Violation violation, boolean force) {
+ if (violation.getResource() == null) {
+ violation.setResource(resourceOrProject(violation.getResource()));
+ }
+ index.addViolation(violation, force);
+ }
+
+ @Override
+ public void saveViolation(Violation violation) {
+ saveViolation(violation, false);
+ }
+
+ @Override
+ public void saveViolations(Collection<Violation> violations) {
+ if (violations != null) {
+ for (Violation violation : violations) {
+ saveViolation(violation);
+ }
+ }
+ }
+
+ @Override
+ public Dependency saveDependency(Dependency dependency) {
+ return index.addDependency(dependency);
+ }
+
+ @Override
+ public Set<Dependency> getDependencies() {
+ return index.getDependencies();
+ }
+
+ @Override
+ public Collection<Dependency> getIncomingDependencies(Resource to) {
+ return index.getIncomingEdges(resourceOrProject(to));
+ }
+
+ @Override
+ public Collection<Dependency> getOutgoingDependencies(Resource from) {
+ return index.getOutgoingEdges(resourceOrProject(from));
+ }
+
+ @Override
+ public void saveSource(Resource reference, String source) {
+ // useless since 4.2.
+ }
+
+ @Override
+ public void saveLink(ProjectLink link) {
+ index.addLink(link);
+ }
+
+ @Override
+ public void deleteLink(String key) {
+ index.deleteLink(key);
+ }
+
+ @Override
+ public List<Event> getEvents(Resource resource) {
+ return index.getEvents(resource);
+ }
+
+ @Override
+ public Event createEvent(Resource resource, String name, String description, String category, Date date) {
+ return index.addEvent(resource, name, description, category, date);
+ }
+
+ @Override
+ public void deleteEvent(Event event) {
+ index.deleteEvent(event);
+ }
+
+ private Resource resourceOrProject(Resource resource) {
+ if (resource == null) {
+ return project;
+ }
+ Resource indexedResource = getResource(resource);
+ return indexedResource != null ? indexedResource : resource;
+ }
+
+ @Override
+ public Measure saveMeasure(InputFile inputFile, Metric metric, Double value) {
+ return saveMeasure(getResource(inputFile), metric, value);
+ }
+
+ @Override
+ public Measure saveMeasure(InputFile inputFile, Measure measure) {
+ return saveMeasure(getResource(inputFile), measure);
+ }
+
+ @Override
+ public Resource getResource(InputPath inputPath) {
+ Resource r;
+ if (inputPath instanceof InputDir) {
+ r = Directory.create(((InputDir) inputPath).relativePath());
+ } else if (inputPath instanceof InputFile) {
+ r = File.create(((InputFile) inputPath).relativePath());
+ } else {
+ throw new IllegalArgumentException("Unknow input path type: " + inputPath);
+ }
+ return getResource(r);
+ }
+}
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;
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;
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;
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;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
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;
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;
}
*/
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;
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;
import javax.annotation.CheckForNull;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
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<>();
issues.add(issue);
}
- for (Measure measure : container.getComponentByType(MeasureCache.class).all()) {
- measures.add(measure);
- }
-
storeFs(container);
+
+ storeMeasures(container);
+
storeComponentData(container);
storeDuplication(container);
// storeTestCases(container);
}
+ 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()) {
return issues;
}
- public List<Measure> measures() {
+ public List<org.sonar.api.batch.sensor.measure.Measure> measures() {
return measures;
}
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;
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;
this.index = index;
this.eventBus = eventBus;
this.project = project;
- this.measurementFilters = measurementFilters;
+ this.coverageFilter = coverageFilter;
}
public void execute() {
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) {
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;
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);
AnalyzerOptimizer.class,
DefaultSensorContext.class,
- SensorContextAdapter.class,
+ DefaultSensorStorage.class,
+ DeprecatedSensorContext.class,
BatchExtensionDictionnary.class,
DefaultTimeMachine.class,
IssueFilters.class,
- MeasurementFilters.class,
+ CoverageExclusions.class,
ResourceFilters.class,
// rules
+++ /dev/null
-/*
- * 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.scan;
-
-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.issue.Issue;
-import org.sonar.api.batch.sensor.issue.Issue.Severity;
-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.component.ResourcePerspectives;
-import org.sonar.api.config.Settings;
-import org.sonar.api.design.Dependency;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.measures.Formula;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.PersistenceMode;
-import org.sonar.api.measures.SumChildDistributionFormula;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.test.MutableTestCase;
-import org.sonar.api.test.MutableTestPlan;
-import org.sonar.api.test.MutableTestable;
-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.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 {
-
- 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;
-
- public SensorContextAdapter(org.sonar.api.batch.SensorContext sensorContext, 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;
- this.metricFinder = metricFinder;
- this.project = project;
- this.perspectives = perspectives;
- this.sonarIndex = sonarIndex;
- }
-
- private Metric findMetricOrFail(String metricKey) {
- Metric m = (Metric) metricFinder.findByKey(metricKey);
- if (m == null) {
- throw new IllegalStateException("Unknow metric with key: " + metricKey);
- }
- return m;
- }
-
- @Override
- public void store(Measure newMeasure) {
- DefaultMeasure measure = (DefaultMeasure) newMeasure;
- org.sonar.api.measures.Metric m = findMetricOrFail(measure.metric().key());
- org.sonar.api.measures.Measure measureToSave = new org.sonar.api.measures.Measure(m);
- setValueAccordingToMetricType(newMeasure, m, measureToSave);
- measureToSave.setFromCore(measure.isFromCore());
- if (newMeasure.inputFile() != null) {
- Formula formula = newMeasure.metric() instanceof org.sonar.api.measures.Metric ?
- ((org.sonar.api.measures.Metric) newMeasure.metric()).getFormula() : null;
- if (formula instanceof SumChildDistributionFormula
- && !Scopes.isHigherThanOrEquals(Scopes.FILE, ((SumChildDistributionFormula) formula).getMinimumScopeToPersist())) {
- measureToSave.setPersistenceMode(PersistenceMode.MEMORY);
- }
- sensorContext.saveMeasure(newMeasure.inputFile(), measureToSave);
- } else {
- sensorContext.saveMeasure(measureToSave);
- }
- }
-
- private void setValueAccordingToMetricType(Measure<?> measure, org.sonar.api.measures.Metric<?> m, org.sonar.api.measures.Measure measureToSave) {
- switch (m.getType()) {
- case BOOL:
- measureToSave.setValue(Boolean.TRUE.equals(measure.value()) ? 1.0 : 0.0);
- break;
- case INT:
- case MILLISEC:
- measureToSave.setValue(Double.valueOf((Integer) measure.value()));
- break;
- case FLOAT:
- case PERCENT:
- case RATING:
- measureToSave.setValue((Double) measure.value());
- break;
- case STRING:
- case LEVEL:
- case DATA:
- case DISTRIB:
- measureToSave.setData((String) measure.value());
- break;
- case WORK_DUR:
- measureToSave.setValue(Double.valueOf((Long) measure.value()));
- break;
- default:
- throw new UnsupportedOperationException("Unsupported type :" + m.getType());
- }
- }
-
- @Override
- public void store(Issue issue) {
- Resource r;
- InputPath inputPath = issue.inputPath();
- if (inputPath != null) {
- if (inputPath instanceof InputDir) {
- r = Directory.create(inputPath.relativePath());
- } else {
- r = File.create(inputPath.relativePath());
- }
- } else {
- r = project;
- }
- Issuable issuable = perspectives.as(Issuable.class, r);
- if (issuable == null) {
- return;
- }
- issuable.addIssue(toDefaultIssue(project.getKey(), ComponentKeys.createEffectiveKey(project, r), issue));
- }
-
- public static DefaultIssue toDefaultIssue(String projectKey, String componentKey, Issue issue) {
- Severity overridenSeverity = issue.overridenSeverity();
- return new org.sonar.core.issue.DefaultIssueBuilder()
- .componentKey(componentKey)
- .projectKey(projectKey)
- .ruleKey(RuleKey.of(issue.ruleKey().repository(), issue.ruleKey().rule()))
- .effortToFix(issue.effortToFix())
- .line(issue.line())
- .message(issue.message())
- .severity(overridenSeverity != null ? overridenSeverity.name() : null)
- .build();
- }
-
- @Override
- public void store(TestCaseExecution testCase) {
- File testRes = getTestResource(((DefaultTestCaseExecution) testCase).testFile());
- MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
- if (testPlan != null) {
- testPlan
- .addTestCase(testCase.name())
- .setDurationInMs(testCase.durationInMs())
- .setType(testCase.type().name())
- .setStatus(org.sonar.api.test.TestCase.Status.valueOf(testCase.status().name()))
- .setMessage(testCase.message())
- .setStackTrace(testCase.stackTrace());
- }
- }
-
- @Override
- public void store(TestCaseCoverage testCaseCoverage) {
- File testRes = getTestResource(testCaseCoverage.testFile());
- File mainRes = getMainResource(testCaseCoverage.coveredFile());
- Testable testAbleFile = perspectives.as(MutableTestable.class, mainRes);
- if (testAbleFile != null) {
- MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
- if (testPlan != null) {
- for (MutableTestCase mutableTestCase : testPlan.testCasesByName(testCaseCoverage.testName())) {
- mutableTestCase.setCoverageBlock(testAbleFile, testCaseCoverage.coveredLines());
- }
- } else {
- throw new IllegalStateException("Unable to get MutableTestPlan perspective from " + testRes);
- }
- } else {
- throw new IllegalStateException("Unable to get MutableTestable perspective from " + mainRes);
- }
- }
-
- private File getTestResource(InputFile testFile) {
- File testRes = File.create(testFile.relativePath());
- testRes.setQualifier(Qualifiers.UNIT_TEST_FILE);
- // Reload
- testRes = sensorContext.getResource(testRes);
- if (testRes == null) {
- throw new IllegalArgumentException("Provided input file is not indexed or not a test file: " + testFile);
- }
- return testRes;
- }
-
- private File getMainResource(InputFile mainFile) {
- File mainRes = File.create(mainFile.relativePath());
- // Reload
- mainRes = sensorContext.getResource(mainRes);
- if (mainRes == null) {
- throw new IllegalArgumentException("Provided input file is not indexed or not a main file: " + mainRes);
- }
- return mainRes;
- }
-
- private File getFile(InputFile file) {
- if (file.type() == InputFile.Type.MAIN) {
- return getMainResource(file);
- } else {
- return getTestResource(file);
- }
- }
-
- @Override
- public void store(org.sonar.api.batch.sensor.dependency.Dependency dep) {
- File fromResource = getFile(dep.from());
- File toResource = getFile(dep.to());
- if (sonarIndex.getEdge(fromResource, toResource) != null) {
- throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved.");
- }
- Directory fromParent = fromResource.getParent();
- Directory toParent = toResource.getParent();
- Dependency parentDep = null;
- if (!fromParent.equals(toParent)) {
- parentDep = sonarIndex.getEdge(fromParent, toParent);
- if (parentDep != null) {
- parentDep.setWeight(parentDep.getWeight() + 1);
- } else {
- parentDep = new Dependency(fromParent, toParent).setUsage(USES).setWeight(1);
- parentDep = sensorContext.saveDependency(parentDep);
- }
- }
- sensorContext.saveDependency(new Dependency(fromResource, toResource)
- .setUsage(USES)
- .setWeight(dep.weight())
- .setParent(parentDep));
- }
-
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-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.dependency.Dependency;
-import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency;
-import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
-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.internal.DefaultMeasure;
-import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
-import org.sonar.api.batch.sensor.test.Coverage;
-import org.sonar.api.batch.sensor.test.TestCaseCoverage;
-import org.sonar.api.batch.sensor.test.TestCaseExecution;
-import org.sonar.api.batch.sensor.test.internal.DefaultCoverage;
-import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;
-import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
-import org.sonar.api.config.Settings;
-import org.sonar.batch.duplication.BlockCache;
-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;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * Common bits between {@link DefaultSensorContext} and {@link SensorContextAdapter}
- * @author julien
- *
- */
-public abstract class BaseSensorContext implements SensorContext, SensorStorage {
-
- private final Settings settings;
- private final FileSystem fs;
- private final ActiveRules activeRules;
- private final ComponentDataCache componentDataCache;
- private final BlockCache blockCache;
- private final DuplicationCache duplicationCache;
-
- protected BaseSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache,
- BlockCache blockCache, DuplicationCache duplicationCache) {
- this.settings = settings;
- this.fs = fs;
- this.activeRules = activeRules;
- this.componentDataCache = componentDataCache;
- this.blockCache = blockCache;
- this.duplicationCache = duplicationCache;
- }
-
- @Override
- public Settings settings() {
- return settings;
- }
-
- @Override
- public FileSystem fileSystem() {
- return fs;
- }
-
- @Override
- public ActiveRules activeRules() {
- return activeRules;
- }
-
- @Override
- public <G extends Serializable> Measure<G> newMeasure() {
- return (Measure<G>) new DefaultMeasure(this);
- }
-
- @Override
- public Issue newIssue() {
- return new DefaultIssue(this);
- }
-
- @Override
- public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
- return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
- }
-
- @Override
- public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
- return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
- }
-
- @Override
- public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
- PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
-
- return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
- }
-
- @Override
- public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
- return new DefaultDuplicationBuilder(inputFile);
- }
-
- @Override
- public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
- Preconditions.checkState(!duplications.isEmpty(), "Empty duplications");
- String effectiveKey = ((DefaultInputFile) inputFile).key();
- for (DuplicationGroup duplicationGroup : duplications) {
- Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
- }
- duplicationCache.put(effectiveKey, duplications);
- }
-
- private int getBlockSize(String languageKey) {
- int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
- if (blockSize == 0) {
- blockSize = getDefaultBlockSize(languageKey);
- }
- return blockSize;
- }
-
- private static int getDefaultBlockSize(String languageKey) {
- if ("cobol".equals(languageKey)) {
- return 30;
- } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
- return 20;
- } else {
- return 10;
- }
- }
-
- @Override
- public Coverage newCoverage() {
- return new DefaultCoverage(this);
- }
-
- @Override
- public TestCaseExecution newTestCaseExecution() {
- return new DefaultTestCaseExecution(this);
- }
-
- @Override
- public TestCaseCoverage newTestCaseCoverage() {
- return new DefaultTestCaseCoverage(this);
- }
-
- @Override
- public Dependency newDependency() {
- return new DefaultDependency(this);
- }
-
-}
+++ /dev/null
-/*
- * 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);
- }
-
-}
+++ /dev/null
-/*
- * 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();
- }
-
-}
+++ /dev/null
-/*
- * 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();
- }
-
-}
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() {
analyzersExecutor.execute(analyzerContext);
- // Export results
- analyzisPublisher.execute();
-
}
}
+++ /dev/null
-/*
- * 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);
- }
- }
-}
+++ /dev/null
-/*
- * 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);
-
-}
+++ /dev/null
-/*
- * 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);
- }
- }
-
-}
--- /dev/null
+/*
+ * 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 com.google.common.base.Preconditions;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+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.dependency.Dependency;
+import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency;
+import org.sonar.api.batch.sensor.duplication.DuplicationBuilder;
+import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
+import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
+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.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;
+import org.sonar.api.batch.sensor.test.TestCaseCoverage;
+import org.sonar.api.batch.sensor.test.TestCaseExecution;
+import org.sonar.api.batch.sensor.test.internal.DefaultCoverage;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseCoverage;
+import org.sonar.api.batch.sensor.test.internal.DefaultTestCaseExecution;
+import org.sonar.api.config.Settings;
+import org.sonar.batch.duplication.BlockCache;
+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.symbol.DefaultSymbolTableBuilder;
+import org.sonar.duplications.internal.pmd.PmdBlockChunker;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Common bits between {@link ExperimentalSensorStorage} and {@link SensorContextAdapter}
+ * @author julien
+ *
+ */
+public class DefaultSensorContext implements SensorContext {
+
+ private final Settings settings;
+ private final FileSystem fs;
+ private final ActiveRules activeRules;
+ private final ComponentDataCache componentDataCache;
+ private final BlockCache blockCache;
+ private final DuplicationCache duplicationCache;
+ private final SensorStorage sensorStorage;
+
+ 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
+ public Settings settings() {
+ return settings;
+ }
+
+ @Override
+ public FileSystem fileSystem() {
+ return fs;
+ }
+
+ @Override
+ public ActiveRules activeRules() {
+ return activeRules;
+ }
+
+ @Override
+ public <G extends Serializable> NewMeasure<G> newMeasure() {
+ return new DefaultMeasure(sensorStorage);
+ }
+
+ @Override
+ public Issue newIssue() {
+ return new DefaultIssue(sensorStorage);
+ }
+
+ @Override
+ public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
+ return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ }
+
+ @Override
+ public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
+ return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ }
+
+ @Override
+ public DuplicationTokenBuilder duplicationTokenBuilder(InputFile inputFile) {
+ PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
+
+ return new DefaultTokenBuilder(inputFile, blockCache, blockChunker);
+ }
+
+ @Override
+ public DuplicationBuilder duplicationBuilder(InputFile inputFile) {
+ return new DefaultDuplicationBuilder(inputFile);
+ }
+
+ @Override
+ public void saveDuplications(InputFile inputFile, List<DuplicationGroup> duplications) {
+ Preconditions.checkState(!duplications.isEmpty(), "Empty duplications");
+ String effectiveKey = ((DefaultInputFile) inputFile).key();
+ for (DuplicationGroup duplicationGroup : duplications) {
+ Preconditions.checkState(effectiveKey.equals(duplicationGroup.originBlock().resourceKey()), "Invalid duplication group");
+ }
+ duplicationCache.put(effectiveKey, duplications);
+ }
+
+ private int getBlockSize(String languageKey) {
+ int blockSize = settings.getInt("sonar.cpd." + languageKey + ".minimumLines");
+ if (blockSize == 0) {
+ blockSize = getDefaultBlockSize(languageKey);
+ }
+ return blockSize;
+ }
+
+ private static int getDefaultBlockSize(String languageKey) {
+ if ("cobol".equals(languageKey)) {
+ return 30;
+ } else if ("abap".equals(languageKey) || "natur".equals(languageKey)) {
+ return 20;
+ } else {
+ return 10;
+ }
+ }
+
+ @Override
+ public Coverage newCoverage() {
+ return new DefaultCoverage(sensorStorage);
+ }
+
+ @Override
+ public TestCaseExecution newTestCaseExecution() {
+ return new DefaultTestCaseExecution(sensorStorage);
+ }
+
+ @Override
+ public TestCaseCoverage newTestCaseCoverage() {
+ return new DefaultTestCaseCoverage(sensorStorage);
+ }
+
+ @Override
+ public Dependency newDependency() {
+ return new DefaultDependency(sensorStorage);
+ }
+
+}
--- /dev/null
+/*
+ * 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.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.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;
+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.component.ResourcePerspectives;
+import org.sonar.api.config.Settings;
+import org.sonar.api.design.Dependency;
+import org.sonar.api.issue.Issuable;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.measures.Formula;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.PersistenceMode;
+import org.sonar.api.measures.SumChildDistributionFormula;
+import org.sonar.api.resources.Directory;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.test.MutableTestCase;
+import org.sonar.api.test.MutableTestPlan;
+import org.sonar.api.test.MutableTestable;
+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.index.DefaultIndex;
+import org.sonar.batch.sensor.coverage.CoverageExclusions;
+import org.sonar.core.component.ComponentKeys;
+
+public class DefaultSensorStorage implements SensorStorage {
+
+ private static final String USES = "USES";
+ private final MetricFinder metricFinder;
+ private final Project project;
+ private final ResourcePerspectives perspectives;
+ private final DefaultIndex sonarIndex;
+ private final CoverageExclusions coverageExclusions;
+
+ public DefaultSensorStorage(MetricFinder metricFinder, Project project,
+ ResourcePerspectives perspectives,
+ Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, BlockCache blockCache,
+ 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) {
+ Metric m = (Metric) metricFinder.findByKey(metricKey);
+ if (m == null) {
+ throw new IllegalStateException("Unknow metric with key: " + metricKey);
+ }
+ return m;
+ }
+
+ @Override
+ public void store(Measure newMeasure) {
+ DefaultMeasure measure = (DefaultMeasure) newMeasure;
+ org.sonar.api.measures.Metric m = findMetricOrFail(measure.metric().key());
+ org.sonar.api.measures.Measure measureToSave = new org.sonar.api.measures.Measure(m);
+ setValueAccordingToMetricType(newMeasure, m, measureToSave);
+ measureToSave.setFromCore(measure.isFromCore());
+ if (newMeasure.inputFile() != null) {
+ Formula formula = newMeasure.metric() instanceof org.sonar.api.measures.Metric ?
+ ((org.sonar.api.measures.Metric) newMeasure.metric()).getFormula() : null;
+ if (formula instanceof SumChildDistributionFormula
+ && !Scopes.isHigherThanOrEquals(Scopes.FILE, ((SumChildDistributionFormula) formula).getMinimumScopeToPersist())) {
+ measureToSave.setPersistenceMode(PersistenceMode.MEMORY);
+ }
+ File sonarFile = getFile(newMeasure.inputFile());
+ if (coverageExclusions.accept(sonarFile, measureToSave)) {
+ sonarIndex.addMeasure(sonarFile, measureToSave);
+ }
+ } else {
+ sonarIndex.addMeasure(project, measureToSave);
+ }
+ }
+
+ private void setValueAccordingToMetricType(Measure<?> measure, org.sonar.api.measures.Metric<?> m, org.sonar.api.measures.Measure measureToSave) {
+ switch (m.getType()) {
+ case BOOL:
+ measureToSave.setValue(Boolean.TRUE.equals(measure.value()) ? 1.0 : 0.0);
+ break;
+ case INT:
+ case MILLISEC:
+ measureToSave.setValue(Double.valueOf((Integer) measure.value()));
+ break;
+ case FLOAT:
+ case PERCENT:
+ case RATING:
+ measureToSave.setValue((Double) measure.value());
+ break;
+ case STRING:
+ case LEVEL:
+ case DATA:
+ case DISTRIB:
+ measureToSave.setData((String) measure.value());
+ break;
+ case WORK_DUR:
+ measureToSave.setValue(Double.valueOf((Long) measure.value()));
+ break;
+ default:
+ throw new UnsupportedOperationException("Unsupported type :" + m.getType());
+ }
+ }
+
+ @Override
+ public void store(Issue issue) {
+ Resource r;
+ InputPath inputPath = issue.inputPath();
+ if (inputPath != null) {
+ if (inputPath instanceof InputDir) {
+ r = Directory.create(inputPath.relativePath());
+ } else {
+ r = File.create(inputPath.relativePath());
+ }
+ } else {
+ r = project;
+ }
+ Issuable issuable = perspectives.as(Issuable.class, r);
+ if (issuable == null) {
+ return;
+ }
+ issuable.addIssue(toDefaultIssue(project.getKey(), ComponentKeys.createEffectiveKey(project, r), issue));
+ }
+
+ public static DefaultIssue toDefaultIssue(String projectKey, String componentKey, Issue issue) {
+ Severity overridenSeverity = issue.overridenSeverity();
+ return new org.sonar.core.issue.DefaultIssueBuilder()
+ .componentKey(componentKey)
+ .projectKey(projectKey)
+ .ruleKey(RuleKey.of(issue.ruleKey().repository(), issue.ruleKey().rule()))
+ .effortToFix(issue.effortToFix())
+ .line(issue.line())
+ .message(issue.message())
+ .severity(overridenSeverity != null ? overridenSeverity.name() : null)
+ .build();
+ }
+
+ @Override
+ public void store(TestCaseExecution testCase) {
+ File testRes = getTestResource(((DefaultTestCaseExecution) testCase).testFile());
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
+ if (testPlan != null) {
+ testPlan
+ .addTestCase(testCase.name())
+ .setDurationInMs(testCase.durationInMs())
+ .setType(testCase.type().name())
+ .setStatus(org.sonar.api.test.TestCase.Status.valueOf(testCase.status().name()))
+ .setMessage(testCase.message())
+ .setStackTrace(testCase.stackTrace());
+ }
+ }
+
+ @Override
+ public void store(TestCaseCoverage testCaseCoverage) {
+ File testRes = getTestResource(testCaseCoverage.testFile());
+ File mainRes = getMainResource(testCaseCoverage.coveredFile());
+ Testable testAbleFile = perspectives.as(MutableTestable.class, mainRes);
+ if (testAbleFile != null) {
+ MutableTestPlan testPlan = perspectives.as(MutableTestPlan.class, testRes);
+ if (testPlan != null) {
+ for (MutableTestCase mutableTestCase : testPlan.testCasesByName(testCaseCoverage.testName())) {
+ mutableTestCase.setCoverageBlock(testAbleFile, testCaseCoverage.coveredLines());
+ }
+ } else {
+ throw new IllegalStateException("Unable to get MutableTestPlan perspective from " + testRes);
+ }
+ } else {
+ throw new IllegalStateException("Unable to get MutableTestable perspective from " + mainRes);
+ }
+ }
+
+ private File getTestResource(InputFile testFile) {
+ File testRes = File.create(testFile.relativePath());
+ testRes.setQualifier(Qualifiers.UNIT_TEST_FILE);
+ // Reload
+ testRes = sonarIndex.getResource(testRes);
+ if (testRes == null) {
+ throw new IllegalArgumentException("Provided input file is not indexed or not a test file: " + testFile);
+ }
+ return testRes;
+ }
+
+ private File getMainResource(InputFile mainFile) {
+ File mainRes = File.create(mainFile.relativePath());
+ // Reload
+ mainRes = sonarIndex.getResource(mainRes);
+ if (mainRes == null) {
+ throw new IllegalArgumentException("Provided input file is not indexed or not a main file: " + mainRes);
+ }
+ return mainRes;
+ }
+
+ private File getFile(InputFile file) {
+ if (file.type() == InputFile.Type.MAIN) {
+ return getMainResource(file);
+ } else {
+ return getTestResource(file);
+ }
+ }
+
+ @Override
+ public void store(org.sonar.api.batch.sensor.dependency.Dependency dep) {
+ File fromResource = getFile(dep.from());
+ File toResource = getFile(dep.to());
+ if (sonarIndex.getEdge(fromResource, toResource) != null) {
+ throw new IllegalStateException("Dependency between " + dep.from() + " and " + dep.to() + " was already saved.");
+ }
+ Directory fromParent = fromResource.getParent();
+ Directory toParent = toResource.getParent();
+ Dependency parentDep = null;
+ if (!fromParent.equals(toParent)) {
+ parentDep = sonarIndex.getEdge(fromParent, toParent);
+ if (parentDep != null) {
+ parentDep.setWeight(parentDep.getWeight() + 1);
+ } else {
+ parentDep = new Dependency(fromParent, toParent).setUsage(USES).setWeight(1);
+ parentDep = sonarIndex.addDependency(parentDep);
+ }
+ }
+ sonarIndex.addDependency(new Dependency(fromResource, toResource)
+ .setUsage(USES)
+ .setWeight(dep.weight())
+ .setParent(parentDep));
+ }
+}
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.collect.ImmutableSet;
+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 java.util.Collection;
+import java.util.Iterator;
+
+public class CoverageExclusions {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CoverageExclusions.class);
+
+ private final Settings settings;
+ private final ImmutableSet<Metric> coverageMetrics;
+ private Collection<WildcardPattern> resourcePatterns;
+
+ public CoverageExclusions(Settings settings) {
+ this.settings = settings;
+ this.coverageMetrics = ImmutableSet.<Metric>builder()
+ .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();
+ }
+
+ public boolean accept(Resource resource, Measure measure) {
+ if (isCoverageMetric(measure.getMetric())) {
+ return !hasMatchingPattern(resource);
+ } else {
+ return true;
+ }
+ }
+
+ private boolean isCoverageMetric(Metric metric) {
+ return this.coverageMetrics.contains(metric);
+ }
+
+ private boolean hasMatchingPattern(Resource resource) {
+ boolean found = false;
+ Iterator<WildcardPattern> iterator = resourcePatterns.iterator();
+ while (!found && iterator.hasNext()) {
+ found = resource.matchFilePattern(iterator.next().toString());
+ }
+ return found;
+ }
+
+ @VisibleForTesting
+ final void initPatterns() {
+ Builder<WildcardPattern> builder = ImmutableList.builder();
+ for (String pattern : settings.getStringArray(CoreProperties.PROJECT_COVERAGE_EXCLUSIONS_PROPERTY)) {
+ builder.add(WildcardPattern.create(pattern));
+ }
+ resourcePatterns = builder.build();
+ log("Excluded sources for coverage: ", resourcePatterns);
+ }
+
+ private void log(String title, Collection<WildcardPattern> patterns) {
+ if (!patterns.isEmpty()) {
+ LOG.info(title);
+ for (WildcardPattern pattern : patterns) {
+ LOG.info(" " + pattern);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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.
+ */
+@javax.annotation.ParametersAreNonnullByDefault
+package org.sonar.batch.sensor;
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;
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
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;
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));
}
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;
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
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
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 {
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;
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");
+++ /dev/null
-/*
- * 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.scan;
-
-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;
-import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputDir;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-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.dependency.internal.DefaultDependency;
-import org.sonar.api.batch.sensor.issue.Issue.Severity;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
-import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.config.Settings;
-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.PersistenceMode;
-import org.sonar.api.resources.Directory;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-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 static org.assertj.core.api.Assertions.assertThat;
-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 {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- private ActiveRules activeRules;
- private DefaultFileSystem fs;
- private SensorContextAdapter adaptor;
- private SensorContext sensorContext;
- private Settings settings;
- private ResourcePerspectives resourcePerspectives;
- private Project project;
- private SonarIndex sonarIndex;
-
- @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);
- 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();
- }
-
- @Test
- public void shouldFailIfUnknowMetric() {
- InputFile file = new DefaultInputFile("foo", "src/Foo.php");
-
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Unknow metric with key: lines");
-
- adaptor.store(new DefaultMeasure()
- .onFile(file)
- .forMetric(CoreMetrics.LINES)
- .withValue(10));
- }
-
- @Test
- public void shouldSaveFileMeasureToSensorContext() {
- 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()
- .onFile(file)
- .forMetric(CoreMetrics.NCLOC)
- .withValue(10));
-
- org.sonar.api.measures.Measure m = argumentCaptor.getValue();
- assertThat(m.getValue()).isEqualTo(10.0);
- assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
- }
-
- @Test
- public void shouldSetAppropriatePersistenceMode() {
- // Metric FUNCTION_COMPLEXITY_DISTRIBUTION is only persisted on directories.
-
- 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()
- .onFile(file)
- .forMetric(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION)
- .withValue("foo"));
-
- org.sonar.api.measures.Measure m = argumentCaptor.getValue();
- assertThat(m.getData()).isEqualTo("foo");
- assertThat(m.getMetric()).isEqualTo(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
- assertThat(m.getPersistenceMode()).isEqualTo(PersistenceMode.MEMORY);
-
- }
-
- @Test
- 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);
-
- adaptor.store(new DefaultMeasure()
- .onProject()
- .forMetric(CoreMetrics.NCLOC)
- .withValue(10));
-
- org.sonar.api.measures.Measure m = argumentCaptor.getValue();
- assertThat(m.getValue()).isEqualTo(10.0);
- assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
- }
-
- @Test
- public void shouldAddIssueOnFile() {
- InputFile file = new DefaultInputFile("foo", "src/Foo.php");
-
- ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
-
- Issuable issuable = mock(Issuable.class);
- when(resourcePerspectives.as(Issuable.class, File.create("src/Foo.php"))).thenReturn(issuable);
-
- when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
-
- adaptor.store(new DefaultIssue()
- .onFile(file)
- .ruleKey(RuleKey.of("foo", "bar"))
- .message("Foo")
- .atLine(3)
- .effortToFix(10.0));
-
- Issue issue = argumentCaptor.getValue();
- assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
- assertThat(issue.message()).isEqualTo("Foo");
- assertThat(issue.line()).isEqualTo(3);
- assertThat(issue.severity()).isNull();
- assertThat(issue.effortToFix()).isEqualTo(10.0);
- }
-
- @Test
- public void shouldAddIssueOnDirectory() {
- InputDir dir = new DefaultInputDir("foo", "src");
-
- ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
-
- Issuable issuable = mock(Issuable.class);
- when(resourcePerspectives.as(Issuable.class, Directory.create("src"))).thenReturn(issuable);
-
- when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
-
- adaptor.store(new DefaultIssue()
- .onDir(dir)
- .ruleKey(RuleKey.of("foo", "bar"))
- .message("Foo")
- .effortToFix(10.0));
-
- Issue issue = argumentCaptor.getValue();
- assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
- assertThat(issue.message()).isEqualTo("Foo");
- assertThat(issue.line()).isNull();
- assertThat(issue.severity()).isNull();
- assertThat(issue.effortToFix()).isEqualTo(10.0);
- }
-
- @Test
- public void shouldAddIssueOnProject() {
- ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
-
- Issuable issuable = mock(Issuable.class);
- when(resourcePerspectives.as(Issuable.class, (Resource) project)).thenReturn(issuable);
-
- when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
-
- adaptor.store(new DefaultIssue()
- .onProject()
- .ruleKey(RuleKey.of("foo", "bar"))
- .message("Foo")
- .overrideSeverity(Severity.BLOCKER)
- .effortToFix(10.0));
-
- Issue issue = argumentCaptor.getValue();
- assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
- assertThat(issue.message()).isEqualTo("Foo");
- assertThat(issue.line()).isNull();
- assertThat(issue.severity()).isEqualTo("BLOCKER");
- assertThat(issue.effortToFix()).isEqualTo(10.0);
- }
-
- @Test
- public void shouldStoreDependencyInSameFolder() {
-
- 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);
-
- adaptor.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());
- assertThat(argumentCaptor.getValue().getFrom()).isEqualTo(foo);
- assertThat(argumentCaptor.getValue().getTo()).isEqualTo(bar);
- assertThat(argumentCaptor.getValue().getWeight()).isEqualTo(3);
- assertThat(argumentCaptor.getValue().getUsage()).isEqualTo("USES");
- }
-
- @Test
- public void throw_if_attempt_to_save_same_dep_twice() {
-
- 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.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()
- .from(new DefaultInputFile("foo", "src/Foo.java").setType(Type.MAIN))
- .to(new DefaultInputFile("foo", "src/Bar.java").setType(Type.MAIN))
- .weight(3));
- }
-
- @Test
- public void shouldStoreDependencyInDifferentFolder() {
-
- 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);
-
- adaptor.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());
- assertThat(argumentCaptor.getAllValues()).hasSize(2);
- Dependency value1 = argumentCaptor.getAllValues().get(0);
- assertThat(value1.getFrom()).isEqualTo(Directory.create("src1"));
- assertThat(value1.getTo()).isEqualTo(Directory.create("src2"));
- assertThat(value1.getWeight()).isEqualTo(1);
- assertThat(value1.getUsage()).isEqualTo("USES");
-
- Dependency value2 = argumentCaptor.getAllValues().get(1);
- assertThat(value2.getFrom()).isEqualTo(foo);
- assertThat(value2.getTo()).isEqualTo(bar);
- assertThat(value2.getWeight()).isEqualTo(3);
- assertThat(value2.getUsage()).isEqualTo("USES");
- }
-
- @Test
- public void shouldIncrementParentWeight() {
-
- File foo = File.create("src1/Foo.java");
- 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);
- Dependency parentDep = new Dependency(src1, src2).setWeight(4);
- when(sonarIndex.getEdge(src1, src2)).thenReturn(parentDep);
-
- adaptor.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());
-
- assertThat(parentDep.getWeight()).isEqualTo(5);
-
- Dependency value = argumentCaptor.getValue();
- assertThat(value.getFrom()).isEqualTo(foo);
- assertThat(value.getTo()).isEqualTo(bar);
- assertThat(value.getWeight()).isEqualTo(3);
- assertThat(value.getUsage()).isEqualTo("USES");
- }
-}
--- /dev/null
+/*
+ * 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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.mockito.ArgumentCaptor;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+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.dependency.internal.DefaultDependency;
+import org.sonar.api.batch.sensor.issue.Issue.Severity;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
+import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.component.ResourcePerspectives;
+import org.sonar.api.config.Settings;
+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;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+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 DefaultSensorStorageTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private ActiveRules activeRules;
+ private DefaultFileSystem fs;
+ private DefaultSensorStorage sensorStorage;
+ private Settings settings;
+ private ResourcePerspectives resourcePerspectives;
+ private Project project;
+ private DefaultIndex sonarIndex;
+
+ @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();
+ resourcePerspectives = mock(ResourcePerspectives.class);
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
+ BlockCache blockCache = mock(BlockCache.class);
+ project = new Project("myProject");
+ 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
+ public void shouldFailIfUnknowMetric() {
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Unknow metric with key: lines");
+
+ sensorStorage.store(new DefaultMeasure()
+ .onFile(file)
+ .forMetric(CoreMetrics.LINES)
+ .withValue(10));
+ }
+
+ @Test
+ public void shouldSaveFileMeasureToSensorContext() {
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+
+ ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
+ 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));
+
+ org.sonar.api.measures.Measure m = argumentCaptor.getValue();
+ assertThat(m.getValue()).isEqualTo(10.0);
+ assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void shouldSetAppropriatePersistenceMode() {
+ // Metric FUNCTION_COMPLEXITY_DISTRIBUTION is only persisted on directories.
+
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+
+ ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
+ 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.FUNCTION_COMPLEXITY_DISTRIBUTION)
+ .withValue("foo"));
+
+ org.sonar.api.measures.Measure m = argumentCaptor.getValue();
+ assertThat(m.getData()).isEqualTo("foo");
+ assertThat(m.getMetric()).isEqualTo(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
+ assertThat(m.getPersistenceMode()).isEqualTo(PersistenceMode.MEMORY);
+
+ }
+
+ @Test
+ public void shouldSaveProjectMeasureToSensorContext() {
+
+ ArgumentCaptor<org.sonar.api.measures.Measure> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.measures.Measure.class);
+ when(sonarIndex.addMeasure(eq(project), argumentCaptor.capture())).thenReturn(null);
+
+ sensorStorage.store(new DefaultMeasure()
+ .onProject()
+ .forMetric(CoreMetrics.NCLOC)
+ .withValue(10));
+
+ org.sonar.api.measures.Measure m = argumentCaptor.getValue();
+ assertThat(m.getValue()).isEqualTo(10.0);
+ assertThat(m.getMetric()).isEqualTo(CoreMetrics.NCLOC);
+ }
+
+ @Test
+ public void shouldAddIssueOnFile() {
+ InputFile file = new DefaultInputFile("foo", "src/Foo.php");
+
+ ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
+
+ Issuable issuable = mock(Issuable.class);
+ when(resourcePerspectives.as(Issuable.class, File.create("src/Foo.php"))).thenReturn(issuable);
+
+ when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
+
+ sensorStorage.store(new DefaultIssue()
+ .onFile(file)
+ .ruleKey(RuleKey.of("foo", "bar"))
+ .message("Foo")
+ .atLine(3)
+ .effortToFix(10.0));
+
+ Issue issue = argumentCaptor.getValue();
+ assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
+ assertThat(issue.message()).isEqualTo("Foo");
+ assertThat(issue.line()).isEqualTo(3);
+ assertThat(issue.severity()).isNull();
+ assertThat(issue.effortToFix()).isEqualTo(10.0);
+ }
+
+ @Test
+ public void shouldAddIssueOnDirectory() {
+ InputDir dir = new DefaultInputDir("foo", "src");
+
+ ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
+
+ Issuable issuable = mock(Issuable.class);
+ when(resourcePerspectives.as(Issuable.class, Directory.create("src"))).thenReturn(issuable);
+
+ when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
+
+ sensorStorage.store(new DefaultIssue()
+ .onDir(dir)
+ .ruleKey(RuleKey.of("foo", "bar"))
+ .message("Foo")
+ .effortToFix(10.0));
+
+ Issue issue = argumentCaptor.getValue();
+ assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
+ assertThat(issue.message()).isEqualTo("Foo");
+ assertThat(issue.line()).isNull();
+ assertThat(issue.severity()).isNull();
+ assertThat(issue.effortToFix()).isEqualTo(10.0);
+ }
+
+ @Test
+ public void shouldAddIssueOnProject() {
+ ArgumentCaptor<Issue> argumentCaptor = ArgumentCaptor.forClass(Issue.class);
+
+ Issuable issuable = mock(Issuable.class);
+ when(resourcePerspectives.as(Issuable.class, (Resource) project)).thenReturn(issuable);
+
+ when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
+
+ sensorStorage.store(new DefaultIssue()
+ .onProject()
+ .ruleKey(RuleKey.of("foo", "bar"))
+ .message("Foo")
+ .overrideSeverity(Severity.BLOCKER)
+ .effortToFix(10.0));
+
+ Issue issue = argumentCaptor.getValue();
+ assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
+ assertThat(issue.message()).isEqualTo("Foo");
+ assertThat(issue.line()).isNull();
+ assertThat(issue.severity()).isEqualTo("BLOCKER");
+ assertThat(issue.effortToFix()).isEqualTo(10.0);
+ }
+
+ @Test
+ public void shouldStoreDependencyInSameFolder() {
+
+ File foo = File.create("src/Foo.java");
+ File bar = File.create("src/Bar.java");
+ when(sonarIndex.getResource(foo)).thenReturn(foo);
+ when(sonarIndex.getResource(bar)).thenReturn(bar);
+
+ 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(sonarIndex).addDependency(argumentCaptor.capture());
+ assertThat(argumentCaptor.getValue().getFrom()).isEqualTo(foo);
+ assertThat(argumentCaptor.getValue().getTo()).isEqualTo(bar);
+ assertThat(argumentCaptor.getValue().getWeight()).isEqualTo(3);
+ assertThat(argumentCaptor.getValue().getUsage()).isEqualTo("USES");
+ }
+
+ @Test
+ public void throw_if_attempt_to_save_same_dep_twice() {
+
+ File foo = File.create("src/Foo.java");
+ File bar = File.create("src/Bar.java");
+ 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.");
+
+ 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));
+ }
+
+ @Test
+ public void shouldStoreDependencyInDifferentFolder() {
+
+ File foo = File.create("src1/Foo.java");
+ File bar = File.create("src2/Bar.java");
+ when(sonarIndex.getResource(foo)).thenReturn(foo);
+ when(sonarIndex.getResource(bar)).thenReturn(bar);
+
+ 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(sonarIndex, times(2)).addDependency(argumentCaptor.capture());
+ assertThat(argumentCaptor.getAllValues()).hasSize(2);
+ Dependency value1 = argumentCaptor.getAllValues().get(0);
+ assertThat(value1.getFrom()).isEqualTo(Directory.create("src1"));
+ assertThat(value1.getTo()).isEqualTo(Directory.create("src2"));
+ assertThat(value1.getWeight()).isEqualTo(1);
+ assertThat(value1.getUsage()).isEqualTo("USES");
+
+ Dependency value2 = argumentCaptor.getAllValues().get(1);
+ assertThat(value2.getFrom()).isEqualTo(foo);
+ assertThat(value2.getTo()).isEqualTo(bar);
+ assertThat(value2.getWeight()).isEqualTo(3);
+ assertThat(value2.getUsage()).isEqualTo("USES");
+ }
+
+ @Test
+ public void shouldIncrementParentWeight() {
+
+ File foo = File.create("src1/Foo.java");
+ File bar = File.create("src2/Bar.java");
+ Directory src1 = Directory.create("src1");
+ Directory src2 = Directory.create("src2");
+ 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);
+
+ 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(sonarIndex).addDependency(argumentCaptor.capture());
+
+ assertThat(parentDep.getWeight()).isEqualTo(5);
+
+ Dependency value = argumentCaptor.getValue();
+ assertThat(value.getFrom()).isEqualTo(foo);
+ assertThat(value.getTo()).isEqualTo(bar);
+ assertThat(value.getWeight()).isEqualTo(3);
+ assertThat(value.getUsage()).isEqualTo("USES");
+ }
+}
--- /dev/null
+/*
+ * 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 org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.measures.Measure;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Resource;
+import org.sonar.core.config.ExclusionProperties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CoverageExclusionsTest {
+
+ private Settings settings;
+
+ private CoverageExclusions filter;
+
+ @Before
+ public void createFilter() {
+ settings = new Settings(new PropertyDefinitions(ExclusionProperties.all()));
+ filter = new CoverageExclusions(settings);
+ }
+
+ @Test
+ public void shouldNotFilterNonCoverageMetrics() {
+ Measure otherMeasure = mock(Measure.class);
+ when(otherMeasure.getMetric()).thenReturn(CoreMetrics.LINES);
+ assertThat(filter.accept(mock(Resource.class), otherMeasure)).isTrue();
+ }
+
+ @Test
+ public void shouldFilterFileBasedOnPattern() {
+ Resource resource = File.create("src/org/polop/File.php", "org/polop/File.php", null, false);
+ Measure coverageMeasure = mock(Measure.class);
+ when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.LINES_TO_COVER);
+
+ settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*");
+ filter.initPatterns();
+ assertThat(filter.accept(resource, coverageMeasure)).isFalse();
+ }
+
+ @Test
+ public void shouldNotFilterFileBasedOnPattern() {
+ Resource resource = File.create("src/org/polop/File.php", "org/polop/File.php", null, false);
+ Measure coverageMeasure = mock(Measure.class);
+ when(coverageMeasure.getMetric()).thenReturn(CoreMetrics.COVERAGE);
+
+ settings.setProperty("sonar.coverage.exclusions", "src/org/other/*");
+ filter.initPatterns();
+ assertThat(filter.accept(resource, coverageMeasure)).isTrue();
+ }
+}
+++ /dev/null
-/*
- * 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.sonar.api.BatchExtension;
-
-import org.sonar.api.resources.Resource;
-import org.sonar.api.measures.Measure;
-
-/**
- * Allows to define filter {@link Measure}s when they are saved on {@link Resource}s
- * @since 4.0
- *
- */
-public interface MeasurementFilter extends BatchExtension {
-
- /**
- *
- * @param resource
- * @param measure
- * @return <code>true</code> if the given measure can be saved for the given resource
- */
- boolean accept(Resource resource, Measure measure);
-}
+++ /dev/null
-/*
- * 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;
- }
-}
+++ /dev/null
-/*
- * 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.core.measure;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
+++ /dev/null
-/*
- * 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);
- }
-}
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;
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);
}
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;
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);
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
/**
* @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.
* </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 {
* 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 {
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;
/**
* See {@link Sensor#execute(SensorContext)}
- * @since 5.0
+ * @since 5.1
*/
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 --------------
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
@CheckForNull
InputFile inputFile();
- /**
- * Set the metric this measure belong to.
- */
- Measure<G> forMetric(Metric<G> metric);
-
/**
* The metric this measure belong to.
*/
Metric<G> metric();
- /**
- * 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();
-
}
--- /dev/null
+/*
+ * 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.api.batch.sensor.measure;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.measure.Metric;
+
+import java.io.Serializable;
+
+/**
+ * Builder to create new Measure.
+ * Should not be implemented by client.
+ * @since 5.1
+ */
+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();
+
+ /**
+ * Set the metric this measure belong to.
+ */
+ 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();
+
+}
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;
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
/**
* @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