@@ -33,9 +33,9 @@ import org.sonar.api.rule.RuleKey; | |||
import org.sonar.batch.scan.LastSnapshots; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.db.IssueDto; | |||
import org.sonar.plugins.core.timemachine.SourceChecksum; | |||
import org.sonar.plugins.core.timemachine.ViolationTrackingBlocksRecognizer; | |||
import org.sonar.plugins.core.timemachine.tracking.*; | |||
import org.sonar.plugins.core.issue.tracking.*; | |||
import org.sonar.plugins.core.issue.tracking.SourceChecksum; | |||
import org.sonar.plugins.core.issue.tracking.ViolationTrackingBlocksRecognizer; | |||
import javax.annotation.Nullable; | |||
import java.util.*; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Wraps a {@link Sequence} to assign hash codes to elements. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Wrap another {@link SequenceComparator} for use with {@link HashedSequence}. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Wraps a {@link Sequence} to assign hash codes to elements. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Wrap another {@link SequenceComparator} for use with {@link RollingHashSequence}. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Arbitrary sequence of elements. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Equivalence function for a {@link Sequence}. |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import com.google.common.collect.Lists; | |||
import org.apache.commons.codec.digest.DigestUtils; |
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import com.google.common.collect.Lists; | |||
@@ -17,7 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
/** | |||
* Equivalence function for {@link StringText}. |
@@ -17,13 +17,13 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.plugins.core.timemachine.tracking.HashedSequence; | |||
import org.sonar.plugins.core.timemachine.tracking.HashedSequenceComparator; | |||
import org.sonar.plugins.core.timemachine.tracking.StringText; | |||
import org.sonar.plugins.core.timemachine.tracking.StringTextComparator; | |||
import org.sonar.plugins.core.issue.tracking.HashedSequence; | |||
import org.sonar.plugins.core.issue.tracking.HashedSequenceComparator; | |||
import org.sonar.plugins.core.issue.tracking.StringText; | |||
import org.sonar.plugins.core.issue.tracking.StringTextComparator; | |||
public class ViolationTrackingBlocksRecognizer { | |||
@@ -19,5 +19,5 @@ | |||
*/ | |||
@javax.annotation.ParametersAreNonnullByDefault | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
@@ -17,9 +17,13 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import org.junit.Test; | |||
import org.sonar.plugins.core.issue.tracking.RollingHashSequence; | |||
import org.sonar.plugins.core.issue.tracking.RollingHashSequenceComparator; | |||
import org.sonar.plugins.core.issue.tracking.StringText; | |||
import org.sonar.plugins.core.issue.tracking.StringTextComparator; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -17,9 +17,10 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import org.junit.Test; | |||
import org.sonar.plugins.core.issue.tracking.SourceChecksum; | |||
import java.util.List; | |||
@@ -17,9 +17,11 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import org.junit.Test; | |||
import org.sonar.plugins.core.issue.tracking.StringText; | |||
import org.sonar.plugins.core.issue.tracking.StringTextComparator; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -17,9 +17,10 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine.tracking; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import org.junit.Test; | |||
import org.sonar.plugins.core.issue.tracking.StringText; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -17,9 +17,10 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.core.timemachine; | |||
package org.sonar.plugins.core.issue.tracking; | |||
import org.junit.Test; | |||
import org.sonar.plugins.core.issue.tracking.ViolationTrackingBlocksRecognizer; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@@ -28,7 +28,7 @@ import org.sonar.batch.events.EventBus; | |||
import org.sonar.batch.index.DefaultIndex; | |||
import org.sonar.batch.index.PersistenceManager; | |||
import org.sonar.batch.index.ScanPersister; | |||
import org.sonar.batch.report.SonarReport; | |||
import org.sonar.batch.scan.JsonReport; | |||
import org.sonar.batch.scan.filesystem.FileSystemLogger; | |||
import org.sonar.batch.scan.maven.MavenPhaseExecutor; | |||
import org.sonar.batch.scan.maven.MavenPluginsConfigurator; | |||
@@ -60,14 +60,14 @@ public final class PhaseExecutor { | |||
private ProjectInitializer pi; | |||
private ScanPersister[] persisters; | |||
private FileSystemLogger fsLogger; | |||
private final SonarReport sonarReport; | |||
private final JsonReport jsonReport; | |||
public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor, | |||
MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, | |||
PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, | |||
PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index, | |||
EventBus eventBus, UpdateStatusJob updateStatusJob, ProjectInitializer pi, | |||
ScanPersister[] persisters, FileSystemLogger fsLogger, SonarReport sonarReport) { | |||
ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport) { | |||
this.phases = phases; | |||
this.decoratorsExecutor = decoratorsExecutor; | |||
this.mavenPhaseExecutor = mavenPhaseExecutor; | |||
@@ -83,16 +83,16 @@ public final class PhaseExecutor { | |||
this.pi = pi; | |||
this.persisters = persisters; | |||
this.fsLogger = fsLogger; | |||
this.sonarReport = sonarReport; | |||
this.jsonReport = jsonReport; | |||
} | |||
public PhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, MavenPhaseExecutor mavenPhaseExecutor, | |||
MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, | |||
PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, | |||
PersistenceManager persistenceManager, SensorContext sensorContext, DefaultIndex index, | |||
EventBus eventBus, ProjectInitializer pi, ScanPersister[] persisters, FileSystemLogger fsLogger, SonarReport sonarReport) { | |||
EventBus eventBus, ProjectInitializer pi, ScanPersister[] persisters, FileSystemLogger fsLogger, JsonReport jsonReport) { | |||
this(phases, decoratorsExecutor, mavenPhaseExecutor, mavenPluginsConfigurator, initializersExecutor, postJobsExecutor, | |||
sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, persisters, fsLogger, sonarReport); | |||
sensorsExecutor, persistenceManager, sensorContext, index, eventBus, null, pi, persisters, fsLogger, jsonReport); | |||
} | |||
/** | |||
@@ -121,7 +121,7 @@ public final class PhaseExecutor { | |||
persistenceManager.setDelayedMode(false); | |||
if (module.isRoot()) { | |||
sonarReport.execute(); | |||
jsonReport.execute(); | |||
LOGGER.info("Store results in database"); | |||
for (ScanPersister persister : persisters) { |
@@ -18,7 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.report; | |||
package org.sonar.batch.scan; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.io.Closeables; | |||
@@ -28,7 +28,6 @@ import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.BatchComponent; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.platform.Server; | |||
import org.sonar.api.rule.RuleKey; | |||
@@ -36,7 +35,6 @@ import org.sonar.api.scan.filesystem.ModuleFileSystem; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.issue.ScanIssues; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.issue.DefaultIssue; | |||
@@ -52,16 +50,16 @@ import static com.google.common.collect.Sets.newHashSet; | |||
* @since 3.6 | |||
*/ | |||
public class SonarReport implements BatchComponent { | |||
public class JsonReport implements BatchComponent { | |||
private static final Logger LOG = LoggerFactory.getLogger(SonarReport.class); | |||
private static final Logger LOG = LoggerFactory.getLogger(JsonReport.class); | |||
private final Settings settings; | |||
private final ModuleFileSystem fileSystem; | |||
private final Server server; | |||
private final RuleI18nManager ruleI18nManager; | |||
private final IssueCache issueCache; | |||
public SonarReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager, IssueCache issueCache) { | |||
public JsonReport(Settings settings, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager, IssueCache issueCache) { | |||
this.settings = settings; | |||
this.fileSystem = fileSystem; | |||
this.server = server; |
@@ -44,7 +44,6 @@ import org.sonar.batch.issue.ScanIssues; | |||
import org.sonar.batch.local.DryRunExporter; | |||
import org.sonar.batch.phases.PhaseExecutor; | |||
import org.sonar.batch.phases.PhasesTimeProfiler; | |||
import org.sonar.batch.report.SonarReport; | |||
import org.sonar.batch.scan.filesystem.*; | |||
import org.sonar.core.component.ScanPerspectives; | |||
@@ -107,7 +106,7 @@ public class ModuleScanContainer extends ComponentContainer { | |||
ViolationFilters.class, | |||
ResourceFilters.class, | |||
DryRunExporter.class, | |||
SonarReport.class, | |||
JsonReport.class, | |||
new ProfileProvider(), | |||
// issues |
@@ -18,7 +18,7 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.batch.report; | |||
package org.sonar.batch.scan; | |||
import com.google.common.collect.Lists; | |||
import org.json.simple.JSONArray; | |||
@@ -36,6 +36,7 @@ import org.sonar.api.rules.Rule; | |||
import org.sonar.api.scan.filesystem.ModuleFileSystem; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.batch.issue.IssueCache; | |||
import org.sonar.batch.scan.JsonReport; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.issue.DefaultIssue; | |||
@@ -48,11 +49,12 @@ import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class SonarReportTest { | |||
public class JsonReportTest { | |||
@org.junit.Rule | |||
public TemporaryFolder temporaryFolder = new TemporaryFolder(); | |||
SonarReport sonarReport; | |||
JsonReport jsonReport; | |||
Resource resource = mock(Resource.class); | |||
ModuleFileSystem fileSystem = mock(ModuleFileSystem.class); | |||
Server server = mock(Server.class); | |||
@@ -67,7 +69,7 @@ public class SonarReportTest { | |||
settings = new Settings(); | |||
settings.setProperty(CoreProperties.DRY_RUN, true); | |||
sonarReport = new SonarReport(settings, fileSystem, server, ruleI18nManager, issueCache); | |||
jsonReport = new JsonReport(settings, fileSystem, server, ruleI18nManager, issueCache); | |||
} | |||
@Test | |||
@@ -78,9 +80,9 @@ public class SonarReportTest { | |||
.setRuleKey(RuleKey.of("squid", "AvoidCycle")) | |||
.setNew(false); | |||
when(sonarReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
JSONObject json = sonarReport.createJson(); | |||
JSONObject json = jsonReport.createJson(); | |||
assertThat(json.values()).hasSize(4); | |||
assertThat(json.get("version")).isEqualTo("3.6"); | |||
@@ -106,9 +108,9 @@ public class SonarReportTest { | |||
.setRuleKey(RuleKey.of("squid", "AvoidCycle")) | |||
.setNew(false); | |||
when(sonarReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
JSONObject json = sonarReport.createJson(); | |||
JSONObject json = jsonReport.createJson(); | |||
assertThat(json.get("version")).isEqualTo("3.6"); | |||
assertThat(json.get("components")).isNotNull(); | |||
@@ -138,9 +140,9 @@ public class SonarReportTest { | |||
.setCloseDate(DateUtils.parseDate("2013-04-26")) | |||
.setNew(false); | |||
when(sonarReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
JSONObject json = sonarReport.createJson(); | |||
JSONObject json = jsonReport.createJson(); | |||
assertThat(json.get("issues")).isNotNull(); | |||
JSONArray issues = (JSONArray) json.get("issues"); | |||
assertThat(issues).hasSize(1); | |||
@@ -172,9 +174,9 @@ public class SonarReportTest { | |||
.setRuleKey(RuleKey.of("squid", "AvoidCycle")); | |||
when(ruleI18nManager.getName("squid", "AvoidCycle", Locale.getDefault())).thenReturn("Avoid Cycle"); | |||
when(sonarReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
JSONObject root = sonarReport.createJson(); | |||
JSONObject root = jsonReport.createJson(); | |||
assertThat(root.get("rules")).isNotNull(); | |||
JSONArray rules = (JSONArray) root.get("rules"); | |||
@@ -196,9 +198,9 @@ public class SonarReportTest { | |||
.setLine(null) | |||
.setRuleKey(RuleKey.of("squid", "AvoidCycle")); | |||
when(sonarReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
when(jsonReport.getIssues()).thenReturn(Lists.<DefaultIssue>newArrayList(issue)); | |||
JSONObject json = sonarReport.createJson(); | |||
JSONObject json = jsonReport.createJson(); | |||
assertThat(json.get("issues")).isNotNull(); | |||
JSONArray issues = (JSONArray) json.get("issues"); | |||
@@ -209,9 +211,9 @@ public class SonarReportTest { | |||
@Test | |||
public void should_ignore_resources_without_issue() { | |||
when(sonarReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
JSONObject json = sonarReport.createJson(); | |||
JSONObject json = jsonReport.createJson(); | |||
assertThat(json.get("version")).isEqualTo("3.6"); | |||
assertThat(json.get("components")).isNotNull(); | |||
@@ -229,12 +231,12 @@ public class SonarReportTest { | |||
Rule rule = Rule.create("squid", "AvoidCycle"); | |||
when(ruleI18nManager.getName(rule, Locale.getDefault())).thenReturn("Avoid Cycle"); | |||
when(sonarReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
when(jsonReport.getIssues()).thenReturn(Collections.<DefaultIssue>emptyList()); | |||
settings.setProperty("sonar.report.export.path", "output.json"); | |||
when(fileSystem.workingDir()).thenReturn(sonarDirectory); | |||
sonarReport.execute(); | |||
jsonReport.execute(); | |||
assertThat(new File(sonarDirectory, "output.json")).exists(); | |||
} |
@@ -1,255 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.review; | |||
import com.google.common.base.Preconditions; | |||
import org.apache.commons.lang.builder.ToStringBuilder; | |||
import org.apache.commons.lang.builder.ToStringStyle; | |||
import javax.annotation.Nullable; | |||
import java.util.Date; | |||
/** | |||
* @since 2.13 | |||
*/ | |||
public final class ReviewDto { | |||
public static final String STATUS_OPEN = "OPEN"; | |||
public static final String STATUS_REOPENED = "REOPENED"; | |||
public static final String STATUS_RESOLVED = "RESOLVED"; | |||
public static final String STATUS_CLOSED = "CLOSED"; | |||
public static final String RESOLUTION_FALSE_POSITIVE = "FALSE-POSITIVE"; | |||
public static final String RESOLUTION_FIXED = "FIXED"; | |||
private Long id; | |||
private Integer userId; | |||
private Long assigneeId; | |||
private String title; | |||
private String status; | |||
private String resolution; | |||
private Integer violationPermanentId; | |||
private Integer projectId; | |||
private Integer resourceId; | |||
private Integer line; | |||
private Date createdAt; | |||
private Date updatedAt; | |||
private String severity; | |||
private Integer ruleId; | |||
private boolean manualViolation; | |||
private boolean manualSeverity; | |||
private Integer actionPlanId; | |||
private String data; | |||
public Long getId() { | |||
return id; | |||
} | |||
public ReviewDto setId(Long id) { | |||
this.id = id; | |||
return this; | |||
} | |||
public Integer getUserId() { | |||
return userId; | |||
} | |||
public ReviewDto setUserId(Integer userId) { | |||
this.userId = userId; | |||
return this; | |||
} | |||
public Long getAssigneeId() { | |||
return assigneeId; | |||
} | |||
public ReviewDto setAssigneeId(@Nullable Long assigneeId) { | |||
this.assigneeId = assigneeId; | |||
return this; | |||
} | |||
public String getTitle() { | |||
return title; | |||
} | |||
public ReviewDto setTitle(String title) { | |||
this.title = title; | |||
return this; | |||
} | |||
public String getStatus() { | |||
return status; | |||
} | |||
public ReviewDto setStatus(@Nullable String status) { | |||
this.status = status; | |||
return this; | |||
} | |||
public String getResolution() { | |||
return resolution; | |||
} | |||
public ReviewDto setResolution(@Nullable String resolution) { | |||
this.resolution = resolution; | |||
return this; | |||
} | |||
public Integer getViolationPermanentId() { | |||
return violationPermanentId; | |||
} | |||
public ReviewDto setViolationPermanentId(Integer violationPermanentId) { | |||
this.violationPermanentId = violationPermanentId; | |||
return this; | |||
} | |||
public Integer getProjectId() { | |||
return projectId; | |||
} | |||
public ReviewDto setProjectId(Integer projectId) { | |||
this.projectId = projectId; | |||
return this; | |||
} | |||
public Integer getResourceId() { | |||
return resourceId; | |||
} | |||
public ReviewDto setResourceId(Integer resourceId) { | |||
this.resourceId = resourceId; | |||
return this; | |||
} | |||
public Integer getLine() { | |||
return line; | |||
} | |||
public ReviewDto setLine(@Nullable Integer line) { | |||
this.line = line; | |||
return this; | |||
} | |||
public Date getCreatedAt() { | |||
return createdAt; | |||
} | |||
public ReviewDto setCreatedAt(Date createdAt) { | |||
this.createdAt = createdAt; | |||
return this; | |||
} | |||
public Date getUpdatedAt() { | |||
return updatedAt; | |||
} | |||
public ReviewDto setUpdatedAt(Date updatedAt) { | |||
this.updatedAt = updatedAt; | |||
return this; | |||
} | |||
public String getSeverity() { | |||
return severity; | |||
} | |||
public ReviewDto setSeverity(@Nullable String severity) { | |||
this.severity = severity; | |||
return this; | |||
} | |||
public Integer getRuleId() { | |||
return ruleId; | |||
} | |||
public ReviewDto setRuleId(Integer ruleId) { | |||
this.ruleId = ruleId; | |||
return this; | |||
} | |||
public boolean getManualViolation() { | |||
return manualViolation; | |||
} | |||
public boolean isManualViolation() { | |||
return manualViolation; | |||
} | |||
public ReviewDto setManualViolation(boolean b) { | |||
this.manualViolation = b; | |||
return this; | |||
} | |||
public boolean getManualSeverity() { | |||
return manualSeverity; | |||
} | |||
public ReviewDto setManualSeverity(boolean b) { | |||
this.manualSeverity = b; | |||
return this; | |||
} | |||
public boolean isManualSeverity() { | |||
return manualSeverity; | |||
} | |||
public Integer getActionPlanId() { | |||
return actionPlanId; | |||
} | |||
public ReviewDto setActionPlanId(@Nullable Integer i) { | |||
this.actionPlanId = i; | |||
return this; | |||
} | |||
public String getData() { | |||
return data; | |||
} | |||
public ReviewDto setData(String s) { | |||
Preconditions.checkArgument(s == null || s.length() <= 4000, | |||
"Review data must not exceed 4000 characters: " + s); | |||
this.data = s; | |||
return this; | |||
} | |||
@Override | |||
public String toString() { | |||
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); | |||
} | |||
@Override | |||
public boolean equals(Object o) { | |||
if (this == o) { | |||
return true; | |||
} | |||
if (o == null || getClass() != o.getClass()) { | |||
return false; | |||
} | |||
ReviewDto reviewDto = (ReviewDto) o; | |||
return !(id != null ? !id.equals(reviewDto.id) : reviewDto.id != null); | |||
} | |||
@Override | |||
public int hashCode() { | |||
return id != null ? id.hashCode() : 0; | |||
} | |||
} |
@@ -1,113 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.workflow; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.sonar.api.workflow.Review; | |||
import org.sonar.api.workflow.internal.DefaultReview; | |||
import java.util.Map; | |||
public final class ImmutableReview implements Review { | |||
private final Long violationId; | |||
private final Long reviewId; | |||
private final String ruleRepositoryKey; | |||
private final String ruleKey; | |||
private final String ruleName; | |||
private final Long line; | |||
private final boolean switchedOff; | |||
private final boolean manual; | |||
private final String message; | |||
private final String status; | |||
private final String resolution; | |||
private final String severity; | |||
private final Map<String, String> properties; | |||
/** | |||
* Warning : implementation is still mutable. | |||
*/ | |||
public ImmutableReview(DefaultReview review) { | |||
this.line = review.getLine(); | |||
this.manual = review.isManual(); | |||
this.message = review.getMessage(); | |||
this.properties = ImmutableMap.copyOf(review.getProperties()); | |||
this.resolution = review.getResolution(); | |||
this.reviewId = review.getReviewId(); | |||
this.ruleKey = review.getRuleKey(); | |||
this.ruleRepositoryKey = review.getRuleRepositoryKey(); | |||
this.ruleName = review.getRuleName(); | |||
this.severity = review.getSeverity(); | |||
this.status = review.getStatus(); | |||
this.switchedOff = review.isSwitchedOff(); | |||
this.violationId = review.getViolationId(); | |||
} | |||
public Long getViolationId() { | |||
return violationId; | |||
} | |||
public Long getReviewId() { | |||
return reviewId; | |||
} | |||
public String getRuleName() { | |||
return ruleName; | |||
} | |||
public String getRuleRepositoryKey() { | |||
return ruleRepositoryKey; | |||
} | |||
public String getRuleKey() { | |||
return ruleKey; | |||
} | |||
public Long getLine() { | |||
return line; | |||
} | |||
public boolean isSwitchedOff() { | |||
return switchedOff; | |||
} | |||
public boolean isManual() { | |||
return manual; | |||
} | |||
public String getMessage() { | |||
return message; | |||
} | |||
public String getStatus() { | |||
return status; | |||
} | |||
public String getResolution() { | |||
return resolution; | |||
} | |||
public String getSeverity() { | |||
return severity; | |||
} | |||
public Map<String, String> getProperties() { | |||
return properties; | |||
} | |||
} |
@@ -1,30 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.workflow; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.workflow.internal.DefaultReview; | |||
import java.util.List; | |||
public interface ReviewStore { | |||
void store(DefaultReview review); | |||
void completeProjectSettings(Long projectId, Settings settings, List<String> propertyKeys); | |||
} |
@@ -1,141 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.workflow; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.base.Strings; | |||
import com.google.common.collect.ArrayListMultimap; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.ListMultimap; | |||
import com.google.common.collect.Lists; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.workflow.Review; | |||
import org.sonar.api.workflow.WorkflowContext; | |||
import org.sonar.api.workflow.condition.Condition; | |||
import org.sonar.api.workflow.function.Function; | |||
import org.sonar.api.workflow.internal.DefaultReview; | |||
import org.sonar.api.workflow.internal.DefaultWorkflow; | |||
import org.sonar.api.workflow.internal.DefaultWorkflowContext; | |||
import org.sonar.api.workflow.screen.Screen; | |||
import javax.annotation.Nullable; | |||
import java.util.List; | |||
import java.util.Map; | |||
public class WorkflowEngine implements ServerComponent { | |||
private final DefaultWorkflow workflow; | |||
private final ReviewStore store; | |||
private final Settings settings; | |||
public WorkflowEngine(DefaultWorkflow workflow, ReviewStore store, Settings settings) { | |||
this.workflow = workflow; | |||
this.store = store; | |||
this.settings = settings; | |||
} | |||
/** | |||
* @return non-null list of screens per review#violationId | |||
*/ | |||
public ListMultimap<Long, Screen> listAvailableScreens(DefaultReview[] reviews, DefaultWorkflowContext context, boolean verifyConditions) { | |||
ListMultimap<Long, Screen> result = ArrayListMultimap.create(); | |||
completeProjectSettings(context); | |||
for (Map.Entry<String, Screen> entry : workflow.getScreensByCommand().entrySet()) { | |||
String commandKey = entry.getKey(); | |||
if (!verifyConditions || verifyConditionsQuietly(null, context, workflow.getContextConditions(commandKey))) { | |||
for (DefaultReview review : reviews) { | |||
if (!verifyConditions || verifyConditionsQuietly(review, context, workflow.getReviewConditions(commandKey))) { | |||
result.put(review.getViolationId(), entry.getValue()); | |||
} | |||
} | |||
} | |||
} | |||
return result; | |||
} | |||
public List<Screen> listAvailableScreens(Review review, DefaultWorkflowContext context, boolean verifyConditions) { | |||
List<Screen> result = Lists.newArrayList(); | |||
completeProjectSettings(context); | |||
for (Map.Entry<String, Screen> entry : workflow.getScreensByCommand().entrySet()) { | |||
String commandKey = entry.getKey(); | |||
if (!verifyConditions || verifyConditionsQuietly(review, context, workflow.getConditions(commandKey))) { | |||
result.add(entry.getValue()); | |||
} | |||
} | |||
return result; | |||
} | |||
/** | |||
* @return the optional (nullable) screen associated to the command | |||
*/ | |||
public Screen getScreen(String commandKey) { | |||
return workflow.getScreen(commandKey); | |||
} | |||
public void execute(String commandKey, DefaultReview review, DefaultWorkflowContext context, Map<String, String> parameters) { | |||
Preconditions.checkArgument(!Strings.isNullOrEmpty(commandKey), "Missing command"); | |||
Preconditions.checkArgument(workflow.hasCommand(commandKey), "Unknown command: " + commandKey); | |||
completeProjectSettings(context); | |||
verifyConditions(review, context, workflow.getConditions(commandKey)); | |||
Map<String, String> immutableParameters = ImmutableMap.copyOf(parameters); | |||
// TODO execute functions are change state before functions that consume state (like "create-jira-issue") | |||
Review initialReview = new ImmutableReview(review); | |||
for (Function function : workflow.getFunctions(commandKey)) { | |||
function.doExecute(review, initialReview, context, immutableParameters); | |||
} | |||
// should it be extracted to a core function ? | |||
store.store(review); | |||
// TODO notify listeners | |||
} | |||
private boolean verifyConditionsQuietly(@Nullable Review review, WorkflowContext context, List<Condition> conditions) { | |||
for (Condition condition : conditions) { | |||
if (!condition.doVerify(review, context)) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
private void verifyConditions(@Nullable Review review, WorkflowContext context, List<Condition> conditions) { | |||
for (Condition condition : conditions) { | |||
if (!condition.doVerify(review, context)) { | |||
throw new IllegalStateException("Condition is not respected: " + condition.toString()); | |||
} | |||
} | |||
} | |||
private void completeProjectSettings(DefaultWorkflowContext context) { | |||
Settings projectSettings = new Settings(settings); | |||
List<String> propertyKeys = workflow.getProjectPropertyKeys(); | |||
store.completeProjectSettings(context.getProjectId(), projectSettings, propertyKeys); | |||
context.setSettings(projectSettings); | |||
} | |||
} |
@@ -1,23 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.core.workflow; | |||
import javax.annotation.ParametersAreNonnullByDefault; |
@@ -1,178 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.core.workflow; | |||
import com.google.common.collect.ListMultimap; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.api.config.Settings; | |||
import org.sonar.api.workflow.internal.DefaultWorkflow; | |||
import org.sonar.api.workflow.Review; | |||
import org.sonar.api.workflow.WorkflowContext; | |||
import org.sonar.api.workflow.condition.Condition; | |||
import org.sonar.api.workflow.condition.HasProjectPropertyCondition; | |||
import org.sonar.api.workflow.function.Function; | |||
import org.sonar.api.workflow.internal.DefaultReview; | |||
import org.sonar.api.workflow.internal.DefaultWorkflowContext; | |||
import org.sonar.api.workflow.screen.CommentScreen; | |||
import org.sonar.api.workflow.screen.Screen; | |||
import org.sonar.core.workflow.ImmutableReview; | |||
import org.sonar.core.workflow.ReviewStore; | |||
import org.sonar.core.workflow.WorkflowEngine; | |||
import java.util.List; | |||
import java.util.Map; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.junit.matchers.JUnitMatchers.hasItem; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.*; | |||
public class WorkflowEngineTest { | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Test | |||
public void listAvailableScreensForReview_empty() { | |||
WorkflowEngine engine = new WorkflowEngine(new DefaultWorkflow(), mock(ReviewStore.class), new Settings()); | |||
List<Screen> screens = engine.listAvailableScreens(new DefaultReview(), new DefaultWorkflowContext(), true); | |||
assertThat(screens).isEmpty(); | |||
} | |||
@Test | |||
public void listAvailableScreensForReview() { | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("command-without-screen"); | |||
workflow.addCommand("resolve"); | |||
CommentScreen screen = new CommentScreen(); | |||
workflow.setScreen("resolve", screen); | |||
WorkflowEngine engine = new WorkflowEngine(workflow, mock(ReviewStore.class), new Settings()); | |||
List<Screen> screens = engine.listAvailableScreens(new DefaultReview(), new DefaultWorkflowContext(), true); | |||
assertThat(screens).containsExactly(screen); | |||
} | |||
@Test | |||
public void listAvailableScreensForReview_verify_conditions() { | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("resolve"); | |||
Condition condition = mock(Condition.class); | |||
when(condition.doVerify(any(Review.class), any(WorkflowContext.class))).thenReturn(false); | |||
workflow.addCondition("resolve", condition); | |||
workflow.setScreen("resolve", new CommentScreen()); | |||
WorkflowEngine engine = new WorkflowEngine(workflow, mock(ReviewStore.class), new Settings()); | |||
DefaultReview review = new DefaultReview(); | |||
DefaultWorkflowContext context = new DefaultWorkflowContext(); | |||
assertThat(engine.listAvailableScreens(review, context, true)).isEmpty(); | |||
verify(condition).doVerify(review, context); | |||
} | |||
@Test | |||
public void listAvailableScreensForReviews_empty() { | |||
WorkflowEngine engine = new WorkflowEngine(new DefaultWorkflow(), mock(ReviewStore.class), new Settings()); | |||
ListMultimap<Long, Screen> screens = engine.listAvailableScreens( | |||
new DefaultReview[]{new DefaultReview().setViolationId(1000L), new DefaultReview().setViolationId(2000L)}, | |||
new DefaultWorkflowContext(), true); | |||
assertThat(screens.size()).isEqualTo(0); | |||
} | |||
@Test | |||
public void listAvailableScreensForReviews() { | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("command-without-screen"); | |||
workflow.addCommand("resolve"); | |||
CommentScreen screen = new CommentScreen(); | |||
workflow.setScreen("resolve", screen); | |||
WorkflowEngine engine = new WorkflowEngine(workflow, mock(ReviewStore.class), new Settings()); | |||
ListMultimap<Long, Screen> screens = engine.listAvailableScreens( | |||
new DefaultReview[]{new DefaultReview().setViolationId(1000L), new DefaultReview().setViolationId(2000L)}, | |||
new DefaultWorkflowContext(), true); | |||
assertThat(screens.size()).isEqualTo(2); | |||
assertThat(screens.get(1000L)).containsExactly(screen); | |||
assertThat(screens.get(2000L)).containsExactly(screen); | |||
} | |||
@Test | |||
public void listAvailableScreensForReviews_load_project_properties() { | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("resolve"); | |||
workflow.addCondition("resolve", new HasProjectPropertyCondition("foo")); | |||
ReviewStore store = mock(ReviewStore.class); | |||
WorkflowEngine engine = new WorkflowEngine(workflow, store, new Settings()); | |||
engine.listAvailableScreens( | |||
new DefaultReview[]{new DefaultReview().setViolationId(1000L), new DefaultReview().setViolationId(2000L)}, | |||
new DefaultWorkflowContext().setProjectId(300L), | |||
true); | |||
verify(store).completeProjectSettings(eq(300L), any(Settings.class), (List<String>) argThat(hasItem("foo"))); | |||
} | |||
@Test | |||
public void execute_conditions_pass() { | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("resolve"); | |||
workflow.addCondition("resolve", new HasProjectPropertyCondition("foo")); | |||
Function function = mock(Function.class); | |||
workflow.addFunction("resolve", function); | |||
ReviewStore store = mock(ReviewStore.class); | |||
Settings settings = new Settings(); | |||
settings.setProperty("foo", "bar"); | |||
WorkflowEngine engine = new WorkflowEngine(workflow, store, settings); | |||
DefaultReview review = new DefaultReview().setViolationId(1000L); | |||
Map<String, String> parameters = Maps.newHashMap(); | |||
DefaultWorkflowContext context = new DefaultWorkflowContext().setProjectId(300L); | |||
engine.execute("resolve", review, context, parameters); | |||
verify(store).completeProjectSettings(eq(300L), any(Settings.class), (List<String>) argThat(hasItem("foo"))); | |||
verify(function).doExecute(eq(review), any(ImmutableReview.class), eq(context), eq(parameters)); | |||
} | |||
@Test | |||
public void execute_fail_if_conditions_dont_pass() { | |||
thrown.expect(IllegalStateException.class); | |||
thrown.expectMessage("Condition is not respected: Property foo must be set"); | |||
DefaultWorkflow workflow = new DefaultWorkflow(); | |||
workflow.addCommand("resolve"); | |||
workflow.addCondition("resolve", new HasProjectPropertyCondition("foo")); | |||
Function function = mock(Function.class); | |||
workflow.addFunction("resolve", function); | |||
ReviewStore store = mock(ReviewStore.class); | |||
Settings settings = new Settings();// missing property 'foo' | |||
WorkflowEngine engine = new WorkflowEngine(workflow, store, settings); | |||
DefaultReview review = new DefaultReview().setViolationId(1000L); | |||
Map<String, String> parameters = Maps.newHashMap(); | |||
DefaultWorkflowContext context = new DefaultWorkflowContext().setProjectId(300L); | |||
engine.execute("resolve", review, context, parameters); | |||
} | |||
} |
@@ -1,74 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.notifications.reviews; | |||
import com.google.common.collect.Sets; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.ServerComponent; | |||
import org.sonar.api.notifications.Notification; | |||
import org.sonar.api.notifications.NotificationManager; | |||
import java.util.Map; | |||
import java.util.Set; | |||
/** | |||
* @since 2.10 | |||
*/ | |||
public class ReviewsNotificationManager implements ServerComponent { | |||
private NotificationManager notificationManager; | |||
public ReviewsNotificationManager(NotificationManager notificationManager) { | |||
this.notificationManager = notificationManager; | |||
} | |||
/** | |||
* @param reviewId reviewId id of review, which was modified | |||
* @param author author of change (username) | |||
* @param oldValues map of old values | |||
* @param newValues map of new values | |||
*/ | |||
public void notifyChanged(Long reviewId, String author, Map<String, String> oldValues, Map<String, String> newValues) { | |||
Notification notification = new Notification("review-changed") | |||
.setDefaultMessage("Review #" + reviewId + " has changed.") | |||
.setFieldValue("reviewId", String.valueOf(reviewId)) | |||
.setFieldValue("project", newValues.get("project")) | |||
.setFieldValue("projectId", newValues.get("projectId")) | |||
.setFieldValue("resource", newValues.get("resource")) | |||
.setFieldValue("title", newValues.get("title")) | |||
.setFieldValue("author", author) | |||
.setFieldValue("creator", newValues.get("creator")) | |||
.setFieldValue("severity", newValues.get("severity")) | |||
.setFieldValue("assignee", newValues.get("assignee")); | |||
Set<String> fields = Sets.newHashSet(); | |||
fields.addAll(oldValues.keySet()); | |||
fields.addAll(newValues.keySet()); | |||
for (String field : fields) { | |||
String oldValue = oldValues.get(field); | |||
String newValue = newValues.get(field); | |||
if (!StringUtils.equals(oldValue, newValue)) { | |||
notification.setFieldValue("new." + field, newValue); | |||
notification.setFieldValue("old." + field, oldValue); | |||
} | |||
} | |||
notificationManager.scheduleForSending(notification); | |||
} | |||
} |
@@ -60,7 +60,6 @@ import org.sonar.core.test.TestablePerspectiveLoader; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.core.user.DefaultUserFinder; | |||
import org.sonar.core.user.HibernateUserFinder; | |||
import org.sonar.core.workflow.WorkflowEngine; | |||
import org.sonar.jpa.dao.MeasuresDao; | |||
import org.sonar.jpa.dao.ProfilesDao; | |||
import org.sonar.jpa.dao.RulesDao; | |||
@@ -75,7 +74,6 @@ import org.sonar.server.database.EmbeddedDatabaseFactory; | |||
import org.sonar.server.issue.*; | |||
import org.sonar.server.notifications.NotificationCenter; | |||
import org.sonar.server.notifications.NotificationService; | |||
import org.sonar.server.notifications.reviews.ReviewsNotificationManager; | |||
import org.sonar.server.plugins.*; | |||
import org.sonar.server.qualitymodel.DefaultModelManager; | |||
import org.sonar.server.rule.RubyRuleService; | |||
@@ -209,7 +207,6 @@ public final class Platform { | |||
private void startServiceComponents() { | |||
servicesContainer = coreContainer.createChild(); | |||
servicesContainer.addSingleton(DefaultWorkflow.class); | |||
servicesContainer.addSingleton(WorkflowEngine.class); | |||
servicesContainer.addSingleton(HttpDownloader.class); | |||
servicesContainer.addSingleton(UriReader.class); | |||
servicesContainer.addSingleton(UpdateCenterClient.class); | |||
@@ -282,7 +279,6 @@ public final class Platform { | |||
servicesContainer.addSingleton(NotificationService.class); | |||
servicesContainer.addSingleton(NotificationCenter.class); | |||
servicesContainer.addSingleton(DefaultNotificationManager.class); | |||
servicesContainer.addSingleton(ReviewsNotificationManager.class); | |||
// graphs and perspective related classes | |||
servicesContainer.addSingleton(TestablePerspectiveLoader.class); |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.ui; | |||
import com.google.common.collect.ListMultimap; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.config.License; | |||
@@ -42,10 +41,6 @@ import org.sonar.api.test.TestPlan; | |||
import org.sonar.api.test.Testable; | |||
import org.sonar.api.utils.ValidationMessages; | |||
import org.sonar.api.web.*; | |||
import org.sonar.api.workflow.Review; | |||
import org.sonar.api.workflow.internal.DefaultReview; | |||
import org.sonar.api.workflow.internal.DefaultWorkflowContext; | |||
import org.sonar.api.workflow.screen.Screen; | |||
import org.sonar.core.component.SnapshotPerspectives; | |||
import org.sonar.core.i18n.RuleI18nManager; | |||
import org.sonar.core.measure.MeasureFilterEngine; | |||
@@ -57,10 +52,8 @@ import org.sonar.core.purge.PurgeDao; | |||
import org.sonar.core.resource.ResourceIndexerDao; | |||
import org.sonar.core.resource.ResourceKeyUpdaterDao; | |||
import org.sonar.core.timemachine.Periods; | |||
import org.sonar.core.workflow.WorkflowEngine; | |||
import org.sonar.server.configuration.Backup; | |||
import org.sonar.server.configuration.ProfilesManager; | |||
import org.sonar.server.notifications.reviews.ReviewsNotificationManager; | |||
import org.sonar.server.platform.*; | |||
import org.sonar.server.plugins.*; | |||
import org.sonar.server.rules.ProfilesConsole; | |||
@@ -456,10 +449,6 @@ public final class JRubyFacade { | |||
return get(Settings.class).getString(CoreProperties.SONAR_HOME); | |||
} | |||
public ReviewsNotificationManager getReviewsNotificationManager() { | |||
return get(ReviewsNotificationManager.class); | |||
} | |||
public ComponentContainer getContainer() { | |||
return Platform.getInstance().getContainer(); | |||
} |
@@ -1,83 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.notifications.reviews; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.mockito.invocation.InvocationOnMock; | |||
import org.mockito.stubbing.Answer; | |||
import org.sonar.api.notifications.Notification; | |||
import org.sonar.api.notifications.NotificationManager; | |||
import java.util.Map; | |||
import static org.hamcrest.Matchers.is; | |||
import static org.hamcrest.Matchers.notNullValue; | |||
import static org.junit.Assert.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.doAnswer; | |||
import static org.mockito.Mockito.mock; | |||
public class ReviewsNotificationManagerTest { | |||
private Notification notification; | |||
private ReviewsNotificationManager manager; | |||
@Before | |||
public void setUp() { | |||
NotificationManager delegate = mock(NotificationManager.class); | |||
doAnswer(new Answer() { | |||
public Object answer(InvocationOnMock invocation) throws Throwable { | |||
notification = (Notification) invocation.getArguments()[0]; | |||
return null; | |||
} | |||
}).when(delegate).scheduleForSending(any(Notification.class)); | |||
manager = new ReviewsNotificationManager(delegate); | |||
} | |||
@Test | |||
public void shouldScheduleNotification() { | |||
Map<String, String> oldValues = Maps.newHashMap(); | |||
Map<String, String> newValues = Maps.newHashMap(); | |||
newValues.put("project", "Sonar"); | |||
newValues.put("projectId", "42"); | |||
newValues.put("resource", "org.sonar.server.ui.DefaultPages"); | |||
newValues.put("title", "Utility classes should not have a public or default constructor."); | |||
newValues.put("creator", "olivier"); | |||
newValues.put("assignee", "godin"); | |||
oldValues.put("assignee", "simon"); | |||
manager.notifyChanged(1L, "freddy", oldValues, newValues); | |||
assertThat(notification, notNullValue()); | |||
assertThat(notification.getType(), is("review-changed")); | |||
assertThat(notification.getDefaultMessage(), is("Review #1 has changed.")); | |||
assertThat(notification.getFieldValue("reviewId"), is("1")); | |||
assertThat(notification.getFieldValue("author"), is("freddy")); | |||
assertThat(notification.getFieldValue("project"), is("Sonar")); | |||
assertThat(notification.getFieldValue("projectId"), is("42")); | |||
assertThat(notification.getFieldValue("resource"), is("org.sonar.server.ui.DefaultPages")); | |||
assertThat(notification.getFieldValue("title"), is("Utility classes should not have a public or default constructor.")); | |||
assertThat(notification.getFieldValue("creator"), is("olivier")); | |||
assertThat(notification.getFieldValue("assignee"), is("godin")); | |||
assertThat(notification.getFieldValue("old.assignee"), is("simon")); | |||
assertThat(notification.getFieldValue("new.assignee"), is("godin")); | |||
} | |||
} |