Reworked fix for SWF-307 and added unit test.

This commit is contained in:
Erwin Vervaet
2007-06-13 09:23:21 +00:00
parent 4c4e46c1ad
commit e2acb79f9b
5 changed files with 45 additions and 25 deletions

View File

@@ -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).

View File

@@ -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.
* <p>
* 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();
}

View File

@@ -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();

View File

@@ -14,4 +14,6 @@
</action-state>
<end-state id="end"/>
<import resource="namedActionFlowContext.xml"/>
</flow>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="aAction" class="org.springframework.webflow.execution.TestAction"/>
<bean id="bBean" class="org.springframework.binding.expression.support.TestBean"/>
<bean id="cAction" class="org.springframework.webflow.execution.TestAction"/>
</beans>