Better model for triggers

- Harmonise how triggers are used
- Now using a trigger context
- Creates a better model so that we add
  more trigger types.
This commit is contained in:
Janne Valkealahti
2015-03-14 08:20:02 +00:00
parent 8908a2f19b
commit 1e3fb04614
18 changed files with 184 additions and 72 deletions

View File

@@ -44,6 +44,7 @@ import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.DefaultInternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.transition.TransitionKind;
import org.springframework.statemachine.trigger.EventTrigger;
import org.springframework.util.ObjectUtils;
/**
@@ -290,12 +291,12 @@ public class EnumStateMachineFactory<S extends Enum<S>, E extends Enum<E>> exten
E event = transitionData.getEvent();
if (transitionData.getKind() == TransitionKind.EXTERNAL) {
DefaultExternalTransition<S, E> transition = new DefaultExternalTransition<S, E>(stateMap.get(source),
stateMap.get(target), transitionData.getActions(), event, transitionData.getGuard());
stateMap.get(target), transitionData.getActions(), event, transitionData.getGuard(), event != null ? new EventTrigger<S, E>(event) : null);
transitions.add(transition);
} else if (transitionData.getKind() == TransitionKind.INTERNAL) {
DefaultInternalTransition<S, E> transition = new DefaultInternalTransition<S, E>(stateMap.get(source),
transitionData.getActions(), event, transitionData.getGuard());
transitionData.getActions(), event, transitionData.getGuard(), event != null ? new EventTrigger<S, E>(event) : null);
transitions.add(transition);
}
}

View File

@@ -49,6 +49,7 @@ import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.transition.TransitionKind;
import org.springframework.statemachine.trigger.DefaultTriggerContext;
import org.springframework.statemachine.trigger.Trigger;
import org.springframework.util.Assert;
@@ -91,6 +92,10 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
private volatile boolean handlersInitialized;
private final Queue<TriggerQueueItem> triggerQueue = new ConcurrentLinkedQueue<TriggerQueueItem>();
private final Map<Trigger<S, E>, Transition<S,E>> triggerToTransitionMap = new HashMap<Trigger<S,E>, Transition<S,E>>();
/**
* Instantiates a new abstract state machine.
*
@@ -188,6 +193,12 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
Assert.state(initialState.getPseudoState() != null
&& initialState.getPseudoState().getKind() == PseudoStateKind.INITIAL,
"Initial state's pseudostate kind must be INITIAL");
for (Transition<S, E> transition : transitions) {
Trigger<S, E> trigger = transition.getTrigger();
if (trigger != null) {
triggerToTransitionMap.put(trigger, transition);
}
}
}
@Override
@@ -241,8 +252,8 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
Trigger<S, E> trigger = transition.getTrigger();
if (StateMachineUtils.containsAtleastOne(source.getIds(), currentState.getIds())) {
if (trigger != null && trigger.evaluate(event.getPayload())) {
eventQueue.add(event);
if (trigger != null && trigger.evaluate(new DefaultTriggerContext<S, E>(event.getPayload()))) {
triggerQueue.add(new TriggerQueueItem(trigger, event));
return true;
} else if (source.getDeferredEvents() != null && source.getDeferredEvents().contains(event.getPayload())) {
defer = event;
@@ -306,20 +317,11 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
Message<E> defer = null;
for (Transition<S,E> transition : transitions) {
State<S,E> source = transition.getSource();
State<S,E> target = transition.getTarget();
Trigger<S, E> trigger = transition.getTrigger();
if (StateMachineUtils.containsAtleastOne(source.getIds(), currentState.getIds())) {
if (trigger != null && trigger.evaluate(queuedEvent.getPayload())) {
StateContext<S, E> stateContext = new DefaultStateContext<S, E>(queuedEvent.getHeaders(), extendedState, transition);
notifyTransitionStart(transition);
boolean transit = transition.transit(stateContext);
if (transit && transition.getKind() != TransitionKind.INTERNAL) {
switchToState(target, queuedEvent, transition);
notifyTransition(transition);
}
notifyTransitionEnd(transition);
break;
if (trigger != null && trigger.evaluate(new DefaultTriggerContext<S, E>(queuedEvent.getPayload()))) {
triggerQueue.add(new TriggerQueueItem(trigger, queuedEvent));
} else if (source.getDeferredEvents() != null && source.getDeferredEvents().contains(queuedEvent.getPayload())) {
defer = queuedEvent;
}
@@ -332,27 +334,25 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
}
}
private void processDeferList() {
private boolean processDeferList() {
log.debug("Process defer list");
boolean triggered = false;
ListIterator<Message<E>> iterator = deferList.listIterator();
while (iterator.hasNext()) {
Message<E> event = iterator.next();
for (Transition<S,E> transition : transitions) {
State<S,E> source = transition.getSource();
State<S,E> target = transition.getTarget();
Trigger<S, E> trigger = transition.getTrigger();
if (source.equals(currentState)) {
if (trigger != null && trigger.evaluate(event.getPayload())) {
StateContext<S, E> stateContext = new DefaultStateContext<S, E>(event.getHeaders(), extendedState, transition);
boolean transit = transition.transit(stateContext);
if (transit && transition.getKind() != TransitionKind.INTERNAL) {
switchToState(target, event, transition);
}
if (trigger != null && trigger.evaluate(new DefaultTriggerContext<S, E>(event.getPayload()))) {
triggerQueue.add(new TriggerQueueItem(trigger, event));
iterator.remove();
triggered = true;
}
}
}
}
return triggered;
}
private void scheduleEventQueueProcessing() {
@@ -361,7 +361,10 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
@Override
public void run() {
processEventQueue();
processDeferList();
processTriggerQueue();
while (processDeferList()) {
processTriggerQueue();
}
task = null;
}
};
@@ -369,6 +372,29 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
}
}
private void processTriggerQueue() {
log.debug("Process trigger queue");
TriggerQueueItem queueItem = null;
while ((queueItem = triggerQueue.poll()) != null) {
Message<E> queuedEvent = queueItem.message;
Transition<S, E> transition = triggerToTransitionMap.get(queueItem.trigger);
StateContext<S, E> stateContext = new DefaultStateContext<S, E>(queuedEvent.getHeaders(), extendedState, transition);
notifyTransitionStart(transition);
if (transition == null) {
continue;
}
boolean transit = transition.transit(stateContext);
if (transit && transition.getKind() != TransitionKind.INTERNAL) {
switchToState(transition.getTarget(), queuedEvent, transition);
notifyTransition(transition);
}
notifyTransitionEnd(transition);
}
}
private void callHandlers(State<S,E> sourceState, State<S,E> targetState, Message<E> event) {
@@ -465,4 +491,13 @@ public abstract class AbstractStateMachine<S, E> extends LifecycleObjectSupport
}
}
private class TriggerQueueItem {
Trigger<S, E> trigger;
Message<E> message;
public TriggerQueueItem(Trigger<S, E> trigger, Message<E> message) {
this.trigger = trigger;
this.message = message;
}
}
}

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public abstract class AbstractExternalTransition<S, E> extends AbstractTransition<S, E> implements Transition<S, E> {
public AbstractExternalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, target, actions, event, TransitionKind.EXTERNAL, guard);
public AbstractExternalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, target, actions, event, TransitionKind.EXTERNAL, guard, trigger);
}

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public class AbstractInternalTransition <S, E> extends AbstractTransition<S, E> implements Transition<S, E> {
public AbstractInternalTransition(State<S, E> source,Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, source, actions, event, TransitionKind.INTERNAL, guard);
public AbstractInternalTransition(State<S, E> source,Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, source, actions, event, TransitionKind.INTERNAL, guard, trigger);
}
}

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public class AbstractLocalTransition <S, E> extends AbstractTransition<S, E> implements Transition<S, E> {
public AbstractLocalTransition(State<S, E> source, State<S,E> target,Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, target, actions, event, TransitionKind.LOCAL, guard);
public AbstractLocalTransition(State<S, E> source, State<S,E> target,Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, target, actions, event, TransitionKind.LOCAL, guard, trigger);
}
}

View File

@@ -21,7 +21,6 @@ import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.EventTrigger;
import org.springframework.statemachine.trigger.Trigger;
import org.springframework.util.Assert;
@@ -48,17 +47,15 @@ public abstract class AbstractTransition<S, E> implements Transition<S, E> {
private Trigger<S, E> trigger;
public AbstractTransition(State<S, E> source, State<S, E> target, Collection<Action<S, E>> actions, E event,
TransitionKind kind, Guard<S, E> guard) {
TransitionKind kind, Guard<S, E> guard, Trigger<S, E> trigger) {
Assert.notNull(source, "Source must be set");
Assert.notNull(kind, "Transition type must be set");
this.source = source;
this.target = target;
this.actions = actions;
if (event != null) {
this.trigger = new EventTrigger<S, E>(event);
}
this.kind = kind;
this.guard = guard;
this.trigger = trigger;
}
@Override

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public class DefaultExternalTransition<S, E> extends AbstractExternalTransition<S, E> {
public DefaultExternalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, target, actions, event, guard);
public DefaultExternalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, target, actions, event, guard, trigger);
}
}

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public class DefaultInternalTransition<S, E> extends AbstractInternalTransition<S, E> {
public DefaultInternalTransition(State<S, E> source, Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, actions, event, guard);
public DefaultInternalTransition(State<S, E> source, Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, actions, event, guard, trigger);
}
}

View File

@@ -20,11 +20,12 @@ import java.util.Collection;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.trigger.Trigger;
public class DefaultLocalTransition<S, E> extends AbstractLocalTransition<S, E> {
public DefaultLocalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard) {
super(source, target, actions, event, guard);
public DefaultLocalTransition(State<S,E> source, State<S,E> target, Collection<Action<S, E>> actions, E event, Guard<S, E> guard, Trigger<S, E> trigger) {
super(source, target, actions, event, guard, trigger);
}
@Override

View File

@@ -0,0 +1,31 @@
/*
* 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.trigger;
public class DefaultTriggerContext<S, E> implements TriggerContext<S, E> {
private final E event;
public DefaultTriggerContext(E event) {
this.event = event;
}
@Override
public E getEvent() {
return event;
}
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.statemachine.trigger;
import org.springframework.util.ObjectUtils;
public class EventTrigger<S, E> implements Trigger<S, E> {
private final E event;
@@ -24,8 +26,8 @@ public class EventTrigger<S, E> implements Trigger<S, E> {
}
@Override
public boolean evaluate(E event) {
return this.event.equals(event);
public boolean evaluate(TriggerContext<S, E> context) {
return ObjectUtils.nullSafeEquals(event, context.getEvent());
}
}

View File

@@ -20,7 +20,7 @@ import org.springframework.statemachine.transition.Transition;
/**
* {@code Trigger} is the cause of the {@link Transition}. Cause is usually an
* event but can be some other signal or a change in some condition.
*
*
* @author Janne Valkealahti
*
* @param <S> the type of state
@@ -28,6 +28,12 @@ import org.springframework.statemachine.transition.Transition;
*/
public interface Trigger<S,E> {
boolean evaluate(E event);
/**
* Evaluate trigger.
*
* @param context the context
* @return true, triggers is fired, false otherwise
*/
boolean evaluate(TriggerContext<S, E> context);
}

View File

@@ -0,0 +1,22 @@
/*
* 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.trigger;
public interface TriggerContext<S, E> {
E getEvent();
}

View File

@@ -27,18 +27,22 @@ import org.junit.Test;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.state.DefaultPseudoState;
import org.springframework.statemachine.state.EnumState;
import org.springframework.statemachine.state.PseudoState;
import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.DefaultInternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;
public class EnumStateMachineTests extends AbstractStateMachineTests {
@Test
public void testSimpleStateSwitch() {
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI);
PseudoState pseudoState = new DefaultPseudoState(PseudoStateKind.INITIAL);
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI, pseudoState);
State<TestStates,TestEvents> stateS1 = new EnumState<TestStates,TestEvents>(TestStates.S1);
State<TestStates,TestEvents> stateS2 = new EnumState<TestStates,TestEvents>(TestStates.S2);
State<TestStates,TestEvents> stateS3 = new EnumState<TestStates,TestEvents>(TestStates.S3);
@@ -54,17 +58,17 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
Collection<Action<TestStates,TestEvents>> actionsFromSIToS1 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromSIToS1.add(new LoggingAction("actionsFromSIToS1"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
Collection<Action<TestStates,TestEvents>> actionsFromS1ToS2 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromS1ToS2.add(new LoggingAction("actionsFromS1ToS2"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS1ToS2 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
Collection<Action<TestStates,TestEvents>> actionsFromS2ToS3 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromS1ToS2.add(new LoggingAction("actionsFromS2ToS3"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS2ToS3 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
transitions.add(transitionFromSIToS1);
transitions.add(transitionFromS1ToS2);
@@ -73,6 +77,7 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
machine.setTaskExecutor(taskExecutor);
machine.afterPropertiesSet();
machine.start();
State<TestStates,TestEvents> initialState = machine.getInitialState();
@@ -101,13 +106,14 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
@Test
public void testDeferredEvents() {
PseudoState pseudoState = new DefaultPseudoState(PseudoStateKind.INITIAL);
Collection<TestEvents> deferred = new ArrayList<TestEvents>();
deferred.add(TestEvents.E2);
deferred.add(TestEvents.E3);
// states
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI, deferred);
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI, deferred, null, null, pseudoState);
State<TestStates,TestEvents> stateS1 = new EnumState<TestStates,TestEvents>(TestStates.S1);
State<TestStates,TestEvents> stateS2 = new EnumState<TestStates,TestEvents>(TestStates.S2);
State<TestStates,TestEvents> stateS3 = new EnumState<TestStates,TestEvents>(TestStates.S3);
@@ -124,17 +130,17 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
Collection<Action<TestStates,TestEvents>> actionsFromSIToS1 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromSIToS1.add(new LoggingAction("actionsFromSIToS1"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
Collection<Action<TestStates,TestEvents>> actionsFromS1ToS2 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromS1ToS2.add(new LoggingAction("actionsFromS1ToS2"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS1ToS2 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
Collection<Action<TestStates,TestEvents>> actionsFromS2ToS3 = new ArrayList<Action<TestStates,TestEvents>>();
actionsFromS1ToS2.add(new LoggingAction("actionsFromS2ToS3"));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS2ToS3 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
transitions.add(transitionFromSIToS1);
transitions.add(transitionFromS1ToS2);
@@ -143,8 +149,8 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
// create machine
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
// StateMachine<State<TestStates, TestEvents>, TestEvents> machine2 = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI);
machine.setTaskExecutor(taskExecutor);
machine.afterPropertiesSet();
machine.start();
State<TestStates,TestEvents> initialState = machine.getInitialState();
@@ -175,7 +181,7 @@ public class EnumStateMachineTests extends AbstractStateMachineTests {
Collection<Action<TestStates,TestEvents>> actionsInSI = new ArrayList<Action<TestStates,TestEvents>>();
actionsInSI.add(new LoggingAction("actionsInSI"));
DefaultInternalTransition<TestStates,TestEvents> transitionInternalSI =
new DefaultInternalTransition<TestStates,TestEvents>(stateSI, actionsInSI, TestEvents.E1, null);
new DefaultInternalTransition<TestStates,TestEvents>(stateSI, actionsInSI, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
// transitions
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();

View File

@@ -39,6 +39,7 @@ import org.springframework.statemachine.state.RegionState;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;
/**
* Statemachine tests using regions.
@@ -50,6 +51,7 @@ public class RegionMachineTests {
@Test
public void testSimpleRegion() throws Exception {
PseudoState pseudoState = new DefaultPseudoState(PseudoStateKind.INITIAL);
TestEntryAction entryActionS1 = new TestEntryAction("S1");
TestExitAction exitActionS1 = new TestExitAction("S1");
Collection<Action<TestStates, TestEvents>> entryActionsS1 = new ArrayList<Action<TestStates, TestEvents>>();
@@ -58,7 +60,7 @@ public class RegionMachineTests {
exitActionsS1.add(exitActionS1);
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI);
State<TestStates,TestEvents> stateSI = new EnumState<TestStates,TestEvents>(TestStates.SI, pseudoState);
State<TestStates,TestEvents> stateS1 = new EnumState<TestStates,TestEvents>(TestStates.S1, null, entryActionsS1, exitActionsS1);
State<TestStates,TestEvents> stateS2 = new EnumState<TestStates,TestEvents>(TestStates.S2);
State<TestStates,TestEvents> stateS3 = new EnumState<TestStates,TestEvents>(TestStates.S3);
@@ -72,13 +74,13 @@ public class RegionMachineTests {
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS1ToS2 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS2ToS3 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
transitions.add(transitionFromSIToS1);
transitions.add(transitionFromS1ToS2);
@@ -87,6 +89,7 @@ public class RegionMachineTests {
SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
EnumStateMachine<TestStates, TestEvents> machine = new EnumStateMachine<TestStates, TestEvents>(states, transitions, stateSI, null);
machine.setTaskExecutor(taskExecutor);
machine.afterPropertiesSet();
machine.start();
Collection<Region<TestStates,TestEvents>> regions = new ArrayList<Region<TestStates,TestEvents>>();
@@ -145,7 +148,7 @@ public class RegionMachineTests {
states11.add(stateS112);
Collection<Transition<TestStates,TestEvents>> transitions11 = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS112 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS112, null, TestEvents.E2, null);
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);
machine11.setTaskExecutor(taskExecutor);
@@ -156,7 +159,7 @@ public class RegionMachineTests {
states12.add(stateS121);
Collection<Transition<TestStates,TestEvents>> transitions12 = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS121 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS111, null, TestEvents.E3, null);
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);
machine12.setTaskExecutor(taskExecutor);
@@ -171,7 +174,7 @@ public class RegionMachineTests {
states.add(stateR);
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToRegionstate =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateR, null, TestEvents.E1, null);
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);

View File

@@ -46,6 +46,7 @@ import org.springframework.statemachine.state.StateMachineState;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.DefaultLocalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;
public class SubStateMachineTests extends AbstractStateMachineTests {
@@ -122,7 +123,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
states.add(stateS1);
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS1, null, TestEvents.E1, null);
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);
@@ -212,7 +213,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
states.add(stateS1);
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromS111ToS112 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS111, stateS112, null, TestEvents.E1, null);
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);
@@ -309,7 +310,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests {
states.add(stateS1);
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultLocalTransition<TestStates,TestEvents> transitionFromS11ToS1 =
new DefaultLocalTransition<TestStates,TestEvents>(stateS111, stateS1, null, TestEvents.E1, null);
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);

View File

@@ -29,6 +29,7 @@ import org.springframework.statemachine.EnumStateMachine;
import org.springframework.statemachine.region.Region;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;
/**
* Tests for states using a submachine.
@@ -55,13 +56,13 @@ public class RegionStateTests extends AbstractStateMachineTests {
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS1ToS2 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS2ToS3 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
transitions.add(transitionFromSIToS1);
transitions.add(transitionFromS1ToS2);

View File

@@ -28,6 +28,7 @@ import org.springframework.statemachine.AbstractStateMachineTests;
import org.springframework.statemachine.EnumStateMachine;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;
/**
* Tests for states using a submachine.
@@ -54,13 +55,13 @@ public class SubmachineStateTests extends AbstractStateMachineTests {
Collection<Transition<TestStates,TestEvents>> transitions = new ArrayList<Transition<TestStates,TestEvents>>();
DefaultExternalTransition<TestStates,TestEvents> transitionFromSIToS1 =
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateSI, stateS1, null, TestEvents.E1, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E1));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS1ToS2 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS1, stateS2, null, TestEvents.E2, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E2));
DefaultExternalTransition<TestStates,TestEvents> transitionFromS2ToS3 =
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null);
new DefaultExternalTransition<TestStates,TestEvents>(stateS2, stateS3, null, TestEvents.E3, null, new EventTrigger<TestStates,TestEvents>(TestEvents.E3));
transitions.add(transitionFromSIToS1);
transitions.add(transitionFromS1ToS2);