Join state should not be entered
- Fix join pseudostate to be transient. - Fix tests which uses wrong concepts. - Fixes #222
This commit is contained in:
@@ -631,7 +631,19 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
|
||||
joins.add(stateMap.get(fs));
|
||||
}
|
||||
}
|
||||
JoinPseudoState<S, E> pseudoState = new JoinPseudoState<S, E>(joins);
|
||||
S ss = null;
|
||||
Collection<TransitionData<S, E>> transitions = stateMachineTransitions.getTransitions();
|
||||
for (TransitionData<S, E> tt : transitions) {
|
||||
if (tt.getSource() == s) {
|
||||
ss = tt.getTarget();
|
||||
break;
|
||||
}
|
||||
}
|
||||
StateHolder<S, E> holder = new StateHolder<S, E>(stateMap.get(ss));
|
||||
if (holder.getState() == null) {
|
||||
holderMap.put(ss, holder);
|
||||
}
|
||||
JoinPseudoState<S, E> pseudoState = new JoinPseudoState<S, E>(joins, holder);
|
||||
state = buildStateInternal(stateData.getState(), stateData.getDeferred(), stateData.getEntryActions(),
|
||||
stateData.getExitActions(), pseudoState);
|
||||
states.add(state);
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.List;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
|
||||
import org.springframework.statemachine.state.PseudoStateContext.PseudoAction;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Join implementation of a {@link PseudoState}.
|
||||
@@ -34,22 +35,26 @@ public class JoinPseudoState<S, E> extends AbstractPseudoState<S, E> {
|
||||
|
||||
private final List<State<S, E>> joins;
|
||||
private volatile JoinTracker tracker;
|
||||
private final StateHolder<S, E> state;
|
||||
|
||||
/**
|
||||
* Instantiates a new join pseudo state.
|
||||
*
|
||||
* @param joins the joins
|
||||
* @param state the holder for target state
|
||||
*/
|
||||
public JoinPseudoState(List<State<S, E>> joins) {
|
||||
public JoinPseudoState(List<State<S, E>> joins, StateHolder<S, E> state) {
|
||||
super(PseudoStateKind.JOIN);
|
||||
Assert.notNull(state, "Holder must be set");
|
||||
this.joins = joins;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State<S, E> entry(StateContext<S, E> context) {
|
||||
tracker = new JoinTracker(this, new ArrayList<State<S,E>>(joins));
|
||||
context.getStateMachine().addStateListener(tracker);
|
||||
return null;
|
||||
return state.getState();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -146,7 +146,6 @@ public class RegionState<S, E> extends AbstractState<S, E> {
|
||||
|
||||
@Override
|
||||
public void entry(StateContext<S, E> context) {
|
||||
System.out.println("XXXXXX " + context);
|
||||
if (join != null) {
|
||||
join.entry(context);
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
|
||||
private State<S,E> followLinkedPseudoStates(State<S,E> state, StateContext<S, E> stateContext) {
|
||||
PseudoStateKind kind = state.getPseudoState() != null ? state.getPseudoState().getKind() : null;
|
||||
if (kind == PseudoStateKind.INITIAL || kind == PseudoStateKind.JOIN || kind == PseudoStateKind.FORK) {
|
||||
if (kind == PseudoStateKind.INITIAL || kind == PseudoStateKind.FORK) {
|
||||
return state;
|
||||
} else if (kind != null) {
|
||||
State<S,E> toState = state.getPseudoState().entry(stateContext);
|
||||
@@ -776,6 +776,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
State<S, E> toState = findStateWithPseudoState(pseudoState);
|
||||
StateContext<S, E> stateContext = buildStateContext(Stage.STATE_EXIT, null, null, getRelayStateMachine());
|
||||
pseudoState.exit(stateContext);
|
||||
toState = followLinkedPseudoStates(toState, stateContext);
|
||||
switchToState(toState, null, null, getRelayStateMachine());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -146,10 +146,10 @@ public class StateMachineTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S2, TestStates.S21, TestStates.S30));
|
||||
|
||||
listener.reset(3);
|
||||
listener.reset(2);
|
||||
machine.sendEvent(TestEvents.E3);
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(3));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
assertThat(machine.getState().getIds(), containsInAnyOrder(TestStates.S4));
|
||||
}
|
||||
|
||||
|
||||
@@ -70,10 +70,10 @@ public class JoinStateTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
|
||||
listener.reset(3);
|
||||
listener.reset(2);
|
||||
machine.sendEvent(TestEvents.E3);
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(3));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
|
||||
assertThat(machine.getState().getIds(), contains(TestStates.S4));
|
||||
}
|
||||
@@ -144,10 +144,10 @@ public class JoinStateTests extends AbstractStateMachineTests {
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(1));
|
||||
|
||||
listener.reset(3);
|
||||
listener.reset(2);
|
||||
machine.sendEvent(TestEvents.E3);
|
||||
assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.stateChangedCount, is(3));
|
||||
assertThat(listener.stateChangedCount, is(2));
|
||||
|
||||
assertThat(machine.getState().getIds(), contains(TestStates.S4));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user