@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))
}
}
+ public List<String> statusKeys() {
+ return machine.stateKeys();
+ }
+
private State stateOf(DefaultIssue issue) {
State state = machine.state(issue.status());
if (state==null) {
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;
public class StateMachine {
- private Map<String, State> states = Maps.newHashMap();
+ private final List<String> keys;
+ private final Map<String, State> byKey;
private StateMachine(Builder builder) {
+ this.keys = ImmutableList.copyOf(builder.states);
+ ImmutableMap.Builder<String, State> mapBuilder = ImmutableMap.builder();
for (String stateKey : builder.states) {
List<Transition> 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<String> stateKeys() {
+ return keys;
}
public static Builder builder() {
}
public static class Builder {
- private final Set<String> states = Sets.newTreeSet();
+ private final Set<String> states = Sets.newLinkedHashSet();
// transitions per originating state
private final ListMultimap<String, Transition> outTransitions = ArrayListMultimap.create();
+ private Builder() {
+ }
+
public Builder states(String... keys) {
states.addAll(Arrays.asList(keys));
return this;
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();
--- /dev/null
+/*
+ * 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();
+ }
+}