diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/state/AbstractState.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/state/AbstractState.java index ce53815d..36a461de 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/state/AbstractState.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/state/AbstractState.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2017 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. @@ -198,17 +198,13 @@ public abstract class AbstractState extends LifecycleObjectSupport impleme public void exit(StateContext context) { cancelStateActions(); stateListener.onExit(context); - for (Trigger trigger : triggers) { - trigger.disarm(); - } + disarmTriggers(); } @Override public void entry(StateContext context) { stateListener.onEntry(context); - for (Trigger trigger : triggers) { - trigger.arm(); - } + armTriggers(); scheduleStateActions(context); } @@ -292,6 +288,16 @@ public abstract class AbstractState extends LifecycleObjectSupport impleme } } + @Override + protected void doStart() { + armTriggers(); + } + + @Override + protected void doStop() { + disarmTriggers(); + } + /** * Gets the submachine. * @@ -332,6 +338,24 @@ public abstract class AbstractState extends LifecycleObjectSupport impleme return triggers; } + /** + * Arm triggers. + */ + protected void armTriggers() { + for (Trigger trigger : triggers) { + trigger.arm(); + } + } + + /** + * Disarm triggers. + */ + protected void disarmTriggers() { + for (Trigger trigger : triggers) { + trigger.disarm(); + } + } + /** * Cancel existing state actions and clear list. */ diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java index a63b0aaa..342ce9d3 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/support/AbstractStateMachine.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.context.Lifecycle; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; @@ -727,6 +728,9 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo if (stateSet && stateMachineContext.getExtendedState() != null) { this.extendedState = stateMachineContext.getExtendedState(); } + if (currentState instanceof Lifecycle) { + ((Lifecycle)currentState).start(); + } } @Override diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineResetTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineResetTests.java index d874cf2f..2e3ba6e7 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineResetTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/StateMachineResetTests.java @@ -33,7 +33,9 @@ import org.springframework.statemachine.access.StateMachineAccess; import org.springframework.statemachine.access.StateMachineFunction; import org.springframework.statemachine.action.Action; import org.springframework.statemachine.config.EnableStateMachine; +import org.springframework.statemachine.config.EnableStateMachineFactory; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; +import org.springframework.statemachine.config.StateMachineFactory; import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; @@ -251,6 +253,31 @@ public class StateMachineResetTests extends AbstractStateMachineTests { assertThat(machine.getExtendedState().getVariables().size(), is(0)); } + @Test + public void testRestoreWithTimer() throws Exception { + context.register(Config4.class); + context.refresh(); + @SuppressWarnings("unchecked") + StateMachineFactory factory = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINEFACTORY, + StateMachineFactory.class); + StateMachine machine = factory.getStateMachine(); + + DefaultStateMachineContext stateMachineContext = new DefaultStateMachineContext(States.S1, null, + null, null); + machine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction>() { + + @Override + public void apply(StateMachineAccess function) { + function.resetStateMachine(stateMachineContext); + } + }); + + machine.start(); + Thread.sleep(1100); + assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2)); + + } + @Configuration @EnableStateMachine static class Config1 extends EnumStateMachineConfigurerAdapter { @@ -420,6 +447,36 @@ public class StateMachineResetTests extends AbstractStateMachineTests { } + @Configuration + @EnableStateMachineFactory + static class Config4 extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineStateConfigurer states) + throws Exception { + states + .withStates() + .initial(States.S0) + .state(States.S1) + .state(States.S2); + } + + @Override + public void configure(StateMachineTransitionConfigurer transitions) + throws Exception { + transitions + .withExternal() + .source(States.S0) + .target(States.S1) + .event(Events.A) + .and() + .withExternal() + .source(States.S1) + .target(States.S2) + .timerOnce(1000); + } + } + public static enum States { S0, S1, S11, S12, S2, S21, S211, S212 }