variable autowiring

This commit is contained in:
Keith Donald
2008-02-29 17:13:26 +00:00
parent d371131d05
commit 940a6c9d1b
15 changed files with 152 additions and 388 deletions

View File

@@ -52,8 +52,8 @@ public class SpringBeanWebFlowELResolver extends SpringBeanFacesELResolver {
protected BeanFactory getBeanFactory(ELContext elContext) {
RequestContext rc = RequestContextHolder.getRequestContext();
if (rc.getActiveFlow() instanceof BeanFactory) {
return (BeanFactory) rc.getActiveFlow();
if (rc.getActiveFlow().getBeanFactory() != null) {
return rc.getActiveFlow().getBeanFactory();
} else {
return EMPTY_BEAN_FACTORY;
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.webflow.definition;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.io.ResourceLoader;
/**
* The definition of a flow, a program that when executed carries out the orchestration of a task on behalf of a single
* client.
@@ -60,4 +63,15 @@ public interface FlowDefinition extends Annotated {
* @throws IllegalArgumentException if a state with this id does not exist
*/
public StateDefinition getState(String id) throws IllegalArgumentException;
/**
* Returns a reference to a bean factory hosting application objects needed by this flow definition.
*/
public BeanFactory getBeanFactory();
/**
* Returns a reference to a resource loader capable of loading resources relative to this flow.
*/
public ResourceLoader getResourceLoader();
}

View File

@@ -21,14 +21,10 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.StaticListableBeanFactory;
import org.springframework.binding.mapping.AttributeMapper;
import org.springframework.binding.mapping.MappingContext;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.style.StylerUtils;
import org.springframework.core.style.ToStringCreator;
@@ -108,7 +104,7 @@ import org.springframework.webflow.execution.RequestContext;
* @author Colin Sampaleanu
* @author Jeremy Grelle
*/
public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory, ResourceLoader {
public class Flow extends AnnotatedObject implements FlowDefinition {
/**
* Logger, can be used in subclasses.
@@ -138,7 +134,7 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
/**
* The mapper to map flow input attributes.
*/
private AttributeMapper inputMapper = new NoInputMapper();
private AttributeMapper inputMapper;
/**
* The list of actions to execute when this flow starts.
@@ -161,7 +157,7 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
/**
* The mapper to map flow output attributes.
*/
private AttributeMapper outputMapper = new NoOutputMapper();
private AttributeMapper outputMapper;
/**
* The set of exception handlers for this flow.
@@ -219,6 +215,14 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
return getStateInstance(stateId);
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public ResourceLoader getResourceLoader() {
return resourceLoader;
}
/**
* Add given state definition to this flow definition. Marked protected, as this method is to be called by the
* (privileged) state definition classes themselves during state construction as part of a FlowBuilder invocation.
@@ -382,7 +386,6 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
* @param inputMapper the input mapper
*/
public void setInputMapper(AttributeMapper inputMapper) {
Assert.notNull(inputMapper, "The input mapper cannot be null");
this.inputMapper = inputMapper;
}
@@ -417,7 +420,6 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
* @param outputMapper the output mapper
*/
public void setOutputMapper(AttributeMapper outputMapper) {
Assert.notNull(outputMapper, "The output mapper cannot be null");
this.outputMapper = outputMapper;
}
@@ -498,7 +500,9 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
public void start(RequestControlContext context, MutableAttributeMap input) throws FlowExecutionException {
assertStartStateSet();
createVariables(context);
inputMapper.map(input, context, null);
if (inputMapper != null) {
inputMapper.map(input, context, null);
}
startActionList.execute(context);
startState.enter(context);
}
@@ -547,7 +551,9 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
*/
public void end(RequestControlContext context, MutableAttributeMap output) throws FlowExecutionException {
endActionList.execute(context);
outputMapper.map(context, output, null);
if (outputMapper != null) {
outputMapper.map(context, output, null);
}
}
/**
@@ -560,52 +566,6 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
return getExceptionHandlerSet().handleException(exception, context);
}
// implementing bean factory
public boolean containsBean(String name) {
return beanFactory.containsBean(name);
}
public String[] getAliases(String name) {
return beanFactory.getAliases(name);
}
public Object getBean(String name, Class requiredType) throws BeansException {
return beanFactory.getBean(name, requiredType);
}
public Object getBean(String name, Object[] args) throws BeansException {
return beanFactory.getBean(name, args);
}
public Object getBean(String name) throws BeansException {
return beanFactory.getBean(name);
}
public Class getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isPrototype(name);
}
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}
public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
return beanFactory.isTypeMatch(name, targetType);
}
public ClassLoader getClassLoader() {
return resourceLoader.getClassLoader();
}
public Resource getResource(String name) {
return resourceLoader.getResource(name);
}
// internal helpers
private void assertStartStateSet() {
@@ -653,31 +613,6 @@ public class Flow extends AnnotatedObject implements FlowDefinition, BeanFactory
return (TransitionableState) currentState;
}
/**
* Maps no input attributes. The default implementation.
*/
private class NoInputMapper implements AttributeMapper {
public void map(Object source, Object target, MappingContext context) {
}
public String toString() {
return "none";
}
}
/**
* Maps no input attributes. The default implementation.
*/
private class NoOutputMapper implements AttributeMapper {
public void map(Object source, Object target, MappingContext context) {
}
public String toString() {
return "none";
}
}
public String toString() {
return new ToStringCreator(this).append("id", id).append("states", states).append("startState", startState)
.append("variables", variables).append("inputMapper", inputMapper).append("startActionList",

View File

@@ -15,12 +15,10 @@
*/
package org.springframework.webflow.engine;
import java.io.Serializable;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.execution.FlowSession;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.ScopeType;
/**
* A value object that defines a specification for a flow variable. Encapsulates information about the variable and the
@@ -28,7 +26,7 @@ import org.springframework.webflow.execution.ScopeType;
*
* @author Keith Donald
*/
public abstract class FlowVariable extends AnnotatedObject implements Serializable {
public class FlowVariable extends AnnotatedObject {
/**
* The variable name.
@@ -36,20 +34,27 @@ public abstract class FlowVariable extends AnnotatedObject implements Serializab
private String name;
/**
* The variable scope.
* Is this flow variable local or global? Local variables go into flow scope. Global variables go into conversation
* scope.
*/
private ScopeType scope;
private Boolean local;
/**
* The value factory that provides this variable's value.
*/
private VariableValueFactory valueFactory;
/**
* Creates a new flow variable.
* @param name the variable name
* @param scope the variable scope type
* @param local the local variable
*/
public FlowVariable(String name, ScopeType scope) {
public FlowVariable(String name, VariableValueFactory valueFactory, boolean local) {
Assert.hasText(name, "The variable name is required");
Assert.notNull(scope, "The variable scope type is required");
Assert.notNull(valueFactory, "The variable value factory is required");
this.name = name;
this.scope = scope;
this.valueFactory = valueFactory;
this.local = Boolean.valueOf(local);
}
/**
@@ -60,10 +65,10 @@ public abstract class FlowVariable extends AnnotatedObject implements Serializab
}
/**
* Returns the scope of this variable.
* Is this a local flow variable or a conversation-scoped flow variable?
*/
public ScopeType getScope() {
return scope;
public boolean isLocal() {
return local.booleanValue();
}
// name and scope based equality
@@ -73,11 +78,11 @@ public abstract class FlowVariable extends AnnotatedObject implements Serializab
return false;
}
FlowVariable other = (FlowVariable) o;
return name.equals(other.name) && scope.equals(other.scope);
return name.equals(other.name) && valueFactory.equals(other.valueFactory) && local.equals(other.local);
}
public int hashCode() {
return name.hashCode() + scope.hashCode();
return name.hashCode() + valueFactory.hashCode() + local.hashCode();
}
/**
@@ -85,18 +90,26 @@ public abstract class FlowVariable extends AnnotatedObject implements Serializab
* @param context the flow execution request context
*/
public final void create(RequestContext context) {
scope.getScope(context).put(name, createVariableValue(context));
Object value = valueFactory.createVariableValue(context);
if (local == Boolean.TRUE) {
context.getFlowScope().put(name, value);
} else {
context.getConversationScope().put(name, value);
}
}
/**
* Hook method that needs to be implemented by subclasses to calculate the value of this flow variable based on the
* information available in the request context.
* @param context the flow execution request context
* @return the flow variable value
*/
protected abstract Object createVariableValue(RequestContext context);
public final Object restore(FlowSession session, RequestContext context) {
Object value;
if (local == Boolean.TRUE) {
value = session.getScope().get(name);
} else {
value = context.getConversationScope().get(name);
}
return valueFactory.restoreReferences(value, context);
}
public String toString() {
return new ToStringCreator(this).append("name", name).append("scope", scope).toString();
return new ToStringCreator(this).append("name", name).append("valueFactory", valueFactory).append("local",
local).toString();
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.webflow.engine.builder.xml;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ResourceLoader;
import org.springframework.webflow.action.BeanInvokingActionFactory;
import org.springframework.webflow.core.collection.AttributeMap;
@@ -35,9 +36,9 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
private FlowBuilderContext parent;
private BeanFactory localFlowBeanFactory;
private GenericApplicationContext localFlowBeanFactory;
public LocalFlowBuilderContext(FlowBuilderContext parent, BeanFactory localFlowBeanFactory) {
public LocalFlowBuilderContext(FlowBuilderContext parent, GenericApplicationContext localFlowBeanFactory) {
this.parent = parent;
this.localFlowBeanFactory = localFlowBeanFactory;
}
@@ -100,10 +101,10 @@ class LocalFlowBuilderContext implements FlowBuilderContext {
}
public ResourceLoader getResourceLoader() {
return (ResourceLoader) getBeanFactory();
return localFlowBeanFactory;
}
public BeanFactory getBeanFactory() {
return localFlowBeanFactory;
return localFlowBeanFactory.getBeanFactory();
}
}

View File

@@ -25,6 +25,7 @@ import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.binding.convert.ConversionException;
@@ -68,13 +69,13 @@ import org.springframework.webflow.engine.FlowVariable;
import org.springframework.webflow.engine.TargetStateResolver;
import org.springframework.webflow.engine.Transition;
import org.springframework.webflow.engine.TransitionCriteria;
import org.springframework.webflow.engine.VariableValueFactory;
import org.springframework.webflow.engine.builder.FlowArtifactFactory;
import org.springframework.webflow.engine.builder.FlowBuilderException;
import org.springframework.webflow.engine.builder.support.AbstractFlowBuilder;
import org.springframework.webflow.engine.builder.support.ActionExecutingViewFactory;
import org.springframework.webflow.engine.support.BeanFactoryFlowVariable;
import org.springframework.webflow.engine.support.BeanFactoryVariableValueFactory;
import org.springframework.webflow.engine.support.BooleanExpressionTransitionCriteria;
import org.springframework.webflow.engine.support.SimpleFlowVariable;
import org.springframework.webflow.engine.support.TransitionCriteriaChain;
import org.springframework.webflow.engine.support.TransitionExecutingFlowExecutionExceptionHandler;
import org.springframework.webflow.execution.Action;
@@ -437,7 +438,7 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
this.localFlowBuilderContext = new LocalFlowBuilderContext(getContext(), createFlowBeanFactory(resources));
}
private BeanFactory createFlowBeanFactory(Resource[] resources) {
private GenericApplicationContext createFlowBeanFactory(Resource[] resources) {
// see if this factory has a parent
BeanFactory parent = getContext().getBeanFactory();
// determine the context implementation based on the current environment
@@ -478,24 +479,20 @@ public class XmlFlowBuilder extends AbstractFlowBuilder implements ResourceHolde
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(parseFlowVariable((Element) it.next()));
}
}
private FlowVariable parseVariable(Element element) {
private FlowVariable parseFlowVariable(Element element) {
Class clazz = (Class) fromStringTo(Class.class).execute(element.getAttribute(CLASS_ATTRIBUTE));
VariableValueFactory valueFactory = new BeanFactoryVariableValueFactory(clazz,
(AutowireCapableBeanFactory) getFlow().getBeanFactory());
ScopeType scope = parseScope(element, ScopeType.FLOW);
if (StringUtils.hasText(element.getAttribute(BEAN_ATTRIBUTE))) {
return new BeanFactoryFlowVariable(element.getAttribute(NAME_ATTRIBUTE), element
.getAttribute(BEAN_ATTRIBUTE), getLocalContext().getBeanFactory(), scope);
} else {
if (StringUtils.hasText(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 {
return new BeanFactoryFlowVariable(element.getAttribute(NAME_ATTRIBUTE), null, getLocalContext()
.getBeanFactory(), scope);
}
if (!(scope == ScopeType.FLOW || scope == ScopeType.CONVERSATION)) {
throw new IllegalArgumentException("Only " + ScopeType.FLOW + " or " + ScopeType.CONVERSATION
+ " scope is allowed for flow variables");
}
return new FlowVariable(element.getAttribute("name"), valueFactory, scope == ScopeType.FLOW ? true : false);
}
private void parseAndAddStartActions(Element element, Flow flow) {

View File

@@ -259,7 +259,8 @@ The persistence context can be referenced from within this flow by the "entityMa
<xsd:annotation>
<xsd:documentation>
<![CDATA[
A flow variable definition. Flow variables are automatically created when an execution of this flow starts.
A flow variable definition. Flow variables are automatically created when an execution of this flow starts.
A flow variable can either be stored in 'flow' or 'conversation' scope.
]]>
</xsd:documentation>
</xsd:annotation>
@@ -623,47 +624,33 @@ of a non-singleton bean in the configured Bean Factory to use as the initial var
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="scopeType" default="default">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
This scope of this variable. The available scope types are:
<ol>
<li>request - The variable goes out of scope when a call to start this flow completes.
<li>flash - The variable goes out of scope when the next user event is signaled.
<li>flow - The variable goes out of scope when this flow session ends.
<li>conversation - The variable goes out of scope when the overall conversation governing this flow ends.
</ol>
<br>
If not specified the default scope type is used ('flow' by default).
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="class" type="xsd:string">
<xsd:attribute name="class" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The implementation class of the variable's value. The class may be an alias (e.g 'int') or a
fully-qualified class (e.g. 'java.lang.Integer'). The class cannot be abstract or an interface.
Only required if the variable should be instantiated directly by calling the default constructor
on its class rather than having the initial variable value returned by a Spring Bean Factory.
Use this or the 'bean' attribute, not both.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="bean" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
The bean defining the initial flow variable value. The bean *must* be a non-singleton prototype.
Only required if the bean name differs from the variable name.
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="scope" type="scopeType" default="default">
<xsd:annotation>
<xsd:documentation>
<![CDATA[
This scope of this variable. The available scope types are:
<ol>
<li>request - The variable goes out of scope when a call to start this flow completes.
<li>flash - The variable goes out of scope when the next user event is signaled.
<li>flow - The variable goes out of scope when this flow session ends.
<li>conversation - The variable goes out of scope when the overall conversation governing this flow ends.
</ol>
<br>
If not specified the default scope type is used ('flow' by default).
]]>
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2004-2007 the original author or authors.
* Copyright 2004-2008 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.

View File

@@ -1,77 +0,0 @@
/*
* Copyright 2004-2007 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.webflow.engine.support;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.webflow.engine.FlowVariable;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.ScopeType;
/**
* A concrete flow variable subclass that obtains variable values from a Spring {@link BeanFactory}.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class BeanFactoryFlowVariable extends FlowVariable {
/**
* The name of the bean whose value will be used as the flow variable. The bean should be a prototype.
*/
private String beanName;
/**
* The bean factory where initial variable values will be obtained.
*/
private BeanFactory beanFactory;
/**
* Convenience constructor to create a new bean factory flow variable. Defaults the bean name to the variable name.
* @param name the variable name which will also be used as the bean name
* @param beanFactory the bean factory where initial variable values will be obtained
* @param scope the variable scope
* @since 1.0.2
*/
public BeanFactoryFlowVariable(String name, BeanFactory beanFactory, ScopeType scope) {
this(name, name, beanFactory, scope);
}
/**
* Creates a new bean factory flow variable.
* @param variableName the variable name
* @param beanName the bean name, will default to the variable name if not specified
* @param beanFactory the bean factory where initial variable values will be obtained
* @param scope the variable scope
*/
public BeanFactoryFlowVariable(String variableName, String beanName, BeanFactory beanFactory, ScopeType scope) {
super(variableName, scope);
if (StringUtils.hasText(beanName)) {
this.beanName = beanName;
} else {
this.beanName = variableName;
}
Assert.notNull(beanFactory, "The bean factory is required");
Assert.isTrue(!beanFactory.isSingleton(this.beanName), "The bean with name '" + this.beanName
+ "' must be a prototype (singleton=false)");
this.beanFactory = beanFactory;
}
protected Object createVariableValue(RequestContext context) {
return beanFactory.getBean(beanName);
}
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright 2004-2007 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.webflow.engine.support;
import java.lang.reflect.Modifier;
import org.springframework.beans.BeanUtils;
import org.springframework.util.Assert;
import org.springframework.webflow.engine.FlowVariable;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.ScopeType;
/**
* A trivial concrete flow variable subclass that creates new variable values using Java reflection.
*
* @author Keith Donald
*/
public class SimpleFlowVariable extends FlowVariable {
/**
* The concrete variable value class.
*/
private Class variableClass;
/**
* Creates a new simple flow variable.
* @param name the variable name
* @param variableClass the concrete variable class
* @param scope the variable scope
*/
public SimpleFlowVariable(String name, Class variableClass, ScopeType scope) {
super(name, scope);
Assert.notNull(variableClass, "The variable class is required");
Assert.isTrue(!variableClass.isInterface(), "The variable class cannot be an interface");
Assert.isTrue(!Modifier.isAbstract(variableClass.getModifiers()), "The variable class cannot be abstract");
this.variableClass = variableClass;
}
/**
* Returns the variable value class.
*/
public Class getVariableClass() {
return variableClass;
}
protected Object createVariableValue(RequestContext context) {
return BeanUtils.instantiateClass(variableClass);
}
}

View File

@@ -17,6 +17,8 @@ package org.springframework.webflow.definition.registry;
import junit.framework.TestCase;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.io.ResourceLoader;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.definition.FlowDefinition;
import org.springframework.webflow.definition.StateDefinition;
@@ -101,6 +103,16 @@ public class FlowDefinitionRegistryImplTests extends TestCase {
public StateDefinition getState(String id) throws IllegalArgumentException {
return null;
}
public BeanFactory getBeanFactory() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ResourceLoader getResourceLoader() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Auto-generated method stub");
}
}
private static class BarFlow implements FlowDefinition {
@@ -129,5 +141,15 @@ public class FlowDefinitionRegistryImplTests extends TestCase {
public StateDefinition getState(String id) throws IllegalArgumentException {
return null;
}
public BeanFactory getBeanFactory() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Auto-generated method stub");
}
public ResourceLoader getResourceLoader() {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Auto-generated method stub");
}
}
}

View File

@@ -21,19 +21,16 @@ import junit.framework.TestCase;
import org.springframework.binding.mapping.DefaultAttributeMapper;
import org.springframework.binding.mapping.MappingBuilder;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.webflow.TestException;
import org.springframework.webflow.action.TestMultiAction;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.expression.DefaultExpressionParserFactory;
import org.springframework.webflow.engine.support.BeanFactoryFlowVariable;
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
import org.springframework.webflow.engine.support.EventIdTransitionCriteria;
import org.springframework.webflow.engine.support.SimpleFlowVariable;
import org.springframework.webflow.engine.support.TransitionExecutingFlowExecutionExceptionHandler;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.ScopeType;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.TestAction;
import org.springframework.webflow.test.MockRequestControlContext;
@@ -184,13 +181,17 @@ public class FlowTests extends TestCase {
public void testStartWithVariables() {
MockRequestControlContext context = new MockRequestControlContext(flow);
flow.addVariable(new SimpleFlowVariable("var1", ArrayList.class, ScopeType.FLOW));
StaticApplicationContext beanFactory = new StaticApplicationContext();
beanFactory.registerPrototype("bean", ArrayList.class);
flow.addVariable(new BeanFactoryFlowVariable("var2", "bean", beanFactory, ScopeType.FLOW));
flow.addVariable(new FlowVariable("var1", new VariableValueFactory() {
public Object createVariableValue(RequestContext context) {
return new ArrayList();
}
public Object restoreReferences(Object value, RequestContext context) {
return value;
}
}, true));
flow.start(context, new LocalAttributeMap());
context.getFlowScope().getRequired("var1", ArrayList.class);
context.getFlowScope().getRequired("var2", ArrayList.class);
}
public void testStartWithMapper() {

View File

@@ -73,4 +73,15 @@ public class XmlFlowBuilderTests extends TestCase {
assertNotNull(flow.getAttributes().get("persistenceContext"));
assertTrue(((Boolean) flow.getAttributes().get("persistenceContext")).booleanValue());
}
public void testFlowVariable() {
ClassPathResource resource = new ClassPathResource("flow-var.xml", getClass());
builder = new XmlFlowBuilder(resource);
FlowAssembler assembler = new FlowAssembler(builder, new MockFlowBuilderContext("flow"));
Flow flow = assembler.assembleFlow();
assertEquals("flow-foo", flow.getVariables()[0].getName());
assertEquals(true, flow.getVariables()[0].isLocal());
assertEquals("conversation-foo", flow.getVariables()[1].getName());
assertEquals(false, flow.getVariables()[1].isLocal());
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2004-2007 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.webflow.engine.support;
import junit.framework.TestCase;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.webflow.execution.ScopeType;
import org.springframework.webflow.test.MockRequestContext;
public class BeanFactoryFlowVariableTests extends TestCase {
private MockRequestContext context = new MockRequestContext();
public void testCreateValidFlowVariable() {
StaticApplicationContext beanFactory = new StaticApplicationContext();
beanFactory.registerPrototype("bean", Object.class);
BeanFactoryFlowVariable variable = new BeanFactoryFlowVariable("var", "bean", beanFactory, ScopeType.FLOW);
variable.create(context);
context.getFlowScope().getRequired("var");
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2004-2007 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.webflow.engine.support;
import java.util.ArrayList;
import junit.framework.TestCase;
import org.springframework.webflow.execution.ScopeType;
import org.springframework.webflow.test.MockRequestContext;
public class SimpleFlowVariableTests extends TestCase {
private MockRequestContext context = new MockRequestContext();
public void testCreateValidFlowVariableCustomScope() {
SimpleFlowVariable variable = new SimpleFlowVariable("var", ArrayList.class, ScopeType.REQUEST);
variable.create(context);
assertTrue(context.getRequestScope().contains("var"));
context.getRequestScope().getRequired("var", ArrayList.class);
}
public void testCreateVariableNoDefaultConstructor() {
SimpleFlowVariable variable = new SimpleFlowVariable("var", Integer.class, ScopeType.FLOW);
try {
variable.create(context);
fail("should have failed");
} catch (Exception e) {
}
}
}