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 2a8aea9e..07ba7c08 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 @@ -812,7 +812,8 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo StateContext stateContext = buildStateContext(Stage.STATE_CHANGED, message, transition, stateMachine); State toState = followLinkedPseudoStates(state, stateContext); PseudoStateKind kind = state.getPseudoState() != null ? state.getPseudoState().getKind() : null; - if (kind != null && (kind != PseudoStateKind.INITIAL && kind != PseudoStateKind.JOIN && kind != PseudoStateKind.FORK)) { + if (kind != null && (kind != PseudoStateKind.INITIAL && kind != PseudoStateKind.JOIN + && kind != PseudoStateKind.FORK && kind != PseudoStateKind.END)) { callPreStateChangeInterceptors(toState, message, transition, stateMachine); } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateChangeInterceptorTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateChangeInterceptorTests.java index 15899a03..9c70a10b 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateChangeInterceptorTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/support/StateChangeInterceptorTests.java @@ -242,6 +242,48 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests { assertThat(interceptor.preStateChangeStates.get(0).getId(), is(interceptor.postStateChangeStates.get(0).getId())); } + @Test + public void testIntercept6() throws InterruptedException { + context.register(Config5.class); + context.refresh(); + @SuppressWarnings("unchecked") + StateMachine machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class); + TestListener listener = new TestListener(); + machine.addStateListener(listener); + TestStateChangeInterceptor interceptor = new TestStateChangeInterceptor(); + + machine.getStateMachineAccessor().doWithRegion(new StateMachineFunction>() { + + @Override + public void apply(StateMachineAccess function) { + function.addStateMachineInterceptor(interceptor); + } + }); + + machine.start(); + assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(listener.stateChangedCount, is(1)); + assertThat(machine.getState().getIds(), containsInAnyOrder(States.S0)); + + interceptor.reset(1); + listener.reset(1); + machine.sendEvent(Events.A); + assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(listener.stateChangedCount, is(1)); + assertThat(machine.getState().getIds(), containsInAnyOrder(States.S1)); + assertThat(interceptor.preStateChangeLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(interceptor.preStateChangeCount, is(1)); + + interceptor.reset(1); + listener.reset(1); + machine.sendEvent(Events.E); + assertThat(listener.stateChangedLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(listener.stateChangedCount, is(1)); + assertThat(machine.getState().getIds(), containsInAnyOrder(States.S2)); + assertThat(interceptor.preStateChangeLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(interceptor.preStateChangeCount, is(1)); + } + @Configuration @EnableStateMachine static class Config1 extends EnumStateMachineConfigurerAdapter { @@ -454,6 +496,35 @@ public class StateChangeInterceptorTests extends AbstractStateMachineTests { } } + @Configuration + @EnableStateMachine + static class Config5 extends EnumStateMachineConfigurerAdapter { + + @Override + public void configure(StateMachineStateConfigurer states) + throws Exception { + states + .withStates() + .initial(States.S0) + .state(States.S1) + .end(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) + .event(Events.E); + } + + } + public static enum States { S0, S1, S11, S12, S2, S21, S211, S212, S3; }