diff --git a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/common/annotation/AbstractImportingAnnotationConfiguration.java b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/common/annotation/AbstractImportingAnnotationConfiguration.java index 9bf7a0fe..c1404d40 100644 --- a/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/common/annotation/AbstractImportingAnnotationConfiguration.java +++ b/spring-statemachine-core/src/main/java/org/springframework/statemachine/config/common/annotation/AbstractImportingAnnotationConfiguration.java @@ -80,6 +80,11 @@ public abstract class AbstractImportingAnnotationConfiguration extends @Override protected BeanDefinition buildBeanDefinition(AnnotationMetadata importingClassMetadata, Class namedAnnotation) throws Exception { + + String enableStateMachineEnclosingClassName = importingClassMetadata.getClassName(); + Class enableStateMachineEnclosingClass = ClassUtils.forName(enableStateMachineEnclosingClassName, + getClass().getClassLoader()); + // return null if it looks like @EnableStateMachine was annotated with class + // not extending StateMachineConfigurer. + if (!ClassUtils.isAssignable(StateMachineConfigurer.class, enableStateMachineEnclosingClass)) { + return null; + } + BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder .rootBeanDefinition(StateMachineDelegatingFactoryBean.class); AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes( diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/RegionMachineTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/RegionMachineTests.java index e3dde05d..ec4ff4fd 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/RegionMachineTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/RegionMachineTests.java @@ -38,7 +38,6 @@ import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; -import org.springframework.statemachine.event.StateMachineEventPublisherConfiguration; import org.springframework.statemachine.region.Region; import org.springframework.statemachine.state.DefaultPseudoState; import org.springframework.statemachine.state.EnumState; @@ -227,7 +226,7 @@ public class RegionMachineTests extends AbstractStateMachineTests { @Test public void testMultiRegion() throws Exception { - context.register(StateMachineEventPublisherConfiguration.class, Config1.class); + context.register(Config1.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked") @@ -259,7 +258,7 @@ public class RegionMachineTests extends AbstractStateMachineTests { @SuppressWarnings("unchecked") @Test public void testRegionsInNestedState() throws Exception { - context.register(StateMachineEventPublisherConfiguration.class, Config2.class); + context.register(Config2.class); context.refresh(); ObjectStateMachine machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); @@ -279,7 +278,7 @@ public class RegionMachineTests extends AbstractStateMachineTests { @Test public void testParallelRegionExecution() throws Exception { - context.register(StateMachineEventPublisherConfiguration.class, Config3.class, BaseConfig2.class); + context.register(Config3.class, BaseConfig2.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked") @@ -319,7 +318,7 @@ public class RegionMachineTests extends AbstractStateMachineTests { @Test public void testParallelRegionExecutionInInitialState() throws Exception { - context.register(StateMachineEventPublisherConfiguration.class, Config4.class, BaseConfig2.class); + context.register(Config4.class, BaseConfig2.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked") diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/SubStateMachineTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/SubStateMachineTests.java index b71f9056..f4437e03 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/SubStateMachineTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/SubStateMachineTests.java @@ -36,7 +36,6 @@ import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; -import org.springframework.statemachine.event.StateMachineEventPublisherConfiguration; import org.springframework.statemachine.state.DefaultPseudoState; import org.springframework.statemachine.state.EnumState; import org.springframework.statemachine.state.PseudoState; @@ -382,7 +381,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests { @Test public void testMixedStates() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config2.class); + context.register(BaseConfig.class, Config2.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked") @@ -396,7 +395,7 @@ public class SubStateMachineTests extends AbstractStateMachineTests { @Test public void testStateChangeWithinMachine() { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config3.class); + context.register(BaseConfig.class, Config3.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked") diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java index 4ede1187..b18d375b 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/config/ConfigurationTests.java @@ -150,7 +150,7 @@ public class ConfigurationTests extends AbstractStateMachineTests { assertThat(((List)o3).size(), is(2)); } - @Test(expected = BeanCreationException.class) + @Test public void testEnableStateMachineNoAdapter() { context.register(Config12.class); context.refresh(); diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ContextEventTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ContextEventTests.java index f8cd21af..f93b7355 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ContextEventTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ContextEventTests.java @@ -29,9 +29,12 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.statemachine.AbstractStateMachineTests; import org.springframework.statemachine.ObjectStateMachine; +import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.StateMachineSystemConstants; import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter; +import org.springframework.statemachine.config.StateMachineBuilder; +import org.springframework.statemachine.config.StateMachineBuilder.Builder; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; @@ -51,7 +54,7 @@ public class ContextEventTests extends AbstractStateMachineTests { @SuppressWarnings("unchecked") @Test public void contextEventsEnabled() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config.class, Config1.class); + context.register(BaseConfig.class, Config.class, Config1.class); context.refresh(); ObjectStateMachine machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); @@ -65,7 +68,7 @@ public class ContextEventTests extends AbstractStateMachineTests { @SuppressWarnings("unchecked") @Test public void contextEventsDisabled() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config.class, Config2.class); + context.register(BaseConfig.class, Config.class, Config2.class); context.refresh(); ObjectStateMachine machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); @@ -76,6 +79,34 @@ public class ContextEventTests extends AbstractStateMachineTests { assertThat(listener.count, is(0)); } + @SuppressWarnings("unchecked") + @Test + public void contextEventsWithManualBuilder() throws Exception { + context.register(BaseConfig.class, Config.class, Config3.class); + context.refresh(); + ObjectStateMachine machine = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); + machine.start(); + machine.sendEvent(TestEvents.E1); + StateMachineApplicationEventListener listener = context.getBean(StateMachineApplicationEventListener.class); + listener.latch.await(1, TimeUnit.SECONDS); + assertThat(listener.count, greaterThan(1)); + } + + @SuppressWarnings("unchecked") + @Test + public void contextEventsWithManualBuilderExternalConfigClass() throws Exception { + context.register(BaseConfig.class, Config.class, ExternalConfig.class); + context.refresh(); + ObjectStateMachine machine = + context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, ObjectStateMachine.class); + machine.start(); + machine.sendEvent(TestEvents.E1); + StateMachineApplicationEventListener listener = context.getBean(StateMachineApplicationEventListener.class); + listener.latch.await(1, TimeUnit.SECONDS); + assertThat(listener.count, greaterThan(1)); + } + @Configuration @EnableStateMachine static class Config1 extends EnumStateMachineConfigurerAdapter { @@ -124,6 +155,28 @@ public class ContextEventTests extends AbstractStateMachineTests { } + @Configuration + @EnableStateMachine + public static class Config3 { + + @Bean + public StateMachine stateMachine() throws Exception { + + Builder builder = StateMachineBuilder.builder(); + builder.configureStates() + .withStates() + .initial(TestStates.S1) + .state(TestStates.S2); + builder.configureTransitions() + .withExternal() + .source(TestStates.S1) + .target(TestStates.S2) + .event(TestEvents.E1); + return builder.build(); + } + + } + @Configuration static class Config { diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ExternalConfig.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ExternalConfig.java new file mode 100644 index 00000000..3541661e --- /dev/null +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/ExternalConfig.java @@ -0,0 +1,47 @@ +/* + * 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.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.statemachine.AbstractStateMachineTests.TestEvents; +import org.springframework.statemachine.AbstractStateMachineTests.TestStates; +import org.springframework.statemachine.StateMachine; +import org.springframework.statemachine.config.EnableStateMachine; +import org.springframework.statemachine.config.StateMachineBuilder; +import org.springframework.statemachine.config.StateMachineBuilder.Builder; + +@Configuration +@EnableStateMachine +public class ExternalConfig { + + @Bean + public StateMachine stateMachine() throws Exception { + + Builder builder = StateMachineBuilder.builder(); + builder.configureStates() + .withStates() + .initial(TestStates.S1) + .state(TestStates.S2); + builder.configureTransitions() + .withExternal() + .source(TestStates.S1) + .target(TestStates.S2) + .event(TestEvents.E1); + return builder.build(); + } + +} diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/StateMachineEventTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/StateMachineEventTests.java index 70d4c513..ad3e8fac 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/StateMachineEventTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/event/StateMachineEventTests.java @@ -15,8 +15,8 @@ */ package org.springframework.statemachine.event; -import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; @@ -57,7 +57,7 @@ public class StateMachineEventTests extends AbstractStateMachineTests { @Test public void testContextEvents() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config1.class); + context.register(BaseConfig.class, Config1.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); TestEventListener listener = context.getBean(TestEventListener.class); @@ -80,7 +80,7 @@ public class StateMachineEventTests extends AbstractStateMachineTests { @Test public void testEventNotAccepted() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config1.class); + context.register(BaseConfig.class, Config1.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); TestEventListener eventListener = context.getBean(TestEventListener.class); @@ -110,7 +110,7 @@ public class StateMachineEventTests extends AbstractStateMachineTests { @Test public void testSubmachineHandlesEvent() throws Exception { - context.register(BaseConfig.class, StateMachineEventPublisherConfiguration.class, Config2.class); + context.register(BaseConfig.class, Config2.class); context.refresh(); assertTrue(context.containsBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE)); @SuppressWarnings("unchecked")