aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java30
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java4
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java4
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java10
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java18
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java13
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java18
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java12
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java104
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java30
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/IssueCache.java (renamed from sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java)11
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java (renamed from sonar-batch/src/main/java/org/sonar/batch/scan2/NewMeasureCache.java)6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java3
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java22
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java78
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/IssueBuilder.java85
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java147
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueBuilder.java131
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java4
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java14
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java38
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java12
32 files changed, 425 insertions, 421 deletions
diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
index d2dd4d2d32c..1b565ff56b3 100644
--- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
+++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/JavaCpdEngineTest.java
@@ -29,8 +29,8 @@ import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile;
-import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplicationBuilder;
import org.sonar.api.batch.sensor.measure.Measure;
@@ -63,14 +63,14 @@ public class JavaCpdEngineTest {
private DefaultDuplicationBuilder duplicationBuilder;
private FileLinesContextFactory contextFactory;
private FileLinesContext linesContext;
- private SensorStorage<Measure> persister = mock(SensorStorage.class);
+ private SensorStorage storage = mock(SensorStorage.class);
@Before
public void before() throws IOException {
when(context.newMeasure()).then(new Answer<Measure>() {
@Override
public Measure answer(InvocationOnMock invocation) throws Throwable {
- return new DefaultMeasure(persister);
+ return new DefaultMeasure(storage);
}
});
inputFile = new DeprecatedDefaultInputFile("foo", "src/main/java/Foo.java");
@@ -97,9 +97,9 @@ public class JavaCpdEngineTest {
List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214)));
JavaCpdEngine.save(context, inputFile, groups, contextFactory);
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
InOrder inOrder = Mockito.inOrder(duplicationBuilder);
inOrder.verify(duplicationBuilder).originBlock(5, 204);
@@ -118,9 +118,9 @@ public class JavaCpdEngineTest {
List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key1", 0, 215, 414)));
JavaCpdEngine.save(context, inputFile, groups, contextFactory);
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(400));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(400));
InOrder inOrder = Mockito.inOrder(duplicationBuilder);
inOrder.verify(duplicationBuilder).originBlock(5, 204);
@@ -133,9 +133,9 @@ public class JavaCpdEngineTest {
List<CloneGroup> groups = Arrays.asList(newCloneGroup(new ClonePart("key1", 0, 5, 204), new ClonePart("key2", 0, 15, 214), new ClonePart("key3", 0, 25, 224)));
JavaCpdEngine.save(context, inputFile, groups, contextFactory);
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(200));
InOrder inOrder = Mockito.inOrder(duplicationBuilder);
inOrder.verify(duplicationBuilder).originBlock(5, 204);
@@ -157,9 +157,9 @@ public class JavaCpdEngineTest {
newCloneGroup(new ClonePart("key1", 0, 15, 214), new ClonePart("key3", 0, 15, 214)));
JavaCpdEngine.save(context, inputFile, groups, contextFactory);
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(210));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_FILES).onFile(inputFile).withValue(1));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_BLOCKS).onFile(inputFile).withValue(2));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.DUPLICATED_LINES).onFile(inputFile).withValue(210));
InOrder inOrder = Mockito.inOrder(duplicationBuilder);
inOrder.verify(duplicationBuilder).originBlock(5, 204);
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
index 041bdd94efd..01b2f8168bd 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java
@@ -50,11 +50,11 @@ public class CreateIssueByInternalKeySensor implements Sensor {
ActiveRule rule = context.activeRules().findByInternalKey(XooRulesDefinition.XOO_REPOSITORY,
context.settings().getString(INTERNAL_KEY_PROPERTY));
if (rule != null) {
- context.addIssue(context.issueBuilder()
+ context.newIssue()
.ruleKey(rule.ruleKey())
.onFile(file)
.message("This issue is generated on each file")
- .build());
+ .save();
}
}
}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
index 6763d0308c8..7a2161b1049 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssueOnDirPerFileSensor.java
@@ -51,11 +51,11 @@ public class OneIssueOnDirPerFileSensor implements Sensor {
RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY);
InputDir inputDir = context.fileSystem().inputDir(file.file().getParentFile());
if (inputDir != null) {
- context.addIssue(context.issueBuilder()
+ context.newIssue()
.ruleKey(ruleKey)
.onDir(inputDir)
.message("This issue is generated for file " + file.relativePath())
- .build());
+ .save();
}
}
}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
index e9fab499c18..7a11c639e38 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
@@ -23,7 +23,7 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.batch.sensor.issue.IssueBuilder;
+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;
@@ -53,16 +53,16 @@ public class OneIssuePerLineSensor implements Sensor {
private void createIssues(InputFile file, SensorContext context) {
RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY);
- IssueBuilder issueBuilder = context.issueBuilder();
+ String severity = context.settings().getString(FORCE_SEVERITY_PROPERTY);
for (int line = 1; line <= file.lines(); line++) {
- context.addIssue(issueBuilder
+ context.newIssue()
.ruleKey(ruleKey)
.onFile(file)
.atLine(line)
.effortToFix(context.settings().getDouble(EFFORT_TO_FIX_PROPERTY))
- .severity(context.settings().getString(FORCE_SEVERITY_PROPERTY))
+ .overrideSeverity(severity != null ? Severity.valueOf(severity) : null)
.message("This issue is generated on each line")
- .build());
+ .save();
}
}
}
diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
index 11be6dfcccc..2e04e8184db 100644
--- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
+++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
@@ -30,8 +30,8 @@ import org.mockito.stubbing.Answer;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
@@ -58,7 +58,7 @@ public class MeasureSensorTest {
private File baseDir;
private MetricFinder metricFinder;
- private SensorStorage<DefaultMeasure> persister;
+ private SensorStorage storage;
@Before
public void prepare() throws IOException {
@@ -67,11 +67,11 @@ public class MeasureSensorTest {
sensor = new MeasureSensor(metricFinder);
fileSystem = new DefaultFileSystem();
when(context.fileSystem()).thenReturn(fileSystem);
- persister = mock(SensorStorage.class);
+ storage = mock(SensorStorage.class);
when(context.newMeasure()).then(new Answer<DefaultMeasure>() {
@Override
public DefaultMeasure answer(InvocationOnMock invocation) throws Throwable {
- return new DefaultMeasure(persister);
+ return new DefaultMeasure(storage);
}
});
}
@@ -106,11 +106,11 @@ public class MeasureSensorTest {
sensor.execute(context);
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.NCLOC).onFile(inputFile).withValue(12));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.BRANCH_COVERAGE).onFile(inputFile).withValue(5.3));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.TECHNICAL_DEBT).onFile(inputFile).withValue(300L));
- verify(persister).store(new DefaultMeasure().forMetric(booleanMetric).onFile(inputFile).withValue(true));
- verify(persister).store(new DefaultMeasure().forMetric(CoreMetrics.COMMENT_LINES_DATA).onFile(inputFile).withValue("1=1,2=1"));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.NCLOC).onFile(inputFile).withValue(12));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.BRANCH_COVERAGE).onFile(inputFile).withValue(5.3));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.TECHNICAL_DEBT).onFile(inputFile).withValue(300L));
+ verify(storage).store(new DefaultMeasure().forMetric(booleanMetric).onFile(inputFile).withValue(true));
+ verify(storage).store(new DefaultMeasure().forMetric(CoreMetrics.COMMENT_LINES_DATA).onFile(inputFile).withValue("1=1,2=1"));
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
index d73f1fcab1a..70393580638 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java
@@ -216,7 +216,7 @@ public class DefaultIndex extends SonarIndex {
throw new SonarException("Unknown metric: " + measure.getMetricKey());
}
if (DefaultSensorContext.INTERNAL_METRICS.contains(metric)) {
- LOG.warn("Metric " + metric + " is an internal metric computed by SonarQube. Please update your plugin.");
+ LOG.warn("Metric " + metric.key() + " is an internal metric computed by SonarQube. Please update your plugin.");
return measure;
}
measure.setMetric(metric);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
index 69b1dad2385..437d778b7fd 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
@@ -56,8 +56,8 @@ import org.sonar.batch.protocol.input.ProjectReferentials;
import org.sonar.batch.referential.GlobalReferentialsLoader;
import org.sonar.batch.referential.ProjectReferentialsLoader;
import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.batch.scan2.AnalyzerIssueCache;
-import org.sonar.batch.scan2.NewMeasureCache;
+import org.sonar.batch.scan2.IssueCache;
+import org.sonar.batch.scan2.MeasureCache;
import org.sonar.batch.scan2.ProjectScanContainer;
import org.sonar.batch.scan2.ScanTaskObserver;
import org.sonar.batch.symbol.SymbolData;
@@ -240,11 +240,11 @@ public class BatchMediumTester {
@Override
public void scanTaskCompleted(ProjectScanContainer container) {
LOG.info("Store analysis results in memory for later assertions in medium test");
- for (Issue issue : container.getComponentByType(AnalyzerIssueCache.class).all()) {
+ for (Issue issue : container.getComponentByType(IssueCache.class).all()) {
issues.add(issue);
}
- for (DefaultMeasure<?> measure : container.getComponentByType(NewMeasureCache.class).all()) {
+ for (DefaultMeasure<?> measure : container.getComponentByType(MeasureCache.class).all()) {
measures.add(measure);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java
index 8a225c94dc0..f11c6b82f88 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdapter.java
@@ -33,6 +33,7 @@ import org.sonar.api.batch.measure.Metric;
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.test.TestCase;
import org.sonar.api.batch.sensor.test.internal.DefaultTestCase;
@@ -62,7 +63,6 @@ import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.scan2.BaseSensorContext;
import org.sonar.core.component.ComponentKeys;
-import java.io.Serializable;
import java.util.List;
/**
@@ -100,7 +100,7 @@ public class SensorContextAdapter extends BaseSensorContext {
}
@Override
- public void store(Measure<Serializable> measure) {
+ public void store(Measure measure) {
org.sonar.api.measures.Metric<?> m = metricFinder.findByKey(measure.metric().key());
if (m == null) {
throw new IllegalStateException("Unknow metric with key: " + measure.metric().key());
@@ -155,7 +155,7 @@ public class SensorContextAdapter extends BaseSensorContext {
}
@Override
- public boolean addIssue(Issue issue) {
+ public void store(Issue issue) {
Resource r;
InputPath inputPath = issue.inputPath();
if (inputPath != null) {
@@ -169,12 +169,13 @@ public class SensorContextAdapter extends BaseSensorContext {
}
Issuable issuable = perspectives.as(Issuable.class, r);
if (issuable == null) {
- return false;
+ return;
}
- return issuable.addIssue(toDefaultIssue(project.getKey(), ComponentKeys.createEffectiveKey(project, r), issue));
+ 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)
@@ -182,7 +183,7 @@ public class SensorContextAdapter extends BaseSensorContext {
.effortToFix(issue.effortToFix())
.line(issue.line())
.message(issue.message())
- .severity(issue.severity())
+ .severity(overridenSeverity != null ? overridenSeverity.name() : null)
.build();
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
index 824b229897a..1dad931f8b5 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
@@ -27,6 +27,7 @@ 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.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;
@@ -42,13 +43,13 @@ public final class AnalysisPublisher {
private static final Logger LOG = LoggerFactory.getLogger(AnalysisPublisher.class);
private final Settings settings;
private final FileSystem fs;
- private final NewMeasureCache measureCache;
+ private final MeasureCache measureCache;
private final ProjectDefinition def;
- private final AnalyzerIssueCache issueCache;
+ private final IssueCache issueCache;
public AnalysisPublisher(ProjectDefinition def, Settings settings, FileSystem fs,
- NewMeasureCache measureCache,
- AnalyzerIssueCache analyzerIssueCache) {
+ MeasureCache measureCache,
+ IssueCache analyzerIssueCache) {
this.def = def;
this.settings = settings;
this.fs = fs;
@@ -108,9 +109,12 @@ public final class AnalysisPublisher {
}
jsonWriter.prop("message", issue.message())
.prop("effortToFix", issue.effortToFix())
- .prop("line", issue.line())
- .prop("severity", issue.severity())
- .endObject();
+ .prop("line", issue.line());
+ Severity overridenSeverity = issue.overridenSeverity();
+ if (overridenSeverity != null) {
+ jsonWriter.prop("severity", overridenSeverity.name());
+ }
+ jsonWriter.endObject();
}
jsonWriter.endArray()
.endObject()
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java
index 63135f0dc03..09ed5a9f133 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/BaseSensorContext.java
@@ -24,15 +24,15 @@ 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.SensorStorage;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorStorage;
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.IssueBuilder;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
+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;
@@ -56,7 +56,7 @@ import java.util.List;
* @author julien
*
*/
-public abstract class BaseSensorContext implements SensorContext, SensorStorage<Measure<Serializable>> {
+public abstract class BaseSensorContext implements SensorContext, SensorStorage {
private final Settings settings;
private final FileSystem fs;
@@ -96,8 +96,8 @@ public abstract class BaseSensorContext implements SensorContext, SensorStorage<
}
@Override
- public IssueBuilder issueBuilder() {
- return new DefaultIssueBuilder();
+ public Issue newIssue() {
+ return new DefaultIssue(this);
}
@Override
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java
index 5c9559a90eb..545a8d17626 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContext.java
@@ -36,7 +36,7 @@ import java.util.Map;
public class DefaultFileLinesContext implements FileLinesContext {
- private final NewMeasureCache measureCache;
+ private final MeasureCache measureCache;
private final InputFile inputFile;
/**
@@ -46,7 +46,7 @@ public class DefaultFileLinesContext implements FileLinesContext {
private String projectKey;
private MetricFinder metricFinder;
- public DefaultFileLinesContext(MetricFinder metricFinder, NewMeasureCache measureCache, String projectKey, InputFile inputFile) {
+ public DefaultFileLinesContext(MetricFinder metricFinder, MeasureCache measureCache, String projectKey, InputFile inputFile) {
this.metricFinder = metricFinder;
this.projectKey = projectKey;
Preconditions.checkNotNull(measureCache);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java
index 78086efdd8e..c93fb84312f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultFileLinesContextFactory.java
@@ -30,12 +30,12 @@ import org.sonar.batch.scan.filesystem.InputPathCache;
public class DefaultFileLinesContextFactory implements FileLinesContextFactory {
- private final NewMeasureCache measureCache;
+ private final MeasureCache measureCache;
private final MetricFinder metricFinder;
private final ProjectDefinition def;
private InputPathCache fileCache;
- public DefaultFileLinesContextFactory(InputPathCache fileCache, FileSystem fs, MetricFinder metricFinder, NewMeasureCache measureCache,
+ public DefaultFileLinesContextFactory(InputPathCache fileCache, FileSystem fs, MetricFinder metricFinder, MeasureCache measureCache,
ProjectDefinition def) {
this.fileCache = fileCache;
this.metricFinder = metricFinder;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java
new file mode 100644
index 00000000000..61ce8f9166f
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java
@@ -0,0 +1,104 @@
+/*
+ * 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.persistit.Value;
+import com.persistit.encoding.CoderContext;
+import com.persistit.encoding.ValueCoder;
+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.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.issue.Issue.Severity;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.scan.filesystem.InputPathCache;
+
+class DefaultIssueValueCoder implements ValueCoder {
+
+ private final InputPathCache inputPathCache;
+
+ public DefaultIssueValueCoder(InputPathCache inputPathCache) {
+ this.inputPathCache = inputPathCache;
+ }
+
+ @Override
+ public void put(Value value, Object object, CoderContext context) {
+ DefaultIssue issue = (DefaultIssue) object;
+ value.putString(issue.key());
+ InputPath inputPath = issue.inputPath();
+ if (inputPath != null) {
+ if (inputPath instanceof InputDir) {
+ value.put(0);
+ value.putString(((DefaultInputDir) inputPath).moduleKey());
+ value.putString(inputPath.relativePath());
+ } else {
+ value.put(1);
+ value.putString(((DefaultInputFile) inputPath).moduleKey());
+ value.putString(inputPath.relativePath());
+ value.put(issue.line());
+ }
+ } else {
+ value.putNull();
+ }
+ value.put(issue.message());
+ value.put(issue.effortToFix());
+ value.put(issue.ruleKey().repository());
+ value.put(issue.ruleKey().rule());
+ Severity overridenSeverity = issue.overridenSeverity();
+ if (overridenSeverity == null) {
+ value.putNull();
+ } else {
+ value.put(overridenSeverity.ordinal());
+ }
+ }
+
+ @Override
+ public Object get(Value value, Class clazz, CoderContext context) {
+ DefaultIssue newIssue = new DefaultIssue(null);
+ newIssue.withKey(value.getString());
+ if (value.isNull(true)) {
+ newIssue.onProject();
+ } else {
+ int type = value.getInt();
+ String moduleKey = value.getString();
+ String relativePath = value.getString();
+ if (type == 0) {
+ InputDir dir = inputPathCache.getDir(moduleKey, relativePath);
+ newIssue.onDir(dir);
+ } else {
+ InputFile f = inputPathCache.getFile(moduleKey, relativePath);
+ newIssue.onFile(f);
+ if (!value.isNull(true)) {
+ newIssue.atLine(value.getInt());
+ }
+ }
+ }
+ newIssue.message(value.getString());
+ newIssue.effortToFix(value.isNull(true) ? null : value.getDouble());
+ String repo = value.getString();
+ String rule = value.getString();
+ newIssue.ruleKey(RuleKey.of(repo, rule));
+ newIssue.overrideSeverity(value.isNull(true) ? null : Severity.values()[value.getInt()]);
+ return newIssue;
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java
index 53ab539df7b..e0beb814130 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java
@@ -51,7 +51,7 @@ class DefaultMeasureValueCoder implements ValueCoder {
} else {
value.putNull();
}
- value.putUTF(m.metric().key());
+ value.putString(m.metric().key());
value.put(m.value());
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
index 51c13e2bf93..e02999d2375 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
@@ -71,8 +71,8 @@ public class DefaultSensorContext extends BaseSensorContext {
CoreMetrics.FILE_TANGLE_INDEX,
CoreMetrics.FILE_TANGLES
);
- private final NewMeasureCache measureCache;
- private final AnalyzerIssueCache issueCache;
+ private final MeasureCache measureCache;
+ private final IssueCache issueCache;
private final ProjectDefinition def;
private final ActiveRules activeRules;
private final IssueFilters issueFilters;
@@ -80,7 +80,7 @@ public class DefaultSensorContext extends BaseSensorContext {
private final CoveragePerTestCache coveragePerTestCache;
private final DependencyCache dependencyCache;
- public DefaultSensorContext(ProjectDefinition def, NewMeasureCache measureCache, AnalyzerIssueCache issueCache,
+ public DefaultSensorContext(ProjectDefinition def, MeasureCache measureCache, IssueCache issueCache,
Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache,
BlockCache blockCache, DuplicationCache duplicationCache, TestCaseCache testCaseCache, CoveragePerTestCache coveragePerTestCache, DependencyCache dependencyCache) {
super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache);
@@ -95,10 +95,10 @@ public class DefaultSensorContext extends BaseSensorContext {
}
@Override
- public void store(Measure<Serializable> newMeasure) {
+ public void store(Measure newMeasure) {
DefaultMeasure<Serializable> measure = (DefaultMeasure<Serializable>) newMeasure;
if (INTERNAL_METRICS.contains(measure.metric())) {
- LOG.warn("Metric " + measure.metric() + " is an internal metric computed by SonarQube. Please update your plugin.");
+ LOG.warn("Metric " + measure.metric().key() + " is an internal metric computed by SonarQube. Please update your plugin.");
return;
}
InputFile inputFile = measure.inputFile();
@@ -110,7 +110,7 @@ public class DefaultSensorContext extends BaseSensorContext {
}
@Override
- public boolean addIssue(Issue issue) {
+ public void store(Issue issue) {
String resourceKey;
if (issue.inputPath() != null) {
resourceKey = ComponentKeys.createEffectiveKey(def.getKey(), issue.inputPath());
@@ -121,7 +121,8 @@ public class DefaultSensorContext extends BaseSensorContext {
DefaultActiveRule activeRule = (DefaultActiveRule) activeRules.find(ruleKey);
if (activeRule == null) {
// rule does not exist or is not enabled -> ignore the issue
- return false;
+ 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));
@@ -129,21 +130,16 @@ public class DefaultSensorContext extends BaseSensorContext {
updateIssue((DefaultIssue) issue, activeRule);
- if (issueFilters.accept(SensorContextAdapter.toDefaultIssue(def.getKey(), resourceKey, issue), null)) {
- issueCache.put(def.getKey(), resourceKey, (DefaultIssue) issue);
- return true;
+ if (!issueFilters.accept(SensorContextAdapter.toDefaultIssue(def.getKey(), resourceKey, issue), null)) {
+ LOG.debug("Issue {} was excluded by some filters.", issue);
+ return;
}
-
- return false;
+ issueCache.put(def.getKey(), resourceKey, (DefaultIssue) issue);
}
private void updateIssue(DefaultIssue issue, DefaultActiveRule activeRule) {
if (Strings.isNullOrEmpty(issue.message())) {
- issue.setMessage(activeRule.name());
- }
-
- if (issue.severity() == null) {
- issue.setSeverity(activeRule.severity());
+ issue.message(activeRule.name());
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/IssueCache.java
index 9b0fd3f6d60..5de18c1b8c3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerIssueCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/IssueCache.java
@@ -19,21 +19,22 @@
*/
package org.sonar.batch.scan2;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
-
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Caches;
+import org.sonar.batch.scan.filesystem.InputPathCache;
/**
* Shared issues among all project modules
*/
-public class AnalyzerIssueCache implements BatchComponent {
+public class IssueCache implements BatchComponent {
// project key -> resource key -> issue key -> issue
private final Cache<DefaultIssue> cache;
- public AnalyzerIssueCache(Caches caches) {
+ public IssueCache(Caches caches, InputPathCache inputPathCache) {
+ caches.registerValueCoder(DefaultIssue.class, new DefaultIssueValueCoder(inputPathCache));
cache = caches.createCache("issues");
}
@@ -45,7 +46,7 @@ public class AnalyzerIssueCache implements BatchComponent {
return cache.values();
}
- public AnalyzerIssueCache put(String projectKey, String resourceKey, DefaultIssue issue) {
+ public IssueCache put(String projectKey, String resourceKey, DefaultIssue issue) {
cache.put(projectKey, resourceKey, issue.key(), issue);
return this;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/NewMeasureCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java
index 361ed8c181b..57fe7dddbc0 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/NewMeasureCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/MeasureCache.java
@@ -31,12 +31,12 @@ import org.sonar.batch.scan.filesystem.InputPathCache;
/**
* Cache of all measures. This cache is shared amongst all project modules.
*/
-public class NewMeasureCache implements BatchComponent {
+public class MeasureCache implements BatchComponent {
// project key -> component key -> metric key -> measure
private final Cache<DefaultMeasure> cache;
- public NewMeasureCache(Caches caches, MetricFinder metricFinder, InputPathCache inputPathCache) {
+ public MeasureCache(Caches caches, MetricFinder metricFinder, InputPathCache inputPathCache) {
caches.registerValueCoder(DefaultMeasure.class, new DefaultMeasureValueCoder(metricFinder, inputPathCache));
cache = caches.createCache("measures");
}
@@ -53,7 +53,7 @@ public class NewMeasureCache implements BatchComponent {
return cache.get(projectKey, resourceKey, metricKey);
}
- public NewMeasureCache put(String projectKey, String resourceKey, DefaultMeasure<?> measure) {
+ public MeasureCache put(String projectKey, String resourceKey, DefaultMeasure<?> measure) {
Preconditions.checkNotNull(projectKey);
Preconditions.checkNotNull(resourceKey);
Preconditions.checkNotNull(measure);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
index 09b5bdf8db8..8eeb6c5b113 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
@@ -101,14 +101,14 @@ public class ProjectScanContainer extends ComponentContainer {
DefaultLanguagesReferential.class,
// Measures
- NewMeasureCache.class,
+ MeasureCache.class,
// file system
InputPathCache.class,
PathResolver.class,
// issues
- AnalyzerIssueCache.class,
+ IssueCache.class,
// Syntax highlighting and symbols
ComponentDataCache.class,
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
index 0cbe96dd48f..146761ad94f 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.issue.Issue.Severity;
import org.sonar.batch.mediumtest.BatchMediumTester;
import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult;
import org.sonar.batch.protocol.input.ActiveRule;
@@ -91,7 +92,7 @@ public class IssuesMediumTest {
.property("sonar.oneIssuePerLine.forceSeverity", "CRITICAL")
.start();
- assertThat(result.issues().iterator().next().severity()).isEqualTo("CRITICAL");
+ assertThat(result.issues().iterator().next().overridenSeverity()).isEqualTo(Severity.CRITICAL);
}
@Test
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
index a93e87dfe2a..865e3b50f6b 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
@@ -31,7 +31,7 @@ import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
-import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
+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;
@@ -84,7 +84,7 @@ public class SensorContextAdapterTest {
assertThat(adaptor.fileSystem()).isEqualTo(fs);
assertThat(adaptor.settings()).isEqualTo(settings);
- assertThat(adaptor.issueBuilder()).isNotNull();
+ assertThat(adaptor.newIssue()).isNotNull();
assertThat(adaptor.newMeasure()).isNotNull();
}
@@ -116,13 +116,12 @@ public class SensorContextAdapterTest {
when(issuable.addIssue(argumentCaptor.capture())).thenReturn(true);
- adaptor.addIssue(new DefaultIssueBuilder()
+ adaptor.store(new DefaultIssue()
.onFile(file)
.ruleKey(RuleKey.of("foo", "bar"))
.message("Foo")
.atLine(3)
- .effortToFix(10.0)
- .build());
+ .effortToFix(10.0));
Issue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
index f01ab0fa900..a0be6e447ab 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/Sensor.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor;
-import com.google.common.annotations.Beta;
import org.sonar.api.BatchExtension;
/**
@@ -32,9 +31,8 @@ import org.sonar.api.BatchExtension;
* For example the Cobertura Sensor parses Cobertura report and saves the first-level of measures on files.
* </p>
*
- * @since 4.4
+ * @since 5.0
*/
-@Beta
public interface Sensor extends BatchExtension {
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
index 016bda15f94..b79471f7975 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor;
-import com.google.common.annotations.Beta;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.ActiveRules;
@@ -28,7 +27,6 @@ import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
import org.sonar.api.batch.sensor.duplication.DuplicationTokenBuilder;
import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
import org.sonar.api.batch.sensor.issue.Issue;
-import org.sonar.api.batch.sensor.issue.IssueBuilder;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
import org.sonar.api.batch.sensor.test.TestCase;
@@ -41,9 +39,9 @@ import java.io.Serializable;
import java.util.List;
/**
- * @since 4.4
+ * See {@link Sensor#execute(SensorContext)}
+ * @since 5.0
*/
-@Beta
public interface SensorContext {
/**
@@ -64,26 +62,16 @@ public interface SensorContext {
// ----------- MEASURES --------------
/**
- * Builder to create a new {@link Measure}.
+ * Fluent builder to create a new {@link Measure}. Don't forget to call {@link Measure#save()} once all parameters are provided.
*/
<G extends Serializable> Measure<G> newMeasure();
// ----------- ISSUES --------------
/**
- * Builder to create a new {@link Issue}.
+ * Fluent builder to create a new {@link Issue}. Don't forget to call {@link Issue#save()} once all parameters are provided.
*/
- IssueBuilder issueBuilder();
-
- /**
- * Add an issue. Use {@link #issueBuilder()} to create the new issue.
- * @return <code>true</code> if the new issue is registered, <code>false</code> if:
- * <ul>
- * <li>the rule does not exist</li>
- * <li>the rule is disabled in the Quality profile</li>
- * </ul>
- */
- boolean addIssue(Issue issue);
+ Issue newIssue();
// ------------ HIGHLIGHTING ------------
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
index 9fcd030e553..a2187c13c49 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java
@@ -19,16 +19,15 @@
*/
package org.sonar.api.batch.sensor;
-import com.google.common.annotations.Beta;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.Metric;
/**
* Describe what an {@link Sensor} is doing. Information may be used by the platform
* to log interesting information or perform some optimization.
- * @since 4.4
+ * See {@link Sensor#describe(SensorDescriptor)}
+ * @since 5.0
*/
-@Beta
public interface SensorDescriptor {
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java
index c48035c8101..ce2bbc1dbd3 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorStorage.java
@@ -19,11 +19,17 @@
*/
package org.sonar.api.batch.sensor;
+import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.measure.Measure;
+
/**
* Interface for storing data computed by sensors.
+ * @since 5.0
*/
-public interface SensorStorage<G> {
+public interface SensorStorage {
+
+ void store(Measure measure);
- void store(G data);
+ void store(Issue issue);
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java
index a8d2512542a..e126ddef95b 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/Issue.java
@@ -20,25 +20,35 @@
package org.sonar.api.batch.sensor.issue;
import com.google.common.annotations.Beta;
+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.sensor.Sensor;
import org.sonar.api.rule.RuleKey;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
/**
- * Issue reported by an {@link Sensor}
+ * Represents an issue detected by a {@link Sensor}.
*
- * @since 4.4
+ * @since 5.0
*/
@Beta
public interface Issue {
+ public enum Severity {
+ INFO,
+ MINOR,
+ MAJOR,
+ CRITICAL,
+ BLOCKER;
+ }
+
/**
- * The {@link InputPath} this issue belongs to. Returns null if issue is global to the project.
+ * The {@link RuleKey} of the issue.
*/
- @CheckForNull
- InputPath inputPath();
+ Issue ruleKey(RuleKey ruleKey);
/**
* The {@link RuleKey} of this issue.
@@ -46,10 +56,31 @@ public interface Issue {
RuleKey ruleKey();
/**
- * Message of the issue.
+ * The {@link InputFile} the issue belongs to. For global issues call {@link #onProject()}.
+ */
+ Issue onFile(InputFile file);
+
+ /**
+ * The {@link InputDir} the issue belongs to. For global issues call {@link #onProject()}.
+ */
+ Issue onDir(InputDir inputDir);
+
+ /**
+ * Tell that the issue is global to the project.
+ */
+ Issue onProject();
+
+ /**
+ * The {@link InputPath} this issue belongs to. Returns null if issue is global to the project.
*/
@CheckForNull
- String message();
+ InputPath inputPath();
+
+ /**
+ * Line of the issue. Only available for {@link #onFile(InputFile)} issues.
+ * If no line is specified it means that issue is global to the file.
+ */
+ Issue atLine(int line);
/**
* Line of the issue. Null for global issues and issues on directories. Can also be null
@@ -59,16 +90,43 @@ public interface Issue {
Integer line();
/**
+ * Effort to fix the issue.
+ */
+ Issue effortToFix(@Nullable Double effortToFix);
+
+ /**
* Effort to fix the issue. Used by technical debt model.
*/
@CheckForNull
Double effortToFix();
/**
- * See constants in {@link org.sonar.api.rule.Severity}.
- * Can be null before issue is saved. Means to use severity configured in quality profile.
+ * Message of the issue.
+ */
+ Issue message(String message);
+
+ /**
+ * Message of the issue.
*/
@CheckForNull
- String severity();
+ String message();
+
+ /**
+ * Override severity of the issue.
+ * Setting a null value or not calling this method means to use severity configured in quality profile.
+ */
+ Issue overrideSeverity(@Nullable Severity severity);
+
+ /**
+ * Overriden severity.
+ */
+ @CheckForNull
+ Severity overridenSeverity();
+
+ /**
+ * Save the issue. If rule key is unknow or rule not enabled in the current quality profile then a warning is logged but no exception
+ * is thrown.
+ */
+ void save();
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/IssueBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/IssueBuilder.java
deleted file mode 100644
index f6b4fa85aaa..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/IssueBuilder.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.batch.sensor.issue;
-
-import com.google.common.annotations.Beta;
-import org.sonar.api.batch.fs.InputDir;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-
-import javax.annotation.Nullable;
-
-/**
- * Builder for {@link Issue}.
- *
- * @since 4.4
- */
-@Beta
-public interface IssueBuilder {
-
- /**
- * The {@link RuleKey} of the issue.
- */
- IssueBuilder ruleKey(RuleKey ruleKey);
-
- /**
- * The {@link InputFile} the issue belongs to. For global issues call {@link #onProject()}.
- */
- IssueBuilder onFile(InputFile file);
-
- /**
- * The {@link InputDir} the issue belongs to. For global issues call {@link #onProject()}.
- */
- IssueBuilder onDir(InputDir inputDir);
-
- /**
- * Tell that the issue is global to the project.
- */
- IssueBuilder onProject();
-
- /**
- * Line of the issue. Only available for {@link #onFile(InputFile)} issues.
- * If no line is specified it means that issue is global to the file.
- */
- IssueBuilder atLine(int line);
-
- /**
- * Effort to fix the issue.
- */
- IssueBuilder effortToFix(@Nullable Double effortToFix);
-
- /**
- * Message of the issue.
- */
- IssueBuilder message(String message);
-
- /**
- * Severity of the issue. See {@link Severity}.
- * Setting a null value means to use severity configured in quality profile.
- */
- IssueBuilder severity(@Nullable String severity);
-
- /**
- * Build the issue. After call of this method the builder is cleaned and can be used to build another issue.
- */
- Issue build();
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
index f3b56f73b6c..23148378f35 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
@@ -23,82 +23,152 @@ import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
+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.sensor.SensorStorage;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.rule.RuleKey;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import java.io.Serializable;
import java.util.UUID;
-public class DefaultIssue implements Issue, Serializable {
+public class DefaultIssue implements Issue {
- private final String key;
- private final InputPath inputPath;
- private final RuleKey ruleKey;
+ private static final String INPUT_DIR_SHOULD_BE_NON_NULL = "InputDir should be non null";
+ private static final String INPUT_FILE_SHOULD_BE_NON_NULL = "InputFile should be non null";
+ private static final String ON_FILE_OR_ON_DIR_ALREADY_CALLED = "onFile or onDir already called";
+ private static final String ON_PROJECT_ALREADY_CALLED = "onProject already called";
+ private String key;
+ private boolean onProject = false;
+ private InputPath path;
+ private RuleKey ruleKey;
private String message;
- private final Integer line;
- private final Double effortToFix;
- private String severity;
-
- DefaultIssue(DefaultIssueBuilder builder) {
- Preconditions.checkNotNull(builder.ruleKey, "ruleKey is mandatory on issue");
- this.inputPath = builder.path;
- this.ruleKey = builder.ruleKey;
- this.message = builder.message;
- this.line = builder.line;
- this.effortToFix = builder.effortToFix;
- this.severity = builder.severity;
- this.key = builder.key == null ? UUID.randomUUID().toString() : builder.key;
- Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key");
+ private Integer line;
+ private Double effortToFix;
+ private Severity overridenSeverity;
+ private final SensorStorage storage;
+
+ public DefaultIssue() {
+ this.storage = null;
}
- public String key() {
- return key;
+ public DefaultIssue(SensorStorage storage) {
+ this.storage = storage;
}
@Override
- @Nullable
- public InputPath inputPath() {
- return inputPath;
+ public DefaultIssue ruleKey(RuleKey ruleKey) {
+ this.ruleKey = ruleKey;
+ return this;
}
@Override
- public RuleKey ruleKey() {
- return ruleKey;
+ public DefaultIssue onFile(InputFile file) {
+ Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+ Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
+ Preconditions.checkNotNull(file, INPUT_FILE_SHOULD_BE_NON_NULL);
+ this.path = file;
+ return this;
}
- @CheckForNull
@Override
- public String message() {
- return message;
+ public DefaultIssue onDir(InputDir dir) {
+ Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+ Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
+ Preconditions.checkNotNull(dir, INPUT_DIR_SHOULD_BE_NON_NULL);
+ this.path = dir;
+ return this;
+ }
+
+ @Override
+ public DefaultIssue onProject() {
+ Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
+ Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
+ this.onProject = true;
+ return this;
+ }
+
+ @Override
+ public DefaultIssue atLine(int line) {
+ Preconditions.checkState(this.path != null && this.path instanceof InputFile, "atLine should be called after onFile");
+ this.line = line;
+ return this;
+ }
+
+ @Override
+ public DefaultIssue effortToFix(@Nullable Double effortToFix) {
+ this.effortToFix = effortToFix;
+ return this;
}
- public void setMessage(String message) {
+ @Override
+ public DefaultIssue message(String message) {
this.message = message;
+ return this;
+ }
+
+ @Override
+ public Issue overrideSeverity(@Nullable Severity severity) {
+ this.overridenSeverity = severity;
+ return this;
+ }
+
+ @Override
+ public RuleKey ruleKey() {
+ return this.ruleKey;
+ }
+
+ @CheckForNull
+ @Override
+ public InputPath inputPath() {
+ return this.path;
}
@Override
public Integer line() {
- return line;
+ return this.line;
+ }
+
+ @Override
+ public String message() {
+ return this.message;
+ }
+
+ @Override
+ public Severity overridenSeverity() {
+ return this.overridenSeverity;
}
@Override
- @Nullable
public Double effortToFix() {
- return effortToFix;
+ return this.effortToFix;
+ }
+
+ public String key() {
+ return this.key;
}
@Override
- @CheckForNull
- public String severity() {
- return severity;
+ public void save() {
+ Preconditions.checkNotNull(this.storage, "No persister on this object");
+ Preconditions.checkNotNull(this.ruleKey, "ruleKey is mandatory on issue");
+ if (this.key == null) {
+ this.key = UUID.randomUUID().toString();
+ }
+ Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key");
+
+ storage.store(this);
}
- public void setSeverity(String severity) {
- this.severity = severity;
+ /**
+ * For testing only.
+ */
+ public DefaultIssue withKey(String key) {
+ this.key = key;
+ return this;
}
@Override
@@ -122,5 +192,4 @@ public class DefaultIssue implements Issue, Serializable {
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
-
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueBuilder.java
deleted file mode 100644
index 10c0c71f5be..00000000000
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueBuilder.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.api.batch.sensor.issue.internal;
-
-import com.google.common.base.Preconditions;
-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.sensor.issue.IssueBuilder;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-
-import javax.annotation.Nullable;
-
-public class DefaultIssueBuilder implements IssueBuilder {
-
- private static final String INPUT_DIR_SHOULD_BE_NON_NULL = "InputDir should be non null";
- private static final String INPUT_FILE_SHOULD_BE_NON_NULL = "InputFile should be non null";
- private static final String ON_FILE_OR_ON_DIR_ALREADY_CALLED = "onFile or onDir already called";
- private static final String ON_PROJECT_ALREADY_CALLED = "onProject already called";
- String key;
- boolean onProject = false;
- InputPath path;
- RuleKey ruleKey;
- String message;
- Integer line;
- Double effortToFix;
- String severity;
-
- @Override
- public DefaultIssueBuilder ruleKey(RuleKey ruleKey) {
- this.ruleKey = ruleKey;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder onFile(InputFile file) {
- Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
- Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
- Preconditions.checkNotNull(file, INPUT_FILE_SHOULD_BE_NON_NULL);
- this.path = file;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder onDir(InputDir dir) {
- Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
- Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
- Preconditions.checkNotNull(dir, INPUT_DIR_SHOULD_BE_NON_NULL);
- this.path = dir;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder onProject() {
- Preconditions.checkState(!this.onProject, ON_PROJECT_ALREADY_CALLED);
- Preconditions.checkState(this.path == null, ON_FILE_OR_ON_DIR_ALREADY_CALLED);
- this.onProject = true;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder atLine(int line) {
- Preconditions.checkState(this.path != null && this.path instanceof InputFile, "atLine should be called after onFile");
- this.line = line;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder effortToFix(@Nullable Double effortToFix) {
- this.effortToFix = effortToFix;
- return this;
- }
-
- @Override
- public DefaultIssueBuilder message(String message) {
- this.message = message;
- return this;
- }
-
- @Override
- public IssueBuilder severity(@Nullable String severity) {
- Preconditions.checkState(severity == null || Severity.ALL.contains(severity), "Invalid severity: " + severity);
- this.severity = severity;
- return this;
- }
-
- /**
- * For testing only.
- */
- public DefaultIssueBuilder withKey(String key) {
- this.key = key;
- return this;
- }
-
- @Override
- public DefaultIssue build() {
- DefaultIssue result = new DefaultIssue(this);
- reset();
- return result;
- }
-
- private void reset() {
- key = null;
- onProject = false;
- path = null;
- ruleKey = null;
- message = null;
- line = null;
- effortToFix = null;
- severity = null;
- }
-
-}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java
index 2ce2cf98361..86a0abdffad 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/Measure.java
@@ -19,7 +19,6 @@
*/
package org.sonar.api.batch.sensor.measure;
-import com.google.common.annotations.Beta;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.Metric;
@@ -29,9 +28,8 @@ import java.io.Serializable;
/**
* Builder to create new Measure.
- * @since 4.4
+ * @since 5.0
*/
-@Beta
public interface Measure<G extends Serializable> {
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
index f6b191355c7..fee7172f9ea 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasure.java
@@ -36,7 +36,7 @@ import java.io.Serializable;
public class DefaultMeasure<G extends Serializable> implements Measure<G> {
- private final SensorStorage<DefaultMeasure<G>> measureStorage;
+ private final SensorStorage storage;
private boolean onProject = false;
private InputFile file;
private Metric<G> metric;
@@ -44,11 +44,11 @@ public class DefaultMeasure<G extends Serializable> implements Measure<G> {
private boolean saved = false;
public DefaultMeasure() {
- this.measureStorage = null;
+ this.storage = null;
}
- public DefaultMeasure(@Nullable SensorStorage<DefaultMeasure<G>> measureStorage) {
- this.measureStorage = measureStorage;
+ public DefaultMeasure(@Nullable SensorStorage storage) {
+ this.storage = storage;
}
@Override
@@ -86,14 +86,12 @@ public class DefaultMeasure<G extends Serializable> implements Measure<G> {
@Override
public void save() {
- Preconditions.checkNotNull(this.measureStorage, "No persister on this object");
+ Preconditions.checkNotNull(this.storage, "No persister on this object");
Preconditions.checkState(!saved, "This measure was already saved");
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());
- if (measureStorage != null) {
- measureStorage.store(this);
- }
+ storage.store((Measure<Serializable>) this);
this.saved = true;
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
index 6c0d12da82c..722f0948120 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssueTest.java
@@ -23,10 +23,12 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.SensorStorage;
import org.sonar.api.rule.RuleKey;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
public class DefaultIssueTest {
@@ -35,58 +37,56 @@ public class DefaultIssueTest {
@Test
public void build_file_issue() {
- Issue issue = new DefaultIssueBuilder()
+ SensorStorage storage = mock(SensorStorage.class);
+ DefaultIssue issue = new DefaultIssue(storage)
.onFile(new DefaultInputFile("foo", "src/Foo.php"))
.ruleKey(RuleKey.of("repo", "rule"))
.atLine(1)
.effortToFix(10.0)
- .message("Wrong way!")
- .build();
+ .message("Wrong way!");
assertThat(issue.inputPath()).isEqualTo(new DefaultInputFile("foo", "src/Foo.php"));
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
assertThat(issue.line()).isEqualTo(1);
assertThat(issue.effortToFix()).isEqualTo(10.0);
assertThat(issue.message()).isEqualTo("Wrong way!");
+
+ issue.save();
+
+ verify(storage).store(issue);
}
@Test
public void build_project_issue() {
- Issue issue = new DefaultIssueBuilder()
+ SensorStorage storage = mock(SensorStorage.class);
+ DefaultIssue issue = new DefaultIssue(storage)
.onProject()
.ruleKey(RuleKey.of("repo", "rule"))
.effortToFix(10.0)
- .message("Wrong way!")
- .build();
+ .message("Wrong way!");
assertThat(issue.inputPath()).isNull();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("repo", "rule"));
assertThat(issue.line()).isNull();
assertThat(issue.effortToFix()).isEqualTo(10.0);
assertThat(issue.message()).isEqualTo("Wrong way!");
+
+ issue.save();
+
+ verify(storage).store(issue);
}
@Test
public void not_allowed_to_call_onFile_and_onProject() {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("onProject already called");
- new DefaultIssueBuilder()
+ new DefaultIssue()
.onProject()
.onFile(new DefaultInputFile("foo", "src/Foo.php"))
.ruleKey(RuleKey.of("repo", "rule"))
.atLine(1)
.effortToFix(10.0)
- .message("Wrong way!")
- .build();
- }
-
- @Test
- public void validate_severity() {
- thrown.expect(IllegalStateException.class);
- thrown.expectMessage("Invalid severity: FOO");
- new DefaultIssueBuilder()
- .severity("FOO")
- .build();
+ .message("Wrong way!");
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java
index 7085ca90169..7fa5fbfc593 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/measure/internal/DefaultMeasureTest.java
@@ -37,8 +37,8 @@ public class DefaultMeasureTest {
@Test
public void build_file_measure() {
- SensorStorage<DefaultMeasure<Integer>> persister = mock(SensorStorage.class);
- DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(persister)
+ SensorStorage storage = mock(SensorStorage.class);
+ DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage)
.forMetric(CoreMetrics.LINES)
.onFile(new DefaultInputFile("foo", "src/Foo.php"))
.withValue(3);
@@ -49,13 +49,13 @@ public class DefaultMeasureTest {
newMeasure.save();
- verify(persister).store(newMeasure);
+ verify(storage).store(newMeasure);
}
@Test
public void build_project_measure() {
- SensorStorage<DefaultMeasure<Integer>> persister = mock(SensorStorage.class);
- DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(persister)
+ SensorStorage storage = mock(SensorStorage.class);
+ DefaultMeasure<Integer> newMeasure = new DefaultMeasure<Integer>(storage)
.forMetric(CoreMetrics.LINES)
.onProject()
.withValue(3);
@@ -66,7 +66,7 @@ public class DefaultMeasureTest {
newMeasure.save();
- verify(persister).store(newMeasure);
+ verify(storage).store(newMeasure);
}
@Test