aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepository.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImpl.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/IntegrateIssuesVisitor.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/issue/MutableComponentIssuesRepository.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureComputersVisitor.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContext.java22
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImplTest.java5
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureComputersVisitorTest.java12
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContextTest.java58
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java7
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/Issue.java52
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java6
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/IssueImpl.java157
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImplementationContext.java12
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/package-info.java24
16 files changed, 351 insertions, 43 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepository.java
index 51a87d20910..fd8900ce56a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepository.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepository.java
@@ -22,7 +22,7 @@ package org.sonar.server.computation.issue;
import java.util.List;
import org.sonar.api.ce.measure.MeasureComputer;
-import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
/**
@@ -40,6 +40,6 @@ public interface ComponentIssuesRepository {
* @throws IllegalStateException if no issues have been set
* @throws IllegalArgumentException if the component is not the component that contains current issues.
*/
- List<Issue> getIssues(Component component);
+ List<DefaultIssue> getIssues(Component component);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImpl.java
index 16dfd4c9242..b4248320df8 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImpl.java
@@ -22,7 +22,7 @@ package org.sonar.server.computation.issue;
import java.util.List;
import javax.annotation.CheckForNull;
-import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
import static com.google.common.base.Preconditions.checkArgument;
@@ -32,19 +32,19 @@ import static java.util.Objects.requireNonNull;
public class ComponentIssuesRepositoryImpl implements MutableComponentIssuesRepository {
@CheckForNull
- private List<Issue> issues;
+ private List<DefaultIssue> issues;
@CheckForNull
private Component component;
@Override
- public void setIssues(Component component, List<Issue> issues) {
+ public void setIssues(Component component, List<DefaultIssue> issues) {
this.issues = requireNonNull(issues, "issues cannot be null");
this.component = requireNonNull(component, "component cannot be null");
}
@Override
- public List<Issue> getIssues(Component component) {
+ public List<DefaultIssue> getIssues(Component component) {
checkState(this.component != null && this.issues != null, "Issues have not been initialized");
checkArgument(component.equals(this.component),
String.format("Only issues from component '%s' are available, but wanted component is '%s'.",
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IntegrateIssuesVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IntegrateIssuesVisitor.java
index 595b51160ee..db9cfb79529 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IntegrateIssuesVisitor.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/IntegrateIssuesVisitor.java
@@ -22,7 +22,6 @@ package org.sonar.server.computation.issue;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import org.sonar.api.issue.Issue;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.tracking.Tracking;
@@ -42,7 +41,7 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter {
private final MutableComponentIssuesRepository componentIssuesRepository;
private final ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues;
- private final List<Issue> componentIssues = new ArrayList<>();
+ private final List<DefaultIssue> componentIssues = new ArrayList<>();
public IntegrateIssuesVisitor(TrackerExecution tracker, IssueCache issueCache, IssueLifecycle issueLifecycle, IssueVisitors issueVisitors,
ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues, MutableComponentIssuesRepository componentIssuesRepository) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/MutableComponentIssuesRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/MutableComponentIssuesRepository.java
index 6086381ee18..a860d460a39 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/issue/MutableComponentIssuesRepository.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/issue/MutableComponentIssuesRepository.java
@@ -21,7 +21,7 @@
package org.sonar.server.computation.issue;
import java.util.List;
-import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
public interface MutableComponentIssuesRepository extends ComponentIssuesRepository {
@@ -32,6 +32,6 @@ public interface MutableComponentIssuesRepository extends ComponentIssuesReposit
* @throws NullPointerException if {@code component} is {@code null}
* @throws NullPointerException if {@code issues} is {@code null}
*/
- void setIssues(Component component, List<Issue> issues);
+ void setIssues(Component component, List<DefaultIssue> issues);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureComputersVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureComputersVisitor.java
index b47f793a702..43ad33fdf05 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureComputersVisitor.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/MeasureComputersVisitor.java
@@ -24,6 +24,7 @@ import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.server.computation.component.CrawlerDepthLimit;
import org.sonar.server.computation.component.SettingsRepository;
import org.sonar.server.computation.component.TypeAwareVisitorAdapter;
+import org.sonar.server.computation.issue.ComponentIssuesRepository;
import org.sonar.server.computation.measure.api.MeasureComputerImplementationContext;
import org.sonar.server.computation.metric.MetricRepository;
@@ -36,20 +37,23 @@ public class MeasureComputersVisitor extends TypeAwareVisitorAdapter {
private final SettingsRepository settings;
private final MeasureComputersHolder measureComputersHolder;
+ private final ComponentIssuesRepository componentIssuesRepository;
public MeasureComputersVisitor(MetricRepository metricRepository, MeasureRepository measureRepository, SettingsRepository settings,
- MeasureComputersHolder measureComputersHolder) {
+ MeasureComputersHolder measureComputersHolder, ComponentIssuesRepository componentIssuesRepository) {
super(CrawlerDepthLimit.FILE, PRE_ORDER);
this.metricRepository = metricRepository;
this.measureRepository = measureRepository;
this.settings = settings;
this.measureComputersHolder = measureComputersHolder;
+ this.componentIssuesRepository = componentIssuesRepository;
}
@Override
public void visitAny(org.sonar.server.computation.component.Component component) {
for (MeasureComputer computer : measureComputersHolder.getMeasureComputers()) {
- MeasureComputerImplementationContext measureComputerContext = new MeasureComputerImplementationContext(component, computer, settings, measureRepository, metricRepository);
+ MeasureComputerImplementationContext measureComputerContext = new MeasureComputerImplementationContext(component, computer,
+ settings, measureRepository, metricRepository, componentIssuesRepository);
computer.getImplementation().compute(measureComputerContext);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContext.java b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContext.java
index e8f74f449a9..44516db373a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContext.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContext.java
@@ -25,15 +25,19 @@ import com.google.common.base.Optional;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.sonar.api.ce.measure.Component;
+import org.sonar.api.ce.measure.Issue;
import org.sonar.api.ce.measure.Measure;
import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.api.ce.measure.Settings;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.SettingsRepository;
+import org.sonar.server.computation.issue.ComponentIssuesRepository;
import org.sonar.server.computation.measure.MeasureRepository;
import org.sonar.server.computation.metric.Metric;
import org.sonar.server.computation.metric.MetricRepository;
@@ -50,17 +54,19 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
private final org.sonar.server.computation.component.Component internalComponent;
private final Component component;
+ private final List<DefaultIssue> componentIssues;
private final Set<String> allowedMetrics;
public MeasureComputerImplementationContext(org.sonar.server.computation.component.Component component, MeasureComputer measureComputer,
- SettingsRepository settings, MeasureRepository measureRepository, MetricRepository metricRepository) {
+ SettingsRepository settings, MeasureRepository measureRepository, MetricRepository metricRepository, ComponentIssuesRepository componentIssuesRepository) {
this.measureComputer = measureComputer;
this.settings = settings;
this.internalComponent = component;
this.measureRepository = measureRepository;
this.metricRepository = metricRepository;
this.component = newComponent(component);
+ this.componentIssues = componentIssuesRepository.getIssues(component);
this.allowedMetrics = allowedMetric(measureComputer);
}
@@ -70,11 +76,10 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
Component.Type.valueOf(component.getType().name()),
component.getType() == org.sonar.server.computation.component.Component.Type.FILE ?
new ComponentImpl.FileAttributesImpl(component.getFileAttributes().getLanguageKey(), component.getFileAttributes().isUnitTest()) :
- null
- );
+ null);
}
- private static Set<String> allowedMetric(MeasureComputer measureComputer){
+ private static Set<String> allowedMetric(MeasureComputer measureComputer) {
Set<String> allowedMetrics = new HashSet<>();
allowedMetrics.addAll(measureComputer.getInputMetrics());
allowedMetrics.addAll(measureComputer.getOutputMetrics());
@@ -102,7 +107,7 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
};
}
- private org.sonar.api.config.Settings getComponentSettings(){
+ private org.sonar.api.config.Settings getComponentSettings() {
return settings.getSettings(internalComponent);
}
@@ -165,6 +170,11 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
}
}
+ @Override
+ public List<? extends Issue> getIssues() {
+ return componentIssues;
+ }
+
private class ComponentToMeasure implements Function<org.sonar.server.computation.component.Component, Optional<org.sonar.server.computation.measure.Measure>> {
private final Metric metric;
@@ -173,7 +183,6 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
this.metric = metric;
}
- @Nullable
@Override
public Optional<org.sonar.server.computation.measure.Measure> apply(@Nonnull org.sonar.server.computation.component.Component input) {
return measureRepository.getRawMeasure(input, metric);
@@ -189,4 +198,5 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
return input.isPresent() ? new MeasureImpl(input.get()) : null;
}
}
+
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImplTest.java
index 1ec999ae1db..4188f835808 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryImplTest.java
@@ -24,7 +24,6 @@ import java.util.Arrays;
import java.util.Collections;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.api.issue.Issue;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
@@ -39,7 +38,7 @@ public class ComponentIssuesRepositoryImplTest {
static final Component FILE_1 = builder(Component.Type.FILE, 1).build();
static final Component FILE_2 = builder(Component.Type.FILE, 2).build();
- static final Issue DUMB_ISSUE = new DefaultIssue().setKey("ISSUE");
+ static final DefaultIssue DUMB_ISSUE = new DefaultIssue().setKey("ISSUE");
ComponentIssuesRepositoryImpl sut = new ComponentIssuesRepositoryImpl();
@@ -52,7 +51,7 @@ public class ComponentIssuesRepositoryImplTest {
@Test
public void set_empty_issues() throws Exception {
- sut.setIssues(FILE_1, Collections.<Issue>emptyList());
+ sut.setIssues(FILE_1, Collections.<DefaultIssue>emptyList());
assertThat(sut.getIssues(FILE_1)).isEmpty();
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
index ab7995b07e3..dd1950d026f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/issue/ComponentIssuesRepositoryRule.java
@@ -23,7 +23,7 @@ package org.sonar.server.computation.issue;
import java.util.List;
import javax.annotation.CheckForNull;
import org.junit.rules.ExternalResource;
-import org.sonar.api.issue.Issue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ReportTreeRootHolder;
@@ -37,7 +37,7 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
private final ReportTreeRootHolder reportTreeRootHolder;
@CheckForNull
- private List<Issue> issues;
+ private List<DefaultIssue> issues;
@CheckForNull
private Component component;
@@ -47,12 +47,12 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
}
@Override
- public void setIssues(Component component, List<Issue> issues) {
+ public void setIssues(Component component, List<DefaultIssue> issues) {
checkNotNull(component, "component cannot be null");
setIssues(component.getReportAttributes().getRef(), issues);
}
- public void setIssues(int componentRef, List<Issue> issues) {
+ public void setIssues(int componentRef, List<DefaultIssue> issues) {
this.issues = requireNonNull(issues, "issues cannot be null");
Component component = reportTreeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
@@ -60,12 +60,12 @@ public class ComponentIssuesRepositoryRule extends ExternalResource implements M
}
@Override
- public List<Issue> getIssues(Component component) {
+ public List<DefaultIssue> getIssues(Component component) {
checkNotNull(component, "component cannot be null");
return getIssues(component.getReportAttributes().getRef());
}
- public List<Issue> getIssues(int componentRef) {
+ public List<DefaultIssue> getIssues(int componentRef) {
checkState(this.component != null && this.issues != null, "Issues have not been initialized");
Component component = reportTreeRootHolder.getComponentByRef(componentRef);
checkArgument(component != null, String.format("Component '%s' does not exists in the report ", componentRef));
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureComputersVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureComputersVisitorTest.java
index c43e70139ec..9aa1cac9d2e 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureComputersVisitorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/MeasureComputersVisitorTest.java
@@ -25,14 +25,17 @@ import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.ce.measure.MeasureComputer;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.ComponentVisitor;
import org.sonar.server.computation.component.VisitorsCrawler;
+import org.sonar.server.computation.issue.ComponentIssuesRepository;
import org.sonar.server.computation.measure.api.MeasureComputerImpl;
import org.sonar.server.computation.metric.MetricRepositoryRule;
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES;
import static org.sonar.api.measures.CoreMetrics.COMMENT_LINES_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC;
@@ -74,6 +77,9 @@ public class MeasureComputersVisitorTest {
).build();
@Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(ROOT);
+
+ @Rule
public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
.add(NCLOC)
.add(COMMENT_LINES)
@@ -82,6 +88,8 @@ public class MeasureComputersVisitorTest {
@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(ROOT, metricRepository);
+ ComponentIssuesRepository componentIssuesRepository = mock(ComponentIssuesRepository.class);
+
MeasureComputersHolderImpl measureComputersHolder = new MeasureComputersHolderImpl();
@Test
@@ -116,7 +124,7 @@ public class MeasureComputersVisitorTest {
.build()
));
- VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new MeasureComputersVisitor(metricRepository, measureRepository, null, measureComputersHolder)));
+ VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new MeasureComputersVisitor(metricRepository, measureRepository, null, measureComputersHolder, componentIssuesRepository)));
visitorsCrawler.visit(ROOT);
assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).containsOnly(entryOf(NEW_METRIC_KEY, newMeasureBuilder().create(12)));
@@ -140,7 +148,7 @@ public class MeasureComputersVisitorTest {
measureRepository.addRawMeasure(ROOT_REF, COMMENT_LINES_KEY, newMeasureBuilder().create(7));
measureComputersHolder.setMeasureComputers(Collections.<MeasureComputer>emptyList());
- VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new MeasureComputersVisitor(metricRepository, measureRepository, null, measureComputersHolder)));
+ VisitorsCrawler visitorsCrawler = new VisitorsCrawler(Arrays.<ComponentVisitor>asList(new MeasureComputersVisitor(metricRepository, measureRepository, null, measureComputersHolder, componentIssuesRepository)));
visitorsCrawler.visit(ROOT);
assertThat(toEntries(measureRepository.getAddedRawMeasures(FILE_1_REF))).isEmpty();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContextTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContextTest.java
index 3bb8df5ba43..aa8beac7e55 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContextTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/measure/api/MeasureComputerImplementationContextTest.java
@@ -21,7 +21,9 @@
package org.sonar.server.computation.measure.api;
import com.google.common.base.Optional;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
import java.util.Set;
import org.junit.Rule;
import org.junit.Test;
@@ -29,8 +31,12 @@ import org.junit.rules.ExpectedException;
import org.sonar.api.ce.measure.Component;
import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.api.measures.CoreMetrics;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.Duration;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.SettingsRepository;
+import org.sonar.server.computation.issue.ComponentIssuesRepositoryRule;
import org.sonar.server.computation.measure.Measure;
import org.sonar.server.computation.measure.MeasureRepositoryRule;
import org.sonar.server.computation.metric.Metric;
@@ -62,7 +68,9 @@ public class MeasureComputerImplementationContextTest {
private static final String FILE_1_KEY = "fileKey";
private static final int FILE_2_REF = 12342;
- private static final org.sonar.server.computation.component.Component FILE_1 = builder(org.sonar.server.computation.component.Component.Type.FILE, FILE_1_REF).setKey(FILE_1_KEY).build();
+ private static final org.sonar.server.computation.component.Component FILE_1 = builder(org.sonar.server.computation.component.Component.Type.FILE, FILE_1_REF)
+ .setKey(FILE_1_KEY)
+ .build();
@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
@@ -78,12 +86,14 @@ public class MeasureComputerImplementationContextTest {
.add(new MetricImpl(2, INT_METRIC_KEY, "int metric", Metric.MetricType.INT))
.add(new MetricImpl(3, DOUBLE_METRIC_KEY, "double metric", Metric.MetricType.FLOAT))
.add(new MetricImpl(4, LONG_METRIC_KEY, "long metric", Metric.MetricType.MILLISEC))
- .add(new MetricImpl(5, STRING_METRIC_KEY, "string metric", Metric.MetricType.STRING))
- ;
+ .add(new MetricImpl(5, STRING_METRIC_KEY, "string metric", Metric.MetricType.STRING));
@Rule
public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
+ @Rule
+ public ComponentIssuesRepositoryRule componentIssuesRepository = new ComponentIssuesRepositoryRule(treeRootHolder);
+
SettingsRepository settingsRepository = mock(SettingsRepository.class);
@Test
@@ -173,7 +183,7 @@ public class MeasureComputerImplementationContextTest {
MeasureComputer.Implementation.Context underTest = newContext(PROJECT_REF, of(NCLOC_KEY), of(INT_METRIC_KEY));
underTest.addMeasure(INT_METRIC_KEY, 10);
- Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_KEY);
+ Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, INT_METRIC_KEY);
assertThat(measure).isPresent();
assertThat(measure.get().getIntValue()).isEqualTo(10);
}
@@ -183,7 +193,7 @@ public class MeasureComputerImplementationContextTest {
MeasureComputer.Implementation.Context underTest = newContext(PROJECT_REF, of(NCLOC_KEY), of(DOUBLE_METRIC_KEY));
underTest.addMeasure(DOUBLE_METRIC_KEY, 10d);
- Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, DOUBLE_METRIC_KEY);
+ Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, DOUBLE_METRIC_KEY);
assertThat(measure).isPresent();
assertThat(measure.get().getDoubleValue()).isEqualTo(10d);
}
@@ -193,7 +203,7 @@ public class MeasureComputerImplementationContextTest {
MeasureComputer.Implementation.Context underTest = newContext(PROJECT_REF, of(NCLOC_KEY), of(LONG_METRIC_KEY));
underTest.addMeasure(LONG_METRIC_KEY, 10L);
- Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, LONG_METRIC_KEY);
+ Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, LONG_METRIC_KEY);
assertThat(measure).isPresent();
assertThat(measure.get().getLongValue()).isEqualTo(10L);
}
@@ -203,7 +213,7 @@ public class MeasureComputerImplementationContextTest {
MeasureComputer.Implementation.Context underTest = newContext(PROJECT_REF, of(NCLOC_KEY), of(STRING_METRIC_KEY));
underTest.addMeasure(STRING_METRIC_KEY, "data");
- Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, STRING_METRIC_KEY);
+ Optional<Measure> measure = measureRepository.getAddedRawMeasure(PROJECT_REF, STRING_METRIC_KEY);
assertThat(measure).isPresent();
assertThat(measure.get().getStringValue()).isEqualTo("data");
}
@@ -228,11 +238,42 @@ public class MeasureComputerImplementationContextTest {
underTest.addMeasure(INT_METRIC_KEY, 10);
}
+ @Test
+ public void get_issues() throws Exception {
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("KEY")
+ .setRuleKey(RuleKey.of("xoo", "S01"))
+ .setSeverity("MAJOR")
+ .setStatus("CLOSED")
+ .setResolution("FIXED")
+ .setDebt(Duration.create(10l));
+
+ MeasureComputer.Implementation.Context underTest = newContext(PROJECT_REF, Arrays.asList(issue));
+
+ assertThat(underTest.getIssues()).hasSize(1);
+ org.sonar.api.ce.measure.Issue result = underTest.getIssues().get(0);
+ assertThat(result.key()).isEqualTo("KEY");
+ assertThat(result.ruleKey()).isEqualTo(RuleKey.of("xoo", "S01"));
+ assertThat(result.severity()).isEqualTo("MAJOR");
+ assertThat(result.status()).isEqualTo("CLOSED");
+ assertThat(result.resolution()).isEqualTo("FIXED");
+ assertThat(result.debt()).isEqualTo(Duration.create(10l));
+ }
+
private MeasureComputer.Implementation.Context newContext(int componentRef) {
return newContext(componentRef, Collections.<String>emptySet(), Collections.<String>emptySet());
}
+ private MeasureComputer.Implementation.Context newContext(int componentRef, List<DefaultIssue> issues) {
+ return newContext(componentRef, Collections.<String>emptySet(), Collections.<String>emptySet(), issues);
+ }
+
private MeasureComputer.Implementation.Context newContext(int componentRef, final Set<String> inputMetrics, final Set<String> outputMetrics) {
+ return newContext(componentRef, inputMetrics, outputMetrics, Collections.<DefaultIssue>emptyList());
+ }
+
+ private MeasureComputer.Implementation.Context newContext(int componentRef, final Set<String> inputMetrics, final Set<String> outputMetrics, List<DefaultIssue> issues) {
+ componentIssuesRepository.setIssues(componentRef, issues);
MeasureComputer measureComputer = new MeasureComputer() {
@Override
public Set<String> getInputMetrics() {
@@ -249,6 +290,7 @@ public class MeasureComputerImplementationContextTest {
return null;
}
};
- return new MeasureComputerImplementationContext(treeRootHolder.getComponentByRef(componentRef), measureComputer, settingsRepository, measureRepository, metricRepository);
+ return new MeasureComputerImplementationContext(treeRootHolder.getComponentByRef(componentRef), measureComputer,
+ settingsRepository, measureRepository, metricRepository, componentIssuesRepository);
}
}
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
index 7c2fd24f6cc..1b405d50294 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
@@ -51,12 +51,7 @@ import org.sonar.core.issue.tracking.Trackable;
import static java.lang.String.format;
-/**
- * PLUGINS MUST NOT BE USED THIS CLASS, EXCEPT FOR UNIT TESTING.
- *
- * @since 3.6
- */
-public class DefaultIssue implements Issue, Trackable {
+public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.Issue {
private String key;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/Issue.java
new file mode 100644
index 00000000000..e4233c2a6a5
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/Issue.java
@@ -0,0 +1,52 @@
+/*
+ * 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.ce.measure;
+
+import javax.annotation.CheckForNull;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.Duration;
+
+public interface Issue {
+
+ String key();
+
+ RuleKey ruleKey();
+
+ /**
+ * Available list of status can be found in {@link org.sonar.api.issue.Issue#STATUSES}
+ */
+ String status();
+
+ /**
+ * Available list of resolutions can be found in {@link org.sonar.api.issue.Issue#RESOLUTIONS}
+ */
+ @CheckForNull
+ String resolution();
+
+ /**
+ * See constants in {@link org.sonar.api.rule.Severity}.
+ */
+ String severity();
+
+ @CheckForNull
+ Duration debt();
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java
index 0d1e2c866f5..32d5d90e469 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/ce/measure/MeasureComputer.java
@@ -20,6 +20,7 @@
package org.sonar.api.ce.measure;
+import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
@@ -142,6 +143,11 @@ public interface MeasureComputer {
*/
void addMeasure(String metric, String value);
+ /**
+ * Return list of issues of current component.
+ */
+ List<? extends Issue> getIssues();
+
}
}
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/IssueImpl.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/IssueImpl.java
new file mode 100644
index 00000000000..0f47f4ff133
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/IssueImpl.java
@@ -0,0 +1,157 @@
+/*
+ * 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.test.ce.measure;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.ce.measure.Issue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.Duration;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class IssueImpl implements Issue {
+
+ private String key;
+ private String status;
+ private String resolution;
+ private String severity;
+ private RuleKey ruleKey;
+ private Duration debt;
+
+ private IssueImpl(Builder builder) {
+ this.key = builder.key;
+ this.status = builder.status;
+ this.resolution = builder.resolution;
+ this.severity = builder.severity;
+ this.ruleKey = builder.ruleKey;
+ this.debt = builder.debt;
+ }
+
+ @Override
+ public String key() {
+ return key;
+ }
+
+ @Override
+ public RuleKey ruleKey() {
+ return ruleKey;
+ }
+
+ @Override
+ public String status() {
+ return status;
+ }
+
+ @Override
+ @CheckForNull
+ public String resolution() {
+ return resolution;
+ }
+
+ @Override
+ public String severity() {
+ return severity;
+ }
+
+ @Override
+ @CheckForNull
+ public Duration debt() {
+ return debt;
+ }
+
+ public static class Builder {
+ private String key;
+ private String status;
+ private String resolution;
+ private String severity;
+ private RuleKey ruleKey;
+ private Duration debt;
+
+ public Builder setKey(String key) {
+ this.key = validateKey(key);
+ return this;
+ }
+
+ public Builder setResolution(@Nullable String resolution) {
+ this.resolution = validateResolution(resolution);
+ return this;
+ }
+
+ public Builder setSeverity(String severity) {
+ this.severity = validateSeverity(severity);
+ return this;
+ }
+
+ public Builder setStatus(String status) {
+ this.status = validateStatus(status);
+ return this;
+ }
+
+ public Builder setRuleKey(RuleKey ruleKey) {
+ this.ruleKey = validateRuleKey(ruleKey);
+ return this;
+ }
+
+ public Builder setDebt(@Nullable Duration debt) {
+ this.debt = debt;
+ return this;
+ }
+
+ private static String validateKey(String key){
+ checkNotNull(key, "key cannot be null");
+ return key;
+ }
+
+ private static RuleKey validateRuleKey(RuleKey ruleKey){
+ checkNotNull(ruleKey, "ruleKey cannot be null");
+ return ruleKey;
+ }
+
+ private static String validateResolution(@Nullable String resolution){
+ checkArgument(resolution == null || org.sonar.api.issue.Issue.RESOLUTIONS.contains(resolution), String.format("resolution '%s' is invalid", resolution));
+ return resolution;
+ }
+
+ private static String validateSeverity(String severity){
+ checkNotNull(severity, "severity cannot be null");
+ checkArgument(Severity.ALL.contains(severity), String.format("severity '%s' is invalid", severity));
+ return severity;
+ }
+
+ private static String validateStatus(String status){
+ checkNotNull(status, "status cannot be null");
+ checkArgument(org.sonar.api.issue.Issue.STATUSES.contains(status), String.format("status '%s' is invalid", status));
+ return status;
+ }
+
+ public Issue build(){
+ validateKey(key);
+ validateResolution(resolution);
+ validateSeverity(severity);
+ validateStatus(status);
+ validateRuleKey(ruleKey);
+ return new IssueImpl(this);
+ }
+ }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImplementationContext.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImplementationContext.java
index f8182f5483f..a49b2d6611e 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImplementationContext.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/MeasureComputerImplementationContext.java
@@ -22,6 +22,7 @@ package org.sonar.api.test.ce.measure;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -29,6 +30,7 @@ import java.util.Map;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.ce.measure.Component;
+import org.sonar.api.ce.measure.Issue;
import org.sonar.api.ce.measure.Measure;
import org.sonar.api.ce.measure.MeasureComputer;
import org.sonar.api.ce.measure.Settings;
@@ -43,6 +45,7 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
private Map<String, Measure> componentMeasureByMetricKey = new HashMap<>();
private Multimap<String, Measure> childrenComponentMeasureByMetricKey = ArrayListMultimap.create();
+ private List<Issue> issues = new ArrayList<>();
public MeasureComputerImplementationContext(Component component, Settings settings, MeasureComputer measureComputer) {
this.measureComputer = measureComputer;
@@ -137,6 +140,15 @@ public class MeasureComputerImplementationContext implements MeasureComputer.Imp
}
}
+ @Override
+ public List<Issue> getIssues() {
+ return issues;
+ }
+
+ public void setIssues(List<Issue> issues){
+ this.issues = issues;
+ }
+
private void validateInputMetric(String metric) {
Set<String> allowedMetrics = new HashSet<>();
allowedMetrics.addAll(measureComputer.getInputMetrics());
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/package-info.java b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/package-info.java
new file mode 100644
index 00000000000..aaa0831b888
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/test/ce/measure/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * 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.api.test.ce.measure;
+
+import javax.annotation.ParametersAreNonnullByDefault;