Make end state a proper pseudostate
- Remove end state from constructors and handle it as a pseudostate. - When sm enters state marked with end, stop machine. - Added new events which are used to notify sm start and stop which now makes sense with a proper end pseudostate.
This commit is contained in:
@@ -163,10 +163,11 @@ interface. Both of these have pros and cons which will be discussed later.
|
||||
=== Application Context Events
|
||||
Application context events classes are _OnTransitionStartEvent_,
|
||||
_OnTransitionEvent_, _OnTransitionEndEvent_, _OnStateExitEvent_,
|
||||
_OnStateEntryEvent_ and _OnStateChangedEvent_. There can be used as is
|
||||
as spring typed _ApplicationListener_ class but all also share a
|
||||
common class _StateMachineEvent_ which can be used to get events for
|
||||
all.
|
||||
_OnStateEntryEvent_, _OnStateChangedEvent_, _OnStateMachineStart_ and
|
||||
_OnStateMachineStop_. These can be used as is with spring typed
|
||||
_ApplicationListener_ class but they also share a common class
|
||||
_StateMachineEvent_ which can be used to get statemachine related
|
||||
events.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
|
||||
@@ -41,14 +41,24 @@ public class EnumStateMachine<S extends Enum<S>, E extends Enum<E>> extends Abst
|
||||
* @param initialState the initial state
|
||||
*/
|
||||
public EnumStateMachine(Collection<State<S, E>> states, Collection<Transition<S, E>> transitions,
|
||||
State<S, E> initialState, State<S, E> endState) {
|
||||
super(states, transitions, initialState, endState);
|
||||
State<S, E> initialState) {
|
||||
super(states, transitions, initialState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new enum state machine.
|
||||
*
|
||||
* @param states the states
|
||||
* @param transitions the transitions
|
||||
* @param initialState the initial state
|
||||
* @param initialTransition the initial transition
|
||||
* @param initialEvent the initial event
|
||||
* @param extendedState the extended state
|
||||
*/
|
||||
public EnumStateMachine(Collection<State<S, E>> states, Collection<Transition<S, E>> transitions,
|
||||
State<S, E> initialState, Transition<S, E> initialTransition, State<S, E> endState,
|
||||
State<S, E> initialState, Transition<S, E> initialTransition,
|
||||
Message<E> initialEvent, ExtendedState extendedState) {
|
||||
super(states, transitions, initialState, initialTransition, endState, initialEvent, extendedState);
|
||||
super(states, transitions, initialState, initialTransition, initialEvent, extendedState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
|
||||
Collection<State<S, E>> states = new ArrayList<State<S, E>>();
|
||||
states.add(rstate);
|
||||
EnumStateMachine<S, E> m = new EnumStateMachine<S, E>(states, null, rstate,
|
||||
null, null, null, defaultExtendedState);
|
||||
null, null, defaultExtendedState);
|
||||
if (contextEvents != null) {
|
||||
m.setContextEventsEnabled(contextEvents);
|
||||
}
|
||||
@@ -278,7 +278,6 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
|
||||
State<S, E> state = null;
|
||||
State<S, E> initialState = null;
|
||||
Action<S, E> initialAction = null;
|
||||
State<S, E> endState = null;
|
||||
Collection<State<S, E>> states = new ArrayList<State<S,E>>();
|
||||
for (StateData<S, E> stateData : stateDatas) {
|
||||
StateMachine<S, E> stateMachine = machineMap.get(stateData.getState());
|
||||
@@ -299,6 +298,8 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
|
||||
PseudoState pseudoState = null;
|
||||
if (stateData.isInitial()) {
|
||||
pseudoState = new DefaultPseudoState(PseudoStateKind.INITIAL);
|
||||
} else if (stateData.isEnd()) {
|
||||
pseudoState = new DefaultPseudoState(PseudoStateKind.END);
|
||||
}
|
||||
state = new EnumState<S, E>(stateData.getState(), stateData.getDeferred(),
|
||||
stateData.getEntryActions(), stateData.getExitActions(), pseudoState);
|
||||
@@ -306,9 +307,6 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
|
||||
initialState = state;
|
||||
initialAction = stateData.getInitialAction();
|
||||
}
|
||||
if (stateData.isEnd()) {
|
||||
endState = state;
|
||||
}
|
||||
states.add(state);
|
||||
|
||||
}
|
||||
@@ -355,7 +353,7 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
|
||||
}
|
||||
|
||||
EnumStateMachine<S, E> machine = new EnumStateMachine<S, E>(states, transitions, initialState,
|
||||
initialTransition, endState, null, defaultExtendedState);
|
||||
initialTransition, null, defaultExtendedState);
|
||||
if (contextEvents != null) {
|
||||
machine.setContextEventsEnabled(contextEvents);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.statemachine.event;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
|
||||
@@ -92,4 +93,18 @@ public class DefaultStateMachineEventPublisher implements StateMachineEventPubli
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishStateMachineStart(Object source, StateMachine<?, ?> stateMachine) {
|
||||
if (applicationEventPublisher != null) {
|
||||
applicationEventPublisher.publishEvent(new OnStateMachineStart(source, stateMachine));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishStateMachineStop(Object source, StateMachine<?, ?> stateMachine) {
|
||||
if (applicationEventPublisher != null) {
|
||||
applicationEventPublisher.publishEvent(new OnStateMachineStop(source, stateMachine));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.event;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
|
||||
/**
|
||||
* Generic event representing that state machine has been started.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class OnStateMachineStart extends StateMachineEvent {
|
||||
|
||||
private final StateMachine<?, ?> stateMachine;
|
||||
|
||||
/**
|
||||
* Instantiates a new on state exit event.
|
||||
*
|
||||
* @param source the source
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
public OnStateMachineStart(Object source, StateMachine<?, ?> stateMachine) {
|
||||
super(source);
|
||||
this.stateMachine = stateMachine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the statemachine.
|
||||
*
|
||||
* @return the statemachine
|
||||
*/
|
||||
public StateMachine<?, ?> getStateMachine() {
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OnStateMachineStart [stateMachine=" + stateMachine + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.statemachine.event;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
|
||||
/**
|
||||
* Generic event representing that state machine has been stopped or terminated.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class OnStateMachineStop extends StateMachineEvent {
|
||||
|
||||
private final StateMachine<?, ?> stateMachine;
|
||||
|
||||
/**
|
||||
* Instantiates a new on state exit event.
|
||||
*
|
||||
* @param source the source
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
public OnStateMachineStop(Object source, StateMachine<?, ?> stateMachine) {
|
||||
super(source);
|
||||
this.stateMachine = stateMachine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the statemachine.
|
||||
*
|
||||
* @return the statemachine
|
||||
*/
|
||||
public StateMachine<?, ?> getStateMachine() {
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OnStateMachineStart [stateMachine=" + stateMachine + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.statemachine.event;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
|
||||
@@ -75,4 +76,20 @@ public interface StateMachineEventPublisher {
|
||||
*/
|
||||
void publishTransition(Object source, Transition<?, ?> transition);
|
||||
|
||||
/**
|
||||
* Publish a statemachine start event.
|
||||
*
|
||||
* @param source the source
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
void publishStateMachineStart(Object source, StateMachine<?, ?> stateMachine);
|
||||
|
||||
/**
|
||||
* Publish a statemachine stop event.
|
||||
*
|
||||
* @param source the source
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
void publishStateMachineStop(Object source, StateMachine<?, ?> stateMachine);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.springframework.statemachine.listener;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
|
||||
@@ -79,4 +80,20 @@ public class CompositeStateMachineListener<S,E> extends AbstractCompositeListene
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStarted(StateMachine<S, E> stateMachine) {
|
||||
for (Iterator<StateMachineListener<S, E>> iterator = getListeners().reverse(); iterator.hasNext();) {
|
||||
StateMachineListener<S, E> listener = iterator.next();
|
||||
listener.stateMachineStarted(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStopped(StateMachine<S, E> stateMachine) {
|
||||
for (Iterator<StateMachineListener<S, E>> iterator = getListeners().reverse(); iterator.hasNext();) {
|
||||
StateMachineListener<S, E> listener = iterator.next();
|
||||
listener.stateMachineStopped(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.statemachine.listener;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
|
||||
@@ -71,4 +72,18 @@ public interface StateMachineListener<S,E> {
|
||||
*/
|
||||
void transitionEnded(Transition<S, E> transition);
|
||||
|
||||
/**
|
||||
* Notified when statemachine starts
|
||||
*
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
void stateMachineStarted(StateMachine<S, E> stateMachine);
|
||||
|
||||
/**
|
||||
* Notified when statemachine stops
|
||||
*
|
||||
* @param stateMachine the statemachine
|
||||
*/
|
||||
void stateMachineStopped(StateMachine<S, E> stateMachine);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.statemachine.listener;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.transition.Transition;
|
||||
|
||||
@@ -53,4 +54,12 @@ public class StateMachineListenerAdapter<S, E> implements StateMachineListener<S
|
||||
public void transitionEnded(Transition<S, E> transition) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStarted(StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStopped(StateMachine<S, E> stateMachine) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@ package org.springframework.statemachine.state;
|
||||
/**
|
||||
* Defines enumeration of a {@link PseudoState} kind. This is uses within a
|
||||
* transitive states indicating its kind.
|
||||
*
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
*/
|
||||
public enum PseudoStateKind {
|
||||
|
||||
/** Indicates an initial kind. */
|
||||
INITIAL
|
||||
|
||||
INITIAL,
|
||||
|
||||
/** End or terminate kind */
|
||||
END
|
||||
|
||||
}
|
||||
|
||||
@@ -81,8 +81,6 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
|
||||
private final Transition<S, E> initialTransition;
|
||||
|
||||
private final State<S,E> endState;
|
||||
|
||||
private final Message<E> initialEvent;
|
||||
|
||||
private final ExtendedState extendedState;
|
||||
@@ -119,19 +117,6 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
this(states, transitions, initialState, new DefaultExtendedState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract state machine.
|
||||
*
|
||||
* @param states the states
|
||||
* @param transitions the transitions
|
||||
* @param initialState the initial state
|
||||
* @param endState the end state
|
||||
*/
|
||||
public AbstractStateMachine(Collection<State<S, E>> states, Collection<Transition<S, E>> transitions,
|
||||
State<S, E> initialState, State<S, E> endState) {
|
||||
this(states, transitions, initialState, null, endState, null, new DefaultExtendedState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract state machine.
|
||||
*
|
||||
@@ -142,7 +127,7 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
*/
|
||||
public AbstractStateMachine(Collection<State<S, E>> states, Collection<Transition<S, E>> transitions,
|
||||
State<S, E> initialState, ExtendedState extendedState) {
|
||||
this(states, transitions, initialState, null, null, null, extendedState);
|
||||
this(states, transitions, initialState, null, null, extendedState);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,18 +136,16 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
* @param states the states of this machine
|
||||
* @param transitions the transitions of this machine
|
||||
* @param initialState the initial state of this machine
|
||||
* @param endState the final state of this machine
|
||||
* @param initialEvent the initial event of this machine
|
||||
* @param extendedState the extended state of this machine
|
||||
*/
|
||||
public AbstractStateMachine(Collection<State<S, E>> states, Collection<Transition<S, E>> transitions,
|
||||
State<S, E> initialState, Transition<S, E> initialTransition, State<S, E> endState, Message<E> initialEvent, ExtendedState extendedState) {
|
||||
State<S, E> initialState, Transition<S, E> initialTransition, Message<E> initialEvent, ExtendedState extendedState) {
|
||||
super();
|
||||
this.states = states;
|
||||
this.transitions = transitions;
|
||||
this.initialState = initialState;
|
||||
this.initialTransition = initialTransition;
|
||||
this.endState = endState;
|
||||
this.initialEvent = initialEvent;
|
||||
this.extendedState = extendedState != null ? extendedState : new DefaultExtendedState();
|
||||
}
|
||||
@@ -222,6 +205,7 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
@Override
|
||||
protected void doStart() {
|
||||
super.doStart();
|
||||
notifyStateMachineStarted(this);
|
||||
registerTriggerListener();
|
||||
switchToState(initialState, initialEvent, null, this);
|
||||
// TODO: for now execute outside of switchToState
|
||||
@@ -235,6 +219,7 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
@Override
|
||||
protected void doStop() {
|
||||
super.doStop();
|
||||
notifyStateMachineStopped(this);
|
||||
currentState = null;
|
||||
}
|
||||
|
||||
@@ -245,7 +230,12 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return (endState != null && endState.equals(currentState));
|
||||
if (currentState == null) {
|
||||
return !isRunning();
|
||||
} else {
|
||||
return currentState != null && currentState.getPseudoState() != null
|
||||
&& currentState.getPseudoState().getKind() == PseudoStateKind.END;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,7 +323,9 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
switchToState(target, event, t, stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
if (isComplete()) {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
private State<S, E> findDeepParent(State<S, E> state) {
|
||||
@@ -777,6 +769,26 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyStateMachineStarted(StateMachine<S, E> stateMachine) {
|
||||
stateListener.stateMachineStarted(stateMachine);
|
||||
if (contextEventsEnabled) {
|
||||
StateMachineEventPublisher eventPublisher = getStateMachineEventPublisher();
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.publishStateMachineStart(this, stateMachine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyStateMachineStopped(StateMachine<S, E> stateMachine) {
|
||||
stateListener.stateMachineStopped(stateMachine);
|
||||
if (contextEventsEnabled) {
|
||||
StateMachineEventPublisher eventPublisher = getStateMachineEventPublisher();
|
||||
if (eventPublisher != null) {
|
||||
eventPublisher.publishStateMachineStop(this, stateMachine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TriggerQueueItem {
|
||||
Trigger<S, E> trigger;
|
||||
Message<E> message;
|
||||
@@ -823,6 +835,16 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
|
||||
stateListener.transitionEnded(transition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStarted(StateMachine<S, E> stateMachine) {
|
||||
stateListener.stateMachineStarted(stateMachine);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStopped(StateMachine<S, E> stateMachine) {
|
||||
stateListener.stateMachineStopped(stateMachine);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
|
||||
transitions.add(transitionFromS2ToS3);
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.afterPropertiesSet();
|
||||
machine.start();
|
||||
@@ -148,7 +148,7 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
|
||||
|
||||
// create machine
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.afterPropertiesSet();
|
||||
machine.start();
|
||||
@@ -188,7 +188,7 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
|
||||
transitions.add(transitionInternalSI);
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.start();
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class RegionMachineTests {
|
||||
transitions.add(transitionFromS2ToS3);
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.afterPropertiesSet();
|
||||
machine.start();
|
||||
@@ -150,7 +150,7 @@ public class RegionMachineTests {
|
||||
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS112 =
|
||||
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS112, null, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
|
||||
transitions11.add(transitionFromS111ToS112);
|
||||
EnumStateMachine<TestStates, TestEvents> machine11 = new EnumStateMachine<TestStates, TestEvents>(states11, transitions11, stateS111, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine11 = new EnumStateMachine<TestStates, TestEvents>(states11, transitions11, stateS111);
|
||||
machine11.setTaskExecutor(taskExecutor);
|
||||
machine11.afterPropertiesSet();
|
||||
|
||||
@@ -161,7 +161,7 @@ public class RegionMachineTests {
|
||||
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS121 =
|
||||
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS111, null, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
|
||||
transitions12.add(transitionFromSIToS121);
|
||||
EnumStateMachine<TestStates, TestEvents> machine12 = new EnumStateMachine<TestStates, TestEvents>(states12, transitions12, stateS121, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine12 = new EnumStateMachine<TestStates, TestEvents>(states12, transitions12, stateS121);
|
||||
machine12.setTaskExecutor(taskExecutor);
|
||||
machine12.afterPropertiesSet();
|
||||
|
||||
@@ -176,7 +176,7 @@ public class RegionMachineTests {
|
||||
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToRegionstate =
|
||||
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateR, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
|
||||
transitions.add(transitionFromSIToRegionstate);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateR, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateR);
|
||||
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.afterPropertiesSet();
|
||||
|
||||
@@ -94,7 +94,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
Collection<State<TestStates,TestEvents>> substates111 = new ArrayList<State<TestStates,TestEvents>>();
|
||||
substates111.add(stateS111);
|
||||
Collection<Transition<TestStates,TestEvents>> subtransitions111 = new ArrayList<Transition<TestStates,TestEvents>>();
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates111, subtransitions111, stateS111, null);
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates111, subtransitions111, stateS111);
|
||||
|
||||
// submachine 1
|
||||
TestEntryAction entryActionS11 = new TestEntryAction("S11");
|
||||
@@ -108,7 +108,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
Collection<State<TestStates,TestEvents>> substates11 = new ArrayList<State<TestStates,TestEvents>>();
|
||||
substates11.add(stateS11);
|
||||
Collection<Transition<TestStates,TestEvents>> subtransitions11 = new ArrayList<Transition<TestStates,TestEvents>>();
|
||||
EnumStateMachine<TestStates, TestEvents> submachine1 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS11, null);
|
||||
EnumStateMachine<TestStates, TestEvents> submachine1 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS11);
|
||||
|
||||
// machine
|
||||
TestEntryAction entryActionS1 = new TestEntryAction("S1");
|
||||
@@ -125,7 +125,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS1 =
|
||||
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS1, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
|
||||
transitions.add(transitionFromS111ToS1);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1);
|
||||
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
@@ -198,7 +198,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
substates11.add(stateS111);
|
||||
substates11.add(stateS112);
|
||||
Collection<Transition<TestStates,TestEvents>> subtransitions11 = new ArrayList<Transition<TestStates,TestEvents>>();
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS111, null);
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS111);
|
||||
|
||||
// machine
|
||||
TestEntryAction entryActionS1 = new TestEntryAction("S1");
|
||||
@@ -215,7 +215,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS112 =
|
||||
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS112, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
|
||||
transitions.add(transitionFromS111ToS112);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1);
|
||||
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
@@ -281,7 +281,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
Collection<State<TestStates,TestEvents>> substates111 = new ArrayList<State<TestStates,TestEvents>>();
|
||||
substates111.add(stateS111);
|
||||
Collection<Transition<TestStates,TestEvents>> subtransitions111 = new ArrayList<Transition<TestStates,TestEvents>>();
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates111, subtransitions111, stateS111, null);
|
||||
EnumStateMachine<TestStates, TestEvents> submachine11 = new EnumStateMachine<TestStates, TestEvents>(substates111, subtransitions111, stateS111);
|
||||
|
||||
// submachine 1
|
||||
TestEntryAction entryActionS11 = new TestEntryAction("S11");
|
||||
@@ -295,7 +295,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
Collection<State<TestStates,TestEvents>> substates11 = new ArrayList<State<TestStates,TestEvents>>();
|
||||
substates11.add(stateS11);
|
||||
Collection<Transition<TestStates,TestEvents>> subtransitions11 = new ArrayList<Transition<TestStates,TestEvents>>();
|
||||
EnumStateMachine<TestStates, TestEvents> submachine1 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS11, null);
|
||||
EnumStateMachine<TestStates, TestEvents> submachine1 = new EnumStateMachine<TestStates, TestEvents>(substates11, subtransitions11, stateS11);
|
||||
|
||||
// machine
|
||||
TestEntryAction entryActionS1 = new TestEntryAction("S1");
|
||||
@@ -312,7 +312,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
|
||||
DefaultLocalTransition<TestStates,TestEvents> transitionFromS11ToS1 =
|
||||
new DefaultLocalTransition<TestStates,TestEvents>(stateS111, stateS1, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
|
||||
transitions.add(transitionFromS11ToS1);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateS1);
|
||||
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.statemachine.AbstractStateMachineTests;
|
||||
import org.springframework.statemachine.EnumStateMachine;
|
||||
import org.springframework.statemachine.StateMachineSystemConstants;
|
||||
import org.springframework.statemachine.TestUtils;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
@@ -66,20 +65,6 @@ public class ConfigurationTests extends AbstractStateMachineTests {
|
||||
assertThat(testGuard, notNullValue());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void testEndState() throws Exception {
|
||||
context.register(Config3.class);
|
||||
context.refresh();
|
||||
assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
|
||||
EnumStateMachine<TestStates,TestEvents> machine =
|
||||
context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, EnumStateMachine.class);
|
||||
assertThat(machine, notNullValue());
|
||||
Object endState = TestUtils.readField("endState", machine);
|
||||
assertThat(endState, notNullValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
@Test
|
||||
public void testSimpleSubmachine() throws Exception {
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.springframework.statemachine.AbstractStateMachineTests;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
import org.springframework.statemachine.annotation.AnnoStates;
|
||||
import org.springframework.statemachine.annotation.OnTransition;
|
||||
import org.springframework.statemachine.annotation.WithStateMachine;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
@@ -240,6 +239,14 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
|
||||
@Override
|
||||
public void transitionEnded(Transition<States, Events> transition) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStarted(StateMachine<States, Events> stateMachine) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStopped(StateMachine<States, Events> stateMachine) {
|
||||
}
|
||||
}
|
||||
// end::snippetH[]
|
||||
|
||||
@@ -315,16 +322,16 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
|
||||
public static class Config9 extends EnumStateMachineConfigurerAdapter<States, Events> {
|
||||
}
|
||||
// end::snippetN[]
|
||||
|
||||
|
||||
static class DummyShowSendEvent {
|
||||
|
||||
|
||||
// tag::snippetO[]
|
||||
@Autowired
|
||||
StateMachine<States, Events> stateMachine;
|
||||
|
||||
|
||||
void signalMachine() {
|
||||
stateMachine.sendEvent(Events.E1);
|
||||
|
||||
|
||||
Message<Events> message = MessageBuilder
|
||||
.withPayload(Events.E2)
|
||||
.setHeader("foo", "bar")
|
||||
@@ -332,7 +339,7 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests {
|
||||
stateMachine.sendEvent(message);
|
||||
}
|
||||
// end::snippetO[]
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -35,6 +37,7 @@ import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.statemachine.AbstractStateMachineTests;
|
||||
import org.springframework.statemachine.EnumStateMachine;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.StateMachineSystemConstants;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
@@ -54,7 +57,7 @@ public class ListenerTests extends AbstractStateMachineTests {
|
||||
|
||||
@Test
|
||||
public void testStateEvents() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config1.class);
|
||||
assertTrue(ctx.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
|
||||
@SuppressWarnings("unchecked")
|
||||
EnumStateMachine<TestStates,TestEvents> machine =
|
||||
@@ -79,6 +82,26 @@ public class ListenerTests extends AbstractStateMachineTests {
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartEndEvents() throws Exception {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config2.class);
|
||||
assertTrue(ctx.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE));
|
||||
@SuppressWarnings("unchecked")
|
||||
EnumStateMachine<TestStates,TestEvents> machine =
|
||||
ctx.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, EnumStateMachine.class);
|
||||
|
||||
TestStateMachineListener listener = new TestStateMachineListener();
|
||||
machine.addStateListener(listener);
|
||||
|
||||
machine.start();
|
||||
machine.sendEvent(TestEvents.E1);
|
||||
machine.sendEvent(TestEvents.E2);
|
||||
assertThat(listener.stopLatch.await(2, TimeUnit.SECONDS), is(true));
|
||||
assertThat(listener.started, is(1));
|
||||
assertThat(listener.stopped, is(1));
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
private static class LoggingAction implements Action<TestStates, TestEvents> {
|
||||
|
||||
private static final Log log = LogFactory.getLog(LoggingAction.class);
|
||||
@@ -99,6 +122,9 @@ public class ListenerTests extends AbstractStateMachineTests {
|
||||
private static class TestStateMachineListener implements StateMachineListener<TestStates, TestEvents> {
|
||||
|
||||
ArrayList<Holder> states = new ArrayList<Holder>();
|
||||
volatile int started = 0;
|
||||
volatile int stopped = 0;
|
||||
CountDownLatch stopLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void stateChanged(State<TestStates, TestEvents> from, State<TestStates, TestEvents> to) {
|
||||
@@ -134,11 +160,22 @@ public class ListenerTests extends AbstractStateMachineTests {
|
||||
public void transitionEnded(Transition<TestStates, TestEvents> transition) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStarted(StateMachine<TestStates, TestEvents> stateMachine) {
|
||||
started++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateMachineStopped(StateMachine<TestStates, TestEvents> stateMachine) {
|
||||
stopped++;
|
||||
stopLatch.countDown();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
|
||||
static class Config1 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
|
||||
@@ -192,4 +229,40 @@ public class ListenerTests extends AbstractStateMachineTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config2 extends EnumStateMachineConfigurerAdapter<TestStates, TestEvents> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(TestStates.S1)
|
||||
.end(TestStates.S3)
|
||||
.state(TestStates.S1)
|
||||
.state(TestStates.S2)
|
||||
.state(TestStates.S3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(TestStates.S1)
|
||||
.target(TestStates.S2)
|
||||
.event(TestEvents.E1)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates.S2)
|
||||
.target(TestStates.S3)
|
||||
.event(TestEvents.E2);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskExecutor taskExecutor() {
|
||||
return new SyncTaskExecutor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class RegionStateTests extends AbstractStateMachineTests {
|
||||
transitions.add(transitionFromS2ToS3);
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.start();
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SubmachineStateTests extends AbstractStateMachineTests {
|
||||
transitions.add(transitionFromS2ToS3);
|
||||
|
||||
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
|
||||
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
|
||||
machine.setTaskExecutor(taskExecutor);
|
||||
machine.start();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user