aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-02 20:01:59 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2015-07-02 20:01:59 +0200
commitbe9b5a2ea93b7959cbaa4a630bff79467b3ba8d0 (patch)
tree03fad10de15f1cf9d64199e32bfa3b90158035ea /sonar-batch
parente154f3cf3e73c0ba447fffef1d447dc729f8bf9b (diff)
parent1c0b9a97e3bc6d58c4697b4350b39adc81a6efc1 (diff)
downloadsonarqube-be9b5a2ea93b7959cbaa4a630bff79467b3ba8d0.tar.gz
sonarqube-be9b5a2ea93b7959cbaa4a630bff79467b3ba8d0.zip
Merge branch 'feature/ce_issue_tracking'
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java16
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java66
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java218
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/DebtModelProvider.java83
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java142
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java114
-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.java31
-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.java12
-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.java9
-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.java121
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java23
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/report/MetadataPublisher.java74
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java129
-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.java41
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java19
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java16
-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.java353
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/DebtModelProviderTest.java81
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java149
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java376
-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.java113
-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.java4
-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.java107
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java30
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/report/MetadataPublisherTest.java99
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java215
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java70
-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
65 files changed, 267 insertions, 4355 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..53b2f2c1bb1 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
@@ -37,13 +37,7 @@ import org.sonar.batch.compute.OverallCoverageDecorator;
import org.sonar.batch.compute.OverallLineCoverageDecorator;
import org.sonar.batch.compute.UnitTestDecorator;
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;
@@ -87,16 +81,6 @@ public class BatchComponents {
// language
LanguageDistributionDecorator.class,
- // Debt
- IssueChangelogDebtCalculator.class,
- 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/compute/SeverityUtils.java b/sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java
deleted file mode 100644
index fd92039ce98..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/compute/SeverityUtils.java
+++ /dev/null
@@ -1,66 +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.compute;
-
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.rules.RulePriority;
-
-final class SeverityUtils {
- private SeverityUtils() {
- // only static methods
- }
-
- static Metric severityToIssueMetric(RulePriority severity) {
- Metric metric;
- if (severity.equals(RulePriority.BLOCKER)) {
- metric = CoreMetrics.BLOCKER_VIOLATIONS;
- } else if (severity.equals(RulePriority.CRITICAL)) {
- metric = CoreMetrics.CRITICAL_VIOLATIONS;
- } else if (severity.equals(RulePriority.MAJOR)) {
- metric = CoreMetrics.MAJOR_VIOLATIONS;
- } else if (severity.equals(RulePriority.MINOR)) {
- metric = CoreMetrics.MINOR_VIOLATIONS;
- } else if (severity.equals(RulePriority.INFO)) {
- metric = CoreMetrics.INFO_VIOLATIONS;
- } else {
- throw new IllegalArgumentException("Unsupported severity: " + severity);
- }
- return metric;
- }
-
- static Metric severityToNewMetricIssue(RulePriority severity) {
- Metric metric;
- if (severity.equals(RulePriority.BLOCKER)) {
- metric = CoreMetrics.NEW_BLOCKER_VIOLATIONS;
- } else if (severity.equals(RulePriority.CRITICAL)) {
- metric = CoreMetrics.NEW_CRITICAL_VIOLATIONS;
- } else if (severity.equals(RulePriority.MAJOR)) {
- metric = CoreMetrics.NEW_MAJOR_VIOLATIONS;
- } else if (severity.equals(RulePriority.MINOR)) {
- metric = CoreMetrics.NEW_MINOR_VIOLATIONS;
- } else if (severity.equals(RulePriority.INFO)) {
- metric = CoreMetrics.NEW_INFO_VIOLATIONS;
- } else {
- throw new IllegalArgumentException("Unsupported severity: " + severity);
- }
- return metric;
- }
-}
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
deleted file mode 100644
index 5ddb7e45949..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/DebtDecorator.java
+++ /dev/null
@@ -1,218 +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.debt;
-
-import com.google.common.annotations.VisibleForTesting;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-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.rule.Rule;
-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.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilters;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.PersistenceMode;
-import org.sonar.api.measures.RuleMeasure;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RuleFinder;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Maps.newHashMap;
-
-/**
- * Decorator that computes the technical debt metric
- */
-@DependsUpon(DecoratorBarriers.ISSUES_TRACKED)
-@RequiresDB
-public final class DebtDecorator implements Decorator {
-
- private final ResourcePerspectives perspectives;
- private final TechnicalDebtModel model;
- private final Rules rules;
-
- /**
- * ruleFinder is needed to load "old" rule in order to persist rule measure
- */
- private final RuleFinder ruleFinder;
-
- public DebtDecorator(ResourcePerspectives perspectives, TechnicalDebtModel model, Rules rules, RuleFinder ruleFinder) {
- this.perspectives = perspectives;
- this.model = model;
- this.rules = rules;
- this.ruleFinder = ruleFinder;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @DependedUpon
- public List<Metric> generatesMetrics() {
- return Arrays.<Metric>asList(CoreMetrics.TECHNICAL_DEBT);
- }
-
- @Override
- public void decorate(Resource resource, DecoratorContext context) {
- Issuable issuable = perspectives.as(Issuable.class, resource);
- if (issuable != null && shouldSaveMeasure(context)) {
- List<Issue> issues = newArrayList(issuable.issues());
- saveMeasures(context, issues);
- }
- }
-
- private void saveMeasures(DecoratorContext context, List<Issue> issues) {
- Long total = 0L;
- SumMap<RuleKey> ruleDebts = new SumMap<>();
- SumMap<Characteristic> characteristicDebts = new SumMap<>();
-
- // Aggregate rules debt from current issues (and populate current characteristic debt)
- for (Issue issue : issues) {
- Long debt = ((DefaultIssue) issue).debtInMinutes();
- total += computeDebt(debt, issue.ruleKey(), ruleDebts, characteristicDebts);
- }
-
- // Aggregate rules debt from children (and populate children characteristics debt)
- for (Measure measure : context.getChildrenMeasures(MeasuresFilters.rules(CoreMetrics.TECHNICAL_DEBT))) {
- Long debt = measure.getValue().longValue();
- RuleMeasure ruleMeasure = (RuleMeasure) measure;
- total += computeDebt(debt, ruleMeasure.ruleKey(), ruleDebts, characteristicDebts);
- }
-
- context.saveMeasure(CoreMetrics.TECHNICAL_DEBT, total.doubleValue());
- saveOnRule(context, ruleDebts);
- for (Characteristic characteristic : model.characteristics()) {
- Long debt = characteristicDebts.get(characteristic);
- saveCharacteristicMeasure(context, characteristic, debt != null ? debt.doubleValue() : 0d, false);
- }
- }
-
- private Long computeDebt(@Nullable Long debt, RuleKey ruleKey, SumMap<RuleKey> ruleDebts, SumMap<Characteristic> characteristicDebts) {
- if (debt != null) {
- Rule rule = rules.find(ruleKey);
- if (rule != null) {
- String characteristicKey = rule.debtSubCharacteristic();
- if (characteristicKey != null) {
- Characteristic characteristic = model.characteristicByKey(characteristicKey);
- if (characteristic != null) {
- ruleDebts.add(ruleKey, debt);
- characteristicDebts.add(characteristic, debt);
- propagateTechnicalDebtInParents(characteristic.parent(), debt, characteristicDebts);
- return debt;
- }
- }
- }
- }
- return 0L;
- }
-
- private void propagateTechnicalDebtInParents(@Nullable Characteristic characteristic, long value, SumMap<Characteristic> characteristicDebts) {
- if (characteristic != null) {
- characteristicDebts.add(characteristic, value);
- propagateTechnicalDebtInParents(characteristic.parent(), value, characteristicDebts);
- }
- }
-
- private void saveOnRule(DecoratorContext context, SumMap<RuleKey> ruleDebts) {
- for (Map.Entry<RuleKey, Long> entry : ruleDebts.entrySet()) {
- org.sonar.api.rules.Rule oldRule = ruleFinder.findByKey(entry.getKey());
- if (oldRule != null) {
- saveRuleMeasure(context, oldRule, entry.getValue().doubleValue(), ResourceUtils.isEntity(context.getResource()));
- }
- }
- }
-
- @VisibleForTesting
- void saveCharacteristicMeasure(DecoratorContext context, Characteristic characteristic, Double value, boolean inMemory) {
- // we need the value on projects (root or module) even if value==0 in order to display correctly the SQALE history chart (see SQALE-122)
- // BUT we don't want to save zero-values for non top-characteristics (see SQALE-147)
- if (value > 0.0 || (ResourceUtils.isProject(context.getResource()) && characteristic.isRoot())) {
- Measure measure = new Measure(CoreMetrics.TECHNICAL_DEBT);
- measure.setCharacteristic(characteristic);
- saveMeasure(context, measure, value, inMemory);
- }
- }
-
- @VisibleForTesting
- void saveRuleMeasure(DecoratorContext context, org.sonar.api.rules.Rule rule, Double value, boolean inMemory) {
- // we need the value on projects (root or module) even if value==0 in order to display correctly the SQALE history chart (see SQALE-122)
- // BUT we don't want to save zero-values for non top-characteristics (see SQALE-147)
- if (value > 0.0) {
- RuleMeasure measure = new RuleMeasure(CoreMetrics.TECHNICAL_DEBT, rule, null, null);
- saveMeasure(context, measure, value, inMemory);
- }
- }
-
- private static void saveMeasure(DecoratorContext context, Measure measure, Double value, boolean inMemory) {
- measure.setValue(value);
- if (inMemory) {
- measure.setPersistenceMode(PersistenceMode.MEMORY);
- }
- context.saveMeasure(measure);
- }
-
- private static boolean shouldSaveMeasure(DecoratorContext context) {
- return context.getMeasure(CoreMetrics.TECHNICAL_DEBT) == null;
- }
-
- private static class SumMap<E> {
- private Map<E, Long> sumByKeys;
-
- public SumMap() {
- sumByKeys = newHashMap();
- }
-
- public void add(@Nullable E key, Long value) {
- if (key != null) {
- Long currentValue = sumByKeys.get(key);
- sumByKeys.put(key, currentValue != null ? (currentValue + value) : value);
- }
- }
-
- @CheckForNull
- public Long get(E key) {
- return sumByKeys.get(key);
- }
-
- public Set<Map.Entry<E, Long>> entrySet() {
- return sumByKeys.entrySet();
- }
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/debt/DebtModelProvider.java b/sonar-batch/src/main/java/org/sonar/batch/debt/DebtModelProvider.java
deleted file mode 100644
index dc95f8e8679..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/DebtModelProvider.java
+++ /dev/null
@@ -1,83 +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.debt;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import java.util.List;
-import javax.annotation.Nullable;
-import org.picocontainer.injectors.ProviderAdapter;
-import org.sonar.api.batch.debt.DebtCharacteristic;
-import org.sonar.api.batch.debt.DebtModel;
-import org.sonar.api.batch.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.api.batch.debt.internal.DefaultDebtModel;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.log.Profiler;
-import org.sonar.core.technicaldebt.db.CharacteristicDao;
-import org.sonar.core.technicaldebt.db.CharacteristicDto;
-
-public class DebtModelProvider extends ProviderAdapter {
-
- private DebtModel model;
-
- public DebtModel provide(CharacteristicDao dao) {
- if (model == null) {
- Profiler profiler = Profiler.create(Loggers.get(getClass())).startInfo("Load technical debt model");
- model = load(dao);
- profiler.stopDebug();
- }
- return model;
- }
-
- private static DebtModel load(CharacteristicDao dao) {
- DefaultDebtModel debtModel = new DefaultDebtModel();
-
- List<CharacteristicDto> allCharacteristics = dao.selectEnabledCharacteristics();
- for (CharacteristicDto dto : allCharacteristics) {
- Integer parentId = dto.getParentId();
- if (parentId == null) {
- debtModel.addCharacteristic(toDebtCharacteristic(dto));
- } else {
- debtModel.addSubCharacteristic(toDebtCharacteristic(dto), characteristicById(parentId, allCharacteristics).getKey());
- }
- }
- return debtModel;
- }
-
- private static CharacteristicDto characteristicById(final int id, List<CharacteristicDto> allCharacteristics) {
- return Iterables.find(allCharacteristics, new Predicate<CharacteristicDto>() {
- @Override
- public boolean apply(@Nullable CharacteristicDto input) {
- return input != null && id == input.getId();
- }
- });
- }
-
- private static DebtCharacteristic toDebtCharacteristic(CharacteristicDto characteristic) {
- return new DefaultDebtCharacteristic()
- .setId(characteristic.getId())
- .setKey(characteristic.getKey())
- .setName(characteristic.getName())
- .setOrder(characteristic.getOrder())
- .setParentId(characteristic.getParentId());
- }
-
-}
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
deleted file mode 100644
index fb882a7a0eb..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/IssueChangelogDebtCalculator.java
+++ /dev/null
@@ -1,142 +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.debt;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Ordering;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.CheckForNull;
-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.IssueUpdater;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-/**
- * Warning, before modifying this class, please do not forget that it's used by the Dev Cockpit plugin
- */
-@BatchSide
-public class IssueChangelogDebtCalculator {
-
- @CheckForNull
- public Long calculateNewTechnicalDebt(Issue issue, @Nullable Date periodDate) {
- Long debt = ((DefaultIssue) issue).debtInMinutes();
- Date periodDatePlusOneSecond = periodDate != null ? DateUtils.addSeconds(periodDate, 1) : null;
- if (isAfter(issue.creationDate(), periodDatePlusOneSecond)) {
- return debt;
- } else {
- return calculateNewTechnicalDebtValueFromChangelog(debt, issue, periodDate);
- }
- }
-
- @CheckForNull
- private Long calculateNewTechnicalDebtValueFromChangelog(@Nullable Long currentTechnicalDebtValue, Issue issue, Date periodDate) {
- List<FieldDiffs> changelog = technicalDebtHistory(issue);
- for (Iterator<FieldDiffs> iterator = changelog.iterator(); iterator.hasNext();) {
- FieldDiffs diff = iterator.next();
- Date date = diff.creationDate();
- if (isLesserOrEqual(date, periodDate)) {
- // return new value from the change that is just before the period date
- return subtractNeverNegative(currentTechnicalDebtValue, newValue(diff));
- }
- if (!iterator.hasNext()) {
- // return old value from the change that is just after the period date when there's no more element in changelog
- return subtractNeverNegative(currentTechnicalDebtValue, oldValue(diff));
- }
- }
- // Return null when no changelog
- return null;
- }
-
- /**
- * SONAR-5059
- */
- @CheckForNull
- private static Long subtractNeverNegative(@Nullable Long value, @Nullable Long with) {
- Long result = (value != null ? value : 0) - (with != null ? with : 0);
- return result > 0 ? result : null;
- }
-
- private List<FieldDiffs> technicalDebtHistory(Issue issue) {
- List<FieldDiffs> technicalDebtChangelog = changesOnField(((DefaultIssue) issue).changes());
- if (!technicalDebtChangelog.isEmpty()) {
- // Changelog have to be sorted from newest to oldest.
- // Null date should be the first as this happen when technical debt has changed since previous analysis.
- Ordering<FieldDiffs> ordering = Ordering.natural().reverse().nullsFirst().onResultOf(new Function<FieldDiffs, Date>() {
- @Override
- public Date apply(FieldDiffs diff) {
- return diff.creationDate();
- }
- });
- return ordering.immutableSortedCopy(technicalDebtChangelog);
- }
- return Collections.emptyList();
- }
-
- private static List<FieldDiffs> changesOnField(Collection<FieldDiffs> fieldDiffs) {
- List<FieldDiffs> diffs = newArrayList();
- for (FieldDiffs fieldDiff : fieldDiffs) {
- if (fieldDiff.diffs().containsKey(IssueUpdater.TECHNICAL_DEBT)) {
- diffs.add(fieldDiff);
- }
- }
- return diffs;
- }
-
- @CheckForNull
- private static Long newValue(FieldDiffs fieldDiffs) {
- for (Map.Entry<String, FieldDiffs.Diff> entry : fieldDiffs.diffs().entrySet()) {
- if (entry.getKey().equals(IssueUpdater.TECHNICAL_DEBT)) {
- return entry.getValue().newValueLong();
- }
- }
- return null;
- }
-
- @CheckForNull
- private static Long oldValue(FieldDiffs fieldDiffs) {
- for (Map.Entry<String, FieldDiffs.Diff> entry : fieldDiffs.diffs().entrySet()) {
- if (entry.getKey().equals(IssueUpdater.TECHNICAL_DEBT)) {
- return entry.getValue().oldValueLong();
- }
- }
- return null;
- }
-
- private static boolean isAfter(@Nullable Date currentDate, @Nullable Date pastDate) {
- return pastDate == null || (currentDate != null && DateUtils.truncatedCompareTo(currentDate, pastDate, Calendar.SECOND) > 0);
- }
-
- private static boolean isLesserOrEqual(@Nullable Date currentDate, @Nullable Date pastDate) {
- return (currentDate != null) && (pastDate == null || (DateUtils.truncatedCompareTo(currentDate, pastDate, Calendar.SECOND) <= 0));
- }
-
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java
deleted file mode 100644
index c334520aa79..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/debt/NewDebtDecorator.java
+++ /dev/null
@@ -1,114 +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.debt;
-
-import com.google.common.collect.ImmutableList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import javax.annotation.Nullable;
-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.component.ResourcePerspectives;
-import org.sonar.api.issue.Issuable;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasureUtils;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
-import org.sonar.batch.components.Period;
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-/**
- * Decorator that computes the technical debt metric
- */
-@RequiresDB
-@DependsUpon(DecoratorBarriers.ISSUES_TRACKED)
-public final class NewDebtDecorator implements Decorator {
-
- private final ResourcePerspectives perspectives;
- private final TimeMachineConfiguration timeMachineConfiguration;
- private final IssueChangelogDebtCalculator issueChangelogDebtCalculator;
-
- public NewDebtDecorator(ResourcePerspectives perspectives, TimeMachineConfiguration timeMachineConfiguration,
- IssueChangelogDebtCalculator issueChangelogDebtCalculator) {
- this.perspectives = perspectives;
- this.timeMachineConfiguration = timeMachineConfiguration;
- this.issueChangelogDebtCalculator = issueChangelogDebtCalculator;
- }
-
- @Override
- public boolean shouldExecuteOnProject(Project project) {
- return true;
- }
-
- @DependedUpon
- public List<Metric> generatesMetrics() {
- return ImmutableList.<Metric>of(
- CoreMetrics.NEW_TECHNICAL_DEBT
- );
- }
-
- @Override
- public void decorate(Resource resource, DecoratorContext context) {
- Issuable issuable = perspectives.as(Issuable.class, resource);
- if (issuable != null && shouldSaveNewMetrics(context)) {
- List<Issue> issues = newArrayList(issuable.issues());
- saveMeasures(context, issues);
- }
- }
-
- private void saveMeasures(DecoratorContext context, Collection<Issue> issues) {
- Measure measure = new Measure(CoreMetrics.NEW_TECHNICAL_DEBT);
- for (Period period : timeMachineConfiguration.periods()) {
- Date periodDate = period.getDate();
- double value = calculateNewTechnicalDebtValue(issues, periodDate);
- Collection<Measure> children = context.getChildrenMeasures(measure.getMetric());
- double sum = MeasureUtils.sumOnVariation(true, period.getIndex(), children) + value;
- measure.setVariation(period.getIndex(), sum);
- }
- context.saveMeasure(measure);
- }
-
- private long calculateNewTechnicalDebtValue(Collection<Issue> issues, @Nullable Date periodDate) {
- long result = 0;
- for (Issue issue : issues) {
- Long debt = issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, periodDate);
- if (debt != null) {
- result += debt;
- }
- }
- return result;
- }
-
- private static boolean shouldSaveNewMetrics(DecoratorContext context) {
- return context.getMeasure(CoreMetrics.NEW_TECHNICAL_DEBT) == null;
- }
-
-}
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..73c7604860c 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
@@ -19,21 +19,18 @@
*/
package org.sonar.batch.issue;
-import com.google.common.base.Objects;
import com.google.common.base.Strings;
import javax.annotation.Nullable;
-import org.sonar.api.batch.debt.DebtRemediationFunction;
import org.sonar.api.batch.rule.ActiveRule;
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.api.resources.Project;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.Violation;
-import org.sonar.api.utils.Duration;
import org.sonar.api.utils.MessageException;
+import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.DefaultIssueBuilder;
/**
@@ -118,31 +115,5 @@ public class ModuleIssues {
if (issue.severity() == null) {
issue.setSeverity(activeRule.severity());
}
- if (rule != null) {
- DebtRemediationFunction function = rule.debtRemediationFunction();
- if (rule.debtSubCharacteristic() != null && function != null) {
- issue.setDebt(calculateDebt(function, issue.effortToFix(), rule.key()));
- }
- }
- }
-
- private Duration calculateDebt(DebtRemediationFunction function, @Nullable Double effortToFix, RuleKey ruleKey) {
- if (DebtRemediationFunction.Type.CONSTANT_ISSUE.equals(function.type()) && effortToFix != null) {
- throw new IllegalArgumentException("Rule '" + ruleKey + "' can not use 'Constant/issue' remediation function " +
- "because this rule does not have a fixed remediation cost.");
- }
- Duration result = Duration.create(0);
- Duration factor = function.coefficient();
- Duration offset = function.offset();
-
- if (factor != null) {
- int effortToFixValue = Objects.firstNonNull(effortToFix, 1).intValue();
- result = factor.multiply(effortToFixValue);
- }
- if (offset != null) {
- result = result.add(offset);
- }
- return result;
}
-
}
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..729e4d7cff1 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;
@@ -143,7 +143,7 @@ public class LocalIssueTracking {
if (file == null) {
throw new IllegalStateException("Resource " + component.resource() + " was not found in InputPath cache");
}
- sourceHashHolder = new SourceHashHolder((DefaultInputFile) file, lastLineHashes);
+ sourceHashHolder = new SourceHashHolder(file, lastLineHashes);
}
return sourceHashHolder;
}
@@ -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..e41acc6760d 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,11 +104,6 @@ public final class PhaseExecutor {
localIssueTracking();
}
issuesReport();
-
- if (!analysisMode.isPreview()) {
- persistersExecutor.execute();
- }
-
publishReportJob();
postJobsExecutor.execute(sensorContext);
}
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..b3e3692d937 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,15 +21,6 @@ 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;
import org.sonar.batch.index.BatchComponentCache;
@@ -37,23 +28,21 @@ import org.sonar.batch.issue.IssueCache;
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 {
private final BatchComponentCache componentCache;
private final IssueCache issueCache;
- private final ImmutableProjectReactor reactor;
- public IssuesPublisher(ImmutableProjectReactor reactor, BatchComponentCache componentCache, IssueCache issueCache) {
- this.reactor = reactor;
+ public IssuesPublisher(BatchComponentCache componentCache, IssueCache issueCache) {
this.componentCache = componentCache;
this.issueCache = issueCache;
+
}
@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,63 +54,17 @@ public class IssuesPublisher implements ReportPublisherStep {
return toReportIssue(builder, input);
}
}));
- deletedComponentKeys.remove(componentKey);
}
-
- int count = exportIssuesOfDeletedComponents(deletedComponentKeys, writer);
-
- exportMetadata(writer, count);
- }
-
- private void exportMetadata(BatchReportWriter writer, int count) {
- 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);
- String branch = root.properties().get(CoreProperties.PROJECT_BRANCH_PROPERTY);
- if (branch != null) {
- builder.setBranch(branch);
- }
- 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 +79,7 @@ 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;
- }
-
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java
index fe57b624502..8a8ae99436a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/MeasuresPublisher.java
@@ -26,14 +26,10 @@ import com.google.common.collect.Iterables;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric.Level;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.technicaldebt.batch.Characteristic;
import org.sonar.batch.index.BatchComponent;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.Constants.MeasureValueType;
@@ -111,21 +107,6 @@ public class MeasuresPublisher implements ReportPublisherStep {
if (description != null) {
builder.setDescription(description);
}
- if (measure instanceof RuleMeasure) {
- RuleMeasure ruleMeasure = (RuleMeasure) measure;
- RuleKey ruleKey = ruleMeasure.ruleKey();
- if (ruleKey != null) {
- builder.setRuleKey(ruleKey.toString());
- }
- }
- Level alertStatus = measure.getAlertStatus();
- if (alertStatus != null) {
- builder.setAlertStatus(alertStatus.toString());
- }
- String alertText = measure.getAlertText();
- if (alertText != null) {
- builder.setAlertText(alertText);
- }
Double variation1 = measure.getVariation1();
if (variation1 != null) {
builder.setVariationValue1(variation1);
@@ -146,10 +127,6 @@ public class MeasuresPublisher implements ReportPublisherStep {
if (variation5 != null) {
builder.setVariationValue5(variation5);
}
- Characteristic charac = measure.getCharacteristic();
- if (charac != null) {
- builder.setCharactericId(charac.id());
- }
Integer personId = measure.getPersonId();
if (personId != null) {
builder.setPersonId(personId);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/MetadataPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/MetadataPublisher.java
new file mode 100644
index 00000000000..d5c4152d541
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/report/MetadataPublisher.java
@@ -0,0 +1,74 @@
+/*
+ * 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.report;
+
+import com.google.common.base.Function;
+import javax.annotation.Nonnull;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.rule.ActiveRule;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.resources.Project;
+import org.sonar.batch.index.BatchComponent;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.batch.scan.ImmutableProjectReactor;
+
+import static com.google.common.collect.FluentIterable.from;
+
+public class MetadataPublisher implements ReportPublisherStep {
+
+ private final BatchComponentCache componentCache;
+ private final ImmutableProjectReactor reactor;
+ private final ActiveRules activeRules;
+
+ public MetadataPublisher(BatchComponentCache componentCache, ImmutableProjectReactor reactor, ActiveRules activeRules) {
+ this.componentCache = componentCache;
+ this.reactor = reactor;
+ this.activeRules = activeRules;
+ }
+
+ @Override
+ public void publish(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());
+ String branch = root.properties().get(CoreProperties.PROJECT_BRANCH_PROPERTY);
+ if (branch != null) {
+ builder.setBranch(branch);
+ }
+ builder.addAllActiveRuleKey(from(activeRules.findAll()).transform(ToRuleKey.INSTANCE));
+ writer.writeMetadata(builder.build());
+ }
+
+ private enum ToRuleKey implements Function<ActiveRule, String> {
+ INSTANCE;
+ @Nonnull
+ @Override
+ public String apply(@Nonnull ActiveRule input) {
+ return input.ruleKey().toString();
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java
deleted file mode 100644
index 9a8af6d87ef..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java
+++ /dev/null
@@ -1,129 +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.rule;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ListMultimap;
-import java.util.List;
-import javax.annotation.Nullable;
-import org.picocontainer.injectors.ProviderAdapter;
-import org.sonar.api.batch.debt.DebtCharacteristic;
-import org.sonar.api.batch.debt.DebtModel;
-import org.sonar.api.batch.debt.DebtRemediationFunction;
-import org.sonar.api.batch.debt.internal.DefaultDebtModel;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.batch.rule.internal.NewRule;
-import org.sonar.api.batch.rule.internal.RulesBuilder;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.utils.Durations;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.log.Profiler;
-import org.sonar.core.rule.RuleDao;
-import org.sonar.core.rule.RuleDto;
-import org.sonar.core.rule.RuleParamDto;
-
-/**
- * Loads all enabled and non manual rules
- */
-public class RulesProvider extends ProviderAdapter {
-
- private Rules singleton = null;
-
- public Rules provide(RuleDao ruleDao, DebtModel debtModel, Durations durations) {
- if (singleton == null) {
- Profiler profiler = Profiler.create(Loggers.get(getClass())).startInfo("Load rules");
- singleton = load(ruleDao, (DefaultDebtModel) debtModel, durations);
- profiler.stopDebug();
- }
- return singleton;
- }
-
- private Rules load(RuleDao ruleDao, DefaultDebtModel debtModel, Durations durations) {
- RulesBuilder rulesBuilder = new RulesBuilder();
-
- List<RuleParamDto> ruleParamDtos = ruleDao.selectParameters();
- ListMultimap<Integer, RuleParamDto> paramDtosByRuleId = ArrayListMultimap.create();
- for (RuleParamDto dto : ruleParamDtos) {
- paramDtosByRuleId.put(dto.getRuleId(), dto);
- }
- for (RuleDto ruleDto : ruleDao.selectEnablesAndNonManual()) {
- RuleKey ruleKey = RuleKey.of(ruleDto.getRepositoryKey(), ruleDto.getRuleKey());
- NewRule newRule = rulesBuilder.add(ruleKey)
- .setId(ruleDto.getId())
- .setName(ruleDto.getName())
- .setSeverity(ruleDto.getSeverityString())
- .setDescription(ruleDto.getDescription())
- .setStatus(ruleDto.getStatus())
- .setInternalKey(ruleDto.getConfigKey());
-
- if (hasCharacteristic(ruleDto)) {
- newRule.setDebtSubCharacteristic(effectiveCharacteristic(ruleDto, ruleKey, debtModel).key());
- newRule.setDebtRemediationFunction(effectiveFunction(ruleDto, ruleKey, durations));
- }
-
- for (RuleParamDto ruleParamDto : paramDtosByRuleId.get(ruleDto.getId())) {
- newRule.addParam(ruleParamDto.getName())
- .setDescription(ruleParamDto.getDescription());
- }
- }
- return rulesBuilder.build();
- }
-
- private static DebtCharacteristic effectiveCharacteristic(RuleDto ruleDto, RuleKey ruleKey, DefaultDebtModel debtModel) {
- Integer subCharacteristicId = ruleDto.getSubCharacteristicId();
- Integer defaultSubCharacteristicId = ruleDto.getDefaultSubCharacteristicId();
- Integer effectiveSubCharacteristicId = subCharacteristicId != null ? subCharacteristicId : defaultSubCharacteristicId;
- DebtCharacteristic subCharacteristic = debtModel.characteristicById(effectiveSubCharacteristicId);
- if (subCharacteristic == null) {
- throw new IllegalStateException(String.format("Sub characteristic id '%s' on rule '%s' has not been found", effectiveSubCharacteristicId, ruleKey));
- }
- return subCharacteristic;
- }
-
- private DebtRemediationFunction effectiveFunction(RuleDto ruleDto, RuleKey ruleKey, Durations durations) {
- String function = ruleDto.getRemediationFunction();
- String defaultFunction = ruleDto.getDefaultRemediationFunction();
- if (function != null) {
- return createDebtRemediationFunction(function, ruleDto.getRemediationCoefficient(), ruleDto.getRemediationOffset(), durations);
- } else if (defaultFunction != null) {
- return createDebtRemediationFunction(defaultFunction, ruleDto.getDefaultRemediationCoefficient(), ruleDto.getDefaultRemediationOffset(), durations);
- } else {
- throw new IllegalStateException(String.format("Remediation function should not be null on rule '%s'", ruleKey));
- }
- }
-
- private DebtRemediationFunction createDebtRemediationFunction(String function, @Nullable String factor, @Nullable String offset, Durations durations) {
- return DebtRemediationFunction.create(DebtRemediationFunction.Type.valueOf(function),
- factor != null ? durations.decode(factor) : null,
- offset != null ? durations.decode(offset) : null);
- }
-
- /**
- * Return true is the characteristic has not been overridden and a default characteristic is existing or
- * if the characteristic has been overridden but is not disabled
- */
- private static boolean hasCharacteristic(RuleDto ruleDto) {
- Integer subCharacteristicId = ruleDto.getSubCharacteristicId();
- return (subCharacteristicId == null && ruleDto.getDefaultSubCharacteristicId() != null) ||
- (subCharacteristicId != null && !RuleDto.DISABLED_CHARACTERISTIC_ID.equals(subCharacteristicId));
- }
-
-}
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..53aa790b4a4 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
@@ -43,7 +43,6 @@ import org.sonar.batch.bootstrap.ExtensionUtils;
import org.sonar.batch.bootstrap.MetricProvider;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.components.PastMeasuresLoader;
-import org.sonar.batch.debt.DebtModelProvider;
import org.sonar.batch.deprecated.components.DefaultResourceCreationLock;
import org.sonar.batch.deprecated.components.PeriodsDefinition;
import org.sonar.batch.duplication.DuplicationCache;
@@ -53,7 +52,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;
@@ -64,13 +62,13 @@ import org.sonar.batch.report.CoveragePublisher;
import org.sonar.batch.report.DuplicationsPublisher;
import org.sonar.batch.report.IssuesPublisher;
import org.sonar.batch.report.MeasuresPublisher;
+import org.sonar.batch.report.MetadataPublisher;
import org.sonar.batch.report.ReportPublisher;
import org.sonar.batch.report.SourcePublisher;
import org.sonar.batch.report.TestExecutionAndCoveragePublisher;
import org.sonar.batch.repository.ProjectRepositoriesProvider;
import org.sonar.batch.repository.language.DefaultLanguagesRepository;
import org.sonar.batch.rule.ActiveRulesProvider;
-import org.sonar.batch.rule.RulesProvider;
import org.sonar.batch.scan.filesystem.InputPathCache;
import org.sonar.batch.scan.measure.DefaultMetricFinder;
import org.sonar.batch.scan.measure.DeprecatedMetricFinder;
@@ -83,7 +81,6 @@ import org.sonar.core.issue.workflow.FunctionExecutor;
import org.sonar.core.issue.workflow.IssueWorkflow;
import org.sonar.core.permission.PermissionFacade;
import org.sonar.core.platform.ComponentContainer;
-import org.sonar.core.technicaldebt.DefaultTechnicalDebtModel;
public class ProjectScanContainer extends ComponentContainer {
@@ -160,10 +157,10 @@ public class ProjectScanContainer extends ComponentContainer {
InputPathCache.class,
PathResolver.class,
- // rules
+ // rules
new ActiveRulesProvider(),
- // issues
+ // issues
IssueUpdater.class,
FunctionExecutor.class,
IssueWorkflow.class,
@@ -172,31 +169,32 @@ public class ProjectScanContainer extends ComponentContainer {
LocalIssueTracking.class,
ServerIssueRepository.class,
- // metrics
+ // metrics
DefaultMetricFinder.class,
DeprecatedMetricFinder.class,
- // tests
+ // tests
TestPlanBuilder.class,
TestableBuilder.class,
- // lang
+ // lang
Languages.class,
DefaultLanguagesRepository.class,
- // Differential periods
+ // Differential periods
PeriodsDefinition.class,
- // Measures
+ // Measures
MeasureCache.class,
- // Duplications
+ // Duplications
DuplicationCache.class,
- ProjectSettings.class,
+ ProjectSettings.class,
- // Report
+ // Report
ReportPublisher.class,
+ MetadataPublisher.class,
ComponentsPublisher.class,
IssuesPublisher.class,
MeasuresPublisher.class,
@@ -205,22 +203,11 @@ public class ProjectScanContainer extends ComponentContainer {
SourcePublisher.class,
TestExecutionAndCoveragePublisher.class,
- ScanTaskObservers.class);
+ ScanTaskObservers.class);
}
private void addDataBaseComponents() {
- add(
- PastMeasuresLoader.class,
-
- // Rules
- new RulesProvider(),
- new DebtModelProvider(),
-
- // technical debt
- DefaultTechnicalDebtModel.class,
-
- // Issue tracking
- InitialOpenIssuesStack.class);
+ add(PastMeasuresLoader.class);
}
private void addBatchExtensions() {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java
index 92ab2292956..2fd211534ab 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureCache.java
@@ -23,10 +23,7 @@ import com.google.common.base.Preconditions;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Resource;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.batch.index.Cache;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.Caches;
@@ -39,13 +36,8 @@ public class MeasureCache {
private final Cache<Measure> cache;
- public MeasureCache(Caches caches, MetricFinder metricFinder, TechnicalDebtModel techDebtModel) {
- caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder, techDebtModel));
- cache = caches.createCache("measures");
- }
-
public MeasureCache(Caches caches, MetricFinder metricFinder) {
- caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder, null));
+ caches.registerValueCoder(Measure.class, new MeasureValueCoder(metricFinder));
cache = caches.createCache("measures");
}
@@ -88,19 +80,10 @@ public class MeasureCache {
sb.append(m.getMetricKey());
}
sb.append("|");
- Characteristic characteristic = m.getCharacteristic();
- if (characteristic != null) {
- sb.append(characteristic.key());
- }
- sb.append("|");
Integer personId = m.getPersonId();
if (personId != null) {
sb.append(personId);
}
- if (m instanceof RuleMeasure) {
- sb.append("|");
- sb.append(((RuleMeasure) m).ruleKey());
- }
return sb.toString();
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java
index e7dae02780d..b9c8f06511b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/measure/MeasureValueCoder.java
@@ -22,24 +22,18 @@ package org.sonar.batch.scan.measure;
import com.persistit.Value;
import com.persistit.encoding.CoderContext;
import com.persistit.encoding.ValueCoder;
+import javax.annotation.Nullable;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.PersistenceMode;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.api.technicaldebt.batch.Requirement;
-import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
-
-import javax.annotation.Nullable;
class MeasureValueCoder implements ValueCoder {
private final MetricFinder metricFinder;
- private final TechnicalDebtModel techDebtModel;
- public MeasureValueCoder(MetricFinder metricFinder, @Nullable TechnicalDebtModel techDebtModel) {
+ public MeasureValueCoder(MetricFinder metricFinder) {
this.metricFinder = metricFinder;
- this.techDebtModel = techDebtModel;
}
@Override
@@ -58,10 +52,6 @@ class MeasureValueCoder implements ValueCoder {
value.put(m.getVariation4());
value.put(m.getVariation5());
putUTFOrNull(value, m.getUrl());
- Characteristic characteristic = m.getCharacteristic();
- value.put(characteristic != null ? characteristic.id() : null);
- Requirement requirement = m.getRequirement();
- value.put(requirement != null ? requirement.id() : null);
Integer personId = m.getPersonId();
value.put(personId != null ? personId.intValue() : null);
PersistenceMode persistenceMode = m.getPersistenceMode();
@@ -97,8 +87,6 @@ class MeasureValueCoder implements ValueCoder {
m.setVariation4(value.isNull(true) ? null : value.getDouble());
m.setVariation5(value.isNull(true) ? null : value.getDouble());
m.setUrl(value.getString());
- m.setCharacteristic(value.isNull(true) ? null : techDebtModel.characteristicById(value.getInt()));
- m.setRequirement(value.isNull(true) ? null : techDebtModel.requirementsById(value.getInt()));
m.setPersonId(value.isNull(true) ? null : value.getInt());
m.setPersistenceMode(value.isNull(true) ? null : PersistenceMode.valueOf(value.getString()));
return m;
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
deleted file mode 100644
index 5ce426696d5..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/DebtDecoratorTest.java
+++ /dev/null
@@ -1,353 +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.debt;
-
-import com.google.common.collect.Lists;
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.builder.ToStringBuilder;
-import org.apache.commons.lang.builder.ToStringStyle;
-import org.hamcrest.Description;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.batch.DecoratorContext;
-import org.sonar.api.batch.rule.Rules;
-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.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilter;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.RuleMeasure;
-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.RuleFinder;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
-import org.sonar.api.technicaldebt.batch.internal.DefaultCharacteristic;
-import org.sonar.api.test.IsMeasure;
-import org.sonar.api.utils.Duration;
-
-import java.util.Collections;
-
-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.argThat;
-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.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class DebtDecoratorTest {
-
- static final int HOURS_IN_DAY = 8;
-
- static final Long ONE_DAY_IN_MINUTES = 1L * HOURS_IN_DAY * 60;
-
- @Mock
- DecoratorContext context;
-
- @Mock
- Resource resource;
-
- @Mock
- TechnicalDebtModel debtModel;
-
- @Mock
- Issuable issuable;
-
- @Mock
- ResourcePerspectives perspectives;
-
- @Mock
- RuleFinder ruleFinder;
-
- RuleKey ruleKey1 = RuleKey.of("repo1", "rule1");
- RuleKey ruleKey2 = RuleKey.of("repo2", "rule2");
- Rules rules;
-
- DefaultCharacteristic efficiency = new DefaultCharacteristic().setKey("EFFICIENCY");
- DefaultCharacteristic memoryEfficiency = new DefaultCharacteristic().setKey("MEMORY_EFFICIENCY").setParent(efficiency);
-
- DefaultCharacteristic reusability = new DefaultCharacteristic().setKey("REUSABILITY");
- DefaultCharacteristic modularity = new DefaultCharacteristic().setKey("MODULARITY").setParent(reusability);
-
- DebtDecorator decorator;
-
- @Before
- public void before() {
- when(perspectives.as(Issuable.class, resource)).thenReturn(issuable);
- RulesBuilder rulesBuilder = new RulesBuilder();
- rulesBuilder.add(ruleKey1).setName("rule1").setDebtSubCharacteristic("MEMORY_EFFICIENCY");
- rulesBuilder.add(ruleKey2).setName("rule2").setDebtSubCharacteristic("MODULARITY");
- rules = rulesBuilder.build();
-
- when(ruleFinder.findByKey(ruleKey1)).thenReturn(org.sonar.api.rules.Rule.create(ruleKey1.repository(), ruleKey1.rule()));
- when(ruleFinder.findByKey(ruleKey2)).thenReturn(org.sonar.api.rules.Rule.create(ruleKey2.repository(), ruleKey2.rule()));
-
- when(debtModel.characteristics()).thenReturn(newArrayList(efficiency, memoryEfficiency, reusability, modularity));
- when(debtModel.characteristicByKey("EFFICIENCY")).thenReturn(efficiency);
- when(debtModel.characteristicByKey("MEMORY_EFFICIENCY")).thenReturn(memoryEfficiency);
- when(debtModel.characteristicByKey("REUSABILITY")).thenReturn(reusability);
- when(debtModel.characteristicByKey("MODULARITY")).thenReturn(modularity);
-
- decorator = new DebtDecorator(perspectives, debtModel, rules, ruleFinder);
- }
-
- @Test
- public void generates_metrics() {
- assertThat(decorator.generatesMetrics()).hasSize(1);
- }
-
- @Test
- public void execute_on_project() {
- assertThat(decorator.shouldExecuteOnProject(null)).isTrue();
- }
-
- @Test
- public void not_save_if_measure_already_computed() {
- when(context.getMeasure(CoreMetrics.TECHNICAL_DEBT)).thenReturn(new Measure());
-
- decorator.decorate(resource, context);
-
- verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.TECHNICAL_DEBT)));
- }
-
- @Test
- public void add_technical_debt_from_one_issue_and_no_parent() {
- Issue issue = createIssue("rule1", "repo1").setDebt(Duration.create(ONE_DAY_IN_MINUTES));
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, ONE_DAY_IN_MINUTES.doubleValue());
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey1, ONE_DAY_IN_MINUTES.doubleValue())));
- }
-
- @Test
- public void add_technical_debt_from_one_issue_without_debt() {
- Issue issue = createIssue("rule1", "repo1").setDebt(null);
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, 0.0);
- }
-
- @Test
- public void add_technical_debt_from_one_issue_and_propagate_to_parents() {
- Issue issue = createIssue("rule1", "repo1").setDebt(Duration.create(ONE_DAY_IN_MINUTES));
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, ONE_DAY_IN_MINUTES.doubleValue());
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey1, ONE_DAY_IN_MINUTES.doubleValue())));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, efficiency, ONE_DAY_IN_MINUTES.doubleValue())));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, memoryEfficiency, ONE_DAY_IN_MINUTES.doubleValue())));
- }
-
- @Test
- public void add_technical_debt_from_issues() {
- Long technicalDebt1 = ONE_DAY_IN_MINUTES;
- Long technicalDebt2 = 2 * ONE_DAY_IN_MINUTES;
-
- Issue issue1 = createIssue("rule1", "repo1").setDebt(Duration.create(technicalDebt1));
- Issue issue2 = createIssue("rule1", "repo1").setDebt(Duration.create(technicalDebt1));
- Issue issue3 = createIssue("rule2", "repo2").setDebt(Duration.create(technicalDebt2));
- Issue issue4 = createIssue("rule2", "repo2").setDebt(Duration.create(technicalDebt2));
- when(issuable.issues()).thenReturn(newArrayList(issue1, issue2, issue3, issue4));
-
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, 6d * ONE_DAY_IN_MINUTES);
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey1, 2d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey2, 4d * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void add_technical_debt_from_current_and_children_measures() {
- Issue issue1 = createIssue("rule1", "repo1").setDebt(Duration.create(ONE_DAY_IN_MINUTES));
- Issue issue2 = createIssue("rule1", "repo1").setDebt(Duration.create(ONE_DAY_IN_MINUTES));
- when(issuable.issues()).thenReturn(newArrayList(issue1, issue2));
-
- when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Lists.<Measure>newArrayList(
- new RuleMeasure(CoreMetrics.TECHNICAL_DEBT,
- org.sonar.api.rules.Rule.create(ruleKey1.repository(), ruleKey1.rule()), null, null)
- .setValue(5d * ONE_DAY_IN_MINUTES)
- ));
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, 7d * ONE_DAY_IN_MINUTES);
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey1, 7d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, memoryEfficiency, 7d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, efficiency, 7d * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void add_technical_debt_only_from_children_measures() {
- when(issuable.issues()).thenReturn(Collections.<Issue>emptyList());
-
- when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(Lists.<Measure>newArrayList(
- new RuleMeasure(CoreMetrics.TECHNICAL_DEBT,
- org.sonar.api.rules.Rule.create(ruleKey1.repository(), ruleKey1.rule())
- , null, null).setValue(5d * ONE_DAY_IN_MINUTES),
-
- new RuleMeasure(CoreMetrics.TECHNICAL_DEBT,
- org.sonar.api.rules.Rule.create(ruleKey2.repository(), ruleKey2.rule())
- , null, null).setValue(10d * ONE_DAY_IN_MINUTES)
- ));
- decorator.decorate(resource, context);
-
- verify(context).saveMeasure(CoreMetrics.TECHNICAL_DEBT, 15d * ONE_DAY_IN_MINUTES);
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey1, 5d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsRuleMeasure(CoreMetrics.TECHNICAL_DEBT, ruleKey2, 10d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, memoryEfficiency, 5d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, efficiency, 5d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, reusability, 10d * ONE_DAY_IN_MINUTES)));
- verify(context).saveMeasure(argThat(new IsCharacteristicMeasure(CoreMetrics.TECHNICAL_DEBT, modularity, 10d * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void always_save_technical_debt_for_positive_values() {
- // for a project
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getResource()).thenReturn(new Project("foo"));
- decorator.saveCharacteristicMeasure(context, (Characteristic) null, 12.0, false);
- verify(context, times(1)).saveMeasure(new Measure(CoreMetrics.TECHNICAL_DEBT));
-
- // or for a file
- context = mock(DecoratorContext.class);
- when(context.getResource()).thenReturn(File.create("foo"));
- decorator.saveCharacteristicMeasure(context, (Characteristic) null, 12.0, false);
- verify(context, times(1)).saveMeasure(new Measure(CoreMetrics.TECHNICAL_DEBT));
- }
-
- @Test
- public void always_save_technical_debt_for_project_if_top_characteristic() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getResource()).thenReturn(new Project("foo"));
-
- // this is a top characteristic
- DefaultCharacteristic rootCharacteristic = new DefaultCharacteristic().setKey("root");
-
- decorator.saveCharacteristicMeasure(context, rootCharacteristic, 0.0, true);
- verify(context, times(1)).saveMeasure(new Measure(CoreMetrics.TECHNICAL_DEBT).setCharacteristic(rootCharacteristic));
- }
-
- /**
- * SQALE-147
- */
- @Test
- public void never_save_technical_debt_for_project_if_not_top_characteristic() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getResource()).thenReturn(new Project("foo"));
-
- DefaultCharacteristic rootCharacteristic = new DefaultCharacteristic().setKey("EFFICIENCY");
- DefaultCharacteristic characteristic = new DefaultCharacteristic().setKey("MEMORY_EFFICIENCY").setParent(rootCharacteristic);
-
- decorator.saveCharacteristicMeasure(context, characteristic, 0.0, true);
- verify(context, never()).saveMeasure(any(Measure.class));
- }
-
- @Test
- public void not_save_technical_debt_for_file_if_zero() {
- DecoratorContext context = mock(DecoratorContext.class);
- when(context.getResource()).thenReturn(File.create("foo"));
-
- decorator.saveCharacteristicMeasure(context, null, 0.0, true);
- verify(context, never()).saveMeasure(new Measure(CoreMetrics.TECHNICAL_DEBT));
- }
-
- private DefaultIssue createIssue(String ruleKey, String repositoryKey) {
- return new DefaultIssue().setRuleKey(RuleKey.of(repositoryKey, ruleKey));
- }
-
- class IsCharacteristicMeasure extends ArgumentMatcher<Measure> {
- Metric metric = null;
- Characteristic characteristic = null;
- Double value = null;
-
- public IsCharacteristicMeasure(Metric metric, Characteristic characteristic, Double value) {
- this.metric = metric;
- this.characteristic = characteristic;
- this.value = value;
- }
-
- @Override
- public boolean matches(Object o) {
- if (!(o instanceof Measure)) {
- return false;
- }
- Measure m = (Measure) o;
- return ObjectUtils.equals(metric, m.getMetric()) &&
- ObjectUtils.equals(characteristic, m.getCharacteristic()) &&
- ObjectUtils.equals(value, m.getValue());
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText(new StringBuilder()
- .append("value=").append(value).append(",")
- .append("characteristic=").append(characteristic.key()).append(",")
- .append("metric=").append(metric.getKey()).toString());
- }
- }
-
- class IsRuleMeasure extends ArgumentMatcher<RuleMeasure> {
- Metric metric = null;
- RuleKey ruleKey = null;
- Double value = null;
-
- public IsRuleMeasure(Metric metric, RuleKey ruleKey, Double value) {
- this.metric = metric;
- this.ruleKey = ruleKey;
- this.value = value;
- }
-
- @Override
- public boolean matches(Object o) {
- if (!(o instanceof RuleMeasure)) {
- return false;
- }
- RuleMeasure m = (RuleMeasure) o;
- return ObjectUtils.equals(metric, m.getMetric()) &&
- ObjectUtils.equals(ruleKey, m.ruleKey()) &&
- ObjectUtils.equals(value, m.getValue());
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText(ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE));
- }
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/debt/DebtModelProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/debt/DebtModelProviderTest.java
deleted file mode 100644
index 1d434d5d2e5..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/DebtModelProviderTest.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.debt;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.batch.debt.DebtCharacteristic;
-import org.sonar.api.batch.debt.DebtModel;
-import org.sonar.core.technicaldebt.db.CharacteristicDao;
-import org.sonar.core.technicaldebt.db.CharacteristicDto;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class DebtModelProviderTest {
-
- @Mock
- CharacteristicDao dao;
-
- DebtModelProvider provider;
-
- @Before
- public void before() {
- provider = new DebtModelProvider();
- }
-
- @Test
- public void provide_model() {
- CharacteristicDto rootCharacteristicDto = new CharacteristicDto()
- .setId(1)
- .setKey("MEMORY_EFFICIENCY")
- .setName("Memory use")
- .setOrder(1);
-
- CharacteristicDto characteristicDto = new CharacteristicDto()
- .setId(2)
- .setKey("EFFICIENCY")
- .setName("Efficiency")
- .setParentId(1);
-
- when(dao.selectEnabledCharacteristics()).thenReturn(newArrayList(rootCharacteristicDto, characteristicDto));
-
- DebtModel result = provider.provide(dao);
- assertThat(result.characteristics()).hasSize(1);
-
- DebtCharacteristic characteristic = result.characteristicByKey("MEMORY_EFFICIENCY");
- assertThat(characteristic.key()).isEqualTo("MEMORY_EFFICIENCY");
- assertThat(characteristic.name()).isEqualTo("Memory use");
- assertThat(characteristic.isSub()).isFalse();
- assertThat(characteristic.order()).isEqualTo(1);
-
- DebtCharacteristic subCharacteristic = result.characteristicByKey("EFFICIENCY");
- assertThat(subCharacteristic.key()).isEqualTo("EFFICIENCY");
- assertThat(subCharacteristic.name()).isEqualTo("Efficiency");
- assertThat(subCharacteristic.isSub()).isTrue();
- assertThat(subCharacteristic.order()).isNull();
- }
-}
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
deleted file mode 100644
index 952075dec78..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/IssueChangelogDebtCalculatorTest.java
+++ /dev/null
@@ -1,149 +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.debt;
-
-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.api.utils.Duration;
-
-import java.util.Date;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class IssueChangelogDebtCalculatorTest {
-
- private static final int HOURS_IN_DAY = 8;
-
- IssueChangelogDebtCalculator issueChangelogDebtCalculator;
-
- Date rightNow = new Date();
- Date elevenDaysAgo = DateUtils.addDays(rightNow, -11);
- Date tenDaysAgo = DateUtils.addDays(rightNow, -10);
- Date nineDaysAgo = DateUtils.addDays(rightNow, -9);
- Date fiveDaysAgo = DateUtils.addDays(rightNow, -5);
- Date fourDaysAgo = DateUtils.addDays(rightNow, -4);
-
- long oneDay = 1 * HOURS_IN_DAY * 60 * 60L;
- long twoDays = 2 * HOURS_IN_DAY * 60 * 60L;
- long fiveDays = 5 * HOURS_IN_DAY * 60 * 60L;
-
- Duration oneDayDebt = Duration.create(oneDay);
- Duration twoDaysDebt = Duration.create(twoDays);
- Duration fiveDaysDebt = Duration.create(fiveDays);
-
- @Before
- public void setUp() {
- issueChangelogDebtCalculator = new IssueChangelogDebtCalculator();
- }
-
- @Test
- public void calculate_new_technical_debt_with_one_diff_in_changelog() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(twoDaysDebt).setChanges(
- newArrayList(
- // changelog created at is null because it has just been created on the current analysis
- new FieldDiffs().setDiff("technicalDebt", oneDay, twoDays).setCreationDate(null)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(oneDay);
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(oneDay);
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(twoDays);
- }
-
- @Test
- public void calculate_new_technical_debt_with_many_diffs_in_changelog() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(fiveDaysDebt).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", twoDays, fiveDays).setCreationDate(null),
- new FieldDiffs().setDiff("technicalDebt", oneDay, twoDays).setCreationDate(fourDaysAgo)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isEqualTo(3 * oneDay);
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(4 * oneDay);
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(5 * oneDay);
- }
-
- @Test
- public void changelog_can_be_in_wrong_order() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(fiveDaysDebt).setChanges(
- newArrayList(
- // 3rd
- new FieldDiffs().setDiff("technicalDebt", null, oneDay).setCreationDate(nineDaysAgo),
- // 1st
- new FieldDiffs().setDiff("technicalDebt", twoDays, fiveDays).setCreationDate(rightNow),
- // 2nd
- new FieldDiffs().setDiff("technicalDebt", oneDay, twoDays).setCreationDate(fourDaysAgo)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, fiveDaysAgo)).isEqualTo(4 * oneDay);
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, elevenDaysAgo)).isEqualTo(5 * oneDay);
- }
-
- @Test
- public void calculate_new_technical_debt_with_null_date() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(twoDaysDebt).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", oneDay, twoDays).setCreationDate(null)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, null)).isEqualTo(2 * oneDay);
- }
-
- @Test
- public void calculate_new_technical_debt_when_new_debt_is_null() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(null).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", oneDay, null).setCreationDate(null),
- new FieldDiffs().setDiff("technicalDebt", null, oneDay).setCreationDate(nineDaysAgo)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isNull();
- }
-
- @Test
- public void calculate_new_technical_debt_on_issue_without_technical_debt_and_without_changelog() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo);
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isNull();
- }
-
- @Test
- public void not_return_negative_debt() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(oneDayDebt).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", twoDays, oneDay).setCreationDate(null)
- )
- );
-
- assertThat(issueChangelogDebtCalculator.calculateNewTechnicalDebt(issue, rightNow)).isNull();
- }
-
-}
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
deleted file mode 100644
index 8de52b074c2..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/debt/NewDebtDecoratorTest.java
+++ /dev/null
@@ -1,376 +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.debt;
-
-import org.apache.commons.lang.ObjectUtils;
-import org.apache.commons.lang.time.DateUtils;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.DecoratorContext;
-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.api.measures.CoreMetrics;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.resources.Resource;
-import org.sonar.api.test.IsMeasure;
-import org.sonar.api.utils.Duration;
-import org.sonar.batch.components.Period;
-import org.sonar.batch.components.TimeMachineConfiguration;
-
-import java.util.Date;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class NewDebtDecoratorTest {
-
- NewDebtDecorator decorator;
-
- @Mock
- TimeMachineConfiguration timeMachineConfiguration;
-
- @Mock
- Resource resource;
-
- @Mock
- Issuable issuable;
-
- @Mock
- DecoratorContext context;
-
- Date rightNow;
- Date elevenDaysAgo;
- Date tenDaysAgo;
- Date nineDaysAgo;
- Date fiveDaysAgo;
- Date fourDaysAgo;
-
- static final int HOURS_IN_DAY = 8;
-
- static final Long ONE_DAY_IN_MINUTES = 1L * HOURS_IN_DAY * 60;
- static final Long TWO_DAYS_IN_MINUTES = 2L * HOURS_IN_DAY * 60;
- static final Long FIVE_DAYS_IN_MINUTES = 5L * HOURS_IN_DAY * 60;
-
- @Before
- public void setup() {
- Settings settings = new Settings();
- settings.setProperty(CoreProperties.HOURS_IN_DAY, HOURS_IN_DAY);
-
- ResourcePerspectives perspectives = mock(ResourcePerspectives.class);
- when(perspectives.as(Issuable.class, resource)).thenReturn(issuable);
-
- rightNow = new Date();
- elevenDaysAgo = DateUtils.addDays(rightNow, -11);
- tenDaysAgo = DateUtils.addDays(rightNow, -10);
- nineDaysAgo = DateUtils.addDays(rightNow, -9);
- fiveDaysAgo = DateUtils.addDays(rightNow, -5);
- fourDaysAgo = DateUtils.addDays(rightNow, -4);
-
- when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, fiveDaysAgo), new Period(2, tenDaysAgo)));
-
- decorator = new NewDebtDecorator(perspectives, timeMachineConfiguration, new IssueChangelogDebtCalculator());
- }
-
- @Test
- public void generates_metrics() {
- assertThat(decorator.generatesMetrics()).hasSize(1);
- }
-
- @Test
- public void execute_on_project() {
- assertThat(decorator.shouldExecuteOnProject(null)).isTrue();
- }
-
- @Test
- public void save_on_one_issue_with_one_new_changelog() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- // changelog created at is null because it has just been created on the current analysis
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(null)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 1.0 * ONE_DAY_IN_MINUTES, 1.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_with_changelog() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", TWO_DAYS_IN_MINUTES, FIVE_DAYS_IN_MINUTES).setCreationDate(null),
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(fourDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * ONE_DAY_IN_MINUTES, 4.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_with_changelog_only_in_the_past() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(ONE_DAY_IN_MINUTES)).setChanges(
- newArrayList(
- // Change before all periods
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(elevenDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 0.0)));
- }
-
- @Test
- public void save_on_one_issue_with_changelog_having_null_value() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", null, FIVE_DAYS_IN_MINUTES).setCreationDate(null),
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, null).setCreationDate(fourDaysAgo),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * ONE_DAY_IN_MINUTES, 5.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_with_changelog_and_periods_have_no_dates() {
- when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, null), new Period(2, null)));
-
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", null, FIVE_DAYS_IN_MINUTES).setCreationDate(null),
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, null).setCreationDate(fourDaysAgo),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * ONE_DAY_IN_MINUTES, 5.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_with_changelog_having_not_only_technical_debt_changes() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs()
- .setDiff("actionPlan", "1.0", "1.1").setCreationDate(fourDaysAgo)
- .setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(fourDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 4.0 * ONE_DAY_IN_MINUTES, 4.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_issues_with_changelog() {
- Issue issue1 = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", TWO_DAYS_IN_MINUTES, FIVE_DAYS_IN_MINUTES).setCreationDate(rightNow),
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(fourDaysAgo),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
- Issue issue2 = new DefaultIssue().setKey("B").setCreationDate(tenDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(rightNow),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue1, issue2));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * ONE_DAY_IN_MINUTES, 7.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_without_changelog() {
- when(issuable.issues()).thenReturn(newArrayList(
- (Issue) new DefaultIssue().setKey("A").setCreationDate(nineDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)))
- );
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 5.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_one_issue_without_technical_debt_and_without_changelog() {
- when(issuable.issues()).thenReturn(newArrayList(
- (Issue) new DefaultIssue().setKey("A").setCreationDate(nineDaysAgo).setDebt(null))
- );
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 0.0)));
- }
-
- @Test
- public void save_on_one_issue_without_changelog_and_periods_have_no_dates() {
- when(timeMachineConfiguration.periods()).thenReturn(newArrayList(new Period(1, null), new Period(2, null)));
-
- when(issuable.issues()).thenReturn(newArrayList(
- (Issue) new DefaultIssue().setKey("A").setCreationDate(nineDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)))
- );
-
- decorator.decorate(resource, context);
-
- // remember : period1 is null, period2 is null
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * ONE_DAY_IN_MINUTES, 5.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_issues_without_changelog() {
- when(issuable.issues()).thenReturn(newArrayList(
- (Issue) new DefaultIssue().setKey("A").setCreationDate(nineDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)),
- new DefaultIssue().setKey("B").setCreationDate(fiveDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES))
- ));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 7.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void save_on_issues_with_changelog_and_issues_without_changelog() {
- // issue1 and issue2 have changelog
- Issue issue1 = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", TWO_DAYS_IN_MINUTES, FIVE_DAYS_IN_MINUTES).setCreationDate(rightNow),
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(fourDaysAgo),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
- Issue issue2 = new DefaultIssue().setKey("B").setCreationDate(tenDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES)).setChanges(
- newArrayList(
- new FieldDiffs().setDiff("technicalDebt", ONE_DAY_IN_MINUTES, TWO_DAYS_IN_MINUTES).setCreationDate(rightNow),
- new FieldDiffs().setDiff("technicalDebt", null, ONE_DAY_IN_MINUTES).setCreationDate(nineDaysAgo)
- )
- );
-
- // issue3 and issue4 have no changelog
- Issue issue3 = new DefaultIssue().setKey("C").setCreationDate(nineDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES));
- Issue issue4 = new DefaultIssue().setKey("D").setCreationDate(fiveDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES));
- when(issuable.issues()).thenReturn(newArrayList(issue1, issue2, issue3, issue4));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 5.0 * ONE_DAY_IN_MINUTES, 14.0 * ONE_DAY_IN_MINUTES)));
- }
-
- @Test
- public void not_save_if_measure_already_computed() {
- when(context.getMeasure(CoreMetrics.NEW_TECHNICAL_DEBT)).thenReturn(new Measure());
- when(issuable.issues()).thenReturn(newArrayList(
- (Issue) new DefaultIssue().setKey("A").setCreationDate(nineDaysAgo).setDebt(Duration.create(FIVE_DAYS_IN_MINUTES)),
- new DefaultIssue().setKey("B").setCreationDate(fiveDaysAgo).setDebt(Duration.create(TWO_DAYS_IN_MINUTES))
- ));
-
- decorator.decorate(resource, context);
-
- verify(context, never()).saveMeasure(argThat(new IsMeasure(CoreMetrics.NEW_TECHNICAL_DEBT)));
- }
-
- /**
- * SONAR-5059
- */
- @Test
- public void not_return_negative_debt() {
- Issue issue = new DefaultIssue().setKey("A").setCreationDate(tenDaysAgo).setDebt(Duration.create(ONE_DAY_IN_MINUTES)).setChanges(
- newArrayList(
- // changelog created at is null because it has just been created on the current analysis
- new FieldDiffs().setDiff("technicalDebt", TWO_DAYS_IN_MINUTES, ONE_DAY_IN_MINUTES).setCreationDate(null)
- )
- );
- when(issuable.issues()).thenReturn(newArrayList(issue));
-
- decorator.decorate(resource, context);
-
- // remember : period1 is 5daysAgo, period2 is 10daysAgo
- verify(context).saveMeasure(argThat(new IsVariationMeasure(CoreMetrics.NEW_TECHNICAL_DEBT, 0.0, 0.0)));
- }
-
-
- class IsVariationMeasure extends ArgumentMatcher<Measure> {
- Metric metric = null;
- Double var1 = null;
- Double var2 = null;
-
- public IsVariationMeasure(Metric metric, Double var1, Double var2) {
- this.metric = metric;
- this.var1 = var1;
- this.var2 = var2;
- }
-
- public boolean matches(Object o) {
- if (!(o instanceof Measure)) {
- return false;
- }
- Measure m = (Measure) o;
- return ObjectUtils.equals(metric, m.getMetric()) &&
- ObjectUtils.equals(var1, m.getVariation1()) &&
- ObjectUtils.equals(var2, m.getVariation2());
- }
- }
-
-}
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..356b9f9e436 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
@@ -19,6 +19,8 @@
*/
package org.sonar.batch.issue;
+import java.util.Calendar;
+import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
@@ -26,10 +28,8 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
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.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
@@ -37,11 +37,8 @@ import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.rules.Violation;
-import org.sonar.api.utils.Duration;
import org.sonar.api.utils.MessageException;
-
-import java.util.Calendar;
-import java.util.Date;
+import org.sonar.core.issue.DefaultIssue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
@@ -249,110 +246,6 @@ public class ModuleIssuesTest {
verifyZeroInteractions(cache);
}
- @Test
- public void set_debt_with_linear_function() {
- ruleBuilder.add(SQUID_RULE_KEY)
- .setName(SQUID_RULE_NAME)
- .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
- .setDebtRemediationFunction(DebtRemediationFunction.createLinear(Duration.create(10L)));
- activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
- initModuleIssues();
-
- Date analysisDate = new Date();
- when(project.getAnalysisDate()).thenReturn(analysisDate);
-
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(SQUID_RULE_KEY)
- .setSeverity(Severity.CRITICAL)
- .setEffortToFix(2d);
-
- when(filters.accept(issue)).thenReturn(true);
- moduleIssues.initAndAddIssue(issue);
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(cache).put(argument.capture());
- assertThat(argument.getValue().debt()).isEqualTo(Duration.create(20L));
- }
-
- @Test
- public void set_debt_with_linear_with_offset_function() {
- ruleBuilder.add(SQUID_RULE_KEY)
- .setName(SQUID_RULE_NAME)
- .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
- .setDebtRemediationFunction(DebtRemediationFunction.createLinearWithOffset(Duration.create(10L), Duration.create(25L)));
- activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
- initModuleIssues();
-
- Date analysisDate = new Date();
- when(project.getAnalysisDate()).thenReturn(analysisDate);
-
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(SQUID_RULE_KEY)
- .setSeverity(Severity.CRITICAL)
- .setEffortToFix(2d);
-
- when(filters.accept(issue)).thenReturn(true);
- moduleIssues.initAndAddIssue(issue);
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(cache).put(argument.capture());
- assertThat(argument.getValue().debt()).isEqualTo(Duration.create(45L));
- }
-
- @Test
- public void set_debt_with_constant_issue_function() {
- ruleBuilder.add(SQUID_RULE_KEY)
- .setName(SQUID_RULE_NAME)
- .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
- .setDebtRemediationFunction(DebtRemediationFunction.createConstantPerIssue(Duration.create(10L)));
- activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
- initModuleIssues();
-
- Date analysisDate = new Date();
- when(project.getAnalysisDate()).thenReturn(analysisDate);
-
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(SQUID_RULE_KEY)
- .setSeverity(Severity.CRITICAL)
- .setEffortToFix(null);
-
- when(filters.accept(issue)).thenReturn(true);
- moduleIssues.initAndAddIssue(issue);
-
- ArgumentCaptor<DefaultIssue> argument = ArgumentCaptor.forClass(DefaultIssue.class);
- verify(cache).put(argument.capture());
- assertThat(argument.getValue().debt()).isEqualTo(Duration.create(10L));
- }
-
- @Test
- public void fail_to_set_debt_with_constant_issue_function_when_effort_to_fix_is_set() {
- ruleBuilder.add(SQUID_RULE_KEY)
- .setName(SQUID_RULE_NAME)
- .setDebtSubCharacteristic("COMPILER_RELATED_PORTABILITY")
- .setDebtRemediationFunction(DebtRemediationFunction.createConstantPerIssue(Duration.create(25L)));
- activeRulesBuilder.create(SQUID_RULE_KEY).setSeverity(Severity.INFO).activate();
- initModuleIssues();
-
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(SQUID_RULE_KEY)
- .setSeverity(Severity.CRITICAL)
- .setEffortToFix(2d);
-
- when(filters.accept(issue)).thenReturn(true);
-
- try {
- moduleIssues.initAndAddIssue(issue);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class)
- .hasMessage("Rule 'squid:AvoidCycle' can not use 'Constant/issue' remediation function because this rule does not have a fixed remediation cost.");
- }
- }
-
/**
* Every rules and active rules has to be added in builders before creating ModuleIssues
*/
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..616c7fb6ed4 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;
@@ -246,7 +246,7 @@ public class IssueTrackingTest {
DefaultIssue newIssue = newDefaultIssue("1 branch need to be covered", 200, RuleKey.of("squid", "AvoidCycle"), null);
thrown
- .expectMessage("Invalid line number for issue DefaultIssue[key=<null>,componentUuid=<null>,componentKey=<null>,moduleUuid=<null>,moduleUuidPath=<null>,projectUuid=<null>,projectKey=<null>,ruleKey=squid:AvoidCycle,language=<null>,severity=<null>,manualSeverity=false,message=1 branch need to be covered,line=200,effortToFix=<null>,debt=<null>,status=OPEN,resolution=<null>,reporter=<null>,assignee=<null>,checksum=<null>,attributes=<null>,authorLogin=<null>,actionPlanKey=<null>,comments=<null>,tags=<null>,creationDate=<null>,updateDate=<null>,closeDate=<null>,currentChange=<null>,changes=<null>,isNew=true,endOfLife=false,onDisabledRule=false,isChanged=false,sendNotifications=false,selectedAt=<null>]. File has only 17 line(s)");
+ .expectMessage("Invalid line number for issue");
tracking.track(sourceHashHolder, Collections.<ServerIssue>emptyList(), newArrayList(newIssue));
}
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..a27ce7d2447 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
@@ -27,20 +27,16 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
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;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.issue.IssueCache;
-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;
@@ -52,29 +48,27 @@ public class IssuesPublisherTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- private IssueCache issueCache;
- private IssuesPublisher publisher;
+ IssueCache issueCache;
+ ProjectDefinition projectDef;
+ Project project;
- private ProjectDefinition root;
-
- private Project p;
+ IssuesPublisher underTest;
@Before
public void prepare() {
- root = ProjectDefinition.create().setKey("foo");
- p = new Project("foo").setAnalysisDate(new Date(1234567L));
+ projectDef = ProjectDefinition.create().setKey("foo");
+ project = new Project("foo").setAnalysisDate(new Date(1234567L));
BatchComponentCache componentCache = new BatchComponentCache();
org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
- componentCache.add(p, null).setSnapshot(new Snapshot().setId(2));
- componentCache.add(sampleFile, p);
+ componentCache.add(project, null).setSnapshot(new Snapshot().setId(2));
+ componentCache.add(sampleFile, project);
issueCache = mock(IssueCache.class);
when(issueCache.byComponent(anyString())).thenReturn(Collections.<DefaultIssue>emptyList());
- publisher = new IssuesPublisher(new ImmutableProjectReactor(root), componentCache, issueCache);
+ underTest = new IssuesPublisher(componentCache, issueCache);
}
@Test
- public void publishIssuesAndMetadata() throws Exception {
-
+ public void write_issues() throws Exception {
DefaultIssue issue1 = new DefaultIssue();
issue1.setKey("uuid");
issue1.setSeverity("MAJOR");
@@ -86,7 +80,6 @@ public class IssuesPublisherTest {
issue2.setLine(2);
issue2.setMessage("msg");
issue2.setEffortToFix(2d);
- issue2.setDebt(Duration.create(2));
issue2.setResolution("FIXED");
issue2.setStatus("RESOLVED");
issue2.setChecksum("checksum");
@@ -104,85 +97,11 @@ public class IssuesPublisherTest {
File outputDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(outputDir);
- publisher.publish(writer);
+ underTest.publish(writer);
BatchReportReader reader = new BatchReportReader(outputDir);
- 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);
-
- }
-
- @Test
- public void publishMatadataWithBranch() throws Exception {
- root.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
- p.setKey("foo:myBranch");
- p.setEffectiveKey("foo:myBranch");
-
- File outputDir = temp.newFolder();
- BatchReportWriter writer = new BatchReportWriter(outputDir);
-
- publisher.publish(writer);
-
- BatchReportReader reader = new BatchReportReader(outputDir);
- Metadata metadata = reader.readMetadata();
- 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/report/MeasuresPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java
index 658cafcc62d..c4faec31bce 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/report/MeasuresPublisherTest.java
@@ -19,6 +19,11 @@
*/
package org.sonar.batch.report;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -30,23 +35,14 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metric.Level;
import org.sonar.api.measures.Metric.ValueType;
import org.sonar.api.measures.MetricFinder;
-import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.technicaldebt.batch.Characteristic;
import org.sonar.batch.index.BatchComponentCache;
import org.sonar.batch.protocol.output.BatchReportReader;
import org.sonar.batch.protocol.output.BatchReportWriter;
import org.sonar.batch.scan.measure.MeasureCache;
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-
+import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -85,12 +81,8 @@ public class MeasuresPublisherTest {
@Test
public void publishMeasures() throws Exception {
-
Measure measure1 = new Measure<>(CoreMetrics.COVERAGE)
.setValue(2.0)
- .setAlertStatus(Level.ERROR)
- .setAlertText("Foo")
- .setCharacteristic(mock(Characteristic.class))
.setPersonId(2);
// No value on new_xxx
Measure measure2 = new Measure<>(CoreMetrics.NEW_BLOCKER_VIOLATIONS)
@@ -103,9 +95,6 @@ public class MeasuresPublisherTest {
Measure manual = new Measure<>(new Metric<>("manual_metric", ValueType.BOOL))
.setValue(1.0)
.setDescription("Manual");
- // Rule measure
- RuleMeasure ruleMeasureBySeverity = RuleMeasure.createForPriority(CoreMetrics.NCLOC, RulePriority.BLOCKER, 1.0);
- RuleMeasure ruleMeasureByRule = RuleMeasure.createForRule(CoreMetrics.NCLOC, RuleKey.of("squid", "S12345"), 1.0);
// Sqale rating have both a value and a data
Measure rating = new Measure<>(CoreMetrics.SQALE_RATING)
.setValue(2.0)
@@ -116,8 +105,7 @@ public class MeasuresPublisherTest {
// String value
Measure stringMeasure = new Measure<>(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION)
.setData("foo bar");
-
- when(measureCache.byResource(sampleFile)).thenReturn(Arrays.asList(measure1, measure2, manual, ruleMeasureBySeverity, ruleMeasureByRule, rating, longMeasure, stringMeasure));
+ when(measureCache.byResource(sampleFile)).thenReturn(asList(measure1, measure2, manual, rating, longMeasure, stringMeasure));
File outputDir = temp.newFolder();
BatchReportWriter writer = new BatchReportWriter(outputDir);
@@ -128,10 +116,8 @@ public class MeasuresPublisherTest {
assertThat(reader.readComponentMeasures(1)).hasSize(0);
List<org.sonar.batch.protocol.output.BatchReport.Measure> componentMeasures = reader.readComponentMeasures(2);
- assertThat(componentMeasures).hasSize(8);
+ assertThat(componentMeasures).hasSize(6);
assertThat(componentMeasures.get(0).getDoubleValue()).isEqualTo(2.0);
- assertThat(componentMeasures.get(0).getAlertStatus()).isEqualTo("ERROR");
- assertThat(componentMeasures.get(0).getAlertText()).isEqualTo("Foo");
assertThat(componentMeasures.get(0).getPersonId()).isEqualTo(2);
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/MetadataPublisherTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/MetadataPublisherTest.java
new file mode 100644
index 00000000000..23f9860660a
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/report/MetadataPublisherTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.report;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Date;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.batch.rule.internal.DefaultActiveRules;
+import org.sonar.api.batch.rule.internal.NewActiveRule;
+import org.sonar.api.database.model.Snapshot;
+import org.sonar.api.resources.Project;
+import org.sonar.batch.index.BatchComponentCache;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.batch.protocol.output.BatchReportReader;
+import org.sonar.batch.protocol.output.BatchReportWriter;
+import org.sonar.batch.scan.ImmutableProjectReactor;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MetadataPublisherTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ ActiveRules activeRules = new DefaultActiveRules(Collections.<NewActiveRule>emptyList());
+ ProjectDefinition projectDef;
+ Project project;
+
+ MetadataPublisher underTest;
+
+ @Before
+ public void prepare() {
+ projectDef = ProjectDefinition.create().setKey("foo");
+ project = new Project("foo").setAnalysisDate(new Date(1234567L));
+ BatchComponentCache componentCache = new BatchComponentCache();
+ org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
+ componentCache.add(project, null).setSnapshot(new Snapshot().setId(2));
+ componentCache.add(sampleFile, project);
+ underTest = new MetadataPublisher(componentCache, new ImmutableProjectReactor(projectDef), activeRules);
+ }
+
+ @Test
+ public void write_metadata() throws Exception {
+
+ File outputDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(outputDir);
+
+ underTest.publish(writer);
+
+ BatchReportReader reader = new BatchReportReader(outputDir);
+ BatchReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
+ assertThat(metadata.getProjectKey()).isEqualTo("foo");
+
+ }
+
+ @Test
+ public void write_project_branch() throws Exception {
+ projectDef.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
+ project.setKey("foo:myBranch");
+ project.setEffectiveKey("foo:myBranch");
+
+ File outputDir = temp.newFolder();
+ BatchReportWriter writer = new BatchReportWriter(outputDir);
+
+ underTest.publish(writer);
+
+ BatchReportReader reader = new BatchReportReader(outputDir);
+ BatchReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
+ assertThat(metadata.getProjectKey()).isEqualTo("foo");
+ assertThat(metadata.getBranch()).isEqualTo("myBranch");
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java
deleted file mode 100644
index 79ba7df94bc..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java
+++ /dev/null
@@ -1,215 +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.rule;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.batch.debt.DebtRemediationFunction;
-import org.sonar.api.batch.debt.internal.DefaultDebtCharacteristic;
-import org.sonar.api.batch.debt.internal.DefaultDebtModel;
-import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.batch.rule.RuleParam;
-import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.config.Settings;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.utils.Duration;
-import org.sonar.api.utils.Durations;
-import org.sonar.core.persistence.AbstractDaoTestCase;
-import org.sonar.core.rule.RuleDao;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-@RunWith(MockitoJUnitRunner.class)
-public class RulesProviderTest extends AbstractDaoTestCase {
-
- @Mock
- Durations durations;
-
- RuleDao ruleDao;
-
- DefaultDebtModel debtModel;
-
- RulesProvider provider;
-
- @Before
- public void setUp() {
- debtModel = new DefaultDebtModel()
- .addCharacteristic(new DefaultDebtCharacteristic()
- .setId(100)
- .setKey("MEMORY_EFFICIENCY")
- .setName("Memory use")
- .setOrder(1))
- .addCharacteristic(new DefaultDebtCharacteristic()
- .setId(101)
- .setKey("EFFICIENCY")
- .setName("Efficiency")
- .setParentId(100));
- debtModel
- .addCharacteristic(new DefaultDebtCharacteristic()
- .setId(102)
- .setKey("COMPILER_RELATED_PORTABILITY")
- .setName("Compiler")
- .setOrder(1))
- .addCharacteristic(new DefaultDebtCharacteristic()
- .setId(103)
- .setKey("PORTABILITY")
- .setName("Portability")
- .setParentId(102));
-
- durations = new Durations(new Settings().setProperty("sonar.technicalDebt.hoursInDay", 8), null);
- ruleDao = new RuleDao(getMyBatis());
-
- provider = new RulesProvider();
- }
-
- @Test
- public void build_rules() {
- setupData("shared");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- assertThat(rules.findAll()).hasSize(1);
- assertThat(rules.findByRepository("checkstyle")).hasSize(1);
- assertThat(rules.findByRepository("unknown")).isEmpty();
-
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule).isNotNull();
- assertThat(rule.key()).isEqualTo(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.name()).isEqualTo("Avoid Null");
- assertThat(rule.description()).isEqualTo("Should avoid NULL");
- assertThat(rule.severity()).isEqualTo(Severity.MINOR);
- assertThat(rule.internalKey()).isNull();
- assertThat(rule.params()).hasSize(1);
-
- RuleParam param = rule.param("myParameter");
- assertThat(param).isNotNull();
- assertThat(param.description()).isEqualTo("My Parameter");
- }
-
- @Test
- public void build_rules_with_default_debt_definitions() {
- setupData("build_rules_with_default_debt_definitions");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isEqualTo("EFFICIENCY");
- assertThat(rule.debtRemediationFunction()).isEqualTo(DebtRemediationFunction.createLinearWithOffset(Duration.decode("5d", 8), Duration.decode("10h", 8)));
- }
-
- @Test
- public void build_rules_with_overridden_debt_definitions() {
- setupData("build_rules_with_overridden_debt_definitions");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isEqualTo("PORTABILITY");
- assertThat(rule.debtRemediationFunction()).isEqualTo(DebtRemediationFunction.createLinear(Duration.decode("2h", 8)));
- }
-
- @Test
- public void build_rules_with_default_and_overridden_debt_definitions() {
- setupData("build_rules_with_default_and_overridden_debt_definitions");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- // As both default columns and user columns on debt are set, user debt columns should be used
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isEqualTo("PORTABILITY");
- assertThat(rule.debtRemediationFunction()).isEqualTo(DebtRemediationFunction.createLinear(Duration.decode("2h", 8)));
- }
-
- @Test
- public void build_rules_with_default_characteristic_and_overridden_function() {
- setupData("build_rules_with_default_characteristic_and_overridden_function");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- // As both default columns and user columns on debt are set, user debt columns should be used
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isEqualTo("PORTABILITY");
- assertThat(rule.debtRemediationFunction()).isEqualTo(DebtRemediationFunction.createLinear(Duration.decode("2h", 8)));
- }
-
- @Test
- public void build_rules_with_overridden_characteristic_and_default_function() {
- setupData("build_rules_with_overridden_characteristic_and_default_function");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- // As both default columns and user columns on debt are set, user debt columns should be used
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isEqualTo("PORTABILITY");
- assertThat(rule.debtRemediationFunction()).isEqualTo(DebtRemediationFunction.createLinear(Duration.decode("2h", 8)));
- }
-
- @Test
- public void build_rules_with_disable_characteristic() {
- setupData("build_rules_with_disable_characteristic");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isNull();
- assertThat(rule.debtRemediationFunction()).isNull();
- }
-
- @Test
- public void build_rules_with_default_characteristic_and_disable_characteristic() {
- setupData("build_rules_with_default_characteristic_and_disable_characteristic");
-
- Rules rules = provider.provide(ruleDao, debtModel, durations);
-
- Rule rule = rules.find(RuleKey.of("checkstyle", "AvoidNull"));
- assertThat(rule.debtSubCharacteristic()).isNull();
- assertThat(rule.debtRemediationFunction()).isNull();
- }
-
- @Test
- public void fail_if_characteristic_not_found() {
- setupData("fail_if_characteristic_not_found");
-
- try {
- provider.provide(ruleDao, debtModel, durations);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Sub characteristic id '999' on rule 'checkstyle:AvoidNull' has not been found");
- }
- }
-
- @Test
- public void fail_if_no_function() {
- setupData("fail_if_no_function");
-
- try {
- provider.provide(ruleDao, debtModel, durations);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Remediation function should not be null on rule 'checkstyle:AvoidNull'");
- }
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java
index 0575a850182..505ee23191e 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java
@@ -19,7 +19,8 @@
*/
package org.sonar.batch.scan.measure;
-import org.sonar.batch.index.AbstractCachesTest;
+import java.util.Date;
+import java.util.Iterator;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.junit.Before;
import org.junit.Rule;
@@ -29,22 +30,13 @@ import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric.Level;
-import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Directory;
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.RulePriority;
-import org.sonar.api.technicaldebt.batch.Characteristic;
-import org.sonar.api.technicaldebt.batch.Requirement;
-import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
-import org.sonar.api.technicaldebt.batch.internal.DefaultCharacteristic;
+import org.sonar.batch.index.AbstractCachesTest;
import org.sonar.batch.index.Cache.Entry;
-import java.util.Date;
-import java.util.Iterator;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -55,8 +47,6 @@ public class MeasureCacheTest extends AbstractCachesTest {
private MetricFinder metricFinder;
- private TechnicalDebtModel techDebtModel;
-
private MeasureCache measureCache;
@Before
@@ -64,8 +54,7 @@ public class MeasureCacheTest extends AbstractCachesTest {
super.start();
metricFinder = mock(MetricFinder.class);
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
- techDebtModel = mock(TechnicalDebtModel.class);
- measureCache = new MeasureCache(caches, metricFinder, techDebtModel);
+ measureCache = new MeasureCache(caches, metricFinder);
}
@Test
@@ -73,7 +62,6 @@ public class MeasureCacheTest extends AbstractCachesTest {
Project p = new Project("struts");
assertThat(measureCache.entries()).hasSize(0);
-
assertThat(measureCache.byResource(p)).hasSize(0);
Measure m = new Measure(CoreMetrics.NCLOC, 1.0);
@@ -89,13 +77,6 @@ public class MeasureCacheTest extends AbstractCachesTest {
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
-
- Measure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
- measureCache.put(p, mRule);
-
- assertThat(measureCache.entries()).hasSize(2);
-
- assertThat(measureCache.byResource(p)).hasSize(2);
}
@Test
@@ -112,7 +93,7 @@ public class MeasureCacheTest extends AbstractCachesTest {
for (int i = 0; i < 1_048_575; i++) {
data.append("a");
}
-
+
m.setData(data.toString());
measureCache.put(p, m);
@@ -127,12 +108,6 @@ public class MeasureCacheTest extends AbstractCachesTest {
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
-
- RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
- mRule.setRuleKey(RuleKey.of("repo", "rule"));
- measureCache.put(p, mRule);
-
- assertThat(measureCache.entries()).hasSize(2);
}
/**
@@ -166,11 +141,6 @@ public class MeasureCacheTest extends AbstractCachesTest {
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);
- RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
- mRule.setRuleKey(RuleKey.of("repo", "rule"));
- measureCache.put(p, mRule);
-
- assertThat(measureCache.entries()).hasSize(2);
}
@Test
@@ -203,17 +173,12 @@ public class MeasureCacheTest extends AbstractCachesTest {
assertThat(measureCache.byResource(p)).hasSize(0);
Measure m1 = new Measure(CoreMetrics.NCLOC, 1.0);
- Measure m2 = new Measure(CoreMetrics.NCLOC, 1.0).setCharacteristic(new DefaultCharacteristic().setKey("charac"));
- Measure m3 = new Measure(CoreMetrics.NCLOC, 1.0).setPersonId(2);
- Measure m4 = new RuleMeasure(CoreMetrics.NCLOC, RuleKey.of("repo", "rule"), RulePriority.BLOCKER, null);
+ Measure m2 = new Measure(CoreMetrics.NCLOC, 1.0).setPersonId(2);
measureCache.put(p, m1);
measureCache.put(p, m2);
- measureCache.put(p, m3);
- measureCache.put(p, m4);
- assertThat(measureCache.entries()).hasSize(4);
-
- assertThat(measureCache.byResource(p)).hasSize(4);
+ assertThat(measureCache.entries()).hasSize(2);
+ assertThat(measureCache.byResource(p)).hasSize(2);
}
@Test
@@ -259,29 +224,14 @@ public class MeasureCacheTest extends AbstractCachesTest {
public void test_measure_coder() throws Exception {
Resource file1 = File.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
- Measure measure = new Measure(CoreMetrics.NCLOC, 1.786, 5);
- measureCache.put(file1, measure);
-
- Measure savedMeasure = measureCache.byResource(file1).iterator().next();
-
- assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
-
- measure = new Measure(CoreMetrics.NCLOC);
+ Measure measure = new Measure(CoreMetrics.NCLOC, 3.14);
measure.setData("data");
measure.setAlertStatus(Level.ERROR);
measure.setAlertText("alert");
- Characteristic c = mock(Characteristic.class);
- when(c.id()).thenReturn(1);
- when(techDebtModel.characteristicById(1)).thenReturn(c);
- measure.setCharacteristic(c);
measure.setDate(new Date());
measure.setDescription("description");
measure.setPersistenceMode(null);
measure.setPersonId(3);
- Requirement r = mock(Requirement.class);
- when(r.id()).thenReturn(7);
- when(techDebtModel.requirementsById(7)).thenReturn(r);
- measure.setRequirement(r);
measure.setUrl("http://foo");
measure.setVariation1(11.0);
measure.setVariation2(12.0);
@@ -290,7 +240,7 @@ public class MeasureCacheTest extends AbstractCachesTest {
measure.setVariation5(15.0);
measureCache.put(file1, measure);
- savedMeasure = measureCache.byResource(file1).iterator().next();
+ Measure savedMeasure = measureCache.byResource(file1).iterator().next();
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();
}
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 b03d9baf3bd..c42ed5031d9 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
@@ -169,7 +169,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)
@@ -180,7 +180,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);
@@ -192,7 +192,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)
@@ -202,7 +202,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();
@@ -212,7 +212,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()
@@ -223,7 +223,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();