From: Simon Brandhof Date: Thu, 16 May 2013 14:01:12 +0000 (+0200) Subject: SONAR-3755 ability to get list of available issue statuses X-Git-Tag: 3.6~349 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=e06fcaf99022af6a9862aa92f6a0e316a87f5ee7;p=sonarqube.git SONAR-3755 ability to get list of available issue statuses --- diff --git a/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java b/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java index dea050cb492..3b2f2943ad6 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java @@ -44,7 +44,10 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable @Override public void start() { machine = StateMachine.builder() + + // order is important for UI .states(Issue.STATUS_OPEN, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED) + .transition(Transition.builder(DefaultTransitions.RESOLVE) .from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED) .functions(new SetResolution(Issue.RESOLUTION_FIXED)) @@ -131,6 +134,10 @@ public class IssueWorkflow implements BatchComponent, ServerComponent, Startable } } + public List statusKeys() { + return machine.stateKeys(); + } + private State stateOf(DefaultIssue issue) { State state = machine.state(issue.status()); if (state==null) { diff --git a/sonar-core/src/main/java/org/sonar/core/issue/workflow/StateMachine.java b/sonar-core/src/main/java/org/sonar/core/issue/workflow/StateMachine.java index 463e462330e..70260dfe758 100644 --- a/sonar-core/src/main/java/org/sonar/core/issue/workflow/StateMachine.java +++ b/sonar-core/src/main/java/org/sonar/core/issue/workflow/StateMachine.java @@ -20,10 +20,7 @@ package org.sonar.core.issue.workflow; import com.google.common.base.Preconditions; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import com.google.common.collect.*; import javax.annotation.CheckForNull; import java.util.Arrays; @@ -33,19 +30,27 @@ import java.util.Set; public class StateMachine { - private Map states = Maps.newHashMap(); + private final List keys; + private final Map byKey; private StateMachine(Builder builder) { + this.keys = ImmutableList.copyOf(builder.states); + ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); for (String stateKey : builder.states) { List outTransitions = builder.outTransitions.get(stateKey); State state = new State(stateKey, outTransitions.toArray(new Transition[outTransitions.size()])); - states.put(stateKey, state); + mapBuilder.put(stateKey, state); } + byKey = mapBuilder.build(); } @CheckForNull public State state(String stateKey) { - return states.get(stateKey); + return byKey.get(stateKey); + } + + public List stateKeys() { + return keys; } public static Builder builder() { @@ -53,10 +58,13 @@ public class StateMachine { } public static class Builder { - private final Set states = Sets.newTreeSet(); + private final Set states = Sets.newLinkedHashSet(); // transitions per originating state private final ListMultimap outTransitions = ArrayListMultimap.create(); + private Builder() { + } + public Builder states(String... keys) { states.addAll(Arrays.asList(keys)); return this; diff --git a/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java b/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java index 2d63c8a08b5..e4a24c24668 100644 --- a/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java +++ b/sonar-core/src/test/java/org/sonar/core/issue/workflow/IssueWorkflowTest.java @@ -53,6 +53,13 @@ public class IssueWorkflowTest { workflow.stop(); } + @Test + public void should_list_statuses() throws Exception { + workflow.start(); + // order is important for UI + assertThat(workflow.statusKeys()).containsSequence(Issue.STATUS_OPEN, Issue.STATUS_REOPENED, Issue.STATUS_RESOLVED, Issue.STATUS_CLOSED); + } + @Test public void should_list_out_manual_transitions() throws Exception { workflow.start(); diff --git a/sonar-core/src/test/java/org/sonar/core/issue/workflow/StateMachineTest.java b/sonar-core/src/test/java/org/sonar/core/issue/workflow/StateMachineTest.java new file mode 100644 index 00000000000..e28f38c9b07 --- /dev/null +++ b/sonar-core/src/test/java/org/sonar/core/issue/workflow/StateMachineTest.java @@ -0,0 +1,44 @@ +/* + * 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.issue.workflow; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; + +public class StateMachineTest { + @Test + public void keep_order_of_state_keys() throws Exception { + StateMachine machine = StateMachine.builder().states("OPEN", "RESOLVED", "CLOSED").build(); + + assertThat(machine.stateKeys()).containsSequence("OPEN", "RESOLVED", "CLOSED"); + } + + @Test + public void stateKey() throws Exception { + StateMachine machine = StateMachine.builder() + .states("OPEN", "RESOLVED", "CLOSED") + .transition(Transition.builder("resolve").from("OPEN").to("RESOLVED").build()) + .build(); + + assertThat(machine.state("OPEN")).isNotNull(); + assertThat(machine.state("OPEN").transition("resolve")).isNotNull(); + } +}