From f6037802fde01cf1a7fb8fb22fcf39396eb0d3da Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Thu, 26 Nov 2015 12:10:22 +0000 Subject: [PATCH] Fix empty @OnTransition - Fix so that bean method will be called with plain @OnTransition having no source or target defined. - Fixes #128 --- docs/src/reference/asciidoc/sm.adoc | 3 +- .../support/AbstractStateMachine.java | 8 +++-- .../annotation/MethodAnnotationTests.java | 31 +++++++++++++++---- .../docs/DocsConfigurationSampleTests.java | 4 +++ 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/docs/src/reference/asciidoc/sm.adoc b/docs/src/reference/asciidoc/sm.adoc index 3413984e..ddc15216 100644 --- a/docs/src/reference/asciidoc/sm.adoc +++ b/docs/src/reference/asciidoc/sm.adoc @@ -668,7 +668,8 @@ into your beans. === Annotation Support _@WithStateMachine_ annotation can be used to associate a state machine with a existing bean. Within this annotation a property's -_source_ and _target_ can be used to qualify a transition +_source_ and _target_ can be used to qualify a transition. If +_source_ and _target_ is left empty then any transition is matched. [source,java,indent=0] ---- 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 53d9caea..665eb281 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 @@ -23,8 +23,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.Map.Entry; +import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,10 +36,10 @@ import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.ExtendedState; +import org.springframework.statemachine.ExtendedState.ExtendedStateChangeListener; import org.springframework.statemachine.StateContext; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.StateMachineContext; -import org.springframework.statemachine.ExtendedState.ExtendedStateChangeListener; import org.springframework.statemachine.access.StateMachineAccess; import org.springframework.statemachine.access.StateMachineAccessor; import org.springframework.statemachine.access.StateMachineFunction; @@ -907,7 +907,7 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo WithStateMachine withStateMachine = AnnotationUtils.findAnnotation(entry.getValue().getBeanClass(), WithStateMachine.class); if (withStateMachine == null || !ObjectUtils.nullSafeEquals(withStateMachine.name(), getBeanName())) { continue; - } + } OnTransition metaAnnotation = entry.getValue().getMetaAnnotation(); Annotation annotation = entry.getValue().getAnnotation(); if (transitionHandlerMatch(metaAnnotation, annotation, sourceState, targetState)) { @@ -959,6 +959,8 @@ public abstract class AbstractStateMachine extends StateMachineObjectSuppo StateMachineUtils.toStringCollection(targetState.getIds()))) { handle = true; } + } else if (scoll.isEmpty() && tcoll.isEmpty()) { + handle = true; } return handle; diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/annotation/MethodAnnotationTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/annotation/MethodAnnotationTests.java index aed7ac60..1bcd6f6f 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/annotation/MethodAnnotationTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/annotation/MethodAnnotationTests.java @@ -30,8 +30,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.AbstractStateMachineTests; -import org.springframework.statemachine.ObjectStateMachine; import org.springframework.statemachine.ExtendedState; +import org.springframework.statemachine.ObjectStateMachine; import org.springframework.statemachine.StateMachineSystemConstants; import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; @@ -48,15 +48,23 @@ public class MethodAnnotationTests extends AbstractStateMachineTests { ObjectStateMachine machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); assertThat(context.containsBean("fooMachine"), is(true)); + Bean1 bean1 = context.getBean(Bean1.class); machine.start(); - Bean1 bean1 = context.getBean(Bean1.class); + assertThat(bean1.onMethod1Latch.await(2, TimeUnit.SECONDS), is(false)); + assertThat(bean1.onOnTransitionLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(bean1.onMethod1Count, is(0)); + assertThat(bean1.onOnTransitionCount, is(1)); + + bean1.reset(1, 1); // this event should cause 'method1' to get called machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build()); assertThat(bean1.onMethod1Latch.await(2, TimeUnit.SECONDS), is(true)); - assertThat(bean1.onOnTransitionFromS2ToS3Latch.await(2, TimeUnit.SECONDS), is(false)); + assertThat(bean1.onOnTransitionLatch.await(2, TimeUnit.SECONDS), is(true)); + assertThat(bean1.onMethod1Count, is(1)); + assertThat(bean1.onOnTransitionCount, is(1)); context.close(); } @@ -93,16 +101,27 @@ public class MethodAnnotationTests extends AbstractStateMachineTests { static class Bean1 { CountDownLatch onMethod1Latch = new CountDownLatch(1); - CountDownLatch onOnTransitionFromS2ToS3Latch = new CountDownLatch(1); + CountDownLatch onOnTransitionLatch = new CountDownLatch(1); + int onMethod1Count; + int onOnTransitionCount; @OnTransition(source = "S1", target = "S2") public void method1() { + onMethod1Count++; onMethod1Latch.countDown(); } @OnTransition - public void onTransitionFromS2ToS3() { - onOnTransitionFromS2ToS3Latch.countDown(); + public void onTransition() { + onOnTransitionCount++; + onOnTransitionLatch.countDown(); + } + + public void reset(int a1, int a2) { + onMethod1Latch = new CountDownLatch(a1); + onOnTransitionLatch = new CountDownLatch(a2); + onMethod1Count = 0; + onOnTransitionCount = 0; } } diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java index fdca4c08..edd4fa07 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java @@ -415,6 +415,10 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests { @OnTransition(source = "S1", target = "S2") public void fromS1ToS2() { } + + @OnTransition + public void anyTransition() { + } } // end::snippetI[]