diff --git a/spring-webflow/changelog.txt b/spring-webflow/changelog.txt index 80170f3b..790a796c 100644 --- a/spring-webflow/changelog.txt +++ b/spring-webflow/changelog.txt @@ -31,6 +31,9 @@ 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 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). Package org.springframework.webflow.execution * Added a holder for the FlowExecutionContext of a request (SWF-163). @@ -52,6 +55,9 @@ Package org.springframework.webflow.support Package org.springframework.webflow.test * Added the ability to apply multiple listeners to a test case (SWF-334). +* Relaxed 'final' qualifier on AbstractXmlFlowExecutionTests#createFlowBuilder(FlowServiceLocator). + Overriding this method is useful for customizing the builder's population of the bean factory local to the + flow definition (SWF-307). Changes in version 1.0.3 (24.04.2007) ------------------------------------- diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceLocator.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceLocator.java index fa776a55..f64b05f5 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceLocator.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceLocator.java @@ -35,14 +35,14 @@ import org.springframework.webflow.engine.builder.FlowServiceLocator; import org.springframework.webflow.execution.Action; /** - * Searches flow-local registries first before querying the global, externally + * Flow service locator that searches flow-local registries first before querying the global, externally * managed flow service locator. *
* Internal helper class of the {@link org.springframework.webflow.engine.builder.xml.XmlFlowBuilder}. * Package private to highlight it's non-public nature. - * + * * @see org.springframework.webflow.engine.builder.xml.XmlFlowBuilder - * + * * @author Keith Donald */ class LocalFlowServiceLocator implements FlowServiceLocator { @@ -70,17 +70,9 @@ class LocalFlowServiceLocator implements FlowServiceLocator { * @param registry the local registry */ public void push(LocalFlowServiceRegistry registry) { - registry.init(this, parent); localRegistries.push(registry); } - /** - * Pop a registry off the stack. - */ - public LocalFlowServiceRegistry pop() { - return (LocalFlowServiceRegistry)localRegistries.pop(); - } - /** * Pops all registries off the stack until the stack is empty. */ @@ -91,7 +83,14 @@ class LocalFlowServiceLocator implements FlowServiceLocator { } /** - * Returns the top registry on the stack + * Pop a registry off the stack. + */ + public LocalFlowServiceRegistry pop() { + return (LocalFlowServiceRegistry)localRegistries.pop(); + } + + /** + * Returns the top registry on the stack. */ public LocalFlowServiceRegistry top() { return (LocalFlowServiceRegistry)localRegistries.peek(); @@ -183,7 +182,7 @@ class LocalFlowServiceLocator implements FlowServiceLocator { } public BeanFactory getBeanFactory() { - return top().getContext(); + return top().getBeanFactory(); } public ResourceLoader getResourceLoader() { @@ -208,8 +207,7 @@ class LocalFlowServiceLocator implements FlowServiceLocator { } /** - * Does this flow local service locator contain a bean defintion - * for given id? + * Does this flow local service locator contain a bean defintion for the given id? */ protected boolean containsBean(String id) { if (localRegistries.isEmpty()) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceRegistry.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceRegistry.java index cfacfe59..24136742 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceRegistry.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/builder/xml/LocalFlowServiceRegistry.java @@ -16,25 +16,18 @@ package org.springframework.webflow.engine.builder.xml; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.io.Resource; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.webflow.engine.Flow; -import org.springframework.webflow.engine.builder.FlowServiceLocator; /** - * Simple value object that holds a reference to a local artifact registry - * of a flow definition that is in the process of being constructed. + * Simple object that holds a reference to a local bean factory housing services needed by a flow definition + * at execution time. *
- * Internal helper class of the {@link org.springframework.webflow.engine.builder.xml.XmlFlowBuilder}. - * Package private to highlight it's non-public nature. - * + * Internal helper class of the {@link org.springframework.webflow.engine.builder.xml.XmlFlowBuilder}. Package private + * to highlight it's non-public nature. + * * @see org.springframework.webflow.engine.builder.xml.XmlFlowBuilder * @see org.springframework.webflow.engine.builder.xml.LocalFlowServiceLocator - * + * * @author Keith Donald */ class LocalFlowServiceRegistry { @@ -44,25 +37,19 @@ class LocalFlowServiceRegistry { */ private Flow flow; - /** - * The locations of the registry resource definitions. - */ - private Resource[] resources; - /** * The local registry holding the artifacts local to the flow. */ - private GenericApplicationContext context; + private BeanFactory beanFactory; /** - * Create a new registry, loading artifact definitions from - * given resources. + * Create a new local service registry. * @param flow the flow this registry is for (and scoped by) - * @param resources the registry resource definitions + * @param beanFactory the actual backing registry - a Spring bean factory */ - public LocalFlowServiceRegistry(Flow flow, Resource[] resources) { + public LocalFlowServiceRegistry(Flow flow, BeanFactory beanFactory) { this.flow = flow; - this.resources = resources; + this.beanFactory = beanFactory; } /** @@ -73,69 +60,9 @@ class LocalFlowServiceRegistry { } /** - * Returns the resources defining registry artifacts. + * Returns the bean factory acting as the physical registry. */ - public Resource[] getResources() { - return resources; - } - - /** - * Retuns the application context holding registry artifacts. - */ - public ApplicationContext getContext() { - return context; - } - - /** - * Initialize this registry of the local flow service locator. - * @param localFactory the local flow service locator - * @param rootFactory the root service locator - */ - public void init(LocalFlowServiceLocator localFactory, FlowServiceLocator rootFactory) { - BeanFactory parent = null; - if (localFactory.isEmpty()) { - try { - parent = rootFactory.getBeanFactory(); - } - catch (UnsupportedOperationException e) { - // can't link to a parent - } - } - else { - parent = localFactory.top().context; - } - context = createLocalFlowContext(parent, rootFactory); - new XmlBeanDefinitionReader(context).loadBeanDefinitions(resources); - context.refresh(); - } - - /** - * Create the flow local application context. - * @param parent the parent application context - * @param rootFactory the root service locator, used to obtain a resource - * loader - * @return the flow local application context - */ - private GenericApplicationContext createLocalFlowContext(BeanFactory parent, FlowServiceLocator rootFactory) { - if (parent instanceof WebApplicationContext) { - GenericWebApplicationContext context = new GenericWebApplicationContext(); - context.setServletContext(((WebApplicationContext)parent).getServletContext()); - context.setParent((WebApplicationContext)parent); - context.setResourceLoader(rootFactory.getResourceLoader()); - return context; - } - else { - GenericApplicationContext context = new GenericApplicationContext(); - if (parent instanceof ApplicationContext) { - context.setParent((ApplicationContext)parent); - } - else { - if (parent != null) { - context.getBeanFactory().setParentBeanFactory(parent); - } - } - context.setResourceLoader(rootFactory.getResourceLoader()); - return context; - } + public BeanFactory getBeanFactory() { + return beanFactory; } } \ No newline at end of file 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 165eb8e9..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 @@ -25,6 +25,7 @@ import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; import org.springframework.binding.convert.ConversionExecutor; import org.springframework.binding.convert.ConversionService; import org.springframework.binding.expression.Expression; @@ -38,11 +39,15 @@ import org.springframework.binding.mapping.RequiredMapping; import org.springframework.binding.method.MethodSignature; import org.springframework.binding.method.Parameter; import org.springframework.binding.method.Parameters; +import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.io.Resource; import org.springframework.core.style.ToStringCreator; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.webflow.action.ActionResultExposer; import org.springframework.webflow.action.EvaluateAction; import org.springframework.webflow.action.SetAction; @@ -78,34 +83,29 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** - * Flow builder that builds flows as defined in an XML document. The XML document - * should adhere to the following format: - * + * Flow builder that builds flows as defined in an XML document. The XML document should adhere to the following format: + * *
* <?xml version="1.0" encoding="UTF-8"?> * <flow xmlns="http://www.springframework.org/schema/webflow" * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" * xsi:schemaLocation="http://www.springframework.org/schema/webflow * http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd"> - * + * * <!-- Define your states here --> - * + * * </flow> *- * + * *
- * Consult the webflow - * XML schema for more information on the XML-based flow definition format. + * Consult the web flow XML schema + * for more information on the XML-based flow definition format. *
- * This builder will setup a flow-local bean factory for the flow being
- * constructed. That flow-local bean factory will be populated with XML bean
- * definitions contained in files referenced using the "import" element. The
- * flow-local bean factory will use the bean factory defing this flow builder as
- * a parent. As such, the flow can access artifacts in either its flow-local
- * bean factory or in the parent bean factory hierarchy, e.g. the bean factory
- * of the dispatcher.
- *
+ * This builder will setup a flow-local bean factory for the flow being constructed. That flow-local bean factory will
+ * be populated with XML bean definitions contained in files referenced using the "import" element. The flow-local bean
+ * factory will use the bean factory defing this flow builder as a parent. As such, the flow can access artifacts in
+ * either its flow-local bean factory or in the parent bean factory hierarchy, e.g. the bean factory of the dispatcher.
+ *
* @author Erwin Vervaet
* @author Keith Donald
*/
@@ -238,15 +238,14 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private static final String RESOURCE_ATTRIBUTE = "resource";
/**
- * The resource from which the document element being parsed was read. Used
- * as a location for relative resource lookup.
+ * The resource from which the document element being parsed was read. Used as a location for relative resource
+ * lookup.
*/
protected Resource location;
/**
- * A flow service locator local to this builder that first looks in a
- * locally-managed Spring application context for services before searching
- * the externally managed {@link #getFlowServiceLocator()}.
+ * A flow service locator local to this builder that first looks in a locally-managed Spring bean factory for
+ * services before searching the externally managed {@link #getFlowServiceLocator() service locator}.
*/
private LocalFlowServiceLocator localFlowServiceLocator;
@@ -256,14 +255,12 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private DocumentLoader documentLoader = new DefaultDocumentLoader();
/**
- * The in-memory document object model (DOM) of the XML Document read from
- * the flow definition resource.
+ * The in-memory document object model (DOM) of the XML Document read from the flow definition resource.
*/
private Document document;
/**
- * Create a new XML flow builder parsing the document at the specified
- * location.
+ * Create a new XML flow builder parsing the document at the specified location.
* @param location the location of the XML-based flow definition resource
*/
public XmlFlowBuilder(Resource location) {
@@ -271,12 +268,10 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
/**
- * Create a new XML flow builder parsing the document at the specified
- * location, using the provided service locator to access externally managed
- * flow artifacts.
+ * Create a new XML flow builder parsing the document at the specified location, using the provided service locator
+ * to access externally managed flow artifacts.
* @param location the location of the XML-based flow definition resource
- * @param flowServiceLocator the locator for services needed by this builder
- * to build its Flow
+ * @param flowServiceLocator the locator for services needed by this builder to build its Flow
*/
public XmlFlowBuilder(Resource location, FlowServiceLocator flowServiceLocator) {
super(flowServiceLocator);
@@ -284,16 +279,16 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
/**
- * Returns the resource from which the document element was loaded. This is
- * used for location relative loading of other resources.
+ * Returns the resource from which the document element was loaded. This is used for location relative loading of
+ * other resources.
*/
public Resource getLocation() {
return location;
}
/**
- * Sets the resource from which the document element was loaded. This is
- * used for location relative loading of other resources.
+ * Sets the resource from which the document element was loaded. This is used for location relative loading of other
+ * resources.
*/
public void setLocation(Resource location) {
Assert.notNull(location, "The resource location of the XML-based flow definition is required");
@@ -301,8 +296,8 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
/**
- * Sets the loader that will load the XML-based flow definition document.
- * Optional, defaults to {@link DefaultDocumentLoader}.
+ * Sets the loader that will load the XML-based flow definition document. Optional, defaults to
+ * {@link DefaultDocumentLoader}.
* @param documentLoader the document loader
*/
public void setDocumentLoader(DocumentLoader documentLoader) {
@@ -381,7 +376,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
public Resource getResource() {
return location;
}
-
+
// helpers
/**
@@ -406,8 +401,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
/**
- * Returns the artifact factory of the flow service locator local
- * to this builder.
+ * Returns the artifact factory of the flow service locator local to this builder.
*/
protected FlowArtifactFactory getFlowArtifactFactory() {
return getLocalFlowServiceLocator().getFlowArtifactFactory();
@@ -416,28 +410,25 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
// utility (from Spring 2.x DomUtils)
/**
- * Utility method that returns the first child element identified by its
- * name.
+ * Utility method that returns the first child element identified by its name.
* @param ele the DOM element to analyze
* @param childEleName the child element name to look for
- * @return the org.w3c.dom.Element instance, or
- * null if none found
+ * @return the org.w3c.dom.Element instance, or null if none found
*/
protected Element getChildElementByTagName(Element ele, String childEleName) {
NodeList nl = ele.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element && nodeNameEquals(node, childEleName)) {
- return (Element)node;
+ return (Element) node;
}
}
return null;
}
/**
- * Namespace-aware equals comparison. Returns true if either
- * {@link Node#getLocalName} or {@link Node#getNodeName} equals
- * desiredName, otherwise returns false.
+ * Namespace-aware equals comparison. Returns true if either {@link Node#getLocalName} or
+ * {@link Node#getNodeName} equals desiredName, otherwise returns false.
*/
protected boolean nodeNameEquals(Node node, String desiredName) {
return desiredName.equals(node.getNodeName()) || desiredName.equals(node.getLocalName());
@@ -462,7 +453,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
List importElements = DomUtils.getChildElementsByTagName(flowElement, IMPORT_ELEMENT);
Resource[] resources = new Resource[importElements.size()];
for (int i = 0; i < importElements.size(); i++) {
- Element importElement = (Element)importElements.get(i);
+ Element importElement = (Element) importElements.get(i);
try {
resources[i] = getLocation().createRelative(importElement.getAttribute(RESOURCE_ATTRIBUTE));
}
@@ -471,7 +462,57 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
+ importElement.getAttribute(RESOURCE_ATTRIBUTE) + "'", e);
}
}
- localFlowServiceLocator.push(new LocalFlowServiceRegistry(flow, resources));
+ localFlowServiceLocator.push(new LocalFlowServiceRegistry(flow, createLocalBeanFactory(flow, resources)));
+ }
+
+ /**
+ * 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
+ */
+ protected BeanFactory createLocalBeanFactory(Flow flow, Resource[] resources) {
+ // see if this factory has a parent
+ BeanFactory parent = null;
+ if (localFlowServiceLocator.isEmpty()) {
+ try {
+ parent = getFlowServiceLocator().getBeanFactory();
+ }
+ catch (UnsupportedOperationException e) {
+ // can't link to a parent
+ }
+ }
+ else {
+ parent = localFlowServiceLocator.top().getBeanFactory();
+ }
+ // determine the context implementation based on the current environment
+ GenericApplicationContext context;
+ if (parent instanceof WebApplicationContext) {
+ GenericWebApplicationContext webContext = new GenericWebApplicationContext();
+ webContext.setServletContext(((WebApplicationContext) parent).getServletContext());
+ context = webContext;
+ }
+ else {
+ context = new GenericApplicationContext();
+ }
+ // set the parent if necessary
+ if (parent instanceof ApplicationContext) {
+ context.setParent((ApplicationContext) parent);
+ }
+ else {
+ if (parent != null) {
+ context.getBeanFactory().setParentBeanFactory(parent);
+ }
+ }
+ context.setResourceLoader(getFlowServiceLocator().getResourceLoader());
+ new XmlBeanDefinitionReader(context).loadBeanDefinitions(resources);
+ context.refresh();
+ return context;
}
private void destroyLocalServiceRegistry() {
@@ -481,7 +522,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private void parseAndAddFlowVariables(Element flowElement, Flow flow) {
List varElements = DomUtils.getChildElementsByTagName(flowElement, VAR_ELEMENT);
for (Iterator it = varElements.iterator(); it.hasNext();) {
- flow.addVariable(parseVariable((Element)it.next()));
+ flow.addVariable(parseVariable((Element) it.next()));
}
}
@@ -494,7 +535,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
else {
if (StringUtils.hasText(element.getAttribute(CLASS_ATTRIBUTE))) {
- Class variableClass = (Class)fromStringTo(Class.class).execute(element.getAttribute(CLASS_ATTRIBUTE));
+ Class variableClass = (Class) fromStringTo(Class.class).execute(element.getAttribute(CLASS_ATTRIBUTE));
return new SimpleFlowVariable(element.getAttribute(NAME_ATTRIBUTE), variableClass, scope);
}
else {
@@ -528,7 +569,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private void parseAndAddInlineFlowDefinitions(Element parentFlowElement, Flow flow) {
List inlineFlowElements = DomUtils.getChildElementsByTagName(parentFlowElement, INLINE_FLOW_ELEMENT);
for (Iterator it = inlineFlowElements.iterator(); it.hasNext();) {
- Element inlineFlowElement = (Element)it.next();
+ Element inlineFlowElement = (Element) it.next();
String inlineFlowId = inlineFlowElement.getAttribute(ID_ATTRIBUTE);
Element flowElement = getChildElementByTagName(inlineFlowElement, FLOW_ATTRIBUTE);
Flow inlineFlow = parseFlow(inlineFlowId, null, flowElement);
@@ -547,7 +588,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
parseAndAddEndActions(flowElement, inlineFlow);
inlineFlow.setOutputMapper(parseOutputMapper(flowElement));
inlineFlow.getExceptionHandlerSet().addAll(parseExceptionHandlers(flowElement));
-
+
destroyLocalServiceRegistry();
}
@@ -556,7 +597,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
for (int i = 0; i < childNodeList.getLength(); i++) {
Node childNode = childNodeList.item(i);
if (childNode instanceof Element) {
- Element stateElement = (Element)childNode;
+ Element stateElement = (Element) childNode;
if (nodeNameEquals(stateElement, ACTION_STATE_ELEMENT)) {
parseAndAddActionState(stateElement, flow);
}
@@ -588,13 +629,15 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
private void parseAndAddActionState(Element element, Flow flow) {
- getFlowArtifactFactory().createActionState(parseId(element), flow, parseEntryActions(element),
+ getFlowArtifactFactory().createActionState(
+ parseId(element), flow, parseEntryActions(element),
parseAnnotatedActions(element), parseTransitions(element), parseExceptionHandlers(element),
parseExitActions(element), parseAttributes(element));
}
private void parseAndAddViewState(Element element, Flow flow) {
- getFlowArtifactFactory().createViewState(parseId(element), flow, parseEntryActions(element),
+ getFlowArtifactFactory().createViewState(
+ parseId(element), flow, parseEntryActions(element),
parseViewSelector(element), parseRenderActions(element), parseTransitions(element),
parseExceptionHandlers(element), parseExitActions(element), parseAttributes(element));
}
@@ -606,13 +649,15 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
private void parseAndAddSubflowState(Element element, Flow flow) {
- getFlowArtifactFactory().createSubflowState(parseId(element), flow, parseEntryActions(element),
+ getFlowArtifactFactory().createSubflowState(
+ parseId(element), flow, parseEntryActions(element),
parseSubflow(element), parseFlowAttributeMapper(element), parseTransitions(element),
parseExceptionHandlers(element), parseExitActions(element), parseAttributes(element));
}
private void parseAndAddEndState(Element element, Flow flow) {
- getFlowArtifactFactory().createEndState(parseId(element), flow, parseEntryActions(element),
+ getFlowArtifactFactory().createEndState(
+ parseId(element), flow, parseEntryActions(element),
parseViewSelector(element), parseOutputMapper(element), parseExceptionHandlers(element),
parseAttributes(element));
}
@@ -655,29 +700,29 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
List transitions = new LinkedList();
List transitionElements = DomUtils.getChildElementsByTagName(element, TRANSITION_ELEMENT);
for (Iterator it = transitionElements.iterator(); it.hasNext();) {
- Element transitionElement = (Element)it.next();
+ Element transitionElement = (Element) it.next();
if (!StringUtils.hasText(transitionElement.getAttribute(ON_EXCEPTION_ATTRIBUTE))) {
// the "on-exception transition" is not really a transition but rather
// a FlowExecutionExceptionHandler (see parseTransitionExecutingExceptionHandlers)
transitions.add(parseTransition(transitionElement));
}
}
- return (Transition[])transitions.toArray(new Transition[transitions.size()]);
+ return (Transition[]) transitions.toArray(new Transition[transitions.size()]);
}
private Transition parseTransition(Element element) {
- TransitionCriteria matchingCriteria = (TransitionCriteria)fromStringTo(TransitionCriteria.class).execute(
- element.getAttribute(ON_ATTRIBUTE));
- TargetStateResolver targetStateResolver = (TargetStateResolver)fromStringTo(TargetStateResolver.class).execute(
- element.getAttribute(TO_ATTRIBUTE));
+ TransitionCriteria matchingCriteria = (TransitionCriteria)
+ fromStringTo(TransitionCriteria.class).execute(element.getAttribute(ON_ATTRIBUTE));
+ TargetStateResolver targetStateResolver = (TargetStateResolver)
+ fromStringTo(TargetStateResolver.class).execute(element.getAttribute(TO_ATTRIBUTE));
TransitionCriteria executionCriteria = TransitionCriteriaChain.criteriaChainFor(parseAnnotatedActions(element));
- return getFlowArtifactFactory().createTransition(targetStateResolver, matchingCriteria, executionCriteria,
- parseAttributes(element));
+ return getFlowArtifactFactory().createTransition(
+ targetStateResolver, matchingCriteria, executionCriteria, parseAttributes(element));
}
private ViewSelector parseViewSelector(Element element) {
String viewName = element.getAttribute(VIEW_ATTRIBUTE);
- return (ViewSelector)fromStringTo(ViewSelector.class).execute(viewName);
+ return (ViewSelector) fromStringTo(ViewSelector.class).execute(viewName);
}
private Flow parseSubflow(Element element) {
@@ -687,30 +732,30 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private AnnotatedAction[] parseAnnotatedActions(Element element) {
List actions = new LinkedList();
NodeList childNodeList = element.getChildNodes();
- for (int i=0; i < childNodeList.getLength(); i++) {
+ for (int i = 0; i < childNodeList.getLength(); i++) {
Node childNode = childNodeList.item(i);
if (!(childNode instanceof Element)) {
continue;
}
-
+
if (nodeNameEquals(childNode, ACTION_ELEMENT)) {
// parse standard action
- actions.add(parseAnnotatedAction((Element)childNode));
+ actions.add(parseAnnotatedAction((Element) childNode));
}
else if (nodeNameEquals(childNode, BEAN_ACTION_ELEMENT)) {
// parse bean invoking action
- actions.add(parseAnnotatedBeanInvokingAction((Element)childNode));
+ actions.add(parseAnnotatedBeanInvokingAction((Element) childNode));
}
else if (nodeNameEquals(childNode, EVALUATE_ACTION_ELEMENT)) {
// parse evaluate action
- actions.add(parseAnnotatedEvaluateAction((Element)childNode));
+ actions.add(parseAnnotatedEvaluateAction((Element) childNode));
}
else if (nodeNameEquals(childNode, SET_ELEMENT)) {
// parse set action
- actions.add(parseAnnotatedSetAction((Element)childNode));
+ actions.add(parseAnnotatedSetAction((Element) childNode));
}
}
- return (AnnotatedAction[])actions.toArray(new AnnotatedAction[actions.size()]);
+ return (AnnotatedAction[]) actions.toArray(new AnnotatedAction[actions.size()]);
}
private AnnotatedAction parseAnnotatedAction(Element element) {
@@ -759,12 +804,13 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
Parameters parameters = new Parameters();
Iterator it = DomUtils.getChildElementsByTagName(methodArgumentsElement, ARGUMENT_ELEMENT).iterator();
while (it.hasNext()) {
- Element argumentElement = (Element)it.next();
- Expression name = getLocalFlowServiceLocator().getExpressionParser()
- .parseExpression(argumentElement.getAttribute(EXPRESSION_ATTRIBUTE));
+ Element argumentElement = (Element) it.next();
+ Expression name = getLocalFlowServiceLocator().getExpressionParser().parseExpression(
+ argumentElement.getAttribute(EXPRESSION_ATTRIBUTE));
Class type = null;
if (argumentElement.hasAttribute(PARAMETER_TYPE_ATTRIBUTE)) {
- type = (Class)fromStringTo(Class.class).execute(argumentElement.getAttribute(PARAMETER_TYPE_ATTRIBUTE));
+ type = (Class) fromStringTo(Class.class)
+ .execute(argumentElement.getAttribute(PARAMETER_TYPE_ATTRIBUTE));
}
parameters.add(new Parameter(type, name));
}
@@ -793,8 +839,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private Action parseEvaluateAction(Element element) {
String expressionString = element.getAttribute(EXPRESSION_ATTRIBUTE);
- Expression expression = getLocalFlowServiceLocator().getExpressionParser()
- .parseExpression(expressionString);
+ Expression expression = getLocalFlowServiceLocator().getExpressionParser().parseExpression(expressionString);
return new EvaluateAction(expression, parseEvaluationResultExposer(element));
}
@@ -816,15 +861,15 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private Action parseSetAction(Element element) {
String attributeExpressionString = element.getAttribute(ATTRIBUTE_ATTRIBUTE);
SettableExpression attributeExpression = getLocalFlowServiceLocator().getExpressionParser()
- .parseSettableExpression(attributeExpressionString);
- Expression valueExpression = getLocalFlowServiceLocator().getExpressionParser()
- .parseExpression(element.getAttribute(VALUE_ATTRIBUTE));
+ .parseSettableExpression(attributeExpressionString);
+ Expression valueExpression = getLocalFlowServiceLocator().getExpressionParser().parseExpression(
+ element.getAttribute(VALUE_ATTRIBUTE));
return new SetAction(attributeExpression, parseScope(element, ScopeType.REQUEST), valueExpression);
}
private ScopeType parseScope(Element element, ScopeType defaultValue) {
if (element.hasAttribute(SCOPE_ATTRIBUTE) && !element.getAttribute(SCOPE_ATTRIBUTE).equals(DEFAULT_VALUE)) {
- return (ScopeType)fromStringTo(ScopeType.class).execute(element.getAttribute(SCOPE_ATTRIBUTE));
+ return (ScopeType) fromStringTo(ScopeType.class).execute(element.getAttribute(SCOPE_ATTRIBUTE));
}
else {
return defaultValue;
@@ -835,7 +880,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
LocalAttributeMap attributes = new LocalAttributeMap();
List propertyElements = DomUtils.getChildElementsByTagName(element, ATTRIBUTE_ELEMENT);
for (int i = 0; i < propertyElements.size(); i++) {
- parseAndSetAttribute((Element)propertyElements.get(i), attributes);
+ parseAndSetAttribute((Element) propertyElements.get(i), attributes);
}
return attributes;
}
@@ -849,14 +894,14 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
else {
List valueElements = DomUtils.getChildElementsByTagName(element, VALUE_ELEMENT);
Assert.state(valueElements.size() == 1, "A property value should be specified for property '" + name + "'");
- value = DomUtils.getTextValue((Element)valueElements.get(0));
+ value = DomUtils.getTextValue((Element) valueElements.get(0));
}
attributes.put(name, convertPropertyValue(element, value));
}
private Object convertPropertyValue(Element element, String stringValue) {
if (element.hasAttribute(TYPE_ATTRIBUTE)) {
- Class targetClass = (Class)fromStringTo(Class.class).execute(element.getAttribute(TYPE_ATTRIBUTE));
+ Class targetClass = (Class) fromStringTo(Class.class).execute(element.getAttribute(TYPE_ATTRIBUTE));
// convert string value to instance of target class
return fromStringTo(targetClass).execute(stringValue);
}
@@ -869,9 +914,9 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
List transitions = new LinkedList();
List transitionElements = DomUtils.getChildElementsByTagName(element, IF_ELEMENT);
for (Iterator it = transitionElements.iterator(); it.hasNext();) {
- transitions.addAll(Arrays.asList(parseIf((Element)it.next())));
+ transitions.addAll(Arrays.asList(parseIf((Element) it.next())));
}
- return (Transition[])transitions.toArray(new Transition[transitions.size()]);
+ return (Transition[]) transitions.toArray(new Transition[transitions.size()]);
}
private Transition[] parseIf(Element element) {
@@ -886,17 +931,17 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
private Transition parseThen(Element element) {
- Expression expression = getLocalFlowServiceLocator().getExpressionParser()
- .parseExpression(element.getAttribute(TEST_ATTRIBUTE));
+ Expression expression = getLocalFlowServiceLocator().getExpressionParser().parseExpression(
+ element.getAttribute(TEST_ATTRIBUTE));
TransitionCriteria matchingCriteria = new BooleanExpressionTransitionCriteria(expression);
- TargetStateResolver targetStateResolver = (TargetStateResolver)fromStringTo(TargetStateResolver.class).execute(
- element.getAttribute(THEN_ATTRIBUTE));
+ TargetStateResolver targetStateResolver = (TargetStateResolver) fromStringTo(TargetStateResolver.class)
+ .execute(element.getAttribute(THEN_ATTRIBUTE));
return getFlowArtifactFactory().createTransition(targetStateResolver, matchingCriteria, null, null);
}
private Transition parseElse(Element element) {
- TargetStateResolver targetStateResolver = (TargetStateResolver)fromStringTo(TargetStateResolver.class).execute(
- element.getAttribute(ELSE_ATTRIBUTE));
+ TargetStateResolver targetStateResolver = (TargetStateResolver) fromStringTo(TargetStateResolver.class)
+ .execute(element.getAttribute(ELSE_ATTRIBUTE));
return getFlowArtifactFactory().createTransition(targetStateResolver, null, null, null);
}
@@ -945,7 +990,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
ExpressionParser parser = getLocalFlowServiceLocator().getExpressionParser();
List mappingElements = DomUtils.getChildElementsByTagName(element, MAPPING_ELEMENT);
for (Iterator it = mappingElements.iterator(); it.hasNext();) {
- Element mappingElement = (Element)it.next();
+ Element mappingElement = (Element) it.next();
Expression source = parser.parseExpression(mappingElement.getAttribute(SOURCE_ATTRIBUTE));
SettableExpression target = null;
if (StringUtils.hasText(mappingElement.getAttribute(TARGET_ATTRIBUTE))) {
@@ -967,7 +1012,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private void parseSimpleAttributeMappings(DefaultAttributeMapper mapper, List elements) {
ExpressionParser parser = getLocalFlowServiceLocator().getExpressionParser();
for (Iterator it = elements.iterator(); it.hasNext();) {
- Element element = (Element)it.next();
+ Element element = (Element) it.next();
SettableExpression attribute = parser.parseSettableExpression(element.getAttribute(NAME_ATTRIBUTE));
SettableExpression expression = new AttributeExpression(attribute, parseScope(element, ScopeType.FLOW));
if (getRequired(element, false)) {
@@ -981,7 +1026,7 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
private boolean getRequired(Element element, boolean defaultValue) {
if (StringUtils.hasText(element.getAttribute(REQUIRED_ATTRIBUTE))) {
- return ((Boolean)fromStringTo(Boolean.class).execute(element.getAttribute(REQUIRED_ATTRIBUTE)))
+ return ((Boolean) fromStringTo(Boolean.class).execute(element.getAttribute(REQUIRED_ATTRIBUTE)))
.booleanValue();
}
else {
@@ -995,8 +1040,8 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
if (StringUtils.hasText(from)) {
if (StringUtils.hasText(to)) {
ConversionService service = getLocalFlowServiceLocator().getConversionService();
- Class sourceClass = (Class)fromStringTo(Class.class).execute(from);
- Class targetClass = (Class)fromStringTo(Class.class).execute(to);
+ Class sourceClass = (Class) fromStringTo(Class.class).execute(from);
+ Class targetClass = (Class) fromStringTo(Class.class).execute(to);
return service.getConversionExecutor(sourceClass, targetClass);
}
else {
@@ -1013,10 +1058,10 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
FlowExecutionExceptionHandler[] transitionExecutingHandlers = parseTransitionExecutingExceptionHandlers(element);
FlowExecutionExceptionHandler[] customHandlers = parseCustomExceptionHandlers(element);
FlowExecutionExceptionHandler[] exceptionHandlers =
- new FlowExecutionExceptionHandler[transitionExecutingHandlers.length + customHandlers.length];
+ new FlowExecutionExceptionHandler[transitionExecutingHandlers.length + customHandlers.length];
System.arraycopy(transitionExecutingHandlers, 0, exceptionHandlers, 0, transitionExecutingHandlers.length);
System.arraycopy(customHandlers, 0, exceptionHandlers, transitionExecutingHandlers.length,
- customHandlers.length);
+ customHandlers.length);
return exceptionHandlers;
}
@@ -1033,22 +1078,22 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
}
List exceptionHandlers = new LinkedList();
for (Iterator it = transitionElements.iterator(); it.hasNext();) {
- Element transitionElement = (Element)it.next();
+ Element transitionElement = (Element) it.next();
if (StringUtils.hasText(transitionElement.getAttribute(ON_EXCEPTION_ATTRIBUTE))) {
// the "on-exception transitions" are not really transitions but rather
// FlowExecutionExceptionHandlers
exceptionHandlers.add(parseTransitionExecutingExceptionHandler(transitionElement));
}
}
- return (FlowExecutionExceptionHandler[])exceptionHandlers
+ return (FlowExecutionExceptionHandler[]) exceptionHandlers
.toArray(new FlowExecutionExceptionHandler[exceptionHandlers.size()]);
}
private FlowExecutionExceptionHandler parseTransitionExecutingExceptionHandler(Element element) {
TransitionExecutingStateExceptionHandler handler = new TransitionExecutingStateExceptionHandler();
- Class exceptionClass = (Class)fromStringTo(Class.class).execute(element.getAttribute(ON_EXCEPTION_ATTRIBUTE));
- TargetStateResolver targetStateResolver = (TargetStateResolver)fromStringTo(TargetStateResolver.class).execute(
- element.getAttribute(TO_ATTRIBUTE));
+ Class exceptionClass = (Class) fromStringTo(Class.class).execute(element.getAttribute(ON_EXCEPTION_ATTRIBUTE));
+ TargetStateResolver targetStateResolver = (TargetStateResolver)
+ fromStringTo(TargetStateResolver.class).execute(element.getAttribute(TO_ATTRIBUTE));
handler.add(exceptionClass, targetStateResolver);
handler.getActionList().addAll(parseAnnotatedActions(element));
return handler;
@@ -1058,10 +1103,10 @@ public class XmlFlowBuilder extends BaseFlowBuilder implements ResourceHolder {
List exceptionHandlers = new LinkedList();
List handlerElements = DomUtils.getChildElementsByTagName(element, EXCEPTION_HANDLER_ELEMENT);
for (int i = 0; i < handlerElements.size(); i++) {
- Element handlerElement = (Element)handlerElements.get(i);
+ Element handlerElement = (Element) handlerElements.get(i);
exceptionHandlers.add(parseCustomExceptionHandler(handlerElement));
}
- return (FlowExecutionExceptionHandler[])exceptionHandlers
+ return (FlowExecutionExceptionHandler[]) exceptionHandlers
.toArray(new FlowExecutionExceptionHandler[exceptionHandlers.size()]);
}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/execution/AbstractXmlFlowExecutionTests.java b/spring-webflow/src/main/java/org/springframework/webflow/test/execution/AbstractXmlFlowExecutionTests.java
index 5654ec50..91e1e647 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/test/execution/AbstractXmlFlowExecutionTests.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/test/execution/AbstractXmlFlowExecutionTests.java
@@ -71,7 +71,7 @@ public abstract class AbstractXmlFlowExecutionTests extends AbstractExternalized
super(name);
}
- protected final FlowBuilder createFlowBuilder(Resource resource, FlowServiceLocator flowServiceLocator) {
+ protected FlowBuilder createFlowBuilder(Resource resource, FlowServiceLocator flowServiceLocator) {
return new XmlFlowBuilder(resource, flowServiceLocator);
}
}
\ No newline at end of file
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 @@