aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DefaultModuleIssues.java (renamed from sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssues.java)34
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/DefaultModuleIssuesTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssuesTest.java)58
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/ModuleIssues.java41
10 files changed, 143 insertions, 42 deletions
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 caa4a98b0b2..ca8cf60059c 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
@@ -49,7 +49,7 @@ import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
import org.sonar.batch.issue.DeprecatedViolations;
-import org.sonar.batch.issue.ScanIssues;
+import org.sonar.batch.issue.DefaultModuleIssues;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.component.ScanGraph;
@@ -82,7 +82,7 @@ public class DefaultIndex extends SonarIndex {
private Map<Resource, Map<Resource, Dependency>> incomingDependenciesByResource = Maps.newHashMap();
private ProjectTree projectTree;
private final DeprecatedViolations deprecatedViolations;
- private ScanIssues scanIssues;
+ private DefaultModuleIssues moduleIssues;
public DefaultIndex(PersistenceManager persistence, DefaultResourceCreationLock lock, ProjectTree projectTree, MetricFinder metricFinder,
ScanGraph graph, DeprecatedViolations deprecatedViolations) {
@@ -124,12 +124,12 @@ public class DefaultIndex extends SonarIndex {
return currentProject;
}
- public void setCurrentProject(Project project, ResourceFilters resourceFilters, ScanIssues scanIssues) {
+ public void setCurrentProject(Project project, ResourceFilters resourceFilters, DefaultModuleIssues moduleIssues) {
this.currentProject = project;
// the following components depend on the current module, so they need to be reloaded.
this.resourceFilters = resourceFilters;
- this.scanIssues = scanIssues;
+ this.moduleIssues = moduleIssues;
}
/**
@@ -378,7 +378,7 @@ public class DefaultIndex extends SonarIndex {
violation.setSeverity(null);
violation.setResource(bucket.getResource());
- scanIssues.initAndAddViolation(violation);
+ moduleIssues.initAndAddViolation(violation);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
index 0be18b5dff9..5b7c4c8092c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
@@ -33,13 +33,13 @@ import java.util.List;
*/
public class DefaultIssuable implements Issuable {
- private final ScanIssues scanIssues;
+ private final DefaultModuleIssues moduleIssues;
private final IssueCache cache;
private final Component component;
- DefaultIssuable(Component component, ScanIssues scanIssues, IssueCache cache) {
+ DefaultIssuable(Component component, DefaultModuleIssues moduleIssues, IssueCache cache) {
this.component = component;
- this.scanIssues = scanIssues;
+ this.moduleIssues = moduleIssues;
this.cache = cache;
}
@@ -50,7 +50,7 @@ public class DefaultIssuable implements Issuable {
@Override
public boolean addIssue(Issue issue) {
- return scanIssues.initAndAddIssue((DefaultIssue) issue);
+ return moduleIssues.initAndAddIssue((DefaultIssue) issue);
}
@SuppressWarnings("unchecked")
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultModuleIssues.java
index a3b53260897..cdd9f22223a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssues.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultModuleIssues.java
@@ -19,7 +19,10 @@
*/
package org.sonar.batch.issue;
-import org.sonar.api.BatchComponent;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.ModuleIssues;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Project;
@@ -33,14 +36,14 @@ import javax.annotation.Nullable;
/**
* Initialize the issues raised during scan.
*/
-public class ScanIssues implements BatchComponent {
+public class DefaultModuleIssues implements ModuleIssues {
private final RulesProfile qProfile;
private final IssueCache cache;
private final Project project;
private final IssueFilters filters;
- public ScanIssues(RulesProfile qProfile, IssueCache cache, Project project, IssueFilters filters) {
+ public DefaultModuleIssues(RulesProfile qProfile, IssueCache cache, Project project, IssueFilters filters) {
this.qProfile = qProfile;
this.cache = cache;
this.project = project;
@@ -88,4 +91,29 @@ public class ScanIssues implements BatchComponent {
return false;
}
+ @Override
+ public Iterable<Issue> issues() {
+ return (Iterable) Iterables.filter(cache.all(), new ModulePredicate(false));
+ }
+
+ @Override
+ public Iterable<Issue> resolvedIssues() {
+ return (Iterable) Iterables.filter(cache.all(), new ModulePredicate(true));
+ }
+
+ private class ModulePredicate implements Predicate<DefaultIssue> {
+ private final boolean resolved;
+
+ private ModulePredicate(boolean resolved) {
+ this.resolved = resolved;
+ }
+
+ @Override
+ public boolean apply(@Nullable DefaultIssue issue) {
+ if (issue != null && (issue.componentKey().equals(project.getEffectiveKey()) || issue.componentKey().startsWith(project.getEffectiveKey() + ":"))) {
+ return resolved ? issue.resolution() != null : issue.resolution()==null;
+ }
+ return false;
+ }
+ }
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java
index 3e13158a761..cd34582c24c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/IssuableFactory.java
@@ -33,12 +33,12 @@ import javax.annotation.CheckForNull;
*/
public class IssuableFactory extends PerspectiveBuilder<Issuable> {
- private final ScanIssues scanIssues;
+ private final DefaultModuleIssues moduleIssues;
private final IssueCache cache;
- public IssuableFactory(ScanIssues scanIssues, IssueCache cache) {
+ public IssuableFactory(DefaultModuleIssues moduleIssues, IssueCache cache) {
super(Issuable.class);
- this.scanIssues = scanIssues;
+ this.moduleIssues = moduleIssues;
this.cache = cache;
}
@@ -49,6 +49,6 @@ public class IssuableFactory extends PerspectiveBuilder<Issuable> {
if (component instanceof ResourceComponent) {
supported = Scopes.isHigherThanOrEquals(((ResourceComponent) component).scope(), Scopes.FILE);
}
- return supported ? new DefaultIssuable(component, scanIssues, cache) : null;
+ return supported ? new DefaultIssuable(component, moduleIssues, cache) : null;
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
index 0075238fd4e..543f01e2940 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java
@@ -42,7 +42,7 @@ import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.index.ResourcePersister;
import org.sonar.batch.issue.IssuableFactory;
import org.sonar.batch.issue.IssueFilters;
-import org.sonar.batch.issue.ScanIssues;
+import org.sonar.batch.issue.DefaultModuleIssues;
import org.sonar.batch.phases.PhaseExecutor;
import org.sonar.batch.phases.PhasesTimeProfiler;
import org.sonar.batch.scan.filesystem.*;
@@ -113,7 +113,7 @@ public class ModuleScanContainer extends ComponentContainer {
new ProfileProvider(),
// issues
- ScanIssues.class,
+ DefaultModuleIssues.class,
IssuableFactory.class,
ScanPerspectives.class
@@ -140,7 +140,7 @@ public class ModuleScanContainer extends ComponentContainer {
DefaultIndex index = getComponentByType(DefaultIndex.class);
index.setCurrentProject(module,
getComponentByType(ResourceFilters.class),
- getComponentByType(ScanIssues.class));
+ getComponentByType(DefaultModuleIssues.class));
getComponentByType(PhaseExecutor.class).execute(module);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
index e3f2e17300a..2431cefbbb5 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/DefaultIndexTest.java
@@ -39,7 +39,7 @@ import org.sonar.batch.DefaultResourceCreationLock;
import org.sonar.batch.ProjectTree;
import org.sonar.batch.ResourceFilters;
import org.sonar.batch.issue.DeprecatedViolations;
-import org.sonar.batch.issue.ScanIssues;
+import org.sonar.batch.issue.DefaultModuleIssues;
import org.sonar.core.component.ScanGraph;
import static com.google.common.collect.Lists.newArrayList;
@@ -77,7 +77,7 @@ public class DefaultIndexTest {
rule = Rule.create("repoKey", "ruleKey", "Rule");
rule.setId(1);
rulesProfile.activateRule(rule, null);
- index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[]{filter}), mock(ScanIssues.class));
+ index.setCurrentProject(project, new ResourceFilters(new ResourceFilter[]{filter}), mock(DefaultModuleIssues.class));
index.doStart(project);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
index a4ffb41416e..f66cc03aa16 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
@@ -33,7 +33,7 @@ import static org.mockito.Mockito.when;
public class DefaultIssuableTest {
- ScanIssues scanIssues = mock(ScanIssues.class);
+ DefaultModuleIssues moduleIssues = mock(DefaultModuleIssues.class);
IssueCache cache = mock(IssueCache.class);
Component component = mock(Component.class);
@@ -44,7 +44,7 @@ public class DefaultIssuableTest {
DefaultIssue unresolved = new DefaultIssue();
when(cache.byComponent("struts:org.apache.Action")).thenReturn(Arrays.asList(resolved, unresolved));
- DefaultIssuable perspective = new DefaultIssuable(component, scanIssues, cache);
+ DefaultIssuable perspective = new DefaultIssuable(component, moduleIssues, cache);
List<Issue> issues = perspective.issues();
assertThat(issues).containsOnly(unresolved);
@@ -57,7 +57,7 @@ public class DefaultIssuableTest {
DefaultIssue unresolved = new DefaultIssue();
when(cache.byComponent("struts:org.apache.Action")).thenReturn(Arrays.asList(resolved, unresolved));
- DefaultIssuable perspective = new DefaultIssuable(component, scanIssues, cache);
+ DefaultIssuable perspective = new DefaultIssuable(component, moduleIssues, cache);
List<Issue> issues = perspective.resolvedIssues();
assertThat(issues).containsOnly(resolved);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssuesTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultModuleIssuesTest.java
index f67ad671308..27f14f4bcd0 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssuesTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultModuleIssuesTest.java
@@ -19,10 +19,12 @@
*/
package org.sonar.batch.issue;
+import com.google.common.collect.Lists;
import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.JavaFile;
@@ -35,30 +37,36 @@ import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.Violation;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
+import java.util.List;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.*;
-public class ScanIssuesTest {
+public class DefaultModuleIssuesTest {
+
+ static final RuleKey SQUID_RULE_KEY = RuleKey.of("squid", "AvoidCycle");
IssueCache cache = mock(IssueCache.class);
RulesProfile qProfile = mock(RulesProfile.class);
Project project = mock(Project.class);
IssueFilters filters = mock(IssueFilters.class);
- ScanIssues scanIssues = new ScanIssues(qProfile, cache, project, filters);
+ DefaultModuleIssues moduleIssues = new DefaultModuleIssues(qProfile, cache, project, filters);
@Before
public void setUp() {
when(project.getAnalysisDate()).thenReturn(new Date());
+ when(project.getEffectiveKey()).thenReturn("org.apache:struts-core");
}
+
@Test
public void should_ignore_null_active_rule() throws Exception {
when(qProfile.getActiveRule(anyString(), anyString())).thenReturn(null);
- DefaultIssue issue = new DefaultIssue().setRuleKey(RuleKey.of("squid", "AvoidCycle"));
- boolean added = scanIssues.initAndAddIssue(issue);
+ DefaultIssue issue = new DefaultIssue().setRuleKey(SQUID_RULE_KEY);
+ boolean added = moduleIssues.initAndAddIssue(issue);
assertThat(added).isFalse();
verifyZeroInteractions(cache);
@@ -70,8 +78,8 @@ public class ScanIssuesTest {
when(activeRule.getRule()).thenReturn(null);
when(qProfile.getActiveRule(anyString(), anyString())).thenReturn(activeRule);
- DefaultIssue issue = new DefaultIssue().setRuleKey(RuleKey.of("squid", "AvoidCycle"));
- boolean added = scanIssues.initAndAddIssue(issue);
+ DefaultIssue issue = new DefaultIssue().setRuleKey(SQUID_RULE_KEY);
+ boolean added = moduleIssues.initAndAddIssue(issue);
assertThat(added).isFalse();
verifyZeroInteractions(cache);
@@ -90,11 +98,11 @@ public class ScanIssuesTest {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setRuleKey(SQUID_RULE_KEY)
.setSeverity(Severity.CRITICAL);
when(filters.accept(issue, null)).thenReturn(true);
- boolean added = scanIssues.initAndAddIssue(issue);
+ boolean added = moduleIssues.initAndAddIssue(issue);
assertThat(added).isTrue();
ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
@@ -114,9 +122,9 @@ public class ScanIssuesTest {
Date analysisDate = new Date();
when(project.getAnalysisDate()).thenReturn(analysisDate);
- DefaultIssue issue = new DefaultIssue().setRuleKey(RuleKey.of("squid", "AvoidCycle")).setSeverity(null);
+ DefaultIssue issue = new DefaultIssue().setRuleKey(SQUID_RULE_KEY).setSeverity(null);
when(filters.accept(issue, null)).thenReturn(true);
- scanIssues.initAndAddIssue(issue);
+ moduleIssues.initAndAddIssue(issue);
ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
verify(cache).put(argument.capture());
@@ -139,7 +147,7 @@ public class ScanIssuesTest {
when(qProfile.getActiveRule("squid", "AvoidCycle")).thenReturn(activeRule);
when(filters.accept(any(DefaultIssue.class), eq(violation))).thenReturn(true);
- boolean added = scanIssues.initAndAddViolation(violation);
+ boolean added = moduleIssues.initAndAddViolation(violation);
assertThat(added).isTrue();
ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
@@ -163,14 +171,38 @@ public class ScanIssuesTest {
DefaultIssue issue = new DefaultIssue()
.setKey("ABCDE")
- .setRuleKey(RuleKey.of("squid", "AvoidCycle"))
+ .setRuleKey(SQUID_RULE_KEY)
.setSeverity(Severity.CRITICAL);
when(filters.accept(issue, null)).thenReturn(false);
- boolean added = scanIssues.initAndAddIssue(issue);
+ boolean added = moduleIssues.initAndAddIssue(issue);
assertThat(added).isFalse();
verifyZeroInteractions(cache);
}
+
+ @Test
+ public void should_get_module_issues() throws Exception {
+ DefaultIssue issueOnModule = new DefaultIssue().setKey("1").setRuleKey(SQUID_RULE_KEY).setComponentKey("org.apache:struts-core");
+ DefaultIssue issueInModule = new DefaultIssue().setKey("2").setRuleKey(SQUID_RULE_KEY).setComponentKey("org.apache:struts-core:Action");
+ DefaultIssue resolvedIssueInModule = new DefaultIssue().setKey("3").setRuleKey(SQUID_RULE_KEY).setComponentKey("org.apache:struts-core:Action").setResolution(Issue.RESOLUTION_FIXED);
+
+ when(cache.all()).thenReturn(Arrays.<DefaultIssue>asList(
+ // issue on root module
+ new DefaultIssue().setKey("4").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts"),
+
+ // issue in root module
+ new DefaultIssue().setKey("5").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts:FileInRoot"),
+
+ issueOnModule, issueInModule, resolvedIssueInModule
+ ));
+
+ // unresolved issues
+ List<Issue> issues = Lists.newArrayList(moduleIssues.issues());
+ assertThat(issues).containsOnly(issueInModule, issueOnModule);
+
+ List<Issue> resolvedIssues = Lists.newArrayList(moduleIssues.resolvedIssues());
+ assertThat(resolvedIssues).containsOnly(resolvedIssueInModule);
+ }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java
index 9bc450ac5fd..65e4b5d706c 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/IssuableFactoryTest.java
@@ -34,12 +34,12 @@ import static org.mockito.Mockito.mock;
public class IssuableFactoryTest {
- ScanIssues scanIssues = mock(ScanIssues.class);
+ DefaultModuleIssues moduleIssues = mock(DefaultModuleIssues.class);
IssueCache cache = mock(IssueCache.class, Mockito.RETURNS_MOCKS);
@Test
public void file_should_be_issuable() throws Exception {
- IssuableFactory factory = new IssuableFactory(scanIssues, cache);
+ IssuableFactory factory = new IssuableFactory(moduleIssues, cache);
Component component = new ResourceComponent(new File("foo/bar.c").setEffectiveKey("foo/bar.c"));
Issuable issuable = factory.loadPerspective(Issuable.class, component);
@@ -50,7 +50,7 @@ public class IssuableFactoryTest {
@Test
public void project_should_be_issuable() throws Exception {
- IssuableFactory factory = new IssuableFactory(scanIssues, cache);
+ IssuableFactory factory = new IssuableFactory(moduleIssues, cache);
Component component = new ResourceComponent(new Project("Foo").setEffectiveKey("foo"));
Issuable issuable = factory.loadPerspective(Issuable.class, component);
@@ -61,7 +61,7 @@ public class IssuableFactoryTest {
@Test
public void java_file_should_be_issuable() throws Exception {
- IssuableFactory factory = new IssuableFactory(scanIssues, cache);
+ IssuableFactory factory = new IssuableFactory(moduleIssues, cache);
Component component = new ResourceComponent(new JavaFile("org.apache.Action").setEffectiveKey("struts:org.apache.Action"));
Issuable issuable = factory.loadPerspective(Issuable.class, component);
@@ -72,7 +72,7 @@ public class IssuableFactoryTest {
@Test
public void java_class_should_not_be_issuable() throws Exception {
- IssuableFactory factory = new IssuableFactory(scanIssues, cache);
+ IssuableFactory factory = new IssuableFactory(moduleIssues, cache);
Component component = new ResourceComponent(JavaClass.create("org.apache.Action").setEffectiveKey("struts:org.apache.Action"));
Issuable issuable = factory.loadPerspective(Issuable.class, component);
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/ModuleIssues.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/ModuleIssues.java
new file mode 100644
index 00000000000..2f1a974f51c
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/ModuleIssues.java
@@ -0,0 +1,41 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 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.issue;
+
+import org.sonar.api.BatchComponent;
+
+/**
+ * Used by batch components to get the issues of the current module. It does not allow
+ * to get issues of all project modules.
+ *
+ * @since 4.0
+ */
+public interface ModuleIssues extends BatchComponent {
+
+ /**
+ * All the unresolved issues of the current module, including the issues reported by end-users.
+ */
+ Iterable<Issue> issues();
+
+ /**
+ * All the issues of this module that have been marked as resolved during this scan
+ */
+ Iterable<Issue> resolvedIssues();
+}