aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-06-03 10:31:16 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-02 16:06:08 +0200
commitbf4118d6a9ceb9ad24274cdc6537d4a607121815 (patch)
tree8f758ccb7a205da3eae96b05b74f79cade8ceae0 /sonar-batch
parent2f948758eebec934beb54701792cf2d558319251 (diff)
downloadsonarqube-bf4118d6a9ceb9ad24274cdc6537d4a607121815.tar.gz
sonarqube-bf4118d6a9ceb9ad24274cdc6537d4a607121815.zip
SONAR-6623 extract issue tracking algorithm from batch
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/ScanPersister.java29
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java93
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java86
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java141
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java279
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java50
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/PersistersExecutor.java65
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java52
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java11
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java45
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java50
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java23
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java24
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java98
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/IssueFiltersTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java81
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java120
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java62
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java584
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java75
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java57
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java12
52 files changed, 57 insertions, 2066 deletions
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 d40e1c223f7..879ae9afb82 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
@@ -40,10 +40,7 @@ import org.sonar.batch.cpd.CpdComponents;
import org.sonar.batch.debt.DebtDecorator;
import org.sonar.batch.debt.IssueChangelogDebtCalculator;
import org.sonar.batch.debt.NewDebtDecorator;
-import org.sonar.batch.issue.tracking.InitialOpenIssuesSensor;
-import org.sonar.batch.issue.tracking.IssueHandlers;
import org.sonar.batch.issue.tracking.IssueTracking;
-import org.sonar.batch.issue.tracking.IssueTrackingDecorator;
import org.sonar.batch.language.LanguageDistributionDecorator;
import org.sonar.batch.scan.report.ConsoleReport;
import org.sonar.batch.scan.report.HtmlReport;
@@ -92,11 +89,6 @@ public class BatchComponents {
DebtDecorator.class,
NewDebtDecorator.class,
- // Issue tracking
- IssueTrackingDecorator.class,
- IssueHandlers.class,
- InitialOpenIssuesSensor.class,
-
// to be moved to compute engine
UnitTestDecorator.class,
LineCoverageDecorator.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java
index 5ddb7e45949..b339ead086a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java
@@ -38,7 +38,7 @@ import org.sonar.api.batch.rule.Rules;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilters;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java
index fb882a7a0eb..5d34e8f89de 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java
@@ -34,8 +34,8 @@ import javax.annotation.Nullable;
import org.apache.commons.lang.time.DateUtils;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.IssueUpdater;
import static com.google.common.collect.Lists.newArrayList;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ScanPersister.java b/sonar-batch/src/main/java/org/sonar/batch/index/ScanPersister.java
deleted file mode 100644
index 88b749ecb18..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/index/ScanPersister.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.index;
-
-import org.sonar.api.batch.BatchSide;
-
-@BatchSide
-public interface ScanPersister {
-
- void persist();
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
index 89561865d63..9dd268a8d22 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssuable.java
@@ -23,7 +23,7 @@ import com.google.common.collect.Lists;
import java.util.List;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.BatchComponent;
import org.sonar.core.issue.DefaultIssueBuilder;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java
index 1cc682c0e34..ed9de9a5def 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java
@@ -23,7 +23,7 @@ import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.ProjectIssues;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import javax.annotation.Nullable;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java
index dc5daaaafb4..52a29fb7483 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java
@@ -20,7 +20,7 @@
package org.sonar.batch.issue;
import org.sonar.api.batch.BatchSide;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Caches;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java
index 0e623246b50..70bd4d54d5b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueFilters.java
@@ -21,7 +21,7 @@ package org.sonar.batch.issue;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.batch.IssueFilter;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
@BatchSide
public class IssueFilters {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java
index 2586d4f898a..23fa523df44 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java
@@ -28,7 +28,7 @@ import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.Rule;
import org.sonar.api.batch.rule.Rules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Violation;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java
deleted file mode 100644
index ef39e6b77e9..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import java.util.Calendar;
-import java.util.Date;
-import org.apache.commons.lang.time.DateUtils;
-import org.apache.ibatis.session.ResultContext;
-import org.apache.ibatis.session.ResultHandler;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.batch.Sensor;
-import org.sonar.api.batch.SensorContext;
-import org.sonar.api.resources.Project;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-
-/**
- * Load all the issues referenced during the previous scan.
- */
-@RequiresDB
-public class InitialOpenIssuesSensor implements Sensor {
-
- private final InitialOpenIssuesStack initialOpenIssuesStack;
- private final IssueDao issueDao;
- private final IssueChangeDao issueChangeDao;
- private final ResourceDao resourceDao;
-
- public InitialOpenIssuesSensor(InitialOpenIssuesStack initialOpenIssuesStack, IssueDao issueDao, IssueChangeDao issueChangeDao, ResourceDao resourceDao) {
- this.initialOpenIssuesStack = initialOpenIssuesStack;
- this.issueDao = issueDao;
- this.issueChangeDao = issueChangeDao;
- this.resourceDao = resourceDao;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public void analyse(Project project, SensorContext context) {
- ResourceDto module = resourceDao.getResource(ResourceQuery.create().setKey(project.getEffectiveKey()));
- if (module != null) {
- long moduleId = module.getId();
- // Adding one second is a hack for resolving conflicts with concurrent user
- // changes during issue persistence
- final Date now = DateUtils.addSeconds(DateUtils.truncate(new Date(), Calendar.MILLISECOND), 1);
- issueDao.selectNonClosedIssuesByModule(moduleId, new ResultHandler() {
- @Override
- public void handleResult(ResultContext rc) {
- IssueDto dto = (IssueDto) rc.getResultObject();
- dto.setSelectedAt(now.getTime());
- initialOpenIssuesStack.addIssue(dto);
- }
- });
-
- issueChangeDao.selectChangelogOnNonClosedIssuesByModuleAndType(moduleId, new ResultHandler() {
- @Override
- public void handleResult(ResultContext rc) {
- IssueChangeDto dto = (IssueChangeDto) rc.getResultObject();
- initialOpenIssuesStack.addChangelog(dto);
- }
- });
- }
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
deleted file mode 100644
index ea7b9fb6e95..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.batch.index.Cache;
-import org.sonar.batch.index.Caches;
-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;
-
-@BatchSide
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class InitialOpenIssuesStack {
-
- private final Cache<IssueDto> issuesCache;
- private final Cache<ArrayList<IssueChangeDto>> issuesChangelogCache;
-
- public InitialOpenIssuesStack(Caches caches) {
- issuesCache = caches.createCache("last-open-issues");
- issuesChangelogCache = caches.createCache("issues-changelog");
- }
-
- public InitialOpenIssuesStack addIssue(IssueDto issueDto) {
- issuesCache.put(issueDto.getComponentKey(), issueDto.getKee(), issueDto);
- return this;
- }
-
- public List<ServerIssue> selectAndRemoveIssues(String componentKey) {
- Iterable<IssueDto> issues = issuesCache.values(componentKey);
- List<ServerIssue> result = newArrayList();
- for (IssueDto issue : issues) {
- result.add(new ServerIssueFromDb(issue));
- }
- issuesCache.clear(componentKey);
- return result;
- }
-
- public Iterable<IssueDto> selectAllIssues() {
- return issuesCache.values();
- }
-
- public InitialOpenIssuesStack addChangelog(IssueChangeDto issueChangeDto) {
- List<IssueChangeDto> changeDtos = issuesChangelogCache.get(issueChangeDto.getIssueKey());
- if (changeDtos == null) {
- changeDtos = newArrayList();
- }
- changeDtos.add(issueChangeDto);
- issuesChangelogCache.put(issueChangeDto.getIssueKey(), newArrayList(changeDtos));
- return this;
- }
-
- public List<IssueChangeDto> selectChangelog(String issueKey) {
- List<IssueChangeDto> changeDtos = issuesChangelogCache.get(issueKey);
- return changeDtos != null ? changeDtos : Collections.<IssueChangeDto>emptyList();
- }
-
- public void clear() {
- issuesCache.clear();
- issuesChangelogCache.clear();
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java
deleted file mode 100644
index c7ef0dd53c4..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueHandlers.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.api.batch.BatchSide;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.IssueHandler;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.user.User;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.user.DefaultUser;
-
-import javax.annotation.Nullable;
-
-@BatchSide
-public class IssueHandlers {
- private final IssueHandler[] handlers;
- private final DefaultContext context;
-
- public IssueHandlers(IssueUpdater updater, IssueHandler[] handlers) {
- this.handlers = handlers;
- this.context = new DefaultContext(updater);
- }
-
- public IssueHandlers(IssueUpdater updater) {
- this(updater, new IssueHandler[0]);
- }
-
- public void execute(DefaultIssue issue, IssueChangeContext changeContext) {
- context.reset(issue, changeContext);
- for (IssueHandler handler : handlers) {
- handler.onIssue(context);
- }
- }
-
- static class DefaultContext implements IssueHandler.Context {
- private final IssueUpdater updater;
- private DefaultIssue issue;
- private IssueChangeContext changeContext;
-
- private DefaultContext(IssueUpdater updater) {
- this.updater = updater;
- }
-
- private void reset(DefaultIssue i, IssueChangeContext changeContext) {
- this.issue = i;
- this.changeContext = changeContext;
- }
-
- @Override
- public Issue issue() {
- return issue;
- }
-
- @Override
- public boolean isNew() {
- return issue.isNew();
- }
-
- @Override
- public boolean isEndOfLife() {
- return issue.isEndOfLife();
- }
-
- @Override
- public IssueHandler.Context setLine(@Nullable Integer line) {
- updater.setLine(issue, line);
- return this;
- }
-
- @Override
- public IssueHandler.Context setMessage(@Nullable String s) {
- updater.setMessage(issue, s, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setSeverity(String severity) {
- updater.setSeverity(issue, severity, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setAuthorLogin(@Nullable String login) {
- updater.setAuthorLogin(issue, login, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setEffortToFix(@Nullable Double d) {
- updater.setEffortToFix(issue, d, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context setAttribute(String key, @Nullable String value) {
- throw new UnsupportedOperationException("TODO");
- }
-
- @Override
- public IssueHandler.Context assign(@Nullable String assignee) {
- User user = null;
- if (assignee != null) {
- user = new DefaultUser().setLogin(assignee).setName(assignee);
- }
- updater.assign(issue, user, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context assign(@Nullable User user) {
- updater.assign(issue, user, changeContext);
- return this;
- }
-
- @Override
- public IssueHandler.Context addComment(String text) {
- updater.addComment(issue, text, changeContext);
- return this;
- }
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
index bd339571e51..ee089357320 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
@@ -29,7 +29,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import javax.annotation.Nullable;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
deleted file mode 100644
index 7c05341ffe1..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.Decorator;
-import org.sonar.api.batch.DecoratorBarriers;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.DependedUpon;
-import org.sonar.api.batch.DependsUpon;
-import org.sonar.api.batch.RequiresDB;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-
-import java.util.Collection;
-
-@DependsUpon(DecoratorBarriers.ISSUES_ADDED)
-@DependedUpon(DecoratorBarriers.ISSUES_TRACKED)
-@RequiresDB
-public class IssueTrackingDecorator implements Decorator {
-
- private static final Logger LOG = LoggerFactory.getLogger(IssueTrackingDecorator.class);
-
- private final IssueCache issueCache;
- private final InitialOpenIssuesStack initialOpenIssues;
- private final IssueTracking tracking;
- private final ServerLineHashesLoader lastLineHashes;
- private final IssueHandlers handlers;
- private final IssueWorkflow workflow;
- private final IssueUpdater updater;
- private final IssueChangeContext changeContext;
- private final ResourcePerspectives perspectives;
- private final RulesProfile rulesProfile;
- private final RuleFinder ruleFinder;
- private final InputPathCache inputPathCache;
- private final Project project;
-
- public IssueTrackingDecorator(IssueCache issueCache, InitialOpenIssuesStack initialOpenIssues, IssueTracking tracking,
- ServerLineHashesLoader lastLineHashes,
- IssueHandlers handlers, IssueWorkflow workflow,
- IssueUpdater updater,
- Project project,
- ResourcePerspectives perspectives,
- RulesProfile rulesProfile,
- RuleFinder ruleFinder, InputPathCache inputPathCache) {
- this.issueCache = issueCache;
- this.initialOpenIssues = initialOpenIssues;
- this.tracking = tracking;
- this.lastLineHashes = lastLineHashes;
- this.handlers = handlers;
- this.workflow = workflow;
- this.updater = updater;
- this.project = project;
- this.inputPathCache = inputPathCache;
- this.changeContext = IssueChangeContext.createScan(project.getAnalysisDate());
- this.perspectives = perspectives;
- this.rulesProfile = rulesProfile;
- this.ruleFinder = ruleFinder;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @Override
- public void decorate(Resource resource, DecoratorContext context) {
- Issuable issuable = perspectives.as(Issuable.class, resource);
- if (issuable != null) {
- doDecorate(resource);
- }
- }
-
- @VisibleForTesting
- void doDecorate(Resource resource) {
- Collection<DefaultIssue> issues = Lists.newArrayList();
- for (Issue issue : issueCache.byComponent(resource.getEffectiveKey())) {
- issues.add((DefaultIssue) issue);
- }
- issueCache.clear(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<ServerIssue> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
-
- SourceHashHolder sourceHashHolder = null;
- if (ResourceUtils.isFile(resource)) {
- File sonarFile = (File) resource;
- InputFile file = inputPathCache.getFile(project.getEffectiveKey(), sonarFile.getPath());
- if (file == null) {
- throw new IllegalStateException("File " + resource + " was not found in InputPath cache");
- }
- sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes);
- }
-
- IssueTrackingResult trackingResult = tracking.track(sourceHashHolder, dbOpenIssues, issues);
-
- // unmatched = issues that have been resolved + issues on disabled/removed rules + manual issues
- addUnmatched(trackingResult.unmatched(), sourceHashHolder, issues);
-
- mergeMatched(trackingResult);
-
- if (ResourceUtils.isProject(resource)) {
- // issues that relate to deleted components
- addIssuesOnDeletedComponents(issues);
- }
-
- for (DefaultIssue issue : issues) {
- workflow.doAutomaticTransition(issue, changeContext);
- handlers.execute(issue, changeContext);
- issueCache.put(issue);
- }
- }
-
- @VisibleForTesting
- protected void mergeMatched(IssueTrackingResult result) {
- for (DefaultIssue issue : result.matched()) {
- IssueDto ref = ((ServerIssueFromDb) result.matching(issue)).getDto();
-
- // invariant fields
- issue.setKey(ref.getKee());
- issue.setCreationDate(ref.getIssueCreationDate());
- issue.setUpdateDate(ref.getIssueUpdateDate());
- issue.setCloseDate(ref.getIssueCloseDate());
-
- // non-persisted fields
- issue.setNew(false);
- issue.setEndOfLife(false);
- issue.setOnDisabledRule(false);
- issue.setSelectedAt(ref.getSelectedAt());
-
- // fields to update with old values
- issue.setActionPlanKey(ref.getActionPlanKey());
- issue.setResolution(ref.getResolution());
- issue.setStatus(ref.getStatus());
- issue.setAssignee(ref.getAssignee());
- issue.setAuthorLogin(ref.getAuthorLogin());
- issue.setTags(ref.getTags());
-
- if (ref.getIssueAttributes() != null) {
- issue.setAttributes(KeyValueFormat.parse(ref.getIssueAttributes()));
- }
-
- // populate existing changelog
- Collection<IssueChangeDto> issueChangeDtos = initialOpenIssues.selectChangelog(issue.key());
- for (IssueChangeDto issueChangeDto : issueChangeDtos) {
- issue.addChange(issueChangeDto.toFieldDiffs());
- }
-
- // fields to update with current values
- if (ref.isManualSeverity()) {
- issue.setManualSeverity(true);
- issue.setSeverity(ref.getSeverity());
- } else {
- updater.setPastSeverity(issue, ref.getSeverity(), changeContext);
- }
- updater.setPastLine(issue, ref.getLine());
- updater.setPastMessage(issue, ref.getMessage(), changeContext);
- updater.setPastEffortToFix(issue, ref.getEffortToFix(), changeContext);
- Long debtInMinutes = ref.getDebt();
- Duration previousTechnicalDebt = debtInMinutes != null ? Duration.create(debtInMinutes) : null;
- updater.setPastTechnicalDebt(issue, previousTechnicalDebt, changeContext);
- updater.setPastProject(issue, ref.getProjectKey(), changeContext);
- }
- }
-
- private void addUnmatched(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
- for (ServerIssue unmatchedIssue : unmatchedIssues) {
- IssueDto unmatchedDto = ((ServerIssueFromDb) unmatchedIssue).getDto();
- DefaultIssue unmatched = unmatchedDto.toDefaultIssue();
- if (StringUtils.isNotBlank(unmatchedDto.getReporter()) && !Issue.STATUS_CLOSED.equals(unmatchedDto.getStatus())) {
- relocateManualIssue(unmatched, unmatchedDto, sourceHashHolder);
- }
- updateUnmatchedIssue(unmatched, false /* manual issues can be kept open */);
- issues.add(unmatched);
- }
- }
-
- private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) {
- for (IssueDto deadDto : initialOpenIssues.selectAllIssues()) {
- DefaultIssue dead = deadDto.toDefaultIssue();
- updateUnmatchedIssue(dead, true);
- issues.add(dead);
- }
- initialOpenIssues.clear();
- }
-
- private void updateUnmatchedIssue(DefaultIssue issue, boolean forceEndOfLife) {
- issue.setNew(false);
-
- boolean manualIssue = !Strings.isNullOrEmpty(issue.reporter());
- Rule rule = ruleFinder.findByKey(issue.ruleKey());
- if (manualIssue) {
- // Manual rules are not declared in Quality profiles, so no need to check ActiveRule
- boolean isRemovedRule = rule == null || Rule.STATUS_REMOVED.equals(rule.getStatus());
- issue.setEndOfLife(forceEndOfLife || isRemovedRule);
- issue.setOnDisabledRule(isRemovedRule);
- } else {
- ActiveRule activeRule = rulesProfile.getActiveRule(issue.ruleKey().repository(), issue.ruleKey().rule());
- issue.setEndOfLife(true);
- issue.setOnDisabledRule(activeRule == null || rule == null || Rule.STATUS_REMOVED.equals(rule.getStatus()));
- }
- }
-
- private void relocateManualIssue(DefaultIssue newIssue, IssueDto oldIssue, SourceHashHolder sourceHashHolder) {
- LOG.debug("Trying to relocate manual issue {}", oldIssue.getKee());
-
- Integer previousLine = oldIssue.getLine();
- if (previousLine == null) {
- LOG.debug("Cannot relocate issue at resource level");
- return;
- }
-
- Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine);
- LOG.debug("Found the following lines with same hash: {}", newLinesWithSameHash);
- if (newLinesWithSameHash.isEmpty()) {
- if (previousLine > sourceHashHolder.getHashedSource().length()) {
- LOG.debug("Old issue line {} is out of new source, closing and removing line number", previousLine);
- 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.getMessage(), changeContext);
- updater.setPastEffortToFix(newIssue, oldIssue.getEffortToFix(), changeContext);
- }
- } else if (newLinesWithSameHash.size() == 1) {
- Integer newLine = newLinesWithSameHash.iterator().next();
- LOG.debug("Relocating issue to line {}", newLine);
-
- newIssue.setLine(newLine);
- updater.setPastLine(newIssue, previousLine);
- updater.setPastMessage(newIssue, oldIssue.getMessage(), changeContext);
- updater.setPastEffortToFix(newIssue, oldIssue.getEffortToFix(), changeContext);
- }
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
index 8fe3549e66b..e04cdc240b4 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
@@ -23,7 +23,7 @@ import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.apache.commons.lang.StringUtils;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import javax.annotation.Nullable;
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
index a946c9f7dea..733e41d26a1 100644
--- 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
@@ -29,8 +29,8 @@ 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.core.issue.DefaultIssue;
+import org.sonar.core.issue.IssueChangeContext;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.api.rule.RuleKey;
@@ -166,7 +166,7 @@ public class LocalIssueTracking {
// non-persisted fields
issue.setNew(false);
- issue.setEndOfLife(false);
+ issue.setBeingClosed(false);
issue.setOnDisabledRule(false);
// fields to update with old values
@@ -226,9 +226,9 @@ public class LocalIssueTracking {
boolean manualIssue = issue.ruleKey().isManual();
boolean isRemovedRule = activeRule == null;
if (manualIssue) {
- issue.setEndOfLife(forceEndOfLife || isRemovedRule);
+ issue.setBeingClosed(forceEndOfLife || isRemovedRule);
} else {
- issue.setEndOfLife(true);
+ issue.setBeingClosed(true);
}
issue.setOnDisabledRule(isRemovedRule);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
index 55502e9ba78..9b6ece676b1 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
@@ -37,7 +37,7 @@ import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.highlighting.TypeOfText;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.Measure;
import org.sonar.batch.duplication.DuplicationCache;
import org.sonar.batch.index.Cache.Entry;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java
deleted file mode 100644
index cb6574591c7..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/PersisterExecutionEvent.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.phases;
-
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-
-class PersisterExecutionEvent extends AbstractPhaseEvent<PersisterExecutionHandler>
- implements PersisterExecutionHandler.PersisterExecutionEvent {
-
- private final ScanPersister persister;
-
- PersisterExecutionEvent(ScanPersister persister, boolean start) {
- super(start);
- this.persister = persister;
- }
-
- @Override
- public ScanPersister getPersister() {
- return persister;
- }
-
- @Override
- public void dispatch(PersisterExecutionHandler handler) {
- handler.onPersisterExecution(this);
- }
-
- @Override
- public Class getType() {
- return PersisterExecutionHandler.class;
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersExecutor.java
deleted file mode 100644
index 8e114b6ec31..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersExecutor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.phases;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.BatchSide;
-import org.sonar.batch.bootstrap.DefaultAnalysisMode;
-import org.sonar.batch.events.EventBus;
-import org.sonar.batch.index.ScanPersister;
-
-import java.util.Arrays;
-
-@BatchSide
-public class PersistersExecutor {
-
- private static final Logger LOG = LoggerFactory.getLogger(PersistersExecutor.class);
-
- private final ScanPersister[] persisters;
- private final DefaultAnalysisMode analysisMode;
- private final EventBus eventBus;
-
- public PersistersExecutor(DefaultAnalysisMode analysisMode, EventBus eventBus, ScanPersister[] persisters) {
- this.analysisMode = analysisMode;
- this.eventBus = eventBus;
- this.persisters = persisters;
- }
-
- public PersistersExecutor(DefaultAnalysisMode analysisMode, EventBus eventBus) {
- this(analysisMode, eventBus, new ScanPersister[0]);
- }
-
- public void execute() {
- if (analysisMode.isDb()) {
- LOG.info("Store results in database");
- eventBus.fireEvent(new PersistersPhaseEvent(Arrays.asList(persisters), true));
- for (ScanPersister persister : persisters) {
- LOG.debug("Execute {}", persister.getClass().getName());
- eventBus.fireEvent(new PersisterExecutionEvent(persister, true));
- persister.persist();
- eventBus.fireEvent(new PersisterExecutionEvent(persister, false));
- }
-
- eventBus.fireEvent(new PersistersPhaseEvent(Arrays.asList(persisters), false));
- }
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java
deleted file mode 100644
index ad43c00ab36..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/PersistersPhaseEvent.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.phases;
-
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
-
-import java.util.List;
-
-class PersistersPhaseEvent extends AbstractPhaseEvent<PersistersPhaseHandler>
- implements PersistersPhaseHandler.PersistersPhaseEvent {
-
- private final List<ScanPersister> persisters;
-
- PersistersPhaseEvent(List<ScanPersister> persisters, boolean start) {
- super(start);
- this.persisters = persisters;
- }
-
- @Override
- public List<ScanPersister> getPersisters() {
- return persisters;
- }
-
- @Override
- protected void dispatch(PersistersPhaseHandler handler) {
- handler.onPersistersPhase(this);
- }
-
- @Override
- protected Class getType() {
- return PersistersPhaseHandler.class;
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
index af07cf80cb0..3a616e62465 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
@@ -44,7 +44,6 @@ public final class PhaseExecutor {
private final SensorContext sensorContext;
private final DefaultIndex index;
private final ProjectInitializer pi;
- private final PersistersExecutor persistersExecutor;
private final FileSystemLogger fsLogger;
private final DefaultModuleFileSystem fs;
private final QProfileVerifier profileVerifier;
@@ -57,7 +56,7 @@ public final class PhaseExecutor {
InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
SensorContext sensorContext, DefaultIndex index,
EventBus eventBus, ReportPublisher reportPublisher, ProjectInitializer pi,
- PersistersExecutor persistersExecutor, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
+ FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
IssueExclusionsLoader issueExclusionsLoader, DefaultAnalysisMode analysisMode, LocalIssueTracking localIssueTracking) {
this.decoratorsExecutor = decoratorsExecutor;
this.postJobsExecutor = postJobsExecutor;
@@ -68,7 +67,6 @@ public final class PhaseExecutor {
this.eventBus = eventBus;
this.reportPublisher = reportPublisher;
this.pi = pi;
- this.persistersExecutor = persistersExecutor;
this.fsLogger = fsLogger;
this.issuesReport = jsonReport;
this.fs = fs;
@@ -106,16 +104,11 @@ public final class PhaseExecutor {
localIssueTracking();
}
issuesReport();
-
- if (!analysisMode.isPreview()) {
- persistersExecutor.execute();
- }
-
publishReportJob();
postJobsExecutor.execute(sensorContext);
}
cleanMemory();
- eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
+ eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
}
private void publishReportJob() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java
deleted file mode 100644
index 7df8dae4ade..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersisterExecutionHandler.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.phases.event;
-
-import org.sonar.api.batch.events.EventHandler;
-import org.sonar.batch.index.ScanPersister;
-
-public interface PersisterExecutionHandler extends EventHandler {
-
- /**
- * This interface is not intended to be implemented by clients.
- */
- interface PersisterExecutionEvent {
-
- ScanPersister getPersister();
-
- boolean isStart();
-
- boolean isEnd();
-
- }
-
- /**
- * Called before and after execution of {@link ScanPersister}.
- */
- void onPersisterExecution(PersisterExecutionEvent event);
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java
deleted file mode 100644
index 087755bacab..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/event/PersistersPhaseHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.phases.event;
-
-import org.sonar.api.batch.events.EventHandler;
-import org.sonar.batch.index.ScanPersister;
-
-import java.util.List;
-
-public interface PersistersPhaseHandler extends EventHandler {
-
- /**
- * This interface is not intended to be implemented by clients.
- */
- interface PersistersPhaseEvent {
-
- /**
- * @return list of Persisters in the order of execution
- */
- List<ScanPersister> getPersisters();
-
- boolean isStart();
-
- boolean isEnd();
-
- }
-
- /**
- * Called before and after execution of all {@link ScanPersister}s.
- */
- void onPersistersPhase(PersistersPhaseEvent event);
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java
deleted file mode 100644
index 6aefbe5b6bb..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/phases/event/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.batch.phases.event;
-
-import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
index 6f46c012ce9..7b1edddabec 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
@@ -28,7 +28,7 @@ import org.sonar.api.batch.postjob.PostJobContext;
import org.sonar.api.batch.postjob.issue.Issue;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java b/sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java
index 97e5c09dcdb..1da5585e762 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/profiling/PhasesSumUpTimeProfiler.java
@@ -48,16 +48,13 @@ import org.sonar.api.utils.System2;
import org.sonar.api.utils.TimeUtils;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.events.BatchStepHandler;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
import org.sonar.batch.util.BatchUtils;
import static org.sonar.batch.profiling.AbstractTimeProfiling.sortByDescendingTotalTime;
import static org.sonar.batch.profiling.AbstractTimeProfiling.truncate;
public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorExecutionHandler, DecoratorExecutionHandler, PostJobExecutionHandler, DecoratorsPhaseHandler,
- SensorsPhaseHandler, PostJobsPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler, PersistersPhaseHandler,
- PersisterExecutionHandler {
+ SensorsPhaseHandler, PostJobsPhaseHandler, InitializersPhaseHandler, InitializerExecutionHandler, BatchStepHandler {
static final Logger LOG = LoggerFactory.getLogger(PhasesSumUpTimeProfiler.class);
private static final int TEXT_RIGHT_PAD = 60;
@@ -175,25 +172,6 @@ public class PhasesSumUpTimeProfiler implements ProjectAnalysisHandler, SensorEx
}
@Override
- public void onPersistersPhase(PersistersPhaseEvent event) {
- if (event.isStart()) {
- currentModuleProfiling.addPhaseProfiling(Phase.PERSISTER);
- } else {
- currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).stop();
- }
- }
-
- @Override
- public void onPersisterExecution(PersisterExecutionEvent event) {
- PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER);
- if (event.isStart()) {
- profiling.newItemProfiling(event.getPersister());
- } else {
- profiling.getProfilingPerItem(event.getPersister()).stop();
- }
- }
-
- @Override
public void onDecoratorExecution(DecoratorExecutionEvent event) {
PhaseProfiling profiling = currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR);
if (event.isStart()) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java
index 08be39df953..0377b3e0889 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/IssuesPublisher.java
@@ -21,14 +21,8 @@ package org.sonar.batch.report;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import javax.annotation.Nullable;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.batch.index.BatchComponent;
@@ -38,6 +32,7 @@ import org.sonar.batch.protocol.Constants;
import org.sonar.batch.protocol.output.BatchReport;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.ImmutableProjectReactor;
+import org.sonar.core.issue.DefaultIssue;
public class IssuesPublisher implements ReportPublisherStep {
@@ -53,7 +48,6 @@ public class IssuesPublisher implements ReportPublisherStep {
@Override
public void publish(BatchReportWriter writer) {
- Collection<Object> deletedComponentKeys = issueCache.componentKeys();
for (BatchComponent resource : componentCache.all()) {
String componentKey = resource.resource().getEffectiveKey();
Iterable<DefaultIssue> issues = issueCache.byComponent(componentKey);
@@ -65,23 +59,19 @@ public class IssuesPublisher implements ReportPublisherStep {
return toReportIssue(builder, input);
}
}));
- deletedComponentKeys.remove(componentKey);
}
- int count = exportIssuesOfDeletedComponents(deletedComponentKeys, writer);
-
- exportMetadata(writer, count);
+ exportMetadata(writer);
}
- private void exportMetadata(BatchReportWriter writer, int count) {
+ private void exportMetadata(BatchReportWriter writer) {
ProjectDefinition root = reactor.getRoot();
BatchComponent rootProject = componentCache.getRoot();
BatchReport.Metadata.Builder builder = BatchReport.Metadata.newBuilder()
.setAnalysisDate(((Project) rootProject.resource()).getAnalysisDate().getTime())
// Here we want key without branch
.setProjectKey(root.getKey())
- .setRootComponentRef(rootProject.batchId())
- .setDeletedComponentsCount(count);
+ .setRootComponentRef(rootProject.batchId());
String branch = root.properties().get(CoreProperties.PROJECT_BRANCH_PROPERTY);
if (branch != null) {
builder.setBranch(branch);
@@ -89,39 +79,14 @@ public class IssuesPublisher implements ReportPublisherStep {
writer.writeMetadata(builder.build());
}
- private int exportIssuesOfDeletedComponents(Collection<Object> deletedComponentKeys, BatchReportWriter writer) {
- int deletedComponentCount = 0;
- for (Object componentKey : deletedComponentKeys) {
- deletedComponentCount++;
- Iterable<DefaultIssue> issues = issueCache.byComponent(componentKey.toString());
- Iterator<DefaultIssue> iterator = issues.iterator();
- if (iterator.hasNext()) {
- String componentUuid = iterator.next().componentUuid();
- writer.writeDeletedComponentIssues(deletedComponentCount, componentUuid, Iterables.transform(issues, new Function<DefaultIssue, BatchReport.Issue>() {
- private BatchReport.Issue.Builder builder = BatchReport.Issue.newBuilder();
-
- @Override
- public BatchReport.Issue apply(DefaultIssue input) {
- return toReportIssue(builder, input);
- }
- }));
- }
- }
- return deletedComponentCount;
- }
-
private BatchReport.Issue toReportIssue(BatchReport.Issue.Builder builder, DefaultIssue issue) {
builder.clear();
// non-null fields
- builder.setUuid(issue.key());
- builder.setIsNew(issue.isNew());
builder.setSeverity(Constants.Severity.valueOf(issue.severity()));
builder.setRuleRepository(issue.ruleKey().repository());
builder.setRuleKey(issue.ruleKey().rule());
builder.setAttributes(KeyValueFormat.format(issue.attributes()));
builder.addAllTag(issue.tags());
- builder.setMustSendNotification(issue.mustSendNotifications());
- builder.setIsChanged(issue.isChanged());
// nullable fields
Integer line = issue.line();
@@ -136,65 +101,12 @@ public class IssuesPublisher implements ReportPublisherStep {
if (effortToFix != null) {
builder.setEffortToFix(effortToFix);
}
-
Long debtInMinutes = issue.debtInMinutes();
if (debtInMinutes != null) {
builder.setDebtInMinutes(debtInMinutes);
}
- String resolution = issue.resolution();
- if (resolution != null) {
- builder.setResolution(resolution);
- }
- String status = issue.status();
- if (status != null) {
- builder.setStatus(status);
- }
- String checksum = issue.checksum();
- if (checksum != null) {
- builder.setChecksum(checksum);
- }
- builder.setManualSeverity(issue.manualSeverity());
- String reporter = issue.reporter();
- if (reporter != null) {
- builder.setReporter(reporter);
- }
- String assignee = issue.assignee();
- if (assignee != null) {
- builder.setAssignee(assignee);
- }
- String actionPlanKey = issue.actionPlanKey();
- if (actionPlanKey != null) {
- builder.setActionPlanKey(actionPlanKey);
- }
- String authorLogin = issue.authorLogin();
- if (authorLogin != null) {
- builder.setAuthorLogin(authorLogin);
- }
- String diff = diffsToString(issue.currentChange());
- if (diff != null) {
- builder.setDiffFields(diff);
- }
- Date creationDate = issue.creationDate();
- if (creationDate != null) {
- builder.setCreationDate(creationDate.getTime());
- }
- Long selectedAt = issue.selectedAt();
- if (selectedAt != null) {
- builder.setSelectedAt(selectedAt);
- }
- Date closeDate = issue.closeDate();
- if (closeDate != null) {
- builder.setCloseDate(closeDate.getTime());
- }
- Date updateDate = issue.updateDate();
- if (updateDate != null) {
- builder.setUpdateDate(updateDate.getTime());
- }
- return builder.build();
- }
- private String diffsToString(@Nullable FieldDiffs diffs) {
- return diffs != null ? diffs.toString() : null;
+ return builder.build();
}
}
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 4d4fb03fff9..c4524dca799 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
@@ -50,7 +50,6 @@ import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader;
import org.sonar.batch.issue.ignore.scanner.IssueExclusionsRegexpScanner;
import org.sonar.batch.phases.DecoratorsExecutor;
import org.sonar.batch.phases.InitializersExecutor;
-import org.sonar.batch.phases.PersistersExecutor;
import org.sonar.batch.phases.PhaseExecutor;
import org.sonar.batch.phases.PostJobsExecutor;
import org.sonar.batch.phases.ProjectInitializer;
@@ -120,7 +119,6 @@ public class ModuleScanContainer extends ComponentContainer {
PostJobsExecutor.class,
DecoratorsExecutor.class,
SensorsExecutor.class,
- PersistersExecutor.class,
InitializersExecutor.class,
ProjectInitializer.class,
moduleDefinition.getContainerExtensions(),
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 1c3e864170d..83f24753ef4 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
@@ -53,7 +53,6 @@ import org.sonar.batch.index.Caches;
import org.sonar.batch.index.DefaultIndex;
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.ServerIssueRepository;
import org.sonar.batch.mediumtest.ScanTaskObservers;
@@ -217,10 +216,7 @@ public class ProjectScanContainer extends ComponentContainer {
new DebtModelProvider(),
// technical debt
- DefaultTechnicalDebtModel.class,
-
- // Issue tracking
- InitialOpenIssuesStack.class);
+ DefaultTechnicalDebtModel.class);
}
private void addBatchExtensions() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
index e23e8a816e3..2634fdd9af9 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
@@ -25,7 +25,7 @@ import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
index 72c48f9bb7a..43e423e7fa7 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
@@ -23,7 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Rule;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
index e2959d9352d..b13b5468d67 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
@@ -34,7 +34,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
index 0277408cbe4..4ddfe03452e 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
@@ -42,7 +42,7 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.Formula;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.PersistenceMode;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java
index 5ce426696d5..94a58c79b0d 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java
@@ -37,7 +37,7 @@ import org.sonar.api.batch.rule.internal.RulesBuilder;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java
index 952075dec78..fb2bf2e90f5 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java
@@ -24,8 +24,8 @@ import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.utils.Duration;
import java.util.Date;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java
index 8de52b074c2..8b00495711b 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java
@@ -34,8 +34,8 @@ import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issuable;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
index 42843ddd8ec..7f50a767efe 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssuableTest.java
@@ -23,7 +23,7 @@ import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.batch.index.BatchComponent;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java
index b46e3551a6d..99c6d5f7100 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java
@@ -22,7 +22,7 @@ package org.sonar.batch.issue;
import com.google.common.collect.Lists;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
index 25fefe6f13d..18e90aff802 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
@@ -26,7 +26,7 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import javax.annotation.Nullable;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/IssueFiltersTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/IssueFiltersTest.java
index 46aea62325c..b99aefe9bb8 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/IssueFiltersTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/IssueFiltersTest.java
@@ -21,7 +21,7 @@ package org.sonar.batch.issue;
import org.junit.Test;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java
index 2577ba98a41..f1157f16572 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/ModuleIssuesTest.java
@@ -29,7 +29,7 @@ import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.api.batch.debt.DebtRemediationFunction;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.batch.rule.internal.RulesBuilder;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java
deleted file mode 100644
index 1b4a6adf544..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensorTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.apache.ibatis.session.ResultHandler;
-import org.junit.Test;
-import org.sonar.api.resources.Project;
-import org.sonar.core.issue.db.IssueChangeDao;
-import org.sonar.core.issue.db.IssueDao;
-import org.sonar.core.resource.ResourceDao;
-import org.sonar.core.resource.ResourceDto;
-import org.sonar.core.resource.ResourceQuery;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class InitialOpenIssuesSensorTest {
-
- InitialOpenIssuesStack stack = mock(InitialOpenIssuesStack.class);
- IssueDao issueDao = mock(IssueDao.class);
- IssueChangeDao issueChangeDao = mock(IssueChangeDao.class);
- ResourceDao resourceDao = mock(ResourceDao.class);
-
- InitialOpenIssuesSensor sensor = new InitialOpenIssuesSensor(stack, issueDao, issueChangeDao, resourceDao);
-
- @Test
- public void should_select_module_open_issues() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L));
-
- sensor.analyse(new Project("key"), null);
-
- verify(issueDao).selectNonClosedIssuesByModule(eq(1L), any(ResultHandler.class));
- }
-
- @Test
- public void should_select_module_open_issues_changelog() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(new ResourceDto().setId(1L));
-
- sensor.analyse(new Project("key"), null);
-
- verify(issueChangeDao).selectChangelogOnNonClosedIssuesByModuleAndType(eq(1L), any(ResultHandler.class));
- }
-
- @Test
- public void nothing_to_on_new_component() {
- when(resourceDao.getResource(any(ResourceQuery.class))).thenReturn(null);
-
- sensor.analyse(new Project("key"), null);
-
- verifyZeroInteractions(issueDao);
- verifyZeroInteractions(issueChangeDao);
- }
-
- @Test
- public void test_toString() throws Exception {
- assertThat(sensor.toString()).isEqualTo("InitialOpenIssuesSensor");
-
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
deleted file mode 100644
index c6f42f12b6a..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.batch.issue.tracking;
-
-import org.sonar.batch.index.AbstractCachesTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-
-import java.util.List;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class InitialOpenIssuesStackTest extends AbstractCachesTest {
-
- InitialOpenIssuesStack stack;
-
- @Before
- public void before() {
- stack = new InitialOpenIssuesStack(caches);
- }
-
- @After
- public void after() {
- caches.stop();
- }
-
- @Test
- public void get_and_remove_issues() {
- IssueDto issueDto = new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1");
- stack.addIssue(issueDto);
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
- assertThat(issueDtos).hasSize(1);
- assertThat(issueDtos.get(0).key()).isEqualTo("ISSUE-1");
-
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void get_and_remove_with_many_issues_on_same_resource() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-2"));
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
- assertThat(issueDtos).hasSize(2);
-
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void get_and_remove_do_nothing_if_resource_not_found() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
-
- List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("Other");
- assertThat(issueDtos).hasSize(0);
-
- assertThat(stack.selectAllIssues()).hasSize(1);
- }
-
- @Test
- public void select_changelog() {
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-1").setIssueKey("ISSUE-1"));
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-2").setIssueKey("ISSUE-1"));
-
- List<IssueChangeDto> issueChangeDtos = stack.selectChangelog("ISSUE-1");
- assertThat(issueChangeDtos).hasSize(2);
- assertThat(issueChangeDtos.get(0).getKey()).isEqualTo("CHANGE-1");
- assertThat(issueChangeDtos.get(1).getKey()).isEqualTo("CHANGE-2");
- }
-
- @Test
- public void return_empty_changelog() {
- assertThat(stack.selectChangelog("ISSUE-1")).isEmpty();
- }
-
- @Test
- public void clear_issues() {
- stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
-
- assertThat(stack.selectAllIssues()).hasSize(1);
-
- // issues are not removed
- assertThat(stack.selectAllIssues()).hasSize(1);
-
- stack.clear();
- assertThat(stack.selectAllIssues()).isEmpty();
- }
-
- @Test
- public void clear_issues_changelog() {
- stack.addChangelog(new IssueChangeDto().setKey("CHANGE-1").setIssueKey("ISSUE-1"));
-
- assertThat(stack.selectChangelog("ISSUE-1")).hasSize(1);
-
- stack.clear();
- assertThat(stack.selectChangelog("ISSUE-1")).isEmpty();
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java
deleted file mode 100644
index fe81ee2006b..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueHandlersTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.issue.IssueHandler;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.core.issue.IssueUpdater;
-
-import java.util.Date;
-
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class IssueHandlersTest {
- @Test
- public void should_execute_handlers() {
- IssueHandler h1 = mock(IssueHandler.class);
- IssueHandler h2 = mock(IssueHandler.class);
- IssueUpdater updater = mock(IssueUpdater.class);
-
- IssueHandlers handlers = new IssueHandlers(updater, new IssueHandler[]{h1, h2});
- final DefaultIssue issue = new DefaultIssue();
- handlers.execute(issue, IssueChangeContext.createScan(new Date()));
-
- verify(h1).onIssue(argThat(new ArgumentMatcher<IssueHandler.Context>() {
- @Override
- public boolean matches(Object o) {
- return ((IssueHandler.Context) o).issue() == issue;
- }
- }));
- }
-
- @Test
- public void test_no_handlers() {
- IssueUpdater updater = mock(IssueUpdater.class);
- IssueHandlers handlers = new IssueHandlers(updater);
- handlers.execute(new DefaultIssue(), IssueChangeContext.createScan(new Date()));
- verifyZeroInteractions(updater);
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
deleted file mode 100644
index d09c7908d20..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.component.ResourcePerspectives;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.IssueChangeContext;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.System2;
-import org.sonar.batch.issue.IssueCache;
-import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.IssueUpdater;
-import org.sonar.core.issue.db.IssueChangeDto;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.issue.workflow.IssueWorkflow;
-import org.sonar.java.api.JavaClass;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollection;
-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.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 {
-
- @org.junit.Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- IssueTrackingDecorator decorator;
- IssueCache issueCache = mock(IssueCache.class, RETURNS_MOCKS);
- InitialOpenIssuesStack initialOpenIssues = mock(InitialOpenIssuesStack.class);
- IssueTracking tracking = mock(IssueTracking.class, RETURNS_MOCKS);
- ServerLineHashesLoader lastSnapshots = mock(ServerLineHashesLoader.class);
- IssueHandlers handlers = mock(IssueHandlers.class);
- IssueWorkflow workflow = mock(IssueWorkflow.class);
- IssueUpdater updater = mock(IssueUpdater.class);
- ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
- RulesProfile profile = mock(RulesProfile.class);
- RuleFinder ruleFinder = mock(RuleFinder.class);
- InputPathCache inputPathCache = mock(InputPathCache.class);
-
- @Before
- public void init() {
- decorator = new IssueTrackingDecorator(
- issueCache,
- initialOpenIssues,
- tracking,
- lastSnapshots,
- handlers,
- workflow,
- updater,
- new Project("foo"),
- perspectives,
- profile,
- ruleFinder,
- inputPathCache);
- }
-
- @Test
- public void should_execute_on_project() {
- Project project = mock(Project.class);
- assertThat(decorator.shouldExecuteOnProject(project)).isTrue();
- }
-
- @Test
- public void should_not_be_executed_on_classes_not_methods() {
- DecoratorContext context = mock(DecoratorContext.class);
- decorator.decorate(JavaClass.create("org.foo.Bar"), context);
- verifyZeroInteractions(context, issueCache, tracking, handlers, workflow);
- }
-
- @Test
- public void should_process_open_issues() {
- Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
- final DefaultIssue issue = new DefaultIssue();
-
- // INPUT : one issue, no open issues during previous scan, no filtering
- when(issueCache.byComponent("struts:Action.java")).thenReturn(Arrays.asList(issue));
- List<ServerIssue> dbIssues = Collections.emptyList();
- when(initialOpenIssues.selectAndRemoveIssues("struts:Action.java")).thenReturn(dbIssues);
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
- decorator.doDecorate(file);
-
- // Apply filters, track, apply transitions, notify extensions then update cache
- verify(tracking).track(isA(SourceHashHolder.class), eq(dbIssues), argThat(new ArgumentMatcher<Collection<DefaultIssue>>() {
- @Override
- public boolean matches(Object o) {
- List<DefaultIssue> issues = (List<DefaultIssue>) o;
- return issues.size() == 1 && issues.get(0) == issue;
- }
- }));
- verify(workflow).doAutomaticTransition(eq(issue), any(IssueChangeContext.class));
- verify(handlers).execute(eq(issue), any(IssueChangeContext.class));
- verify(issueCache).put(issue);
- }
-
- @Test
- public void should_register_unmatched_issues_as_end_of_life() {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
- Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle"));
-
- IssueTrackingResult trackingResult = new IssueTrackingResult();
- trackingResult.addUnmatched(unmatchedIssue);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_moved_if_matching_line_found() throws Exception {
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n" // Original issue here
- + "}";
- String newSource = "public interface Action {\n"
- + " void method5();\n" // New issue here
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(2);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- private Resource mockHashes(String originalSource, String newSource) throws IOException {
- DefaultInputFile inputFile = mock(DefaultInputFile.class);
- java.io.File f = temp.newFile();
- when(inputFile.path()).thenReturn(f.toPath());
- when(inputFile.file()).thenReturn(f);
- when(inputFile.charset()).thenReturn(StandardCharsets.UTF_8);
- when(inputFile.lines()).thenReturn(StringUtils.countMatches(newSource, "\n") + 1);
- FileUtils.write(f, newSource, StandardCharsets.UTF_8);
- when(inputFile.key()).thenReturn("foo:Action.java");
- when(inputPathCache.getFile("foo", "Action.java")).thenReturn(inputFile);
- when(lastSnapshots.getLineHashes("foo:Action.java")).thenReturn(computeHexHashes(originalSource));
- Resource file = File.create("Action.java");
- return file;
- }
-
- @Test
- public void manual_issues_should_be_untouched_if_already_closed() throws Exception {
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {}";
- Resource file = mockHashes(originalSource, originalSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(1);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- assertThat(issue.status()).isEqualTo("CLOSED");
- }
-
- @Test
- public void manual_issues_should_be_untouched_if_line_is_null() throws Exception {
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {}";
- Resource file = mockHashes(originalSource, originalSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(null);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- assertThat(issue.status()).isEqualTo("OPEN");
- }
-
- @Test
- public void manual_issues_should_be_kept_if_matching_line_not_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- final int issueOnLine = 6;
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n" // Original issue here
- + "}";
- String newSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method6();\n" // Poof, no method5 anymore
- + "}";
-
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(issueOnLine);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- @Test
- public void manual_issues_should_be_kept_if_multiple_matching_lines_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- final int issueOnLine = 3;
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public class Action {\n"
- + " void method1() {\n"
- + " notify();\n" // initial issue
- + " }\n"
- + "}";
- String newSource = "public class Action {\n"
- + " \n"
- + " void method1() {\n" // new issue will appear here
- + " notify();\n"
- + " }\n"
- + " void method2() {\n"
- + " notify();\n"
- + " }\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.line()).isEqualTo(issueOnLine);
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isFalse();
- assertThat(issue.isOnDisabledRule()).isFalse();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_manual_rule_is_removed() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String source = "public interface Action {}";
- Resource file = mockHashes(source, source);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_manual_rule_is_not_found() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String source = "public interface Action {}";
- Resource file = mockHashes(source, source);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void manual_issues_should_be_closed_if_new_source_is_shorter() throws Exception {
- // "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
-
- // INPUT : one issue existing during previous scan
- ServerIssue unmatchedIssue = new ServerIssueFromDb(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();
- trackingResult.addUnmatched(unmatchedIssue);
-
- String originalSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + " void method3();\n"
- + " void method4();\n"
- + " void method5();\n"
- + "}";
- String newSource = "public interface Action {\n"
- + " void method1();\n"
- + " void method2();\n"
- + "}";
- Resource file = mockHashes(originalSource, newSource);
-
- when(tracking.track(isA(SourceHashHolder.class), anyCollection(), anyCollection())).thenReturn(trackingResult);
-
- decorator.doDecorate(file);
-
- verify(workflow, times(1)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(1)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(issueCache).put(argument.capture());
-
- DefaultIssue issue = argument.getValue();
- verify(updater).setResolution(eq(issue), eq(Issue.RESOLUTION_REMOVED), any(IssueChangeContext.class));
- verify(updater).setStatus(eq(issue), eq(Issue.STATUS_CLOSED), any(IssueChangeContext.class));
-
- assertThat(issue.key()).isEqualTo("ABCDE");
- assertThat(issue.isNew()).isFalse();
- assertThat(issue.isEndOfLife()).isTrue();
- assertThat(issue.isOnDisabledRule()).isTrue();
- }
-
- @Test
- public void should_register_issues_on_deleted_components() {
- Project project = new Project("struts");
- DefaultIssue openIssue = new DefaultIssue();
- when(issueCache.byComponent("struts")).thenReturn(Arrays.asList(openIssue));
- IssueDto deadIssue = new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle");
- when(initialOpenIssues.selectAllIssues()).thenReturn(Arrays.asList(deadIssue));
-
- decorator.doDecorate(project);
-
- // the dead issue must be closed -> apply automatic transition, notify handlers and add to cache
- verify(workflow, times(2)).doAutomaticTransition(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(handlers, times(2)).execute(any(DefaultIssue.class), any(IssueChangeContext.class));
- verify(issueCache, times(2)).put(any(DefaultIssue.class));
-
- verify(issueCache).put(argThat(new ArgumentMatcher<DefaultIssue>() {
- @Override
- public boolean matches(Object o) {
- DefaultIssue dead = (DefaultIssue) o;
- return "ABCDE".equals(dead.key()) && !dead.isNew() && dead.isEndOfLife();
- }
- }));
- }
-
- @Test
- public void merge_matched_issue() {
- ServerIssue previousIssue = new ServerIssueFromDb(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);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- verify(updater).setPastSeverity(eq(issue), eq("MAJOR"), any(IssueChangeContext.class));
- verify(updater).setPastLine(eq(issue), eq(10));
- verify(updater).setPastMessage(eq(issue), eq("Message"), any(IssueChangeContext.class));
- verify(updater).setPastEffortToFix(eq(issue), eq(1.5), any(IssueChangeContext.class));
- verify(updater).setPastTechnicalDebt(eq(issue), eq(Duration.create(1L)), any(IssueChangeContext.class));
- verify(updater).setPastProject(eq(issue), eq("sample"), any(IssueChangeContext.class));
- }
-
- @Test
- public void merge_matched_issue_on_manual_severity() {
- ServerIssue previousIssue = new ServerIssueFromDb(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);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- assertThat(issue.manualSeverity()).isTrue();
- assertThat(issue.severity()).isEqualTo("MAJOR");
- verify(updater, never()).setPastSeverity(eq(issue), anyString(), any(IssueChangeContext.class));
- }
-
- @Test
- public void merge_issue_changelog_with_previous_changelog() {
- when(initialOpenIssues.selectChangelog("ABCDE")).thenReturn(newArrayList(new IssueChangeDto().setIssueKey("ABCD").setCreatedAt(System2.INSTANCE.now())));
-
- ServerIssue previousIssue = new ServerIssueFromDb(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);
- when(trackingResult.matched()).thenReturn(newArrayList(issue));
- when(trackingResult.matching(eq(issue))).thenReturn(previousIssue);
- decorator.mergeMatched(trackingResult);
-
- assertThat(issue.changes()).hasSize(1);
- }
-
- private String[] computeHexHashes(String source) {
- String[] lines = source.split("\n");
- String[] hashes = new String[lines.length];
- for (int i = 0; i < lines.length; i++) {
- hashes[i] = DigestUtils.md5Hex(lines[i].replaceAll("[\t ]", ""));
- }
- return hashes;
- }
-
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
index 062c539b457..ae678c34bd3 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
@@ -32,7 +32,7 @@ import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.rule.RuleKey;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
index 5db240ddeb5..081dcb968b5 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
@@ -26,7 +26,7 @@ import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.postjob.issue.Issue;
import org.sonar.api.batch.rule.Severity;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.resources.File;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java b/sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java
index 0aa11588a8c..1ff8b82c9c4 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/profiling/PhasesSumUpTimeProfilerTest.java
@@ -20,6 +20,10 @@
package org.sonar.batch.profiling;
import com.google.common.collect.Maps;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -48,14 +52,6 @@ import org.sonar.api.resources.Resource;
import org.sonar.api.utils.System2;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.events.BatchStepEvent;
-import org.sonar.batch.index.ScanPersister;
-import org.sonar.batch.phases.event.PersisterExecutionHandler;
-import org.sonar.batch.phases.event.PersistersPhaseHandler;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.spy;
@@ -88,7 +84,6 @@ public class PhasesSumUpTimeProfilerTest {
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.INIT).getProfilingPerItem(new FakeInitializer()).totalTime()).isEqualTo(7L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
- assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
assertThat(profiler.currentModuleProfiling.getProfilingPerBatchStep("Free memory").totalTime()).isEqualTo(9L);
@@ -109,14 +104,12 @@ public class PhasesSumUpTimeProfilerTest {
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(10L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(20L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(10L);
- assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(40L);
assertThat(profiler.currentModuleProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(30L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.INIT).getProfilingPerItem(new FakeInitializer()).totalTime()).isEqualTo(21L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.SENSOR).getProfilingPerItem(new FakeSensor()).totalTime()).isEqualTo(30L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator1()).totalTime()).isEqualTo(60L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.DECORATOR).getProfilingPerItem(new FakeDecorator2()).totalTime()).isEqualTo(30L);
- assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.PERSISTER).getProfilingPerItem(new FakeScanPersister()).totalTime()).isEqualTo(120L);
assertThat(profiler.totalProfiling.getProfilingPerPhase(Phase.POSTJOB).getProfilingPerItem(new FakePostJob()).totalTime()).isEqualTo(90L);
}
@@ -164,7 +157,6 @@ public class PhasesSumUpTimeProfilerTest {
initializerPhase(profiler);
sensorPhase(profiler);
decoratorPhase(profiler);
- persistersPhase(profiler);
postJobPhase(profiler);
batchStep(profiler);
// End of moduleA
@@ -234,19 +226,6 @@ public class PhasesSumUpTimeProfilerTest {
profiler.onSensorsPhase(sensorsEvent(false));
}
- private void persistersPhase(PhasesSumUpTimeProfiler profiler) {
- ScanPersister persister = new FakeScanPersister();
- // Start of persister phase
- profiler.onPersistersPhase(persistersEvent(true));
- // Start of a ScanPersister
- profiler.onPersisterExecution(persisterEvent(persister, true));
- clock.sleep(40);
- // End of a ScanPersister
- profiler.onPersisterExecution(persisterEvent(persister, false));
- // End of persister phase
- profiler.onPersistersPhase(persistersEvent(false));
- }
-
private void postJobPhase(PhasesSumUpTimeProfiler profiler) {
PostJob postJob = new FakePostJob();
// Start of sensor phase
@@ -340,26 +319,6 @@ public class PhasesSumUpTimeProfilerTest {
};
}
- private PersisterExecutionHandler.PersisterExecutionEvent persisterEvent(final ScanPersister persister, final boolean start) {
- return new PersisterExecutionHandler.PersisterExecutionEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public ScanPersister getPersister() {
- return persister;
- }
- };
- }
-
private SensorsPhaseEvent sensorsEvent(final boolean start) {
return new SensorsPhaseHandler.SensorsPhaseEvent() {
@@ -420,26 +379,6 @@ public class PhasesSumUpTimeProfilerTest {
};
}
- private PersistersPhaseHandler.PersistersPhaseEvent persistersEvent(final boolean start) {
- return new PersistersPhaseHandler.PersistersPhaseEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public List<ScanPersister> getPersisters() {
- return null;
- }
- };
- }
-
private DecoratorsPhaseHandler.DecoratorsPhaseEvent decoratorsEvent(final boolean start) {
return new DecoratorsPhaseHandler.DecoratorsPhaseEvent() {
@@ -528,10 +467,4 @@ public class PhasesSumUpTimeProfilerTest {
public void executeOn(Project project, SensorContext context) {
}
}
-
- public class FakeScanPersister implements ScanPersister {
- @Override
- public void persist() {
- }
- }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java
index 8e49ddb719f..fbe835369f3 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/report/IssuesPublisherTest.java
@@ -30,8 +30,6 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.database.model.Snapshot;
-import org.sonar.api.issue.internal.DefaultIssue;
-import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.Duration;
@@ -41,6 +39,8 @@ import org.sonar.batch.protocol.output.BatchReport.Metadata;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.ImmutableProjectReactor;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyString;
@@ -110,7 +110,6 @@ public class IssuesPublisherTest {
Metadata metadata = reader.readMetadata();
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("foo");
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(0);
assertThat(reader.readComponentIssues(1)).hasSize(0);
assertThat(reader.readComponentIssues(2)).hasSize(2);
@@ -118,7 +117,7 @@ public class IssuesPublisherTest {
}
@Test
- public void publishMatadataWithBranch() throws Exception {
+ public void publishMetadataWithBranch() throws Exception {
root.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
p.setKey("foo:myBranch");
p.setEffectiveKey("foo:myBranch");
@@ -133,56 +132,6 @@ public class IssuesPublisherTest {
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("foo");
assertThat(metadata.getBranch()).isEqualTo("myBranch");
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(0);
}
- @Test
- public void publishIssuesOfDeletedComponents() throws Exception {
-
- DefaultIssue issue1 = new DefaultIssue();
- issue1.setKey("uuid");
- issue1.setComponentUuid("deletedUuid");
- issue1.setSeverity("MAJOR");
- issue1.setRuleKey(RuleKey.of("repo", "rule"));
- DefaultIssue issue2 = new DefaultIssue();
- issue2.setKey("uuid2");
- issue2.setComponentUuid("deletedUuid");
- issue2.setSeverity("MAJOR");
- issue2.setRuleKey(RuleKey.of("repo", "rule"));
- issue2.setLine(2);
- issue2.setMessage("msg");
- issue2.setEffortToFix(2d);
- issue2.setDebt(Duration.create(2));
- issue2.setResolution("FIXED");
- issue2.setStatus("RESOLVED");
- issue2.setChecksum("checksum");
- issue2.setReporter("reporter");
- issue2.setAssignee("assignee");
- issue2.setActionPlanKey("action");
- issue2.setAuthorLogin("author");
- issue2.setCurrentChange(new FieldDiffs().setUserLogin("foo"));
- issue2.setCreationDate(new Date());
- issue2.setUpdateDate(new Date());
- issue2.setCloseDate(new Date());
- issue2.setSelectedAt(1234L);
-
- when(issueCache.byComponent("foo:deleted.php")).thenReturn(Arrays.asList(issue1, issue2));
-
- when(issueCache.componentKeys()).thenReturn(Arrays.<Object>asList("foo:deleted.php"));
-
- File outputDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(outputDir);
-
- publisher.publish(writer);
-
- BatchReportReader reader = new BatchReportReader(outputDir);
- Metadata metadata = reader.readMetadata();
- assertThat(metadata.getDeletedComponentsCount()).isEqualTo(1);
-
- assertThat(reader.readComponentIssues(1)).hasSize(0);
- assertThat(reader.readComponentIssues(2)).hasSize(0);
- assertThat(reader.readDeletedComponentIssues(1).getComponentUuid()).isEqualTo("deletedUuid");
- assertThat(reader.readDeletedComponentIssues(1).getIssueList()).hasSize(2);
-
- }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
index f5a1482e608..fc3355952c0 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
@@ -25,7 +25,7 @@ import org.junit.Test;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.config.Settings;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.rule.Severity;
import org.sonar.api.utils.log.LogTester;
import org.sonar.batch.issue.IssueCache;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
index 0a346666ad5..afc0d4c39aa 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
@@ -33,7 +33,7 @@ import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.api.platform.Server;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
index d62fd760616..69b176538a1 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java
@@ -144,7 +144,7 @@ public class DefaultSensorStorageTest {
public void shouldAddIssueOnFile() {
InputFile file = new DefaultInputFile("foo", "src/Foo.php").setLines(4);
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onFile(file)
@@ -155,7 +155,7 @@ public class DefaultSensorStorageTest {
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isEqualTo(3);
@@ -167,7 +167,7 @@ public class DefaultSensorStorageTest {
public void shouldAddIssueOnDirectory() {
InputDir dir = new DefaultInputDir("foo", "src");
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onDir(dir)
@@ -177,7 +177,7 @@ public class DefaultSensorStorageTest {
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isNull();
@@ -187,7 +187,7 @@ public class DefaultSensorStorageTest {
@Test
public void shouldAddIssueOnProject() {
- ArgumentCaptor<org.sonar.api.issue.internal.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.api.issue.internal.DefaultIssue.class);
+ ArgumentCaptor<org.sonar.core.issue.DefaultIssue> argumentCaptor = ArgumentCaptor.forClass(org.sonar.core.issue.DefaultIssue.class);
sensorStorage.store(new DefaultIssue()
.onProject()
@@ -198,7 +198,7 @@ public class DefaultSensorStorageTest {
verify(moduleIssues).initAndAddIssue(argumentCaptor.capture());
- org.sonar.api.issue.internal.DefaultIssue issue = argumentCaptor.getValue();
+ org.sonar.core.issue.DefaultIssue issue = argumentCaptor.getValue();
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("foo", "bar"));
assertThat(issue.message()).isEqualTo("Foo");
assertThat(issue.line()).isNull();