aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java10
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/CreateIssueByInternalKeySensor.java7
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java7
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java64
-rw-r--r--sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectRepository.java (renamed from sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java)14
-rw-r--r--sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssue.java9
-rw-r--r--sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java5
-rw-r--r--sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectRepositoryTest.java (renamed from sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectReferentialsTest.java)6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java17
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java11
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/FileHashes.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/FileHashes.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensor.java)4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesStack.java)10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueHandlers.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTracking.java)95
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizer.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizer.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingDecorator.java)13
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingResult.java)60
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java227
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java47
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java62
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java61
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java84
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/RollingFileHashes.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/RollingFileHashes.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/SourceHashHolder.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SourceHashHolder.java)3
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/package-info.java (renamed from plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/package-info.java)6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java40
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java15
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalReferentialsLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/DefaultGlobalReferentialsLoader.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java55
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectReferentialsLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/DefaultProjectReferentialsLoader.java)10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsLoader.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsProvider.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsProvider.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java30
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsLoader.java)8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsProvider.java)12
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/package-info.java (renamed from sonar-batch/src/main/java/org/sonar/batch/referential/package-info.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java13
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java16
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensorTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java)10
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueHandlersTest.java)4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizerTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizerTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingDecoratorTest.java)44
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingTest.java)57
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/RollingFileHashesTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/RollingFileHashesTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/SourceHashHolderTest.java (renamed from plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/SourceHashHolderTest.java)2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java11
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectReferentialsLoaderTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/referential/DefaultProjectReferentialsLoaderTest.java)5
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java11
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileMetadataTest.java12
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java4
-rw-r--r--sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures1
-rw-r--r--sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures1
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v1.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v1.txt)0
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v2.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v2.txt)0
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v1.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v1.txt)0
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v2.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v2.txt)0
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v1.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v1.txt)0
-rw-r--r--sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v2.txt (renamed from plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v2.txt)0
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java2
77 files changed, 995 insertions, 308 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
index 9040b071b1a..2187ca1cf85 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
+++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
@@ -34,11 +34,6 @@ import org.sonar.plugins.core.dashboards.ProjectIssuesDashboard;
import org.sonar.plugins.core.dashboards.ProjectTimeMachineDashboard;
import org.sonar.plugins.core.issue.CountFalsePositivesDecorator;
import org.sonar.plugins.core.issue.CountUnresolvedIssuesDecorator;
-import org.sonar.plugins.core.issue.InitialOpenIssuesSensor;
-import org.sonar.plugins.core.issue.InitialOpenIssuesStack;
-import org.sonar.plugins.core.issue.IssueHandlers;
-import org.sonar.plugins.core.issue.IssueTracking;
-import org.sonar.plugins.core.issue.IssueTrackingDecorator;
import org.sonar.plugins.core.measurefilters.MyFavouritesFilter;
import org.sonar.plugins.core.measurefilters.ProjectFilter;
import org.sonar.plugins.core.notifications.alerts.NewAlerts;
@@ -325,13 +320,8 @@ public final class CorePlugin extends SonarPlugin {
DistributionAreaChart.class,
// issues
- IssueTrackingDecorator.class,
- IssueTracking.class,
- IssueHandlers.class,
CountUnresolvedIssuesDecorator.class,
CountFalsePositivesDecorator.class,
- InitialOpenIssuesSensor.class,
- InitialOpenIssuesStack.class,
HotspotMostViolatedRulesWidget.class,
MyUnresolvedIssuesWidget.class,
FalsePositiveIssuesWidget.class,
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 886104c14a0..01973adef97 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
@@ -19,7 +19,10 @@
*/
package org.sonar.xoo.rule;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
@@ -40,7 +43,9 @@ public class CreateIssueByInternalKeySensor implements Sensor {
@Override
public void execute(SensorContext context) {
- for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ FileSystem fs = context.fileSystem();
+ FilePredicates p = fs.predicates();
+ for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(Type.MAIN)))) {
createIssues(file, context);
}
}
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 3e0b9f48ee5..7e79e2857f6 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
@@ -19,7 +19,10 @@
*/
package org.sonar.xoo.rule;
+import org.sonar.api.batch.fs.FilePredicates;
+import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
@@ -43,7 +46,9 @@ public class OneIssuePerLineSensor implements Sensor {
@Override
public void execute(SensorContext context) {
- for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ FileSystem fs = context.fileSystem();
+ FilePredicates p = fs.predicates();
+ for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(Type.MAIN)))) {
createIssues(file, context);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java
index 9f87aa9ad1f..a6a40efbc45 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryAction.java
@@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.RequestHandler;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.server.plugins.MimeTypes;
public class ProjectRepositoryAction implements RequestHandler {
@@ -67,7 +67,7 @@ public class ProjectRepositoryAction implements RequestHandler {
@Override
public void handle(Request request, Response response) throws Exception {
- ProjectReferentials ref = projectReferentialsLoader.load(ProjectRepositoryQuery.create()
+ ProjectRepository ref = projectReferentialsLoader.load(ProjectRepositoryQuery.create()
.setModuleKey(request.mandatoryParam(PARAM_KEY))
.setProfileName(request.param(PARAM_PROFILE))
.setPreview(request.mandatoryParamAsBoolean(PARAM_PREVIEW)));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java
index 90d0151b79c..deea4177e33 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectRepositoryLoader.java
@@ -28,7 +28,7 @@ import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.core.UtcDateUtils;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.component.FilePathWithHashDto;
@@ -77,13 +77,13 @@ public class ProjectRepositoryLoader implements ServerComponent {
this.languages = languages;
}
- public ProjectReferentials load(ProjectRepositoryQuery query) {
+ public ProjectRepository load(ProjectRepositoryQuery query) {
boolean hasScanPerm = UserSession.get().hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
checkPermission(query.isPreview());
DbSession session = dbClient.openSession(false);
try {
- ProjectReferentials ref = new ProjectReferentials();
+ ProjectRepository ref = new ProjectRepository();
String projectKey = query.getModuleKey();
ComponentDto module = dbClient.componentDao().getNullableByKey(session, query.getModuleKey());
// Current project/module can be null when analysing a new project
@@ -145,7 +145,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
}
}
- private void addSettingsToChildrenModules(ProjectReferentials ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
+ private void addSettingsToChildrenModules(ProjectRepository ref, String moduleKey, Map<String, String> parentProperties, TreeModuleSettings treeModuleSettings,
boolean hasScanPerm, DbSession session) {
Map<String, String> currentParentProperties = newHashMap();
currentParentProperties.putAll(parentProperties);
@@ -158,7 +158,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
}
}
- private void addSettings(ProjectReferentials ref, String module, Map<String, String> properties) {
+ private void addSettings(ProjectRepository ref, String module, Map<String, String> properties) {
if (!properties.isEmpty()) {
ref.addSettings(module, properties);
}
@@ -180,7 +180,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
return !key.contains(".secured") || hasScanPerm;
}
- private void addProfiles(ProjectReferentials ref, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
+ private void addProfiles(ProjectRepository ref, @Nullable String projectKey, @Nullable String profileName, DbSession session) {
for (Language language : languages.all()) {
String languageKey = language.getKey();
QualityProfileDto qualityProfileDto = getProfile(languageKey, projectKey, profileName, session);
@@ -212,7 +212,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
}
}
- private void addActiveRules(ProjectReferentials ref) {
+ private void addActiveRules(ProjectRepository ref) {
for (org.sonar.batch.protocol.input.QProfile qProfile : ref.qProfiles()) {
for (ActiveRule activeRule : qProfileLoader.findActiveRulesByProfile(qProfile.key())) {
Rule rule = ruleService.getNonNullByKey(activeRule.key().ruleKey());
@@ -231,7 +231,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
}
}
- private void addManualRules(ProjectReferentials ref) {
+ private void addManualRules(ProjectRepository ref) {
Result<Rule> ruleSearchResult = ruleService.search(new RuleQuery().setRepositories(newArrayList(RuleKey.MANUAL_REPOSITORY_KEY)), new QueryContext().setScroll(true)
.setFieldsToReturn(newArrayList(RuleNormalizer.RuleField.KEY.field(), RuleNormalizer.RuleField.NAME.field())));
Iterator<Rule> rules = ruleSearchResult.scroll();
@@ -245,7 +245,7 @@ public class ProjectRepositoryLoader implements ServerComponent {
}
}
- private void addFileData(DbSession session, ProjectReferentials ref, List<ComponentDto> moduleChildren, String moduleKey) {
+ private void addFileData(DbSession session, ProjectRepository ref, List<ComponentDto> moduleChildren, String moduleKey) {
Map<String, String> moduleKeysByUuid = newHashMap();
for (ComponentDto module : moduleChildren) {
moduleKeysByUuid.put(module.uuid(), module.key());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java
index 4dd4ae8e46f..97085c32ad9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryActionTest.java
@@ -26,7 +26,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.server.ws.WsTester;
import static org.assertj.core.api.Assertions.assertThat;
@@ -51,7 +51,7 @@ public class ProjectRepositoryActionTest {
public void project_referentials() throws Exception {
String projectKey = "org.codehaus.sonar:sonar";
- ProjectReferentials projectReferentials = mock(ProjectReferentials.class);
+ ProjectRepository projectReferentials = mock(ProjectRepository.class);
when(projectReferentials.toJson()).thenReturn("{\"settingsByModule\": {}}");
ArgumentCaptor<ProjectRepositoryQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectRepositoryQuery.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
index 5726333c222..0b3ed071d82 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
@@ -31,7 +31,7 @@ import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.utils.DateUtils;
import org.sonar.batch.protocol.input.ActiveRule;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.batch.protocol.input.QProfile;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.permission.GlobalPermissions;
@@ -99,7 +99,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession);
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
Map<String, String> projectSettings = ref.settings(project.key());
assertThat(projectSettings).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR",
@@ -124,7 +124,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession);
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()).setPreview(true));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()).setPreview(true));
Map<String, String> projectSettings = ref.settings(project.key());
assertThat(projectSettings).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR"
@@ -156,7 +156,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR",
"sonar.jira.login.secured", "john"
@@ -189,7 +189,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR",
"sonar.jira.login.secured", "john"
@@ -232,7 +232,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR",
"sonar.jira.login.secured", "john"
@@ -278,7 +278,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
"sonar.jira.project.key", "SONAR",
"sonar.jira.login.secured", "john"
@@ -295,6 +295,28 @@ public class ProjectRepositoryLoaderMediumTest {
}
@Test
+ public void return_provisioned_project_settings() throws Exception {
+ MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+
+ // No snapshot attached on the project -> provisioned project
+ ComponentDto project = ComponentTesting.newProjectDto();
+ tester.get(DbClient.class).componentDao().insert(dbSession, project);
+ addDefaultProfile();
+
+ // Project properties
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()), dbSession);
+ tester.get(DbClient.class).propertiesDao().setProperty(new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()), dbSession);
+
+ dbSession.commit();
+
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ assertThat(ref.settings(project.key())).isEqualTo(ImmutableMap.of(
+ "sonar.jira.project.key", "SONAR",
+ "sonar.jira.login.secured", "john"
+ ));
+ }
+
+ @Test
public void return_sub_module_settings() throws Exception {
MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
@@ -317,7 +339,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
assertThat(ref.settings(project.key())).isEmpty();
assertThat(ref.settings(module.key())).isEmpty();
assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
@@ -352,7 +374,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
assertThat(ref.settings(project.key())).isEmpty();
assertThat(ref.settings(module.key())).isEmpty();
assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
@@ -385,7 +407,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
assertThat(ref.settings(project.key())).isEmpty();
assertThat(ref.settings(module.key())).isEmpty();
assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
@@ -419,7 +441,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(subModule.key()));
assertThat(ref.settings(project.key())).isEmpty();
assertThat(ref.settings(module.key())).isEmpty();
assertThat(ref.settings(subModule.key())).isEqualTo(ImmutableMap.of(
@@ -444,7 +466,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
List<QProfile> profiles = newArrayList(ref.qProfiles());
assertThat(profiles).hasSize(1);
assertThat(profiles.get(0).key()).isEqualTo("abcd");
@@ -468,7 +490,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
List<QProfile> profiles = newArrayList(ref.qProfiles());
assertThat(profiles).hasSize(1);
assertThat(profiles.get(0).key()).isEqualTo("abcd");
@@ -492,7 +514,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()).setProfileName("SonarQube way"));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()).setProfileName("SonarQube way"));
List<QProfile> profiles = newArrayList(ref.qProfiles());
assertThat(profiles).hasSize(1);
assertThat(profiles.get(0).key()).isEqualTo("abcd");
@@ -513,7 +535,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey("project"));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey("project"));
List<QProfile> profiles = newArrayList(ref.qProfiles());
assertThat(profiles).hasSize(1);
assertThat(profiles.get(0).key()).isEqualTo("abcd");
@@ -538,7 +560,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
List<QProfile> profiles = newArrayList(ref.qProfiles());
assertThat(profiles).hasSize(1);
assertThat(profiles.get(0).key()).isEqualTo("abcd");
@@ -589,7 +611,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
List<ActiveRule> activeRules = newArrayList(ref.activeRules());
assertThat(activeRules).hasSize(1);
assertThat(activeRules.get(0).repositoryKey()).isEqualTo("squid");
@@ -614,7 +636,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
List<ActiveRule> activeRules = newArrayList(ref.activeRules());
assertThat(activeRules).extracting("repositoryKey").containsOnly(RuleKey.MANUAL_REPOSITORY_KEY);
assertThat(activeRules).extracting("ruleKey").containsOnly("manualRuleKey");
@@ -671,7 +693,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.fileDataByPath(project.key())).hasSize(1);
FileData fileData = ref.fileData(project.key(), file.path());
assertThat(fileData.hash()).isEqualTo("123456");
@@ -700,7 +722,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(project.key()));
assertThat(ref.fileData(project.key(), projectFile.path()).hash()).isEqualTo("123456");
assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
}
@@ -728,7 +750,7 @@ public class ProjectRepositoryLoaderMediumTest {
dbSession.commit();
- ProjectReferentials ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(module.key()));
+ ProjectRepository ref = loader.load(ProjectRepositoryQuery.create().setModuleKey(module.key()));
assertThat(ref.fileData(module.key(), moduleFile.path()).hash()).isEqualTo("789456");
assertThat(ref.fileData(project.key(), projectFile.path())).isNull();
}
diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectRepository.java
index 8e83d0fabf5..f207a34d989 100644
--- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectReferentials.java
+++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/ProjectRepository.java
@@ -30,7 +30,7 @@ import java.util.*;
* Container for all project data going from server to batch.
* This is not an API since server and batch always share the same version.
*/
-public class ProjectReferentials {
+public class ProjectRepository {
private long timestamp;
private Map<String, QProfile> qprofilesByLanguage = new HashMap<String, QProfile>();
@@ -43,7 +43,7 @@ public class ProjectReferentials {
return settingsByModule.containsKey(moduleKey) ? settingsByModule.get(moduleKey) : Collections.<String, String>emptyMap();
}
- public ProjectReferentials addSettings(String moduleKey, Map<String, String> settings) {
+ public ProjectRepository addSettings(String moduleKey, Map<String, String> settings) {
Map<String, String> existingSettings = settingsByModule.get(moduleKey);
if (existingSettings == null) {
existingSettings = new HashMap<>();
@@ -57,7 +57,7 @@ public class ProjectReferentials {
return qprofilesByLanguage.values();
}
- public ProjectReferentials addQProfile(QProfile qProfile) {
+ public ProjectRepository addQProfile(QProfile qProfile) {
qprofilesByLanguage.put(qProfile.language(), qProfile);
return this;
}
@@ -66,7 +66,7 @@ public class ProjectReferentials {
return activeRules;
}
- public ProjectReferentials addActiveRule(ActiveRule activeRule) {
+ public ProjectRepository addActiveRule(ActiveRule activeRule) {
activeRules.add(activeRule);
return this;
}
@@ -75,7 +75,7 @@ public class ProjectReferentials {
return fileDataByModuleAndPath.containsKey(moduleKey) ? fileDataByModuleAndPath.get(moduleKey) : Collections.<String, FileData>emptyMap();
}
- public ProjectReferentials addFileData(String moduleKey, String path, FileData fileData) {
+ public ProjectRepository addFileData(String moduleKey, String path, FileData fileData) {
Map<String, FileData> existingFileDataByPath = fileDataByModuleAndPath.get(moduleKey);
if (existingFileDataByPath == null) {
existingFileDataByPath = new HashMap<>();
@@ -111,8 +111,8 @@ public class ProjectReferentials {
return GsonHelper.create().toJson(this);
}
- public static ProjectReferentials fromJson(String json) {
- return GsonHelper.create().fromJson(json, ProjectReferentials.class);
+ public static ProjectRepository fromJson(String json) {
+ return GsonHelper.create().fromJson(json, ProjectRepository.class);
}
}
diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssue.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssue.java
index 27afc945c29..10f44f1e390 100644
--- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssue.java
+++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssue.java
@@ -19,10 +19,11 @@
*/
package org.sonar.batch.protocol.input.issues;
-import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-public class PreviousIssue {
+import java.io.Serializable;
+
+public class PreviousIssue implements Serializable {
private String key;
private String componentKey;
@@ -30,6 +31,7 @@ public class PreviousIssue {
private String ruleRepo;
private Integer line;
private String message;
+ // For manual issues and when user has overriden severity
private String overriddenSeverity;
private String resolution;
private String status;
@@ -45,7 +47,7 @@ public class PreviousIssue {
return key;
}
- public PreviousIssue setComponentKey(@Nullable String key) {
+ public PreviousIssue setComponentKey(String key) {
this.componentKey = key;
return this;
}
@@ -95,7 +97,6 @@ public class PreviousIssue {
return this;
}
- @CheckForNull
public String overriddenSeverity() {
return overriddenSeverity;
}
diff --git a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java
index 14e4e4a3785..056b0077eea 100644
--- a/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java
+++ b/sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/issues/PreviousIssueHelper.java
@@ -70,7 +70,7 @@ public class PreviousIssueHelper implements Closeable {
}
}
- public Iterable<PreviousIssue> getIssues(final Reader reader) {
+ public static Iterable<PreviousIssue> getIssues(final Reader reader) {
return new Iterable<PreviousIssue>() {
@Override
@@ -80,9 +80,10 @@ public class PreviousIssueHelper implements Closeable {
};
}
- private final class PreviousIssueIterator implements Iterator<PreviousIssue> {
+ private final static class PreviousIssueIterator implements Iterator<PreviousIssue> {
private JsonReader jsonreader;
+ private final Gson gson = GsonHelper.create();
public PreviousIssueIterator(Reader reader) {
try {
diff --git a/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectReferentialsTest.java b/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectRepositoryTest.java
index 348fcd8187f..d60222b455a 100644
--- a/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectReferentialsTest.java
+++ b/sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/ProjectRepositoryTest.java
@@ -29,11 +29,11 @@ import java.util.HashMap;
import static org.assertj.core.api.Assertions.assertThat;
-public class ProjectReferentialsTest {
+public class ProjectRepositoryTest {
@Test
public void testToJson() throws Exception {
- ProjectReferentials ref = new ProjectReferentials();
+ ProjectRepository ref = new ProjectRepository();
assertThat(ref.settings("foo")).isEmpty();
ref.addQProfile(new QProfile("squid-java", "Java", "java", new SimpleDateFormat("dd/MM/yyyy").parse("14/03/1984")));
@@ -66,7 +66,7 @@ public class ProjectReferentialsTest {
@Test
public void testFromJson() throws JSONException, ParseException {
- ProjectReferentials ref = ProjectReferentials
+ ProjectRepository ref = ProjectRepository
.fromJson("{timestamp:1,"
+ "qprofilesByLanguage:{java:{key:\"squid-java\",name:Java,language:java,rulesUpdatedAt:\"1984-03-14T00:00:00+0100\"}},"
+ "activeRules:[{repositoryKey:repo,ruleKey:rule,name:Rule,severity:MAJOR,internalKey:rule1,language:java,params:{param1:value1}}],"
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
index 333a041f13f..dca499c6869 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java
@@ -26,6 +26,7 @@ import org.sonar.batch.design.FileTangleIndexDecorator;
import org.sonar.batch.design.MavenDependenciesSensor;
import org.sonar.batch.design.ProjectDsmDecorator;
import org.sonar.batch.design.SubProjectDsmDecorator;
+import org.sonar.batch.issue.tracking.IssueTracking;
import org.sonar.batch.maven.DefaultMavenPluginExecutor;
import org.sonar.batch.maven.MavenProjectBootstrapper;
import org.sonar.batch.maven.MavenProjectBuilder;
@@ -66,6 +67,9 @@ public class BatchComponents {
LinesSensor.class,
+ // Issues tracking
+ IssueTracking.class,
+
// Reports
ConsoleReport.class,
JSONReport.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
index 75071b09ef1..d3749c4cf7f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
@@ -35,11 +35,13 @@ import org.sonar.batch.components.PastSnapshotFinderByDays;
import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis;
import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion;
import org.sonar.batch.components.PastSnapshotFinderByVersion;
-import org.sonar.batch.referential.DefaultGlobalReferentialsLoader;
-import org.sonar.batch.referential.DefaultProjectReferentialsLoader;
-import org.sonar.batch.referential.GlobalReferentialsLoader;
-import org.sonar.batch.referential.GlobalReferentialsProvider;
-import org.sonar.batch.referential.ProjectReferentialsLoader;
+import org.sonar.batch.repository.DefaultGlobalReferentialsLoader;
+import org.sonar.batch.repository.DefaultPreviousIssuesLoader;
+import org.sonar.batch.repository.DefaultProjectReferentialsLoader;
+import org.sonar.batch.repository.GlobalReferentialsLoader;
+import org.sonar.batch.repository.GlobalReferentialsProvider;
+import org.sonar.batch.repository.PreviousIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
import org.sonar.batch.user.UserRepository;
import org.sonar.core.cluster.NullQueue;
import org.sonar.core.config.Logback;
@@ -113,9 +115,12 @@ public class BootstrapContainer extends ComponentContainer {
if (getComponentByType(GlobalReferentialsLoader.class) == null) {
add(DefaultGlobalReferentialsLoader.class);
}
- if (getComponentByType(ProjectReferentialsLoader.class) == null) {
+ if (getComponentByType(ProjectRepositoriesLoader.class) == null) {
add(DefaultProjectReferentialsLoader.class);
}
+ if (getComponentByType(PreviousIssuesLoader.class) == null) {
+ add(DefaultPreviousIssuesLoader.class);
+ }
}
private void addDatabaseComponents() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
index 470f0f79686..3b53ae97c19 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java
@@ -103,7 +103,7 @@ public class ServerClient implements BatchComponent {
}
}
- private InputSupplier<InputStream> doRequest(String pathStartingWithSlash, String requestMethod, @Nullable Integer timeoutMillis) {
+ public InputSupplier<InputStream> doRequest(String pathStartingWithSlash, String requestMethod, @Nullable Integer timeoutMillis) {
Preconditions.checkArgument(pathStartingWithSlash.startsWith("/"), "Path must start with slash /");
String path = StringEscapeUtils.escapeHtml(pathStartingWithSlash);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
index afa2ed7fee3..4a97a6c8ab8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/ResourceCache.java
@@ -38,6 +38,8 @@ public class ResourceCache implements BatchComponent {
// dedicated cache for libraries
private final Map<Library, BatchResource> libraries = Maps.newLinkedHashMap();
+ private BatchResource root;
+
@CheckForNull
public BatchResource get(String componentKey) {
return resources.get(componentKey);
@@ -56,10 +58,13 @@ public class ResourceCache implements BatchComponent {
String componentKey = resource.getEffectiveKey();
Preconditions.checkState(!Strings.isNullOrEmpty(componentKey), "Missing resource effective key");
BatchResource parent = parentResource != null ? get(parentResource.getEffectiveKey()) : null;
- BatchResource batchResource = new BatchResource((long) resources.size() + 1, resource, parent);
+ BatchResource batchResource = new BatchResource(resources.size() + 1, resource, parent);
if (!(resource instanceof Library)) {
// Libraries can have the same effective key than a project so we can't cache by effectiveKey
resources.put(componentKey, batchResource);
+ if (parent == null) {
+ root = batchResource;
+ }
} else {
libraries.put((Library) resource, batchResource);
}
@@ -73,4 +78,8 @@ public class ResourceCache implements BatchComponent {
public Collection<BatchResource> allLibraries() {
return libraries.values();
}
+
+ public BatchResource getRoot() {
+ return root;
+ }
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/FileHashes.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/FileHashes.java
index d45ac2d65cc..49b0405787b 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/FileHashes.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/FileHashes.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue.tracking;
+package org.sonar.batch.issue.tracking;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensor.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java
index 17f22757db8..a58f5c93a80 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.apache.commons.lang.time.DateUtils;
import org.apache.ibatis.session.ResultContext;
@@ -25,6 +25,7 @@ import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.resources.Project;
+import org.sonar.core.DryRunIncompatible;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueDao;
@@ -36,6 +37,7 @@ import java.util.Date;
/**
* Load all the issues referenced during the previous scan.
*/
+@DryRunIncompatible
public class InitialOpenIssuesSensor implements Sensor {
private final InitialOpenIssuesStack initialOpenIssuesStack;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesStack.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
index 1d6f3592547..acc9ebf21b8 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesStack.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
@@ -18,9 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
-import java.util.Collections;
import org.sonar.api.BatchExtension;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.batch.index.Cache;
@@ -29,6 +28,7 @@ import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueDto;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
@@ -49,11 +49,11 @@ public class InitialOpenIssuesStack implements BatchExtension {
return this;
}
- public List<IssueDto> selectAndRemoveIssues(String componentKey) {
+ public List<PreviousIssue> selectAndRemoveIssues(String componentKey) {
Iterable<IssueDto> issues = issuesCache.values(componentKey);
- List<IssueDto> result = newArrayList();
+ List<PreviousIssue> result = newArrayList();
for (IssueDto issue : issues) {
- result.add(issue);
+ result.add(new PreviousIssueFromDb(issue));
}
issuesCache.clear(componentKey);
return result;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueHandlers.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java
index d416b57f061..f8a98c29b00 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueHandlers.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.sonar.api.BatchExtension;
import org.sonar.api.issue.Issue;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
index da4059eeb0d..2c1c49afa97 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTracking.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
@@ -26,13 +26,9 @@ import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.sonar.api.BatchExtension;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.plugins.core.issue.tracking.FileHashes;
-import org.sonar.plugins.core.issue.tracking.IssueTrackingBlocksRecognizer;
-import org.sonar.plugins.core.issue.tracking.RollingFileHashes;
import javax.annotation.Nullable;
@@ -42,12 +38,13 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
-public class IssueTracking implements BatchExtension {
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public class IssueTracking implements BatchComponent {
/**
* @param sourceHashHolder Null when working on resource that is not a file (directory/project)
*/
- public IssueTrackingResult track(@Nullable SourceHashHolder sourceHashHolder, Collection<IssueDto> dbIssues, Collection<DefaultIssue> newIssues) {
+ public IssueTrackingResult track(@Nullable SourceHashHolder sourceHashHolder, Collection<PreviousIssue> previousIssues, Collection<DefaultIssue> newIssues) {
IssueTrackingResult result = new IssueTrackingResult();
if (sourceHashHolder != null) {
@@ -55,7 +52,7 @@ public class IssueTracking implements BatchExtension {
}
// Map new issues with old ones
- mapIssues(newIssues, dbIssues, sourceHashHolder, result);
+ mapIssues(newIssues, previousIssues, sourceHashHolder, result);
return result;
}
@@ -72,12 +69,12 @@ public class IssueTracking implements BatchExtension {
}
@VisibleForTesting
- void mapIssues(Collection<DefaultIssue> newIssues, @Nullable Collection<IssueDto> lastIssues, @Nullable SourceHashHolder sourceHashHolder, IssueTrackingResult result) {
+ void mapIssues(Collection<DefaultIssue> newIssues, @Nullable Collection<PreviousIssue> previousIssues, @Nullable SourceHashHolder sourceHashHolder, IssueTrackingResult result) {
boolean hasLastScan = false;
- if (lastIssues != null) {
+ if (previousIssues != null) {
hasLastScan = true;
- mapLastIssues(newIssues, lastIssues, result);
+ mapLastIssues(newIssues, previousIssues, result);
}
// If each new issue matches an old one we can stop the matching mechanism
@@ -92,8 +89,8 @@ public class IssueTracking implements BatchExtension {
}
}
- private void mapLastIssues(Collection<DefaultIssue> newIssues, Collection<IssueDto> lastIssues, IssueTrackingResult result) {
- for (IssueDto lastIssue : lastIssues) {
+ private void mapLastIssues(Collection<DefaultIssue> newIssues, Collection<PreviousIssue> previousIssues, IssueTrackingResult result) {
+ for (PreviousIssue lastIssue : previousIssues) {
result.addUnmatched(lastIssue);
}
@@ -121,7 +118,7 @@ public class IssueTracking implements BatchExtension {
RollingFileHashes b = RollingFileHashes.create(hashedSource, 5);
Multimap<Integer, DefaultIssue> newIssuesByLines = newIssuesByLines(newIssues, rec, result);
- Multimap<Integer, IssueDto> lastIssuesByLines = lastIssuesByLines(result.unmatched(), rec);
+ Multimap<Integer, PreviousIssue> lastIssuesByLines = lastIssuesByLines(result.unmatched(), rec);
Map<Integer, HashOccurrence> map = Maps.newHashMap();
@@ -207,12 +204,12 @@ public class IssueTracking implements BatchExtension {
}
}
- private void map(Collection<DefaultIssue> newIssues, Collection<IssueDto> lastIssues, IssueTrackingResult result) {
+ private void map(Collection<DefaultIssue> newIssues, Collection<PreviousIssue> previousIssues, IssueTrackingResult result) {
for (DefaultIssue newIssue : newIssues) {
if (isNotAlreadyMapped(newIssue, result)) {
- for (IssueDto pastIssue : lastIssues) {
- if (isNotAlreadyMapped(pastIssue, result) && Objects.equal(newIssue.ruleKey(), RuleKey.of(pastIssue.getRuleRepo(), pastIssue.getRule()))) {
- mapIssue(newIssue, pastIssue, result);
+ for (PreviousIssue previousIssue : previousIssues) {
+ if (isNotAlreadyMapped(previousIssue, result) && Objects.equal(newIssue.ruleKey(), previousIssue.ruleKey())) {
+ mapIssue(newIssue, previousIssue, result);
break;
}
}
@@ -230,72 +227,72 @@ public class IssueTracking implements BatchExtension {
return newIssuesByLines;
}
- private Multimap<Integer, IssueDto> lastIssuesByLines(Collection<IssueDto> lastIssues, IssueTrackingBlocksRecognizer rec) {
- Multimap<Integer, IssueDto> lastIssuesByLines = LinkedHashMultimap.create();
- for (IssueDto pastIssue : lastIssues) {
- if (rec.isValidLineInReference(pastIssue.getLine())) {
- lastIssuesByLines.put(pastIssue.getLine(), pastIssue);
+ private Multimap<Integer, PreviousIssue> lastIssuesByLines(Collection<PreviousIssue> previousIssues, IssueTrackingBlocksRecognizer rec) {
+ Multimap<Integer, PreviousIssue> previousIssuesByLines = LinkedHashMultimap.create();
+ for (PreviousIssue previousIssue : previousIssues) {
+ if (rec.isValidLineInReference(previousIssue.line())) {
+ previousIssuesByLines.put(previousIssue.line(), previousIssue);
}
}
- return lastIssuesByLines;
+ return previousIssuesByLines;
}
- private IssueDto findLastIssueWithSameChecksum(DefaultIssue newIssue, Collection<IssueDto> lastIssues) {
- for (IssueDto pastIssue : lastIssues) {
- if (isSameChecksum(newIssue, pastIssue)) {
- return pastIssue;
+ private PreviousIssue findLastIssueWithSameChecksum(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
+ for (PreviousIssue previousIssue : previousIssues) {
+ if (isSameChecksum(newIssue, previousIssue)) {
+ return previousIssue;
}
}
return null;
}
- private IssueDto findLastIssueWithSameLineAndMessage(DefaultIssue newIssue, Collection<IssueDto> lastIssues) {
- for (IssueDto pastIssue : lastIssues) {
- if (isSameLine(newIssue, pastIssue) && isSameMessage(newIssue, pastIssue)) {
- return pastIssue;
+ private PreviousIssue findLastIssueWithSameLineAndMessage(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
+ for (PreviousIssue previousIssue : previousIssues) {
+ if (isSameLine(newIssue, previousIssue) && isSameMessage(newIssue, previousIssue)) {
+ return previousIssue;
}
}
return null;
}
- private IssueDto findLastIssueWithSameChecksumAndMessage(DefaultIssue newIssue, Collection<IssueDto> lastIssues) {
- for (IssueDto pastIssue : lastIssues) {
- if (isSameChecksum(newIssue, pastIssue) && isSameMessage(newIssue, pastIssue)) {
- return pastIssue;
+ private PreviousIssue findLastIssueWithSameChecksumAndMessage(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
+ for (PreviousIssue previousIssue : previousIssues) {
+ if (isSameChecksum(newIssue, previousIssue) && isSameMessage(newIssue, previousIssue)) {
+ return previousIssue;
}
}
return null;
}
- private IssueDto findLastIssueWithSameLineAndChecksum(DefaultIssue newIssue, IssueTrackingResult result) {
- Collection<IssueDto> sameRuleAndSameLineAndSameChecksum = result.unmatchedForRuleAndForLineAndForChecksum(newIssue.ruleKey(), newIssue.line(), newIssue.checksum());
+ private PreviousIssue findLastIssueWithSameLineAndChecksum(DefaultIssue newIssue, IssueTrackingResult result) {
+ Collection<PreviousIssue> sameRuleAndSameLineAndSameChecksum = result.unmatchedForRuleAndForLineAndForChecksum(newIssue.ruleKey(), newIssue.line(), newIssue.checksum());
if (!sameRuleAndSameLineAndSameChecksum.isEmpty()) {
return sameRuleAndSameLineAndSameChecksum.iterator().next();
}
return null;
}
- private boolean isNotAlreadyMapped(IssueDto pastIssue, IssueTrackingResult result) {
- return result.unmatched().contains(pastIssue);
+ private boolean isNotAlreadyMapped(PreviousIssue previousIssue, IssueTrackingResult result) {
+ return result.unmatched().contains(previousIssue);
}
private boolean isNotAlreadyMapped(DefaultIssue newIssue, IssueTrackingResult result) {
return !result.isMatched(newIssue);
}
- private boolean isSameChecksum(DefaultIssue newIssue, IssueDto pastIssue) {
- return Objects.equal(pastIssue.getChecksum(), newIssue.checksum());
+ private boolean isSameChecksum(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ return Objects.equal(previousIssue.checksum(), newIssue.checksum());
}
- private boolean isSameLine(DefaultIssue newIssue, IssueDto pastIssue) {
- return Objects.equal(pastIssue.getLine(), newIssue.line());
+ private boolean isSameLine(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ return Objects.equal(previousIssue.line(), newIssue.line());
}
- private boolean isSameMessage(DefaultIssue newIssue, IssueDto pastIssue) {
- return Objects.equal(newIssue.message(), pastIssue.getMessage());
+ private boolean isSameMessage(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ return Objects.equal(newIssue.message(), previousIssue.message());
}
- private void mapIssue(DefaultIssue issue, @Nullable IssueDto ref, IssueTrackingResult result) {
+ private void mapIssue(DefaultIssue issue, @Nullable PreviousIssue ref, IssueTrackingResult result) {
if (ref != null) {
result.setMatch(issue, ref);
}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizer.java
index 11611ad952d..c7e01c9020d 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizer.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue.tracking;
+package org.sonar.batch.issue.tracking;
import javax.annotation.Nullable;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
index 3d2bfc48e9d..8bc86e35fa7 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingDecorator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
@@ -50,6 +50,7 @@ import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.scan.LastLineHashes;
import org.sonar.batch.scan.filesystem.InputPathCache;
+import org.sonar.core.DryRunIncompatible;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueDto;
@@ -59,6 +60,7 @@ import java.util.Collection;
@DependsUpon(DecoratorBarriers.ISSUES_ADDED)
@DependedUpon(DecoratorBarriers.ISSUES_TRACKED)
+@DryRunIncompatible
public class IssueTrackingDecorator implements Decorator {
private static final Logger LOG = LoggerFactory.getLogger(IssueTrackingDecorator.class);
@@ -123,7 +125,7 @@ public class IssueTrackingDecorator implements Decorator {
// issues = all the issues created by rule engines during this module scan and not excluded by filters
// all the issues that are not closed in db before starting this module scan, including manual issues
- Collection<IssueDto> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
+ Collection<PreviousIssue> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
SourceHashHolder sourceHashHolder = null;
if (ResourceUtils.isFile(resource)) {
@@ -157,7 +159,7 @@ public class IssueTrackingDecorator implements Decorator {
@VisibleForTesting
protected void mergeMatched(IssueTrackingResult result) {
for (DefaultIssue issue : result.matched()) {
- IssueDto ref = result.matching(issue);
+ IssueDto ref = ((PreviousIssueFromDb) result.matching(issue)).getDto();
// invariant fields
issue.setKey(ref.getKee());
@@ -206,8 +208,9 @@ public class IssueTrackingDecorator implements Decorator {
}
}
- private void addUnmatched(Collection<IssueDto> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
- for (IssueDto unmatchedDto : unmatchedIssues) {
+ private void addUnmatched(Collection<PreviousIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
+ for (PreviousIssue unmatchedIssue : unmatchedIssues) {
+ IssueDto unmatchedDto = ((PreviousIssueFromDb) unmatchedIssue).getDto();
DefaultIssue unmatched = unmatchedDto.toDefaultIssue();
if (StringUtils.isNotBlank(unmatchedDto.getReporter()) && !Issue.STATUS_CLOSED.equals(unmatchedDto.getStatus())) {
relocateManualIssue(unmatched, unmatchedDto, sourceHashHolder);
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingResult.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
index f63f94f8115..f7b4e8d119e 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/IssueTrackingResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
@@ -25,7 +25,6 @@ import com.google.common.collect.Multimap;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.RuleKey;
-import org.sonar.core.issue.db.IssueDto;
import javax.annotation.Nullable;
@@ -35,30 +34,29 @@ import java.util.HashMap;
import java.util.Map;
class IssueTrackingResult {
- private final Map<String, IssueDto> unmatchedByKey = new HashMap<String, IssueDto>();
- private final Map<RuleKey, Map<String, IssueDto>> unmatchedByRuleAndKey = new HashMap<RuleKey, Map<String, IssueDto>>();
- private final Map<RuleKey, Map<Integer, Multimap<String, IssueDto>>> unmatchedByRuleAndLineAndChecksum =
- new HashMap<RuleKey, Map<Integer, Multimap<String, IssueDto>>>();
- private final Map<DefaultIssue, IssueDto> matched = Maps.newIdentityHashMap();
+ private final Map<String, PreviousIssue> unmatchedByKey = new HashMap<>();
+ private final Map<RuleKey, Map<String, PreviousIssue>> unmatchedByRuleAndKey = new HashMap<>();
+ private final Map<RuleKey, Map<Integer, Multimap<String, PreviousIssue>>> unmatchedByRuleAndLineAndChecksum = new HashMap<>();
+ private final Map<DefaultIssue, PreviousIssue> matched = Maps.newIdentityHashMap();
- Collection<IssueDto> unmatched() {
+ Collection<PreviousIssue> unmatched() {
return unmatchedByKey.values();
}
- Map<String, IssueDto> unmatchedByKeyForRule(RuleKey ruleKey) {
- return unmatchedByRuleAndKey.containsKey(ruleKey) ? unmatchedByRuleAndKey.get(ruleKey) : Collections.<String, IssueDto>emptyMap();
+ Map<String, PreviousIssue> unmatchedByKeyForRule(RuleKey ruleKey) {
+ return unmatchedByRuleAndKey.containsKey(ruleKey) ? unmatchedByRuleAndKey.get(ruleKey) : Collections.<String, PreviousIssue>emptyMap();
}
- Collection<IssueDto> unmatchedForRuleAndForLineAndForChecksum(RuleKey ruleKey, @Nullable Integer line, @Nullable String checksum) {
+ Collection<PreviousIssue> unmatchedForRuleAndForLineAndForChecksum(RuleKey ruleKey, @Nullable Integer line, @Nullable String checksum) {
if (!unmatchedByRuleAndLineAndChecksum.containsKey(ruleKey)) {
return Collections.emptyList();
}
- Map<Integer, Multimap<String, IssueDto>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
+ Map<Integer, Multimap<String, PreviousIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
Integer lineNotNull = line != null ? line : 0;
if (!unmatchedForRule.containsKey(lineNotNull)) {
return Collections.emptyList();
}
- Multimap<String, IssueDto> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
+ Multimap<String, PreviousIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
String checksumNotNull = StringUtils.defaultString(checksum, "");
if (!unmatchedForRuleAndLine.containsKey(checksumNotNull)) {
return Collections.emptyList();
@@ -74,40 +72,40 @@ class IssueTrackingResult {
return matched.containsKey(issue);
}
- IssueDto matching(DefaultIssue issue) {
+ PreviousIssue matching(DefaultIssue issue) {
return matched.get(issue);
}
- void addUnmatched(IssueDto i) {
- unmatchedByKey.put(i.getKee(), i);
- RuleKey ruleKey = RuleKey.of(i.getRuleRepo(), i.getRule());
+ void addUnmatched(PreviousIssue i) {
+ unmatchedByKey.put(i.key(), i);
+ RuleKey ruleKey = i.ruleKey();
if (!unmatchedByRuleAndKey.containsKey(ruleKey)) {
- unmatchedByRuleAndKey.put(ruleKey, new HashMap<String, IssueDto>());
- unmatchedByRuleAndLineAndChecksum.put(ruleKey, new HashMap<Integer, Multimap<String, IssueDto>>());
+ unmatchedByRuleAndKey.put(ruleKey, new HashMap<String, PreviousIssue>());
+ unmatchedByRuleAndLineAndChecksum.put(ruleKey, new HashMap<Integer, Multimap<String, PreviousIssue>>());
}
- unmatchedByRuleAndKey.get(ruleKey).put(i.getKee(), i);
- Map<Integer, Multimap<String, IssueDto>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
+ unmatchedByRuleAndKey.get(ruleKey).put(i.key(), i);
+ Map<Integer, Multimap<String, PreviousIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
Integer lineNotNull = lineNotNull(i);
if (!unmatchedForRule.containsKey(lineNotNull)) {
- unmatchedForRule.put(lineNotNull, HashMultimap.<String, IssueDto>create());
+ unmatchedForRule.put(lineNotNull, HashMultimap.<String, PreviousIssue>create());
}
- Multimap<String, IssueDto> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
- String checksumNotNull = StringUtils.defaultString(i.getChecksum(), "");
+ Multimap<String, PreviousIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
+ String checksumNotNull = StringUtils.defaultString(i.checksum(), "");
unmatchedForRuleAndLine.put(checksumNotNull, i);
}
- private Integer lineNotNull(IssueDto i) {
- Integer line = i.getLine();
+ private Integer lineNotNull(PreviousIssue i) {
+ Integer line = i.line();
return line != null ? line : 0;
}
- void setMatch(DefaultIssue issue, IssueDto matching) {
+ void setMatch(DefaultIssue issue, PreviousIssue matching) {
matched.put(issue, matching);
- RuleKey ruleKey = RuleKey.of(matching.getRuleRepo(), matching.getRule());
- unmatchedByRuleAndKey.get(ruleKey).remove(matching.getKee());
- unmatchedByKey.remove(matching.getKee());
+ RuleKey ruleKey = matching.ruleKey();
+ unmatchedByRuleAndKey.get(ruleKey).remove(matching.key());
+ unmatchedByKey.remove(matching.key());
Integer lineNotNull = lineNotNull(matching);
- String checksumNotNull = StringUtils.defaultString(matching.getChecksum(), "");
+ String checksumNotNull = StringUtils.defaultString(matching.checksum(), "");
unmatchedByRuleAndLineAndChecksum.get(ruleKey).get(lineNotNull).get(checksumNotNull).remove(matching);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
new file mode 100644
index 00000000000..99542db8cb6
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
@@ -0,0 +1,227 @@
+/*
+ * 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.issue.tracking;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.rule.ActiveRule;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.issue.internal.IssueChangeContext;
+import org.sonar.api.resources.File;
+import org.sonar.api.resources.Project;
+import org.sonar.api.resources.ResourceUtils;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.index.BatchResource;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.scan.LastLineHashes;
+import org.sonar.batch.scan.filesystem.InputPathCache;
+import org.sonar.core.issue.IssueUpdater;
+import org.sonar.core.issue.workflow.IssueWorkflow;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class LocalIssueTracking implements BatchComponent {
+
+ private final IssueCache issueCache;
+ private final IssueTracking tracking;
+ private final LastLineHashes lastLineHashes;
+ private final IssueWorkflow workflow;
+ private final IssueUpdater updater;
+ private final IssueChangeContext changeContext;
+ private final ActiveRules activeRules;
+ private final InputPathCache inputPathCache;
+ private final ResourceCache resourceCache;
+ private final PreviousIssueRepository previousIssueCache;
+
+ public LocalIssueTracking(ResourceCache resourceCache, IssueCache issueCache, IssueTracking tracking,
+ LastLineHashes lastLineHashes, IssueWorkflow workflow, IssueUpdater updater,
+ ActiveRules activeRules, InputPathCache inputPathCache, PreviousIssueRepository previousIssueCache) {
+ this.resourceCache = resourceCache;
+ this.issueCache = issueCache;
+ this.tracking = tracking;
+ this.lastLineHashes = lastLineHashes;
+ this.workflow = workflow;
+ this.updater = updater;
+ this.inputPathCache = inputPathCache;
+ this.previousIssueCache = previousIssueCache;
+ this.changeContext = IssueChangeContext.createScan(((Project) resourceCache.getRoot().resource()).getAnalysisDate());
+ this.activeRules = activeRules;
+ }
+
+ public void execute() {
+ previousIssueCache.load();
+
+ for (BatchResource component : resourceCache.all()) {
+ trackIssues(component);
+ }
+ }
+
+ public void trackIssues(BatchResource component) {
+
+ Collection<DefaultIssue> issues = Lists.newArrayList();
+ for (Issue issue : issueCache.byComponent(component.resource().getEffectiveKey())) {
+ issues.add((DefaultIssue) issue);
+ }
+ issueCache.clear(component.resource().getEffectiveKey());
+ // issues = all the issues created by rule engines during this module scan and not excluded by filters
+
+ // all the issues that are not closed in db before starting this module scan, including manual issues
+ Collection<PreviousIssue> previousIssues = new ArrayList<>();
+ for (org.sonar.batch.protocol.input.issues.PreviousIssue previousIssue : previousIssueCache.byComponent(component)) {
+ previousIssues.add(new PreviousIssueFromWs(previousIssue));
+ }
+
+ SourceHashHolder sourceHashHolder = null;
+ if (ResourceUtils.isFile(component.resource())) {
+ File sonarFile = (File) component.resource();
+ InputFile file = inputPathCache.getFile(component.parent().parent().resource().getEffectiveKey(), sonarFile.getPath());
+ if (file == null) {
+ throw new IllegalStateException("Resource " + component.resource() + " was not found in InputPath cache");
+ }
+ sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes);
+ }
+
+ IssueTrackingResult trackingResult = tracking.track(sourceHashHolder, previousIssues, issues);
+
+ // unmatched = issues that have been resolved + issues on disabled/removed rules + manual issues
+ addUnmatched(trackingResult.unmatched(), sourceHashHolder, issues);
+
+ mergeMatched(trackingResult);
+
+ if (ResourceUtils.isRootProject(component.resource())) {
+ // issues that relate to deleted components
+ addIssuesOnDeletedComponents(issues);
+ }
+
+ for (DefaultIssue issue : issues) {
+ workflow.doAutomaticTransition(issue, changeContext);
+ issueCache.put(issue);
+ }
+ }
+
+ @VisibleForTesting
+ protected void mergeMatched(IssueTrackingResult result) {
+ for (DefaultIssue issue : result.matched()) {
+ org.sonar.batch.protocol.input.issues.PreviousIssue ref = ((PreviousIssueFromWs) result.matching(issue)).getDto();
+
+ // invariant fields
+ issue.setKey(ref.key());
+
+ // non-persisted fields
+ issue.setNew(false);
+ issue.setEndOfLife(false);
+ issue.setOnDisabledRule(false);
+
+ // fields to update with old values
+ issue.setResolution(ref.resolution());
+ issue.setStatus(ref.status());
+ issue.setAssignee(ref.assigneeLogin());
+
+ String overriddenSeverity = ref.overriddenSeverity();
+ if (overriddenSeverity != null) {
+ // Severity overriden by user
+ issue.setSeverity(overriddenSeverity);
+ }
+ }
+ }
+
+ private void addUnmatched(Collection<PreviousIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
+ for (PreviousIssue unmatchedIssue : unmatchedIssues) {
+ org.sonar.batch.protocol.input.issues.PreviousIssue unmatchedPreviousIssue = ((PreviousIssueFromWs) unmatchedIssue).getDto();
+ ActiveRule activeRule = activeRules.find(unmatchedIssue.ruleKey());
+ DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue);
+ if (activeRule != null && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.status())) {
+ relocateManualIssue(unmatched, unmatchedIssue, sourceHashHolder);
+ }
+ updateUnmatchedIssue(unmatched, false /* manual issues can be kept open */);
+ issues.add(unmatched);
+ }
+ }
+
+ private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) {
+ for (org.sonar.batch.protocol.input.issues.PreviousIssue previous : previousIssueCache.issuesOnMissingComponents()) {
+ DefaultIssue dead = toUnmatchedIssue(previous);
+ updateUnmatchedIssue(dead, true);
+ issues.add(dead);
+ }
+ }
+
+ private DefaultIssue toUnmatchedIssue(org.sonar.batch.protocol.input.issues.PreviousIssue previous) {
+ DefaultIssue issue = new DefaultIssue();
+ issue.setKey(previous.key());
+ issue.setStatus(previous.status());
+ issue.setResolution(previous.resolution());
+ issue.setMessage(previous.message());
+ issue.setLine(previous.line());
+ String overriddenSeverity = previous.overriddenSeverity();
+ if (overriddenSeverity != null) {
+ issue.setSeverity(overriddenSeverity);
+ } else {
+ ActiveRule activeRule = activeRules.find(RuleKey.of(previous.ruleRepo(), previous.ruleKey()));
+ if (activeRule != null) {
+ // FIXME if rule was removed we can't guess what was the severity of the issue
+ issue.setSeverity(activeRule.severity());
+ }
+ }
+ issue.setAssignee(previous.assigneeLogin());
+ issue.setComponentKey(previous.componentKey());
+ issue.setManualSeverity(overriddenSeverity != null);
+ issue.setRuleKey(RuleKey.of(previous.ruleRepo(), previous.ruleKey()));
+ issue.setNew(false);
+ return issue;
+ }
+
+ private void updateUnmatchedIssue(DefaultIssue issue, boolean forceEndOfLife) {
+ ActiveRule activeRule = activeRules.find(issue.ruleKey());
+ boolean isRemovedRule = activeRule == null;
+ issue.setEndOfLife(forceEndOfLife || isRemovedRule);
+ issue.setOnDisabledRule(isRemovedRule);
+ }
+
+ private void relocateManualIssue(DefaultIssue newIssue, PreviousIssue oldIssue, SourceHashHolder sourceHashHolder) {
+ Integer previousLine = oldIssue.line();
+ if (previousLine == null) {
+ return;
+ }
+
+ Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine);
+ if (newLinesWithSameHash.isEmpty()) {
+ if (previousLine > sourceHashHolder.getHashedSource().length()) {
+ newIssue.setLine(null);
+ updater.setStatus(newIssue, Issue.STATUS_CLOSED, changeContext);
+ updater.setResolution(newIssue, Issue.RESOLUTION_REMOVED, changeContext);
+ updater.setPastLine(newIssue, previousLine);
+ updater.setPastMessage(newIssue, oldIssue.message(), changeContext);
+ }
+ } else if (newLinesWithSameHash.size() == 1) {
+ Integer newLine = newLinesWithSameHash.iterator().next();
+ newIssue.setLine(newLine);
+ updater.setPastLine(newIssue, previousLine);
+ updater.setPastMessage(newIssue, oldIssue.message(), changeContext);
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java
new file mode 100644
index 00000000000..dcef8caaa5a
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java
@@ -0,0 +1,47 @@
+/*
+ * 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.issue.tracking;
+
+import org.sonar.api.rule.RuleKey;
+
+import javax.annotation.CheckForNull;
+
+public interface PreviousIssue {
+
+ String key();
+
+ RuleKey ruleKey();
+
+ /**
+ * Null for issue with no line
+ */
+ @CheckForNull
+ String checksum();
+
+ /**
+ * Global issues have no line
+ */
+ @CheckForNull
+ Integer line();
+
+ @CheckForNull
+ String message();
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java
new file mode 100644
index 00000000000..f20f420def4
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java
@@ -0,0 +1,62 @@
+/*
+ * 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.issue.tracking;
+
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.issue.db.IssueDto;
+
+public class PreviousIssueFromDb implements PreviousIssue {
+
+ private IssueDto dto;
+
+ public PreviousIssueFromDb(IssueDto dto) {
+ this.dto = dto;
+ }
+
+ public IssueDto getDto() {
+ return dto;
+ }
+
+ @Override
+ public String key() {
+ return dto.getKee();
+ }
+
+ @Override
+ public RuleKey ruleKey() {
+ return dto.getRuleKey();
+ }
+
+ @Override
+ public String checksum() {
+ return dto.getChecksum();
+ }
+
+ @Override
+ public Integer line() {
+ return dto.getLine();
+ }
+
+ @Override
+ public String message() {
+ return dto.getMessage();
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java
new file mode 100644
index 00000000000..a9a435abb8c
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java
@@ -0,0 +1,61 @@
+/*
+ * 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.issue.tracking;
+
+import org.sonar.api.rule.RuleKey;
+
+public class PreviousIssueFromWs implements PreviousIssue {
+
+ private org.sonar.batch.protocol.input.issues.PreviousIssue dto;
+
+ public PreviousIssueFromWs(org.sonar.batch.protocol.input.issues.PreviousIssue dto) {
+ this.dto = dto;
+ }
+
+ public org.sonar.batch.protocol.input.issues.PreviousIssue getDto() {
+ return dto;
+ }
+
+ @Override
+ public String key() {
+ return dto.key();
+ }
+
+ @Override
+ public RuleKey ruleKey() {
+ return RuleKey.of(dto.ruleRepo(), dto.ruleKey());
+ }
+
+ @Override
+ public String checksum() {
+ return dto.checksum();
+ }
+
+ @Override
+ public Integer line() {
+ return dto.line();
+ }
+
+ @Override
+ public String message() {
+ return dto.message();
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java
new file mode 100644
index 00000000000..6bad06cf818
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java
@@ -0,0 +1,84 @@
+/*
+ * 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.issue.tracking;
+
+import com.google.common.base.Function;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.InstantiationStrategy;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.batch.index.BatchResource;
+import org.sonar.batch.index.Cache;
+import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.repository.PreviousIssuesLoader;
+
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public class PreviousIssueRepository implements BatchComponent {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PreviousIssueRepository.class);
+
+ private final Caches caches;
+ private Cache<PreviousIssue> issuesCache;
+ private final PreviousIssuesLoader previousIssuesLoader;
+ private final ProjectReactor reactor;
+ private final ResourceCache resourceCache;
+
+ public PreviousIssueRepository(Caches caches, PreviousIssuesLoader previousIssuesLoader, ProjectReactor reactor, ResourceCache resourceCache) {
+ this.caches = caches;
+ this.previousIssuesLoader = previousIssuesLoader;
+ this.reactor = reactor;
+ this.resourceCache = resourceCache;
+ }
+
+ public void load() {
+ TimeProfiler profiler = new TimeProfiler(LOG).start("Load previous issues");
+ try {
+ this.issuesCache = caches.createCache("previousIssues");
+ previousIssuesLoader.load(reactor, new Function<PreviousIssue, Void>() {
+
+ @Override
+ public Void apply(PreviousIssue issue) {
+ String componentKey = issue.componentKey();
+ BatchResource r = resourceCache.get(componentKey);
+ if (r == null) {
+ // Deleted resource
+ issuesCache.put(0, issue.key(), issue);
+ }
+ issuesCache.put(r.batchId(), issue.key(), issue);
+ return null;
+ }
+ });
+ } finally {
+ profiler.stop();
+ }
+ }
+
+ public Iterable<PreviousIssue> byComponent(BatchResource component) {
+ return issuesCache.values(component.batchId());
+ }
+
+ public Iterable<PreviousIssue> issuesOnMissingComponents() {
+ return issuesCache.values(0);
+ }
+}
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/RollingFileHashes.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/RollingFileHashes.java
index 313507a4d69..84beecd42ed 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/RollingFileHashes.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/RollingFileHashes.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue.tracking;
+package org.sonar.batch.issue.tracking;
/**
* Compute hashes of block around each line
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SourceHashHolder.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/SourceHashHolder.java
index 612968e8fc9..38f0af7745a 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/SourceHashHolder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/SourceHashHolder.java
@@ -17,13 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import com.google.common.collect.ImmutableSet;
import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.batch.scan.LastLineHashes;
-import org.sonar.plugins.core.issue.tracking.FileHashes;
import javax.annotation.CheckForNull;
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/package-info.java
index 4a3c6986229..8df05a16129 100644
--- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/tracking/package-info.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/package-info.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+@ParametersAreNonnullByDefault
+package org.sonar.batch.issue.tracking;
-@javax.annotation.ParametersAreNonnullByDefault
-package org.sonar.plugins.core.issue.tracking;
-
+import javax.annotation.ParametersAreNonnullByDefault;
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 1afdd61be6d..27bbc64ef0a 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
@@ -19,6 +19,7 @@
*/
package org.sonar.batch.mediumtest;
+import com.google.common.base.Function;
import org.apache.commons.io.Charsets;
import org.sonar.api.SonarPlugin;
import org.sonar.api.batch.bootstrap.ProjectReactor;
@@ -32,9 +33,11 @@ import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.protocol.input.ActiveRule;
import org.sonar.batch.protocol.input.GlobalReferentials;
-import org.sonar.batch.protocol.input.ProjectReferentials;
-import org.sonar.batch.referential.GlobalReferentialsLoader;
-import org.sonar.batch.referential.ProjectReferentialsLoader;
+import org.sonar.batch.protocol.input.ProjectRepository;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.repository.GlobalReferentialsLoader;
+import org.sonar.batch.repository.PreviousIssuesLoader;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.RemotePlugin;
@@ -65,6 +68,7 @@ public class BatchMediumTester {
private final FakeGlobalReferentialsLoader globalRefProvider = new FakeGlobalReferentialsLoader();
private final FakeProjectReferentialsLoader projectRefProvider = new FakeProjectReferentialsLoader();
private final FakePluginsReferential pluginsReferential = new FakePluginsReferential();
+ private final FakePreviousIssuesLoader previousIssues = new FakePreviousIssuesLoader();
private final Map<String, String> bootstrapProperties = new HashMap<String, String>();
public BatchMediumTester build() {
@@ -114,6 +118,11 @@ public class BatchMediumTester {
return this;
}
+ public BatchMediumTesterBuilder addPreviousIssue(PreviousIssue issue) {
+ previousIssues.getPreviousIssues().add(issue);
+ return this;
+ }
+
}
public void start() {
@@ -132,6 +141,7 @@ public class BatchMediumTester {
builder.pluginsReferential,
builder.globalRefProvider,
builder.projectRefProvider,
+ builder.previousIssues,
new DefaultDebtModel())
.setBootstrapProperties(builder.bootstrapProperties)
.build();
@@ -217,12 +227,12 @@ public class BatchMediumTester {
}
}
- private static class FakeProjectReferentialsLoader implements ProjectReferentialsLoader {
+ private static class FakeProjectReferentialsLoader implements ProjectRepositoriesLoader {
- private ProjectReferentials ref = new ProjectReferentials();
+ private ProjectRepository ref = new ProjectRepository();
@Override
- public ProjectReferentials load(ProjectReactor reactor, TaskProperties taskProperties) {
+ public ProjectRepository load(ProjectReactor reactor, TaskProperties taskProperties) {
return ref;
}
@@ -272,4 +282,22 @@ public class BatchMediumTester {
}
+ private static class FakePreviousIssuesLoader implements PreviousIssuesLoader {
+
+ List<PreviousIssue> previousIssues = new ArrayList<>();
+
+ public List<PreviousIssue> getPreviousIssues() {
+ return previousIssues;
+ }
+
+ @Override
+ public void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer) {
+ for (PreviousIssue previousIssue : previousIssues) {
+ consumer.apply(previousIssue);
+ }
+
+ }
+
+ }
+
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java
index de4bd65a3b4..80c2fe8c078 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java
@@ -25,6 +25,7 @@ import org.sonar.batch.events.BatchStepEvent;
import org.sonar.batch.events.EventBus;
import org.sonar.batch.index.DefaultIndex;
import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
+import org.sonar.batch.issue.tracking.LocalIssueTracking;
import org.sonar.batch.rule.QProfileVerifier;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.batch.scan.filesystem.FileSystemLogger;
@@ -46,13 +47,14 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
private final QProfileVerifier profileVerifier;
private final IssueExclusionsLoader issueExclusionsLoader;
private final IssuesReports issuesReport;
+ private final LocalIssueTracking localIssueTracking;
public PreviewPhaseExecutor(Phases phases,
MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor,
SensorsExecutor sensorsExecutor,
SensorContext sensorContext, DefaultIndex index,
EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
- IssueExclusionsLoader issueExclusionsLoader) {
+ IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking) {
this.phases = phases;
this.mavenPluginsConfigurator = mavenPluginsConfigurator;
this.initializersExecutor = initializersExecutor;
@@ -66,6 +68,7 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
this.fs = fs;
this.profileVerifier = profileVerifier;
this.issueExclusionsLoader = issueExclusionsLoader;
+ this.localIssueTracking = localIssueTracking;
}
/**
@@ -95,6 +98,9 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
}
if (module.isRoot()) {
+
+ localIssueTracking();
+
issuesReport();
}
@@ -102,6 +108,13 @@ public final class PreviewPhaseExecutor implements PhaseExecutor {
eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
}
+ private void localIssueTracking() {
+ String stepName = "Local Issue Tracking";
+ eventBus.fireEvent(new BatchStepEvent(stepName, true));
+ localIssueTracking.execute();
+ eventBus.fireEvent(new BatchStepEvent(stepName, false));
+ }
+
private void issuesReport() {
String stepName = "Issues Reports";
eventBus.fireEvent(new BatchStepEvent(stepName, true));
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/DefaultGlobalReferentialsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalReferentialsLoader.java
index 17fd6821a6c..91012f9a6e3 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/DefaultGlobalReferentialsLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultGlobalReferentialsLoader.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.protocol.input.GlobalReferentials;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java
new file mode 100644
index 00000000000..d2831e4a8f2
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java
@@ -0,0 +1,55 @@
+/*
+ * 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.repository;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Function;
+import com.google.common.io.InputSupplier;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.batch.bootstrap.ServerClient;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.protocol.input.issues.PreviousIssueHelper;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+public class DefaultPreviousIssuesLoader implements PreviousIssuesLoader {
+
+ private final ServerClient serverClient;
+
+ public DefaultPreviousIssuesLoader(ServerClient serverClient) {
+ this.serverClient = serverClient;
+ }
+
+ @Override
+ public void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer) {
+ InputSupplier<InputStream> request = serverClient.doRequest("/batch/issues?key=" + ServerClient.encodeForUrl(reactor.getRoot().getKeyWithBranch()), "GET", null);
+ try (InputStream is = request.getInput(); Reader reader = new InputStreamReader(is, Charsets.UTF_8)) {
+ for (PreviousIssue issue : PreviousIssueHelper.getIssues(reader)) {
+ consumer.apply(issue);
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to get previous issues", e);
+ }
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/DefaultProjectReferentialsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectReferentialsLoader.java
index 90a10bc1191..de45aeaf428 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/DefaultProjectReferentialsLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectReferentialsLoader.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
@@ -35,7 +35,7 @@ import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.bootstrap.TaskProperties;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.batch.rule.ModuleQProfiles;
import javax.annotation.CheckForNull;
@@ -48,7 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-public class DefaultProjectReferentialsLoader implements ProjectReferentialsLoader {
+public class DefaultProjectReferentialsLoader implements ProjectRepositoriesLoader {
private static final Logger LOG = LoggerFactory.getLogger(DefaultProjectReferentialsLoader.class);
@@ -71,7 +71,7 @@ public class DefaultProjectReferentialsLoader implements ProjectReferentialsLoad
}
@Override
- public ProjectReferentials load(ProjectReactor reactor, TaskProperties taskProperties) {
+ public ProjectRepository load(ProjectReactor reactor, TaskProperties taskProperties) {
String projectKey = reactor.getRoot().getKeyWithBranch();
String url = BATCH_PROJECT_URL + "?key=" + ServerClient.encodeForUrl(projectKey);
if (taskProperties.properties().containsKey(ModuleQProfiles.SONAR_PROFILE_PROP)) {
@@ -80,7 +80,7 @@ public class DefaultProjectReferentialsLoader implements ProjectReferentialsLoad
url += "&profile=" + ServerClient.encodeForUrl(taskProperties.properties().get(ModuleQProfiles.SONAR_PROFILE_PROP));
}
url += "&preview=" + analysisMode.isPreview();
- ProjectReferentials ref = ProjectReferentials.fromJson(serverClient.request(url));
+ ProjectRepository ref = ProjectRepository.fromJson(serverClient.request(url));
if (session != null) {
for (ProjectDefinition module : reactor.getProjects()) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsLoader.java
index d355867d433..1dbbb520882 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsLoader.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import org.sonar.batch.protocol.input.GlobalReferentials;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsProvider.java
index 5e10e6c61e4..d3c99dc6552 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/GlobalReferentialsProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/GlobalReferentialsProvider.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import org.picocontainer.injectors.ProviderAdapter;
import org.slf4j.Logger;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java
new file mode 100644
index 00000000000..fe706da3e73
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java
@@ -0,0 +1,30 @@
+/*
+ * 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.repository;
+
+import com.google.common.base.Function;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
+
+public interface PreviousIssuesLoader {
+
+ void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer);
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
index e4bad9f1e13..75caa6f3b4f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesLoader.java
@@ -17,14 +17,14 @@
* 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.referential;
+package org.sonar.batch.repository;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.batch.bootstrap.TaskProperties;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
-public interface ProjectReferentialsLoader {
+public interface ProjectRepositoriesLoader {
- ProjectReferentials load(ProjectReactor reactor, TaskProperties taskProperties);
+ ProjectRepository load(ProjectReactor reactor, TaskProperties taskProperties);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsProvider.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
index 03486bfdcee..c9cf9e40537 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/ProjectReferentialsProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ProjectRepositoriesProvider.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import org.picocontainer.injectors.ProviderAdapter;
import org.slf4j.Logger;
@@ -25,15 +25,15 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.batch.bootstrap.TaskProperties;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
-public class ProjectReferentialsProvider extends ProviderAdapter {
+public class ProjectRepositoriesProvider extends ProviderAdapter {
- private static final Logger LOG = LoggerFactory.getLogger(ProjectReferentialsProvider.class);
+ private static final Logger LOG = LoggerFactory.getLogger(ProjectRepositoriesProvider.class);
- private ProjectReferentials projectReferentials;
+ private ProjectRepository projectReferentials;
- public ProjectReferentials provide(ProjectReferentialsLoader loader, ProjectReactor reactor, TaskProperties taskProps) {
+ public ProjectRepository provide(ProjectRepositoriesLoader loader, ProjectReactor reactor, TaskProperties taskProps) {
if (projectReferentials == null) {
TimeProfiler profiler = new TimeProfiler(LOG).start("Load project referentials");
try {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/referential/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/repository/package-info.java
index 1a50ff50cdf..353f019b08f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/referential/package-info.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/package-info.java
@@ -18,6 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
-package org.sonar.batch.referential;
+package org.sonar.batch.repository;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java
index a539b744073..4ae65303f0e 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java
@@ -25,26 +25,26 @@ import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.batch.rule.internal.NewActiveRule;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.protocol.input.ActiveRule;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import java.util.Map.Entry;
/**
* Loads the rules that are activated on the Quality profiles
- * used by the current module and build {@link org.sonar.api.batch.rule.ActiveRules}.
+ * used by the current project and build {@link org.sonar.api.batch.rule.ActiveRules}.
*/
public class ActiveRulesProvider extends ProviderAdapter {
private ActiveRules singleton = null;
- public ActiveRules provide(ProjectReferentials ref) {
+ public ActiveRules provide(ProjectRepository ref) {
if (singleton == null) {
singleton = load(ref);
}
return singleton;
}
- private ActiveRules load(ProjectReferentials ref) {
+ private ActiveRules load(ProjectRepository ref) {
ActiveRulesBuilder builder = new ActiveRulesBuilder();
for (ActiveRule activeRule : ref.activeRules()) {
NewActiveRule newActiveRule = builder.create(RuleKey.of(activeRule.repositoryKey(), activeRule.ruleKey()));
diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java
index dba6cd74a9b..badcc7878c6 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ModuleQProfiles.java
@@ -21,7 +21,7 @@ package org.sonar.batch.rule;
import com.google.common.collect.ImmutableMap;
import org.sonar.api.BatchComponent;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import javax.annotation.CheckForNull;
@@ -36,7 +36,7 @@ public class ModuleQProfiles implements BatchComponent {
public static final String SONAR_PROFILE_PROP = "sonar.profile";
private final Map<String, QProfile> byLanguage;
- public ModuleQProfiles(ProjectReferentials ref) {
+ public ModuleQProfiles(ProjectRepository ref) {
ImmutableMap.Builder<String, QProfile> builder = ImmutableMap.builder();
for (org.sonar.batch.protocol.input.QProfile qProfile : ref.qProfiles()) {
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 59dc45098d5..c54806dd347 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
@@ -19,8 +19,6 @@
*/
package org.sonar.batch.scan;
-import org.sonar.batch.sensor.AnalyzerOptimizer;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
@@ -59,6 +57,9 @@ import org.sonar.batch.issue.ignore.pattern.IssueExclusionPatternInitializer;
import org.sonar.batch.issue.ignore.pattern.IssueInclusionPatternInitializer;
import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
+import org.sonar.batch.issue.tracking.InitialOpenIssuesSensor;
+import org.sonar.batch.issue.tracking.IssueHandlers;
+import org.sonar.batch.issue.tracking.IssueTrackingDecorator;
import org.sonar.batch.language.LanguageDistributionDecorator;
import org.sonar.batch.phases.DecoratorsExecutor;
import org.sonar.batch.phases.DefaultPhaseExecutor;
@@ -75,7 +76,6 @@ import org.sonar.batch.qualitygate.QualityGateVerifier;
import org.sonar.batch.report.ComponentsPublisher;
import org.sonar.batch.report.IssuesPublisher;
import org.sonar.batch.report.PublishReportJob;
-import org.sonar.batch.rule.ActiveRulesProvider;
import org.sonar.batch.rule.ModuleQProfiles;
import org.sonar.batch.rule.QProfileDecorator;
import org.sonar.batch.rule.QProfileEventsDecorator;
@@ -97,6 +97,7 @@ import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter;
import org.sonar.batch.scan.filesystem.StatusDetectionFactory;
import org.sonar.batch.scan.maven.MavenPluginsConfigurator;
import org.sonar.batch.scan.report.IssuesReports;
+import org.sonar.batch.sensor.AnalyzerOptimizer;
import org.sonar.batch.sensor.DefaultSensorContext;
import org.sonar.batch.sensor.DefaultSensorStorage;
import org.sonar.batch.sensor.coverage.CoverageExclusions;
@@ -185,7 +186,6 @@ public class ModuleScanContainer extends ComponentContainer {
// rules
ModuleQProfiles.class,
- new ActiveRulesProvider(),
new RulesProfileProvider(),
QProfileSensor.class,
QProfileDecorator.class,
@@ -229,6 +229,11 @@ public class ModuleScanContainer extends ComponentContainer {
SqaleRatingDecorator.class,
SqaleRatingSettings.class,
+ // Issue tracking
+ IssueTrackingDecorator.class,
+ IssueHandlers.class,
+ InitialOpenIssuesSensor.class,
+
QProfileEventsDecorator.class,
TimeMachineConfiguration.class);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java
index f7c2d9fa27d..83b1c328deb 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java
@@ -27,7 +27,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.GlobalSettings;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import java.util.List;
@@ -36,10 +36,10 @@ import java.util.List;
*/
public class ModuleSettings extends Settings {
- private final ProjectReferentials projectReferentials;
+ private final ProjectRepository projectReferentials;
private AnalysisMode analysisMode;
- public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition project, ProjectReferentials projectReferentials,
+ public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition project, ProjectRepository projectReferentials,
AnalysisMode analysisMode) {
super(batchSettings.getDefinitions());
this.projectReferentials = projectReferentials;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index 0a3c22ef77a..d6a47de9952 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -59,11 +59,15 @@ import org.sonar.batch.index.ResourcePersister;
import org.sonar.batch.index.SourcePersister;
import org.sonar.batch.issue.DefaultProjectIssues;
import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.issue.tracking.InitialOpenIssuesStack;
+import org.sonar.batch.issue.tracking.LocalIssueTracking;
+import org.sonar.batch.issue.tracking.PreviousIssueRepository;
import org.sonar.batch.languages.DefaultLanguagesReferential;
import org.sonar.batch.mediumtest.ScanTaskObservers;
import org.sonar.batch.phases.GraphPersister;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
-import org.sonar.batch.referential.ProjectReferentialsProvider;
+import org.sonar.batch.repository.ProjectRepositoriesProvider;
+import org.sonar.batch.rule.ActiveRulesProvider;
import org.sonar.batch.rule.RulesProvider;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.maven.FakeMavenPluginExecutor;
@@ -131,7 +135,7 @@ public class ProjectScanContainer extends ComponentContainer {
private void addBatchComponents() {
add(
- new ProjectReferentialsProvider(),
+ new ProjectRepositoriesProvider(),
DefaultResourceCreationLock.class,
CodeColorizers.class,
DefaultNotificationManager.class,
@@ -148,6 +152,9 @@ public class ProjectScanContainer extends ComponentContainer {
InputPathCache.class,
PathResolver.class,
+ // rules
+ new ActiveRulesProvider(),
+
// issues
IssueUpdater.class,
FunctionExecutor.class,
@@ -155,6 +162,8 @@ public class ProjectScanContainer extends ComponentContainer {
IssueCache.class,
DefaultProjectIssues.class,
IssueChangelogDebtCalculator.class,
+ LocalIssueTracking.class,
+ PreviousIssueRepository.class,
// tests
TestPlanPerspectiveLoader.class,
@@ -203,6 +212,9 @@ public class ProjectScanContainer extends ComponentContainer {
// technical debt
DefaultTechnicalDebtModel.class,
+ // Issue tracking
+ InitialOpenIssuesStack.class,
+
ProjectLock.class);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java
index 72218e95ce3..f6539dbfa7f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java
@@ -28,18 +28,18 @@ import org.sonar.api.config.Settings;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.GlobalSettings;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
public class ProjectSettings extends Settings {
private static final Logger LOG = LoggerFactory.getLogger(ProjectSettings.class);
private final GlobalSettings globalSettings;
- private final ProjectReferentials projectReferentials;
+ private final ProjectRepository projectReferentials;
private final AnalysisMode mode;
public ProjectSettings(ProjectReactor reactor, GlobalSettings globalSettings, PropertyDefinitions propertyDefinitions,
- ProjectReferentials projectReferentials, AnalysisMode mode) {
+ ProjectRepository projectReferentials, AnalysisMode mode) {
super(propertyDefinitions);
this.mode = mode;
getEncryption().setPathToSecretKey(globalSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java
index 8843e604989..883268fcc01 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetection.java
@@ -22,13 +22,13 @@ package org.sonar.batch.scan.filesystem;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
class StatusDetection {
- private final ProjectReferentials projectReferentials;
+ private final ProjectRepository projectReferentials;
- StatusDetection(ProjectReferentials projectReferentials) {
+ StatusDetection(ProjectRepository projectReferentials) {
this.projectReferentials = projectReferentials;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java
index 830cb346c09..15e19d6457b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/StatusDetectionFactory.java
@@ -20,13 +20,13 @@
package org.sonar.batch.scan.filesystem;
import org.sonar.api.BatchComponent;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
public class StatusDetectionFactory implements BatchComponent {
- private final ProjectReferentials projectReferentials;
+ private final ProjectRepository projectReferentials;
- public StatusDetectionFactory(ProjectReferentials projectReferentials) {
+ public StatusDetectionFactory(ProjectRepository projectReferentials) {
this.projectReferentials = projectReferentials;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java
index 00f6839bfdb..fc42a20e18c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java
@@ -34,7 +34,7 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.core.DryRunIncompatible;
import java.util.LinkedList;
@@ -48,10 +48,10 @@ public final class ScmSensor implements Sensor {
private final ProjectDefinition projectDefinition;
private final ScmConfiguration configuration;
private final FileSystem fs;
- private final ProjectReferentials projectReferentials;
+ private final ProjectRepository projectReferentials;
public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration,
- ProjectReferentials projectReferentials, FileSystem fs) {
+ ProjectRepository projectReferentials, FileSystem fs) {
this.projectDefinition = projectDefinition;
this.configuration = configuration;
this.projectReferentials = projectReferentials;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java
index e1c70330963..85c1e43c51a 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.apache.ibatis.session.ResultHandler;
import org.junit.Test;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
index ed7782e138b..34adce38fa1 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.junit.After;
import org.junit.Before;
@@ -73,9 +73,9 @@ public class InitialOpenIssuesStackTest {
IssueDto issueDto = new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1");
stack.addIssue(issueDto);
- List<IssueDto> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
+ List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
assertThat(issueDtos).hasSize(1);
- assertThat(issueDtos.get(0).getKee()).isEqualTo("ISSUE-1");
+ assertThat(issueDtos.get(0).key()).isEqualTo("ISSUE-1");
assertThat(stack.selectAllIssues()).isEmpty();
}
@@ -85,7 +85,7 @@ public class InitialOpenIssuesStackTest {
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-2"));
- List<IssueDto> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
+ List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
assertThat(issueDtos).hasSize(2);
assertThat(stack.selectAllIssues()).isEmpty();
@@ -95,7 +95,7 @@ public class InitialOpenIssuesStackTest {
public void get_and_remove_do_nothing_if_resource_not_found() {
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
- List<IssueDto> issueDtos = stack.selectAndRemoveIssues("Other");
+ List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("Other");
assertThat(issueDtos).hasSize(0);
assertThat(stack.selectAllIssues()).hasSize(1);
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueHandlersTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java
index b1f745927e5..8b210bd731d 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueHandlersTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java
@@ -17,7 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
+
+import org.sonar.batch.issue.tracking.IssueHandlers;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizerTest.java
index 55d84685253..30bf045483d 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/IssueTrackingBlocksRecognizerTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingBlocksRecognizerTest.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue.tracking;
+package org.sonar.batch.issue.tracking;
import org.junit.Test;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
index 337f16b94fe..7691dbf6538 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingDecoratorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Before;
@@ -61,7 +61,13 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.RETURNS_MOCKS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
public class IssueTrackingDecoratorTest {
@@ -115,7 +121,7 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue, no open issues during previous scan, no filtering
when(issueCache.byComponent("struts:Action.java")).thenReturn(Arrays.asList(issue));
- List<IssueDto> dbIssues = Collections.emptyList();
+ List<PreviousIssue> dbIssues = Collections.emptyList();
when(initialOpenIssues.selectAndRemoveIssues("struts:Action.java")).thenReturn(dbIssues);
when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
decorator.doDecorate(file);
@@ -139,7 +145,7 @@ public class IssueTrackingDecoratorTest {
Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
trackingResult.addUnmatched(unmatchedIssue);
@@ -164,7 +170,7 @@ public class IssueTrackingDecoratorTest {
@Test
public void manual_issues_should_be_moved_if_matching_line_found() throws Exception {
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -219,7 +225,7 @@ public class IssueTrackingDecoratorTest {
public void manual_issues_should_be_untouched_if_already_closed() throws Exception {
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("CLOSED").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("CLOSED").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -251,7 +257,7 @@ public class IssueTrackingDecoratorTest {
public void manual_issues_should_be_untouched_if_line_is_null() throws Exception {
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(null).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(null).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -285,7 +291,8 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue existing during previous scan
final int issueOnLine = 6;
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
+ .setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -332,7 +339,8 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue existing during previous scan
final int issueOnLine = 3;
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
+ .setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -377,7 +385,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance").setStatus(Rule.STATUS_REMOVED));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -408,7 +416,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -439,7 +447,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- IssueDto unmatchedIssue = new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance");
+ PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -504,8 +512,8 @@ public class IssueTrackingDecoratorTest {
@Test
public void merge_matched_issue() throws Exception {
- IssueDto previousIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L).setProjectKey("sample");
+ PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ .setLine(10).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L).setProjectKey("sample"));
DefaultIssue issue = new DefaultIssue();
IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
@@ -523,8 +531,8 @@ public class IssueTrackingDecoratorTest {
@Test
public void merge_matched_issue_on_manual_severity() throws Exception {
- IssueDto previousIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setManualSeverity(true).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L);
+ PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ .setLine(10).setManualSeverity(true).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L));
DefaultIssue issue = new DefaultIssue();
IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
@@ -541,8 +549,8 @@ public class IssueTrackingDecoratorTest {
public void merge_issue_changelog_with_previous_changelog() throws Exception {
when(initialOpenIssues.selectChangelog("ABCDE")).thenReturn(newArrayList(new IssueChangeDto().setIssueKey("ABCD").setCreatedAt(System2.INSTANCE.now())));
- IssueDto previousIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
- .setLine(10).setMessage("Message").setEffortToFix(1.5).setDebt(1L).setCreatedAt(System2.INSTANCE.now());
+ PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ .setLine(10).setMessage("Message").setEffortToFix(1.5).setDebt(1L).setCreatedAt(System2.INSTANCE.now()));
DefaultIssue issue = new DefaultIssue();
IssueTrackingResult trackingResult = mock(IssueTrackingResult.class);
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
index 7fb8b6a9103..2efb24c13eb 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/IssueTrackingTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
@@ -18,9 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import org.apache.commons.codec.digest.DigestUtils;
import org.junit.Before;
@@ -62,22 +63,24 @@ public class IssueTrackingTest {
@Test
public void key_should_be_the_prioritary_field_to_check() {
- IssueDto referenceIssue1 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum1").setKee("100");
- IssueDto referenceIssue2 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum2").setKee("200");
+ PreviousIssueFromDb referenceIssue1 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum1");
+ referenceIssue1.getDto().setKee("100");
+ PreviousIssueFromDb referenceIssue2 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum2");
+ referenceIssue2.getDto().setKee("200");
// exactly the fields of referenceIssue1 but not the same key
DefaultIssue newIssue = newDefaultIssue("message", 10, RuleKey.of("squid", "AvoidCycle"), "checksum1").setKey("200");
IssueTrackingResult result = new IssueTrackingResult();
- tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue1, referenceIssue2), null, result);
+ tracking.mapIssues(newArrayList(newIssue), Lists.<PreviousIssue>newArrayList(referenceIssue1, referenceIssue2), null, result);
// same key
assertThat(result.matching(newIssue)).isSameAs(referenceIssue2);
}
@Test
public void checksum_should_have_greater_priority_than_line() {
- IssueDto referenceIssue1 = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum1");
- IssueDto referenceIssue2 = newReferenceIssue("message", 3, "squid", "AvoidCycle", "checksum2");
+ PreviousIssue referenceIssue1 = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum1");
+ PreviousIssue referenceIssue2 = newReferenceIssue("message", 3, "squid", "AvoidCycle", "checksum2");
DefaultIssue newIssue1 = newDefaultIssue("message", 3, RuleKey.of("squid", "AvoidCycle"), "checksum1");
DefaultIssue newIssue2 = newDefaultIssue("message", 5, RuleKey.of("squid", "AvoidCycle"), "checksum2");
@@ -94,7 +97,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_null_line_and_checksum_but_different_messages() {
DefaultIssue newIssue = newDefaultIssue("new message", null, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("old message", null, "squid", "AvoidCycle", "checksum1");
+ PreviousIssue referenceIssue = newReferenceIssue("old message", null, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -104,7 +107,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_line_and_checksum_but_different_messages() {
DefaultIssue newIssue = newDefaultIssue("new message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("old message", 1, "squid", "AvoidCycle", "checksum1");
+ PreviousIssue referenceIssue = newReferenceIssue("old message", 1, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -114,7 +117,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_line_message() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
+ PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -124,7 +127,7 @@ public class IssueTrackingTest {
@Test
public void should_ignore_reference_measure_without_checksum() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), null);
- IssueDto referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", null);
+ PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", null);
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -134,7 +137,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_message_and_checksum_but_different_line() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum1");
+ PreviousIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -147,7 +150,7 @@ public class IssueTrackingTest {
@Test
public void same_checksum_and_rule_but_different_line_and_different_message() {
DefaultIssue newIssue = newDefaultIssue("new message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("old message", 2, "squid", "AvoidCycle", "checksum1");
+ PreviousIssue referenceIssue = newReferenceIssue("old message", 2, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -157,7 +160,7 @@ public class IssueTrackingTest {
@Test
public void should_create_new_issue_when_same_rule_same_message_but_different_line_and_checksum() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum2");
+ PreviousIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -167,7 +170,7 @@ public class IssueTrackingTest {
@Test
public void should_not_track_issue_if_different_rule() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", "checksum1");
+ PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -179,7 +182,7 @@ public class IssueTrackingTest {
// issue messages are trimmed and can be abbreviated when persisted in database.
// Comparing issue messages must use the same format.
DefaultIssue newIssue = newDefaultIssue(" message ", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- IssueDto referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
+ PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -191,7 +194,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("Indentation", 9, RuleKey.of("squid", "AvoidCycle"), "foo");
- IssueDto referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -203,7 +206,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("1 branch need to be covered", null, RuleKey.of("squid", "AvoidCycle"), "foo");
- IssueDto referenceIssue = newReferenceIssue("Indentationd", 7, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue = newReferenceIssue("Indentationd", 7, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -218,7 +221,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("1 branch need to be covered", null, RuleKey.of("squid", "AvoidCycle"), null);
- IssueDto referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -232,8 +235,8 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example1() throws Exception {
initLastHashes("example1-v1", "example1-v2");
- IssueDto referenceIssue1 = newReferenceIssue("Indentation", 7, "squid", "AvoidCycle", null);
- IssueDto referenceIssue2 = newReferenceIssue("Indentation", 11, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue1 = newReferenceIssue("Indentation", 7, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue2 = newReferenceIssue("Indentation", 11, "squid", "AvoidCycle", null);
DefaultIssue newIssue1 = newDefaultIssue("Indentation", 9, RuleKey.of("squid", "AvoidCycle"), null);
DefaultIssue newIssue2 = newDefaultIssue("Indentation", 13, RuleKey.of("squid", "AvoidCycle"), null);
@@ -255,7 +258,7 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example2() throws Exception {
initLastHashes("example2-v1", "example2-v2");
- IssueDto referenceIssue1 = newReferenceIssue("SystemPrintln", 5, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue1 = newReferenceIssue("SystemPrintln", 5, "squid", "AvoidCycle", null);
DefaultIssue newIssue1 = newDefaultIssue("SystemPrintln", 6, RuleKey.of("squid", "AvoidCycle"), null);
DefaultIssue newIssue2 = newDefaultIssue("SystemPrintln", 10, RuleKey.of("squid", "AvoidCycle"), null);
@@ -276,9 +279,9 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example3() throws Exception {
initLastHashes("example3-v1", "example3-v2");
- IssueDto referenceIssue1 = newReferenceIssue("Avoid unused local variables such as 'j'.", 6, "squid", "AvoidCycle", "63c11570fc0a76434156be5f8138fa03");
- IssueDto referenceIssue2 = newReferenceIssue("Avoid unused private methods such as 'myMethod()'.", 13, "squid", "NullDeref", "ef23288705d1ef1e512448ace287586e");
- IssueDto referenceIssue3 = newReferenceIssue("Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.", 9, "pmd",
+ PreviousIssue referenceIssue1 = newReferenceIssue("Avoid unused local variables such as 'j'.", 6, "squid", "AvoidCycle", "63c11570fc0a76434156be5f8138fa03");
+ PreviousIssue referenceIssue2 = newReferenceIssue("Avoid unused private methods such as 'myMethod()'.", 13, "squid", "NullDeref", "ef23288705d1ef1e512448ace287586e");
+ PreviousIssue referenceIssue3 = newReferenceIssue("Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.", 9, "pmd",
"UnusedLocalVariable", "ed5cdd046fda82727d6fedd1d8e3a310");
// New issue
@@ -311,7 +314,7 @@ public class IssueTrackingTest {
public void dont_load_checksum_if_no_new_issue() throws Exception {
sourceHashHolder = mock(SourceHashHolder.class);
- IssueDto referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
tracking.track(sourceHashHolder, newArrayList(referenceIssue), Collections.<DefaultIssue>emptyList());
@@ -326,7 +329,7 @@ public class IssueTrackingTest {
return new DefaultIssue().setMessage(message).setLine(line).setRuleKey(ruleKey).setChecksum(checksum).setStatus(Issue.STATUS_OPEN);
}
- private IssueDto newReferenceIssue(String message, Integer lineId, String ruleRepo, String ruleKey, String lineChecksum) {
+ private PreviousIssueFromDb newReferenceIssue(String message, Integer lineId, String ruleRepo, String ruleKey, String lineChecksum) {
IssueDto referenceIssue = new IssueDto();
Long id = violationId++;
referenceIssue.setId(id);
@@ -337,7 +340,7 @@ public class IssueTrackingTest {
referenceIssue.setChecksum(lineChecksum);
referenceIssue.setResolution(null);
referenceIssue.setStatus(Issue.STATUS_OPEN);
- return referenceIssue;
+ return new PreviousIssueFromDb(referenceIssue);
}
private void initLastHashes(String reference, String newSource) throws IOException {
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/RollingFileHashesTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/RollingFileHashesTest.java
index 50c3d0eefa0..25abe186d2e 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/tracking/RollingFileHashesTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/RollingFileHashesTest.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue.tracking;
+package org.sonar.batch.issue.tracking;
import org.junit.Test;
diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/SourceHashHolderTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/SourceHashHolderTest.java
index c9942c852b4..6ac6645bbae 100644
--- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/SourceHashHolderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/SourceHashHolderTest.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.plugins.core.issue;
+package org.sonar.batch.issue.tracking;
import org.junit.Before;
import org.junit.Test;
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 89f926e296f..a6bed59f2fd 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
@@ -66,7 +66,7 @@ public class IssuesMediumTest {
.newScanTask(new File(projectDir, "sonar-project.properties"))
.start();
- assertThat(result.issues()).hasSize(26);
+ assertThat(result.issues()).hasSize(14);
}
@Test
@@ -78,7 +78,7 @@ public class IssuesMediumTest {
.property("sonar.xoo.internalKey", "OneIssuePerLine.internal")
.start();
- assertThat(result.issues()).hasSize(26 /* 26 lines */+ 3 /* 3 files */);
+ assertThat(result.issues()).hasSize(14 /* 8 + 6 lines */+ 2 /* 2 files */);
}
@Test
@@ -103,7 +103,7 @@ public class IssuesMediumTest {
.property("sonar.issue.ignore.allfile.1.fileRegexp", "object")
.start();
- assertThat(result.issues()).hasSize(20);
+ assertThat(result.issues()).hasSize(8);
}
@Test
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java
index 23f6b90f2c4..04c588ad63f 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java
@@ -20,6 +20,7 @@
package org.sonar.batch.mediumtest.issues;
import com.google.common.collect.ImmutableMap;
+import org.apache.commons.codec.digest.DigestUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -27,6 +28,7 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.batch.mediumtest.BatchMediumTester;
import org.sonar.batch.mediumtest.TaskResult;
import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.batch.protocol.input.issues.PreviousIssue;
import org.sonar.xoo.XooPlugin;
import java.io.File;
@@ -43,6 +45,13 @@ public class ReportsMediumTest {
.addDefaultQProfile("xoo", "Sonar Way")
.activateRule(new ActiveRule("xoo", "OneIssuePerLine", "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo"))
.bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+ .addPreviousIssue(new PreviousIssue().setKey("xyz")
+ .setComponentKey("sample:xources/hello/HelloJava.xoo")
+ .setRuleKey("xoo", "OneIssuePerLine")
+ .setLine(1)
+ .setOverriddenSeverity("MAJOR")
+ .setChecksum(DigestUtils.md5Hex("packagehello;"))
+ .setStatus("OPEN"))
.build();
@Before
@@ -64,7 +73,7 @@ public class ReportsMediumTest {
.property("sonar.issuesReport.console.enable", "true")
.start();
- assertThat(result.issues()).hasSize(26);
+ assertThat(result.issues()).hasSize(14);
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/referential/DefaultProjectReferentialsLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectReferentialsLoaderTest.java
index 2a66a09cc59..108151f5aac 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/referential/DefaultProjectReferentialsLoaderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectReferentialsLoaderTest.java
@@ -17,7 +17,9 @@
* 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.referential;
+package org.sonar.batch.repository;
+
+import org.sonar.batch.repository.DefaultProjectReferentialsLoader;
import com.google.common.collect.Maps;
import org.junit.Before;
@@ -29,7 +31,6 @@ import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.ServerClient;
import org.sonar.batch.bootstrap.TaskProperties;
import org.sonar.batch.rule.ModuleQProfiles;
-
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java
index 6a8e64d6ccf..2c03cd472f4 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java
@@ -29,7 +29,7 @@ import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.utils.MessageException;
import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.GlobalSettings;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import java.util.List;
@@ -42,12 +42,12 @@ public class ModuleSettingsTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- ProjectReferentials projectRef;
+ ProjectRepository projectRef;
private AnalysisMode mode;
@Before
public void before() {
- projectRef = new ProjectReferentials();
+ projectRef = new ProjectRepository();
mode = mock(AnalysisMode.class);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
index ca6a0aa84e5..3326102185e 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
@@ -19,6 +19,8 @@
*/
package org.sonar.batch.scan;
+import org.sonar.batch.repository.ProjectRepositoriesLoader;
+
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.BatchExtension;
@@ -41,8 +43,7 @@ import org.sonar.batch.bootstrap.GlobalSettings;
import org.sonar.batch.bootstrap.TaskProperties;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
import org.sonar.batch.protocol.input.GlobalReferentials;
-import org.sonar.batch.protocol.input.ProjectReferentials;
-import org.sonar.batch.referential.ProjectReferentialsLoader;
+import org.sonar.batch.protocol.input.ProjectRepository;
import org.sonar.batch.scan.maven.MavenPluginExecutor;
import java.util.Collections;
@@ -72,10 +73,10 @@ public class ProjectScanContainerTest {
GlobalReferentials globalRef = new GlobalReferentials();
settings = new GlobalSettings(bootstrapProperties, new PropertyDefinitions(), globalRef, analysisMode);
parentContainer.add(settings);
- ProjectReferentialsLoader projectReferentialsLoader = new ProjectReferentialsLoader() {
+ ProjectRepositoriesLoader projectReferentialsLoader = new ProjectRepositoriesLoader() {
@Override
- public ProjectReferentials load(ProjectReactor reactor, TaskProperties taskProperties) {
- return new ProjectReferentials();
+ public ProjectRepository load(ProjectReactor reactor, TaskProperties taskProperties) {
+ return new ProjectRepository();
}
};
parentContainer.add(projectReferentialsLoader);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java
index c75f7aafb3d..69db0207a8b 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java
@@ -33,7 +33,7 @@ import org.sonar.batch.bootstrap.AnalysisMode;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.GlobalSettings;
import org.sonar.batch.protocol.input.GlobalReferentials;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import java.util.Collections;
@@ -46,7 +46,7 @@ public class ProjectSettingsTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
- ProjectReferentials projectRef;
+ ProjectRepository projectRef;
ProjectDefinition project = ProjectDefinition.create().setKey("struts");
GlobalSettings bootstrapProps;
@@ -54,7 +54,7 @@ public class ProjectSettingsTest {
@Before
public void prepare() {
- projectRef = new ProjectReferentials();
+ projectRef = new ProjectRepository();
mode = mock(AnalysisMode.class);
bootstrapProps = new GlobalSettings(new BootstrapProperties(Collections.<String, String>emptyMap()), new PropertyDefinitions(), new GlobalReferentials(), mode);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileMetadataTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileMetadataTest.java
index e6c73e80fd7..7b01635b67e 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileMetadataTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/FileMetadataTest.java
@@ -77,9 +77,9 @@ public class FileMetadataTest {
assertThat(metadata.lines).isEqualTo(4);
assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n"));
assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18);
- assertThat(metadata.lineHashes[0]).containsOnly(md5("föo"));
- assertThat(metadata.lineHashes[1]).containsOnly(md5("bàr"));
- assertThat(metadata.lineHashes[2]).containsOnly(md5("\u1D11Ebaßz"));
+ assertThat(metadata.lineHashes[0]).containsExactly(md5("föo"));
+ assertThat(metadata.lineHashes[1]).containsExactly(md5("bàr"));
+ assertThat(metadata.lineHashes[2]).containsExactly(md5("\u1D11Ebaßz"));
assertThat(metadata.lineHashes[3]).isNull();
}
@@ -92,9 +92,9 @@ public class FileMetadataTest {
assertThat(metadata.lines).isEqualTo(4);
assertThat(metadata.hash).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n"));
assertThat(metadata.originalLineOffsets).containsOnly(0, 5, 10, 18);
- assertThat(metadata.lineHashes[0]).containsOnly(md5("föo"));
- assertThat(metadata.lineHashes[1]).containsOnly(md5("bàr"));
- assertThat(metadata.lineHashes[2]).containsOnly(md5("\u1D11Ebaßz"));
+ assertThat(metadata.lineHashes[0]).containsExactly(md5("föo"));
+ assertThat(metadata.lineHashes[1]).containsExactly(md5("bàr"));
+ assertThat(metadata.lineHashes[2]).containsExactly(md5("\u1D11Ebaßz"));
assertThat(metadata.lineHashes[3]).isNull();
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java
index 5b1badcd0a5..ddc9d1d376b 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionFactoryTest.java
@@ -20,7 +20,7 @@
package org.sonar.batch.scan.filesystem;
import org.junit.Test;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -28,7 +28,7 @@ import static org.mockito.Mockito.mock;
public class StatusDetectionFactoryTest {
@Test
public void testCreate() throws Exception {
- StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectReferentials.class));
+ StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectRepository.class));
StatusDetection detection = factory.create();
assertThat(detection).isNotNull();
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java
index df3a94ce132..ca3282fc393 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/StatusDetectionTest.java
@@ -22,14 +22,14 @@ package org.sonar.batch.scan.filesystem;
import org.junit.Test;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.batch.protocol.input.FileData;
-import org.sonar.batch.protocol.input.ProjectReferentials;
+import org.sonar.batch.protocol.input.ProjectRepository;
import static org.assertj.core.api.Assertions.assertThat;
public class StatusDetectionTest {
@Test
public void detect_status() throws Exception {
- ProjectReferentials ref = new ProjectReferentials();
+ ProjectRepository ref = new ProjectRepository();
ref.addFileData("foo", "src/Foo.java", new FileData("ABCDE", true, null, null, null));
ref.addFileData("foo", "src/Bar.java", new FileData("FGHIJ", true, null, null, null));
StatusDetection statusDetection = new StatusDetection(ref);
diff --git a/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures b/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures
index 388d08b58a8..9eaf8ba2549 100644
--- a/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures
+++ b/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/HelloJava.xoo.measures
@@ -1,3 +1,2 @@
-lines:8
ncloc:3
complexity:1
diff --git a/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures b/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures
index c47948fc955..d2c8386aed1 100644
--- a/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures
+++ b/sonar-batch/src/test/resources/mediumtest/xoo/sample/xources/hello/helloscala.xoo.measures
@@ -1,3 +1,2 @@
-lines:5
ncloc:5
complexity:2
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v1.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v1.txt
index 1920333ddb6..1920333ddb6 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v1.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v1.txt
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v2.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v2.txt
index 231532452b2..231532452b2 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example1-v2.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example1-v2.txt
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v1.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v1.txt
index a920afe459b..a920afe459b 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v1.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v1.txt
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v2.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v2.txt
index c5c8250cf65..c5c8250cf65 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example2-v2.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example2-v2.txt
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v1.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v1.txt
index facdcbc008c..facdcbc008c 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v1.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v1.txt
diff --git a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v2.txt b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v2.txt
index 91db843fc4d..91db843fc4d 100644
--- a/plugins/sonar-core-plugin/src/test/resources/org/sonar/plugins/core/issue/IssueTrackingTest/example3-v2.txt
+++ b/sonar-batch/src/test/resources/org/sonar/batch/issue/tracking/IssueTrackingTest/example3-v2.txt
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
index cd8bf7c1a36..2b1ecfa0b33 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/FileSystem.java
@@ -48,7 +48,7 @@ import java.util.SortedSet;
* for example :
* <pre>
* DefaultFileSystem fs = new DefaultFileSystem();
- * fs.add(new DefaultInputFile("src/foo/bar.php"));
+ * fs.add(new DefaultInputFile("myprojectKey", "src/foo/bar.php"));
* </pre>
*
* @since 4.2