diff --git a/spring-webflow/changelog.txt b/spring-webflow/changelog.txt index 2a09a50b..9c016268 100644 --- a/spring-webflow/changelog.txt +++ b/spring-webflow/changelog.txt @@ -26,7 +26,7 @@ Package org.springframework.webflow.engine * Added name(String, Action) method to AbstractFlowBuilder for convenient creation of named actions. * AnnotatedAction now has a convenience putAttribute(String, Object) method. * Added annotate(Action) method to AbstractFlowBuilder. -* Added populateLocalContext(Flow, GenericApplicationContext, Resource[]) hook method to XmlFlowBuilder +* Added createLocalBeanFactory(Flow flow, Resource[] resources) hook method to XmlFlowBuilder to allow for control over the registration of beans needed locally by a flow definition. Useful for testing (SWF-307). diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java index 74421572..4b50520b 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/XmlFlowBuilder.java @@ -466,13 +466,17 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder { } /** - * Create the local bean factory from the resources provided. This factory typcially houses services needed locally - * by the flow definition. + * Create the local bean factory from the resources provided. This factory typcially houses services needed + * locally by the flow definition. + *

+ * Subclasses may override this metod to customize the population of the context local to the flow definition + * being built, registering mock implementations of services for a test environment. * @param flow the current flow definition being built * @param resources the file resources to assemble the bean factory from; typically XML-based * @return the bean factory + * @since 1.0.4 */ - private BeanFactory createLocalBeanFactory(Flow flow, Resource[] resources) { + protected BeanFactory createLocalBeanFactory(Flow flow, Resource[] resources) { // see if this factory has a parent BeanFactory parent = null; if (localFlowServiceLocator.isEmpty()) { @@ -506,24 +510,11 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder { } } context.setResourceLoader(getFlowServiceLocator().getResourceLoader()); - // populate and initialize the context - populateLocalContext(flow, context, resources); + new XmlBeanDefinitionReader(context).loadBeanDefinitions(resources); context.refresh(); return context; } - /** - * Hook method subclasses may override to customize the population of the context local to the flow definition being built. - * Such a context typically houses services needed by the flow definition. A subclass might override this method to - * register mock implementations of services for a test environment. - * @param flow the current flow definition being built - * @param context the flow-local context to populate - * @param resources the imported XML resources that typically define the structure of this context - */ - protected void populateLocalContext(Flow flow, GenericApplicationContext context, Resource[] resources) { - new XmlBeanDefinitionReader(context).loadBeanDefinitions(resources); - } - private void destroyLocalServiceRegistry() { localFlowServiceLocator.pop(); } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/NamedActionXmlFlowBuilderTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/NamedActionXmlFlowBuilderTests.java index 0eda8d2d..8e76aa95 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/NamedActionXmlFlowBuilderTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/NamedActionXmlFlowBuilderTests.java @@ -15,9 +15,15 @@ */ package org.springframework.webflow.engine.builder.xml; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.definition.registry.FlowDefinitionResource; +import org.springframework.webflow.engine.Flow; +import org.springframework.webflow.engine.builder.FlowBuilder; +import org.springframework.webflow.engine.builder.FlowServiceLocator; import org.springframework.webflow.execution.Action; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; @@ -31,13 +37,7 @@ import org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests; */ public class NamedActionXmlFlowBuilderTests extends AbstractXmlFlowExecutionTests { - protected FlowDefinitionResource getFlowDefinitionResource() { - return new FlowDefinitionResource( - new ClassPathResource("namedActionFlow.xml", NamedActionXmlFlowBuilderTests.class)); - } - private int executionOrderCounter = 0; - private Action aAction; private int aActionExecutionCount = 0; private int aActionExecutionOrder; @@ -65,13 +65,28 @@ public class NamedActionXmlFlowBuilderTests extends AbstractXmlFlowExecutionTest } }; } - + + protected FlowDefinitionResource getFlowDefinitionResource() { + return new FlowDefinitionResource( + new ClassPathResource("namedActionFlow.xml", NamedActionXmlFlowBuilderTests.class)); + } + protected void registerMockServices(MockFlowServiceLocator serviceRegistry) { serviceRegistry.registerBean("aAction", aAction); serviceRegistry.registerBean("bBean", bBean); serviceRegistry.registerBean("cAction", cAction); } + protected FlowBuilder createFlowBuilder(Resource resource, FlowServiceLocator flowServiceLocator) { + return new XmlFlowBuilder(resource, flowServiceLocator) { + protected BeanFactory createLocalBeanFactory(Flow flow, Resource[] resources) { + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("bBean", bBean); + return beanFactory; + } + }; + } + public void testActionExecutionOrder() { startFlow(); assertFlowExecutionEnded(); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlow.xml b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlow.xml index c012e57d..31a5d6ea 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlow.xml +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlow.xml @@ -14,4 +14,6 @@ + + \ No newline at end of file diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlowContext.xml b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlowContext.xml new file mode 100644 index 00000000..d60baaa5 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/xml/namedActionFlowContext.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file