diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java index 021e7d01..3316c9e7 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParser.java @@ -17,10 +17,14 @@ package org.springframework.webflow.expression; import java.util.Map; +import javax.el.PropertyNotWritableException; + import ognl.ObjectPropertyAccessor; import ognl.OgnlException; import ognl.PropertyAccessor; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.StaticListableBeanFactory; import org.springframework.binding.collection.MapAdaptable; @@ -39,6 +43,8 @@ import org.springframework.webflow.execution.RequestContext; */ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser { + private static final Log logger = LogFactory.getLog(WebFlowOgnlExpressionParser.class); + /** * Creates a webflow-specific ognl expression parser. */ @@ -83,9 +89,15 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser { String property = name.toString(); RequestContext requestContext = (RequestContext) target; if (property.equals("flowRequestContext")) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved the current RequestContext under variable '" + property + "'"); + } return requestContext; } if (securityPresent && property.equals("currentUser")) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved implicit flow variable '" + property + "'"); + } if (SecurityContextHolder.getContext() != null) { return SecurityContextHolder.getContext().getAuthentication(); } else { @@ -93,23 +105,68 @@ public class WebFlowOgnlExpressionParser extends OgnlExpressionParser { } } if (requestContext.getRequestScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved request scoped variable '" + property + "'"); + } return requestContext.getRequestScope().get(property); } else if (requestContext.getFlashScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flash scoped variable '" + property + "'"); + } return requestContext.getFlashScope().get(property); } else if (requestContext.getFlowScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flow scoped variable '" + property + "'"); + } return requestContext.getFlowScope().get(property); } else if (requestContext.getConversationScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved conversation scoped variable '" + property + "'"); + } return requestContext.getConversationScope().get(property); } BeanFactory bf = getBeanFactory(requestContext); if (bf.containsBean(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved variable '" + property + "' in Spring BeanFactory"); + } return bf.getBean(property); } return delegate.getProperty(context, target, name); } public void setProperty(Map context, Object target, Object name, Object value) throws OgnlException { - delegate.setProperty(context, target, name, value); + String property = name.toString(); + RequestContext requestContext = (RequestContext) target; + if (property.equals("flowRequestContext")) { + throw new PropertyNotWritableException("The 'flowRequestContext' variable is not writeable"); + } + if (securityPresent && property.equals("currentUser")) { + throw new PropertyNotWritableException("The 'currentUser' variable is not writeable"); + } + if (requestContext.getRequestScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved request scoped variable '" + property + "'"); + } + requestContext.getRequestScope().put(property, value); + } else if (requestContext.getFlashScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flash scoped variable '" + property + "'"); + } + requestContext.getFlashScope().put(property, value); + } else if (requestContext.getFlowScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flow scoped variable '" + property + "'"); + } + requestContext.getFlowScope().put(property, value); + } else if (requestContext.getConversationScope().contains(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved conversation scoped variable '" + property + "'"); + } + requestContext.getConversationScope().put(property, value); + } else { + delegate.setProperty(context, target, name, value); + } } private BeanFactory getBeanFactory(RequestContext requestContext) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java index 14ec6042..a7e15077 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ActionMethodELResolver.java @@ -6,6 +6,8 @@ import javax.el.ELContext; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.webflow.engine.AnnotatedAction; import org.springframework.webflow.execution.Action; @@ -18,6 +20,8 @@ import org.springframework.webflow.execution.Action; */ public class ActionMethodELResolver extends ELResolver { + private static final Log logger = LogFactory.getLog(ActionMethodELResolver.class); + public Class getCommonPropertyType(ELContext elContext, Object base) { return Action.class; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java index f9bc7493..f3693bd4 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ImplicitFlowVariableELResolver.java @@ -9,11 +9,15 @@ import javax.el.ELContext; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.RequestContextHolder; public class ImplicitFlowVariableELResolver extends ELResolver { + private static final Log logger = LogFactory.getLog(ImplicitFlowVariableELResolver.class); + private RequestContext requestContext; public ImplicitFlowVariableELResolver() { @@ -50,6 +54,9 @@ public class ImplicitFlowVariableELResolver extends ELResolver { return null; } if (ImplicitVariables.matches(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved implicit flow variable '" + property + "'"); + } context.setPropertyResolved(true); return ImplicitVariables.value(context, requestContext, property); } else { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java index 89ade2af..a3279a94 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/RequestContextELResolver.java @@ -6,6 +6,8 @@ import javax.el.ELContext; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.RequestContextHolder; @@ -21,6 +23,8 @@ public class RequestContextELResolver extends ELResolver { */ public static final String REQUEST_CONTEXT_VARIABLE_NAME = "flowRequestContext"; + private static final Log logger = LogFactory.getLog(RequestContextELResolver.class); + private RequestContext context; public RequestContextELResolver() { @@ -49,6 +53,9 @@ public class RequestContextELResolver extends ELResolver { public Object getValue(ELContext elContext, Object base, Object property) { if (base == null && REQUEST_CONTEXT_VARIABLE_NAME.equals(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved the current RequestContext under variable '" + property + "'"); + } elContext.setPropertyResolved(true); return getRequestContext(); } else { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java index d762672d..065b39fb 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/ScopeSearchingELResolver.java @@ -5,6 +5,8 @@ import java.util.Iterator; import javax.el.ELContext; import javax.el.ELResolver; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.RequestContextHolder; @@ -19,6 +21,8 @@ import org.springframework.webflow.execution.RequestContextHolder; */ public class ScopeSearchingELResolver extends ELResolver { + private static final Log logger = LogFactory.getLog(ScopeSearchingELResolver.class); + private RequestContext requestContext; public ScopeSearchingELResolver() { @@ -66,15 +70,27 @@ public class ScopeSearchingELResolver extends ELResolver { } String attributeName = property.toString(); if (requestContext.getRequestScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved request scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); return requestContext.getRequestScope().get(attributeName); } else if (requestContext.getFlashScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flash scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); return requestContext.getFlashScope().get(attributeName); } else if (requestContext.getFlowScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flow scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); return requestContext.getFlowScope().get(attributeName); } else if (requestContext.getConversationScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved conversation scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); return requestContext.getConversationScope().get(attributeName); } else { @@ -112,15 +128,27 @@ public class ScopeSearchingELResolver extends ELResolver { } String attributeName = property.toString(); if (requestContext.getRequestScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved request scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); requestContext.getRequestScope().put(attributeName, value); } else if (requestContext.getFlashScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flash scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); requestContext.getFlashScope().put(attributeName, value); } else if (requestContext.getFlowScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved flow scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); requestContext.getFlowScope().put(attributeName, value); } else if (requestContext.getConversationScope().contains(attributeName)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved conversation scoped variable '" + property + "'"); + } elContext.setPropertyResolved(true); requestContext.getConversationScope().put(attributeName, value); } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java index 85deadee..2b1c1f45 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/el/SpringSecurityELResolver.java @@ -6,6 +6,8 @@ import javax.el.ELContext; import javax.el.ELResolver; import javax.el.PropertyNotWritableException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.security.Authentication; import org.springframework.security.context.SecurityContextHolder; @@ -17,6 +19,8 @@ import org.springframework.security.context.SecurityContextHolder; */ public class SpringSecurityELResolver extends ELResolver { + private static final Log logger = LogFactory.getLog(SpringSecurityELResolver.class); + /** * Name of the security principal variable. */ @@ -41,6 +45,9 @@ public class SpringSecurityELResolver extends ELResolver { public Object getValue(ELContext elContext, Object base, Object property) { if (base == null && SECURITY_PRINCIPAL_VARIABLE_NAME.equals(property)) { + if (logger.isDebugEnabled()) { + logger.debug("Successfully resolved implicit flow variable '" + property + "'"); + } elContext.setPropertyResolved(true); if (SecurityContextHolder.getContext() != null) { return SecurityContextHolder.getContext().getAuthentication(); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java new file mode 100644 index 00000000..ce396f58 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/WebFlowOgnlExpressionParserTests.java @@ -0,0 +1,155 @@ +package org.springframework.webflow.expression; + +import junit.framework.TestCase; + +import org.springframework.beans.factory.support.StaticListableBeanFactory; +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.support.ParserContextImpl; +import org.springframework.security.Authentication; +import org.springframework.security.context.SecurityContextHolder; +import org.springframework.security.context.SecurityContextImpl; +import org.springframework.security.providers.TestingAuthenticationToken; +import org.springframework.webflow.TestBean; +import org.springframework.webflow.action.FormAction; +import org.springframework.webflow.core.collection.AttributeMap; +import org.springframework.webflow.core.collection.LocalAttributeMap; +import org.springframework.webflow.core.collection.MutableAttributeMap; +import org.springframework.webflow.engine.AnnotatedAction; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.execution.TestAction; +import org.springframework.webflow.test.MockRequestContext; + +public class WebFlowOgnlExpressionParserTests extends TestCase { + private WebFlowOgnlExpressionParser parser = new WebFlowOgnlExpressionParser(); + + public void testResolveMap() { + LocalAttributeMap map = new LocalAttributeMap(); + map.put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(AttributeMap.class)); + Expression exp2 = parser.parseExpression("bogus", new ParserContextImpl().eval(AttributeMap.class)); + assertEquals("bar", exp.getValue(map)); + assertEquals(null, exp2.getValue(map)); + } + + public void testSetMap() { + LocalAttributeMap map = new LocalAttributeMap(); + map.put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(MutableAttributeMap.class)); + Expression exp2 = parser.parseExpression("bogus", new ParserContextImpl().eval(MutableAttributeMap.class)); + exp.setValue(map, "baz"); + exp2.setValue(map, "new"); + assertEquals("baz", exp.getValue(map)); + assertEquals("new", exp2.getValue(map)); + } + + public void testResolveFlowRequestContext() { + MockRequestContext context = new MockRequestContext(); + Expression exp = parser.parseExpression("flowRequestContext", new ParserContextImpl() + .eval(RequestContext.class)); + assertSame(context, exp.getValue(context)); + } + + public void testResolveCurrentUser() { + SecurityContextImpl security = new SecurityContextImpl(); + Authentication auth = new TestingAuthenticationToken("user", "password", null); + security.setAuthentication(auth); + SecurityContextHolder.setContext(security); + MockRequestContext context = new MockRequestContext(); + Expression exp = parser.parseExpression("currentUser", new ParserContextImpl().eval(RequestContext.class)); + assertSame(auth, exp.getValue(context)); + } + + public void testResolveRequestScope() { + MockRequestContext context = new MockRequestContext(); + context.getRequestScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetRequestScope() { + MockRequestContext context = new MockRequestContext(); + context.getRequestScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveFlashScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlashScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetFlashScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlashScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveFlowScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlowScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetFlowScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlowScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveConversationScope() { + MockRequestContext context = new MockRequestContext(); + context.getConversationScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetConversationScope() { + MockRequestContext context = new MockRequestContext(); + context.getConversationScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveSpringBean() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("testBean", new TestBean()); + beanFactory.addBean("action", new TestAction()); + beanFactory.addBean("multiAction", new FormAction(TestBean.class)); + context.getRootFlow().setBeanFactory(beanFactory); + context.getConversationScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testResolveAction() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("action", new TestAction()); + context.getRootFlow().setBeanFactory(beanFactory); + Expression exp = parser.parseExpression("action", new ParserContextImpl().eval(RequestContext.class)); + assertSame(beanFactory.getBean("action"), exp.getValue(context)); + } + + public void testResolveMultiAction() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("multiAction", new FormAction()); + context.getRootFlow().setBeanFactory(beanFactory); + Expression exp = parser.parseExpression("multiAction.setupForm", new ParserContextImpl() + .eval(RequestContext.class)); + AnnotatedAction action = (AnnotatedAction) exp.getValue(context); + assertSame(beanFactory.getBean("multiAction"), action.getTargetAction()); + assertEquals("setupForm", action.getMethod()); + } + +} diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java new file mode 100644 index 00000000..58b700e6 --- /dev/null +++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/el/WebFlowELExpressionParserTests.java @@ -0,0 +1,154 @@ +package org.springframework.webflow.expression.el; + +import junit.framework.TestCase; + +import org.springframework.beans.factory.support.StaticListableBeanFactory; +import org.springframework.binding.expression.Expression; +import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils; +import org.springframework.binding.expression.support.ParserContextImpl; +import org.springframework.security.Authentication; +import org.springframework.security.context.SecurityContextHolder; +import org.springframework.security.context.SecurityContextImpl; +import org.springframework.security.providers.TestingAuthenticationToken; +import org.springframework.webflow.TestBean; +import org.springframework.webflow.action.FormAction; +import org.springframework.webflow.core.collection.AttributeMap; +import org.springframework.webflow.core.collection.LocalAttributeMap; +import org.springframework.webflow.core.collection.MutableAttributeMap; +import org.springframework.webflow.engine.AnnotatedAction; +import org.springframework.webflow.execution.RequestContext; +import org.springframework.webflow.execution.TestAction; +import org.springframework.webflow.test.MockRequestContext; + +public class WebFlowELExpressionParserTests extends TestCase { + private WebFlowELExpressionParser parser = new WebFlowELExpressionParser(DefaultExpressionFactoryUtils + .createExpressionFactory()); + + public void testResolveMap() { + LocalAttributeMap map = new LocalAttributeMap(); + map.put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(AttributeMap.class)); + Expression exp2 = parser.parseExpression("bogus", new ParserContextImpl().eval(AttributeMap.class)); + assertEquals("bar", exp.getValue(map)); + assertEquals(null, exp2.getValue(map)); + } + + public void testSetMap() { + LocalAttributeMap map = new LocalAttributeMap(); + map.put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(MutableAttributeMap.class)); + Expression exp2 = parser.parseExpression("bogus", new ParserContextImpl().eval(MutableAttributeMap.class)); + exp.setValue(map, "baz"); + exp2.setValue(map, "new"); + assertEquals("baz", exp.getValue(map)); + assertEquals("new", exp2.getValue(map)); + } + + public void testResolveFlowRequestContext() { + MockRequestContext context = new MockRequestContext(); + Expression exp = parser.parseExpression("flowRequestContext", new ParserContextImpl() + .eval(RequestContext.class)); + assertSame(context, exp.getValue(context)); + } + + public void testResolveCurrentUser() { + SecurityContextImpl security = new SecurityContextImpl(); + Authentication auth = new TestingAuthenticationToken("user", "password", null); + security.setAuthentication(auth); + SecurityContextHolder.setContext(security); + MockRequestContext context = new MockRequestContext(); + Expression exp = parser.parseExpression("currentUser", new ParserContextImpl().eval(RequestContext.class)); + assertSame(auth, exp.getValue(context)); + } + + public void testResolveRequestScope() { + MockRequestContext context = new MockRequestContext(); + context.getRequestScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetRequestScope() { + MockRequestContext context = new MockRequestContext(); + context.getRequestScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveFlashScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlashScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetFlashScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlashScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveFlowScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlowScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetFlowScope() { + MockRequestContext context = new MockRequestContext(); + context.getFlowScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveConversationScope() { + MockRequestContext context = new MockRequestContext(); + context.getConversationScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + assertEquals("bar", exp.getValue(context)); + } + + public void testSetConversationScope() { + MockRequestContext context = new MockRequestContext(); + context.getConversationScope().put("foo", "bar"); + Expression exp = parser.parseExpression("foo", new ParserContextImpl().eval(RequestContext.class)); + exp.setValue(context, "baz"); + assertEquals("baz", exp.getValue(context)); + } + + public void testResolveSpringBean() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("testBean", new TestBean()); + context.getRootFlow().setBeanFactory(beanFactory); + Expression exp = parser.parseExpression("testBean", new ParserContextImpl().eval(RequestContext.class)); + assertSame(beanFactory.getBean("testBean"), exp.getValue(context)); + } + + public void testResolveAction() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("action", new TestAction()); + context.getRootFlow().setBeanFactory(beanFactory); + Expression exp = parser.parseExpression("action", new ParserContextImpl().eval(RequestContext.class)); + assertSame(beanFactory.getBean("action"), exp.getValue(context)); + } + + public void testResolveMultiAction() { + MockRequestContext context = new MockRequestContext(); + StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + beanFactory.addBean("multiAction", new FormAction()); + context.getRootFlow().setBeanFactory(beanFactory); + Expression exp = parser.parseExpression("multiAction.setupForm", new ParserContextImpl() + .eval(RequestContext.class)); + AnnotatedAction action = (AnnotatedAction) exp.getValue(context); + assertSame(beanFactory.getBean("multiAction"), action.getTargetAction()); + assertEquals("setupForm", action.getMethod()); + } + +}