org.springframework
spring-web
diff --git a/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java
index 25b7dd6f..91ec1e94 100644
--- a/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java
+++ b/spring-faces/src/main/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParser.java
@@ -16,7 +16,6 @@
package org.springframework.faces.config;
import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -36,12 +35,11 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
BeanDefinitionParser {
// --------------------------- Full qualified class names ----------------------- //
- private static final String DEFAULT_EXPRESSION_FACTORY_UTILS_CLASS_NAME = "org.springframework.binding.expression.el.DefaultExpressionFactoryUtils";
private static final String FACES_CONVERSION_SERVICE_CLASS_NAME = "org.springframework.faces.model.converter.FacesConversionService";
private static final String FLOW_BUILDER_SERVICES_CLASS_NAME = "org.springframework.webflow.engine.builder.support.FlowBuilderServices";
private static final String JSF_VIEW_FACTORY_CREATOR_CLASS_NAME = "org.springframework.faces.webflow.JsfViewFactoryCreator";
- private static final String JSF_MANAGED_BEAN_AWARE_E_L_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.faces.webflow.JsfManagedBeanAwareELExpressionParser";
- private static final String WEBFLOW_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.webflow.expression.el.WebFlowELExpressionParser";
+ private static final String FACES_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.faces.webflow.FacesSpringELExpressionParser";
+ private static final String WEBFLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser";
// --------------------------- XML Config Attributes ----------------------- //
private static final String CONVERSION_SERVICE_ATTR = "conversion-service";
@@ -106,27 +104,25 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
private void parseExpressionParser(Element element, ParserContext context, BeanDefinitionBuilder definitionBuilder,
boolean enableManagedBeans) {
- String conversionService = getConversionService(definitionBuilder);
+ // String conversionService = getConversionService(definitionBuilder);
String expressionParser = element.getAttribute(EXPRESSION_PARSER_ATTR);
if (!StringUtils.hasText(expressionParser)) {
- BeanDefinitionBuilder expressionFactoryBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(DEFAULT_EXPRESSION_FACTORY_UTILS_CLASS_NAME);
- expressionFactoryBuilder.setFactoryMethod("createExpressionFactory");
+ BeanDefinitionBuilder spelExpressionParser = BeanDefinitionBuilder
+ .genericBeanDefinition("org.springframework.expression.spel.standard.SpelExpressionParser");
BeanDefinitionBuilder expressionParserBuilder;
if (enableManagedBeans) {
expressionParserBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(JSF_MANAGED_BEAN_AWARE_E_L_EXPRESSION_PARSER_CLASS_NAME);
+ .genericBeanDefinition(FACES_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
} else {
expressionParserBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(WEBFLOW_EL_EXPRESSION_PARSER_CLASS_NAME);
+ .genericBeanDefinition(WEBFLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
}
- expressionParserBuilder.addConstructorArgValue(expressionFactoryBuilder.getBeanDefinition());
- expressionParserBuilder.addPropertyReference(CONVERSION_SERVICE_PROPERTY, conversionService);
+ expressionParserBuilder.addConstructorArgValue(spelExpressionParser.getBeanDefinition());
expressionParser = registerInfrastructureComponent(element, context, expressionParserBuilder);
} else if (enableManagedBeans) {
@@ -145,19 +141,12 @@ public class FacesFlowBuilderServicesBeanDefinitionParser extends AbstractSingle
}
}
- private String getConversionService(BeanDefinitionBuilder definitionBuilder) {
- RuntimeBeanReference conversionServiceReference = (RuntimeBeanReference) definitionBuilder.getBeanDefinition()
- .getPropertyValues().getPropertyValue(CONVERSION_SERVICE_PROPERTY).getValue();
- return conversionServiceReference.getBeanName();
- }
-
private String registerInfrastructureComponent(Element element, ParserContext context,
BeanDefinitionBuilder componentBuilder) {
String beanName = context.getReaderContext().generateBeanName(componentBuilder.getRawBeanDefinition());
componentBuilder.getRawBeanDefinition().setSource(context.extractSource(element));
componentBuilder.getRawBeanDefinition().setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- context.registerBeanComponent(new BeanComponentDefinition(componentBuilder.getBeanDefinition(),
- beanName));
+ context.registerBeanComponent(new BeanComponentDefinition(componentBuilder.getBeanDefinition(), beanName));
return beanName;
}
}
\ No newline at end of file
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java
new file mode 100644
index 00000000..6faeef3a
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FacesSpringELExpressionParser.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2004-2010 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.faces.webflow;
+
+import org.springframework.binding.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
+
+/**
+ *
+ * A Spring EL {@link ExpressionParser} for use with JSF. Adds JSF specific Spring EL PropertyAccessors.
+ *
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class FacesSpringELExpressionParser extends WebFlowSpringELExpressionParser {
+
+ public FacesSpringELExpressionParser(SpelExpressionParser expressionParser) {
+ super(expressionParser);
+ addPropertyAccessor(new JsfManagedBeanPropertyAccessor());
+ }
+
+}
diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessor.java b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessor.java
new file mode 100644
index 00000000..4843324f
--- /dev/null
+++ b/spring-faces/src/main/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessor.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2004-2010 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.faces.webflow;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+import javax.faces.context.FacesContext;
+
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.util.Assert;
+import org.springframework.webflow.context.ExternalContext;
+import org.springframework.webflow.core.collection.MutableAttributeMap;
+import org.springframework.webflow.execution.RequestContext;
+import org.springframework.webflow.execution.RequestContextHolder;
+
+/**
+ *
+ * Spring EL PropertyAccessor that checks request, session, and application scopes for existing JSF-managed beans. This
+ * allows traditional JSF-managed beans (defined in faces-config.xml) to be resolved through expressions in a flow
+ * definition.
+ *
+ *
+ * The preferred approach is to instead use Spring to configure such beans, but this is meant to ease migration for
+ * users with existing JSF artifacts. This resolver will delegate to a temporary FacesContext so that JSF managed bean
+ * initialization will be triggered if the bean has not already been initialized by JSF.
+ *
+ *
+ * Source code adapted from {@link JsfManagedBeanResolver}.
+ *
+ *
+ * @author Jeremy Grelle
+ * @author Rossen Stoyanchev
+ *
+ * @since 2.1
+ */
+public class JsfManagedBeanPropertyAccessor implements PropertyAccessor {
+
+ public Class[] getSpecificTargetClasses() {
+ return null;
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return (getJsfManagedBean(name) != null);
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ return new TypedValue(getJsfManagedBean(name));
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return (getScopeForBean(name) != null);
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ MutableAttributeMap map = getScopeForBean(name);
+ if (map != null) {
+ map.put(name, newValue);
+ }
+ }
+
+ /**
+ * Locates a JSF managed bean through a temporary FacesContext. This method is only meant to be called from the Flow
+ * Execution. It assumes the FacesContext will not be available and creates a temporary one on the fly.
+ *
+ * @param name The name of the bean to resolve.
+ * @return The JSF Managed Bean instance if found.
+ */
+ private Object getJsfManagedBean(String name) {
+ RequestContext requestContext = RequestContextHolder.getRequestContext();
+ Assert.notNull(requestContext, "RequestContext cannot be null. "
+ + "This PropertyAccessor is only intended to be invoked from an active Flow Execution.");
+ FacesContext facesContext = FlowFacesContext.newInstance(requestContext, FlowLifecycle.newInstance());
+ try {
+ ExpressionFactory factory = facesContext.getApplication().getExpressionFactory();
+ ELContext elContext = facesContext.getELContext();
+ ValueExpression expression = factory.createValueExpression(elContext, "#{" + name + "}", Object.class);
+ return expression.getValue(facesContext.getELContext());
+ } finally {
+ facesContext.release();
+ }
+ }
+
+ private MutableAttributeMap getScopeForBean(String name) {
+ ExternalContext externalContext = RequestContextHolder.getRequestContext().getExternalContext();
+ if (externalContext.getRequestMap().contains(name)) {
+ return externalContext.getRequestMap();
+ } else if (externalContext.getSessionMap().contains(name)) {
+ return externalContext.getSessionMap();
+ } else if (externalContext.getApplicationMap().contains(name)) {
+ return externalContext.getApplicationMap();
+ }
+ return null;
+ }
+}
diff --git a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
index 93f3c250..b47d33be 100644
--- a/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
+++ b/spring-faces/src/test/java/org/springframework/faces/config/FacesFlowBuilderServicesBeanDefinitionParserTests.java
@@ -11,16 +11,17 @@ import org.springframework.binding.convert.ConversionExecutorNotFoundException;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
+import org.springframework.binding.expression.spel.SpringELExpressionParser;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.faces.model.converter.FacesConversionService;
+import org.springframework.faces.webflow.FacesSpringELExpressionParser;
import org.springframework.faces.webflow.JSFMockHelper;
-import org.springframework.faces.webflow.JsfManagedBeanAwareELExpressionParser;
import org.springframework.faces.webflow.JsfViewFactoryCreator;
import org.springframework.webflow.engine.builder.BinderConfiguration;
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import org.springframework.webflow.execution.ViewFactory;
-import org.springframework.webflow.expression.el.WebFlowELExpressionParser;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase {
@@ -40,7 +41,7 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
public void testConfigureDefaults() {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesDefault");
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof FacesConversionService);
assertFalse(builderServices.getDevelopment());
@@ -49,7 +50,7 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
public void testEnableManagedBeans() {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesLegacy");
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof JsfManagedBeanAwareELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof FacesSpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof FacesConversionService);
assertFalse(builderServices.getDevelopment());
@@ -58,7 +59,7 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
public void testFlowBuilderServicesAllCustomized() {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesAllCustom");
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
assertTrue(builderServices.getDevelopment());
@@ -68,8 +69,8 @@ public class FacesFlowBuilderServicesBeanDefinitionParserTests extends TestCase
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesConversionServiceCustom");
assertNotNull(builderServices);
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
- assertTrue(((WebFlowELExpressionParser) builderServices.getExpressionParser()).getConversionService() instanceof TestConversionService);
+ assertTrue(builderServices.getExpressionParser() instanceof WebFlowSpringELExpressionParser);
+ assertNotNull(((SpringELExpressionParser) builderServices.getExpressionParser()).getConversionService());
assertTrue(builderServices.getViewFactoryCreator() instanceof JsfViewFactoryCreator);
assertFalse(builderServices.getDevelopment());
}
diff --git a/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml
index 53c22281..9b556c63 100644
--- a/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml
+++ b/spring-faces/src/test/java/org/springframework/faces/config/flow-builder-services.xml
@@ -20,7 +20,11 @@
-
+
+
+
+
+
diff --git a/spring-faces/src/test/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessorTests.java b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessorTests.java
new file mode 100644
index 00000000..2af12a81
--- /dev/null
+++ b/spring-faces/src/test/java/org/springframework/faces/webflow/JsfManagedBeanPropertyAccessorTests.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2004-2010 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.faces.webflow;
+
+import junit.framework.TestCase;
+
+import org.springframework.webflow.core.collection.MutableAttributeMap;
+import org.springframework.webflow.execution.RequestContextHolder;
+import org.springframework.webflow.test.MockRequestContext;
+
+public class JsfManagedBeanPropertyAccessorTests extends TestCase {
+
+ JSFMockHelper jsfMock = new JSFMockHelper();
+
+ JsfManagedBeanPropertyAccessor accessor = new JsfManagedBeanPropertyAccessor();
+
+ private MockRequestContext requestContext;
+
+ protected void setUp() throws Exception {
+ jsfMock.setUp();
+ requestContext = new MockRequestContext();
+ RequestContextHolder.setRequestContext(requestContext);
+ }
+
+ protected void tearDown() throws Exception {
+ jsfMock.tearDown();
+ }
+
+ public void testCanRead() throws Exception {
+ jsfMock.externalContext().getRequestMap().put("myJsfBean", new Object());
+ assertTrue(accessor.canRead(null, null, "myJsfBean"));
+ }
+
+ public void testRead() throws Exception {
+ Object jsfBean = new Object();
+ jsfMock.externalContext().getRequestMap().put("myJsfBean", jsfBean);
+ assertEquals(jsfBean, accessor.read(null, null, "myJsfBean").getValue());
+ }
+
+ public void testCanWrite() throws Exception {
+ assertFalse(accessor.canWrite(null, null, "myJsfBean"));
+
+ MutableAttributeMap map = requestContext.getExternalContext().getRequestMap();
+ map.put("myJsfBean", new Object());
+ assertTrue(accessor.canWrite(null, null, "myJsfBean"));
+ map.clear();
+
+ map = requestContext.getExternalContext().getSessionMap();
+ map.put("myJsfBean", new Object());
+ assertTrue(accessor.canWrite(null, null, "myJsfBean"));
+ map.clear();
+
+ map = requestContext.getExternalContext().getApplicationMap();
+ map.put("myJsfBean", new Object());
+ assertTrue(accessor.canWrite(null, null, "myJsfBean"));
+ map.clear();
+ }
+
+ public void testWrite() throws Exception {
+ Object jsfBean1 = new Object();
+ Object jsfBean2 = new Object();
+
+ MutableAttributeMap map = requestContext.getExternalContext().getRequestMap();
+ accessor.write(null, null, "myJsfBean", jsfBean1);
+ assertNull("Write occurs only if bean is present in the map", map.get("myJsfBean"));
+
+ map.put("myJsfBean", jsfBean1);
+ accessor.write(null, null, "myJsfBean", jsfBean2);
+ assertEquals(jsfBean2, map.get("myJsfBean"));
+ map.clear();
+ }
+
+}
diff --git a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
index 8c71fe61..e0fa334e 100755
--- a/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
+++ b/spring-webflow-samples/booking-faces/src/main/webapp/WEB-INF/flows/main/main-flow.xml
@@ -7,7 +7,7 @@
-
+
diff --git a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/login.jsp b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/login.jsp
index 7c888380..57a45ad6 100755
--- a/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/login.jsp
+++ b/spring-webflow-samples/booking-mvc/src/main/webapp/WEB-INF/login.jsp
@@ -1,9 +1,9 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
-<%@ page import="org.springframework.security.ui.AbstractProcessingFilter" %>
-<%@ page import="org.springframework.security.ui.webapp.AuthenticationProcessingFilter" %>
-<%@ page import="org.springframework.security.AuthenticationException" %>
+<%@ page import="org.springframework.security.web.authentication.AbstractProcessingFilter" %>
+<%@ page import="org.springframework.security.web.authentication.AuthenticationProcessingFilter" %>
+<%@ page import="org.springframework.security.core.AuthenticationException" %>
Login Required
diff --git a/spring-webflow/.classpath b/spring-webflow/.classpath
index 75ba73a4..f4dab87b 100644
--- a/spring-webflow/.classpath
+++ b/spring-webflow/.classpath
@@ -32,12 +32,13 @@
-
+
+
diff --git a/spring-webflow/ivy.xml b/spring-webflow/ivy.xml
index 12a959fa..b5df4b8e 100644
--- a/spring-webflow/ivy.xml
+++ b/spring-webflow/ivy.xml
@@ -33,6 +33,7 @@
+
diff --git a/spring-webflow/pom.xml b/spring-webflow/pom.xml
index 4c8954df..3aa12857 100644
--- a/spring-webflow/pom.xml
+++ b/spring-webflow/pom.xml
@@ -27,6 +27,11 @@
spring-core
${spring.version}
+
org.springframework
spring-web
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java
index 13aea516..a79eb8ed 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParser.java
@@ -16,7 +16,6 @@
package org.springframework.webflow.config;
import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -34,7 +33,8 @@ import org.w3c.dom.Element;
class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
// --------------------------- Full qualified class names ----------------------- //
- private static final String DEFAULT_EXPRESSION_PARSER_FACTORY_CLASS_NAME = "org.springframework.webflow.expression.DefaultExpressionParserFactory";
+ private static final String WEB_FLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser";
+ private static final String SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.expression.spel.standard.SpelExpressionParser";
private static final String DEFAULT_CONVERSION_SERVICE_CLASS_NAME = "org.springframework.binding.convert.service.DefaultConversionService";
private static final String FLOW_BUILDER_SERVICES_CLASS_NAME = "org.springframework.webflow.engine.builder.support.FlowBuilderServices";
private static final String MVC_VIEW_FACTORY_CREATOR_CLASS_NAME = "org.springframework.webflow.mvc.builder.MvcViewFactoryCreator";
@@ -82,12 +82,13 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti
private void parseExpressionParser(Element element, ParserContext context, BeanDefinitionBuilder definitionBuilder) {
String expressionParser = element.getAttribute(EXPRESSION_PARSER_ATTR);
if (!StringUtils.hasText(expressionParser)) {
- String conversionService = getConversionService(definitionBuilder);
- BeanDefinitionBuilder expressionParserBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(DEFAULT_EXPRESSION_PARSER_FACTORY_CLASS_NAME);
- expressionParserBuilder.setFactoryMethod("getExpressionParser");
- expressionParserBuilder.addConstructorArgReference(conversionService);
- expressionParser = registerInfrastructureComponent(element, context, expressionParserBuilder);
+ BeanDefinitionBuilder springElExpressionParserBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
+ BeanDefinitionBuilder webFlowElExpressionParserBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(WEB_FLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
+ webFlowElExpressionParserBuilder
+ .addConstructorArgValue(springElExpressionParserBuilder.getBeanDefinition());
+ expressionParser = registerInfrastructureComponent(element, context, webFlowElExpressionParserBuilder);
}
definitionBuilder.addPropertyReference(EXPRESSION_PARSER_PROPERTY, expressionParser);
}
@@ -109,19 +110,12 @@ class FlowBuilderServicesBeanDefinitionParser extends AbstractSingleBeanDefiniti
}
}
- private String getConversionService(BeanDefinitionBuilder definitionBuilder) {
- RuntimeBeanReference conversionServiceReference = (RuntimeBeanReference) definitionBuilder.getBeanDefinition()
- .getPropertyValues().getPropertyValue(CONVERSION_SERVICE_PROPERTY).getValue();
- return conversionServiceReference.getBeanName();
- }
-
private String registerInfrastructureComponent(Element element, ParserContext context,
BeanDefinitionBuilder componentBuilder) {
String beanName = context.getReaderContext().generateBeanName(componentBuilder.getRawBeanDefinition());
componentBuilder.getRawBeanDefinition().setSource(context.extractSource(element));
componentBuilder.getRawBeanDefinition().setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- context.registerBeanComponent(new BeanComponentDefinition(componentBuilder.getBeanDefinition(),
- beanName));
+ context.registerBeanComponent(new BeanComponentDefinition(componentBuilder.getBeanDefinition(), beanName));
return beanName;
}
}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParser.java
index daacacf8..08936215 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParser.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParser.java
@@ -43,7 +43,8 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
// --------------------------- Full qualified class names ----------------------- //
private static final String DEFAULT_CONVERSION_SERVICE_CLASS_NAME = "org.springframework.binding.convert.service.DefaultConversionService";
- private static final String DEFAULT_EXPRESSION_PARSER_FACTORY_CLASS_NAME = "org.springframework.webflow.expression.DefaultExpressionParserFactory";
+ private static final String WEB_FLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser";
+ private static final String SPRING_EL_EXPRESSION_PARSER_CLASS_NAME = "org.springframework.expression.spel.standard.SpelExpressionParser";
private static final String FLOW_BUILDER_SERVICES_CLASS_NAME = "org.springframework.webflow.engine.builder.support.FlowBuilderServices";
private static final String FLOW_REGISTRY_FACTORY_BEAN_CLASS_NAME = "org.springframework.webflow.config.FlowRegistryFactoryBean";
private static final String MVC_VIEW_FACTORY_CREATOR_CLASS_NAME = "org.springframework.webflow.mvc.builder.MvcViewFactoryCreator";
@@ -151,11 +152,15 @@ class FlowRegistryBeanDefinitionParser extends AbstractSingleBeanDefinitionParse
String conversionService = registerInfrastructureComponent(element, context, conversionServiceBuilder);
flowBuilderServicesBuilder.addPropertyReference("conversionService", conversionService);
- BeanDefinitionBuilder expressionParserBuilder = BeanDefinitionBuilder
- .genericBeanDefinition(DEFAULT_EXPRESSION_PARSER_FACTORY_CLASS_NAME);
- expressionParserBuilder.setFactoryMethod("getExpressionParser");
- expressionParserBuilder.addConstructorArgReference(conversionService);
- String expressionParser = registerInfrastructureComponent(element, context, expressionParserBuilder);
+ BeanDefinitionBuilder springElExpressionParserBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
+ BeanDefinitionBuilder webFlowElExpressionParserBuilder = BeanDefinitionBuilder
+ .genericBeanDefinition(WEB_FLOW_SPRING_EL_EXPRESSION_PARSER_CLASS_NAME);
+ webFlowElExpressionParserBuilder
+ .addConstructorArgValue(springElExpressionParserBuilder.getBeanDefinition());
+
+ String expressionParser = registerInfrastructureComponent(element, context,
+ webFlowElExpressionParserBuilder);
flowBuilderServicesBuilder.addPropertyReference("expressionParser", expressionParser);
BeanDefinitionBuilder viewFactoryCreatorBuilder = BeanDefinitionBuilder
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java
deleted file mode 100644
index 57e96bf2..00000000
--- a/spring-webflow/src/main/java/org/springframework/webflow/expression/DefaultExpressionParserFactory.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.
- * 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.expression;
-
-import javax.el.ExpressionFactory;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.binding.convert.ConversionService;
-import org.springframework.binding.expression.ExpressionParser;
-import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils;
-import org.springframework.util.ClassUtils;
-import org.springframework.webflow.expression.el.WebFlowELExpressionParser;
-
-/**
- * Static factory that returns the default {@link ExpressionParser} used by Spring Web Flow. Marked final with a private
- * constructor to prevent subclassing.
- *
- * This factory employs the following algorithm when the returned ExpressionParser instance is used for the first time:
- *
- * - If a Unified EL implementation is configured for the VM, make a {@link WebFlowELExpressionParser} the default.
- *
- If no Unified EL implementation is configured and OGNL is configured, make a {@link WebFlowOgnlExpressionParser}
- * the default.
- *
- If neither Unified EL or OGNL are configured, throw an IllegalStateException with a nice error message.
- *
- *
- * @author Keith Donald
- * @author Erwin Vervaet
- */
-public final class DefaultExpressionParserFactory {
-
- private static final Log logger = LogFactory.getLog(DefaultExpressionParserFactory.class);
-
- /**
- * The singleton instance of the default expression parser.
- */
- private static ExpressionParser INSTANCE;
-
- // static factory - not instantiable
- private DefaultExpressionParserFactory() {
- }
-
- /**
- * Returns the default expression parser for Spring Web Flow. The returned instance is a cached thread-safe object.
- * @return the expression parser
- */
- public static synchronized ExpressionParser getExpressionParser() {
- return getDefaultExpressionParser();
- }
-
- /**
- * Returns the default expression parser for Spring Web Flow configured with the provided ConversionService for type
- * conversion. The returned instance is a thread-safe object.
- * @param conversionService the conversionService
- * @return the expression parser
- */
- public static synchronized ExpressionParser getExpressionParser(final ConversionService conversionService) {
- return createDefaultExpressionParser(conversionService);
- }
-
- /**
- * Returns the default expression parser, creating it if necessary.
- * @return the default expression parser
- */
- private static synchronized ExpressionParser getDefaultExpressionParser() {
- if (INSTANCE == null) {
- INSTANCE = createDefaultExpressionParser(null);
- if (logger.isDebugEnabled()) {
- logger.debug("Initialized shared default Web Flow ExpressionParser " + INSTANCE);
- }
- }
- return INSTANCE;
- }
-
- /**
- * Create the default expression parser. This implementation tries EL first, then OGNL if EL is not configured.
- * @return the default Web Flow expression parser
- */
- private static ExpressionParser createDefaultExpressionParser(ConversionService conversionService)
- throws IllegalStateException {
- try {
- ExpressionFactory elFactory = DefaultExpressionFactoryUtils.createExpressionFactory();
- WebFlowELExpressionParser expressionParser = new WebFlowELExpressionParser(elFactory);
- if (conversionService != null) {
- expressionParser.setConversionService(conversionService);
- }
- return expressionParser;
- } catch (Exception e) {
- try {
- ClassUtils.forName("ognl.Ognl", DefaultExpressionParserFactory.class.getClassLoader());
- WebFlowOgnlExpressionParser expressionParser = new WebFlowOgnlExpressionParser();
- if (conversionService != null) {
- expressionParser.setConversionService(conversionService);
- }
- return expressionParser;
- } catch (ClassNotFoundException ex) {
- IllegalStateException ise = new IllegalStateException(
- "Unable to create the default expression parser for Spring Web Flow: Neither a Unified EL implementation or OGNL could be found.");
- ise.initCause(ex);
- throw ise;
- } catch (NoClassDefFoundError ex) {
- IllegalStateException ise = new IllegalStateException(
- "Unable to create the default expression parser for Spring Web Flow: Neither a Unified EL implementation or OGNL could be found.");
- ise.initCause(ex);
- throw ise;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ActionPropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ActionPropertyAccessor.java
new file mode 100644
index 00000000..ceda9029
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ActionPropertyAccessor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.webflow.action.MultiAction;
+import org.springframework.webflow.execution.Action;
+import org.springframework.webflow.execution.AnnotatedAction;
+
+/**
+ *
+ * Spring EL Property Accessor that allows invocation of methods against a resolved Web Flow action, typically a
+ * {@link MultiAction} in expressions.
+ *
+ *
+ * @see org.springframework.webflow.action.EvaluateAction
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class ActionPropertyAccessor implements PropertyAccessor {
+
+ public Class[] getSpecificTargetClasses() {
+ return new Class[] { Action.class };
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return true;
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ AnnotatedAction annotated = new AnnotatedAction((Action) target);
+ annotated.setMethod(name);
+ return new TypedValue(annotated);
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return false;
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ throw new AccessException("The Action cannot be set with an expression.");
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/BeanFactoryPropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/BeanFactoryPropertyAccessor.java
new file mode 100644
index 00000000..19c48581
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/BeanFactoryPropertyAccessor.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.support.StaticListableBeanFactory;
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.webflow.execution.RequestContext;
+import org.springframework.webflow.execution.RequestContextHolder;
+
+/**
+ * Spring EL PropertyAccessor for reading beans in a {@link org.springframework.beans.factory.BeanFactory}.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class BeanFactoryPropertyAccessor implements PropertyAccessor {
+
+ private static final BeanFactory EMPTY_BEAN_FACTORY = new StaticListableBeanFactory();
+
+ public Class[] getSpecificTargetClasses() {
+ return null;
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return getBeanFactory().containsBean(name);
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ return new TypedValue(getBeanFactory().getBean(name));
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return false;
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ throw new AccessException("Beans in a BeanFactory are read-only");
+ }
+
+ protected BeanFactory getBeanFactory() {
+ RequestContext requestContext = RequestContextHolder.getRequestContext();
+ if (requestContext != null) {
+ BeanFactory beanFactory = requestContext.getActiveFlow().getApplicationContext();
+ if (beanFactory != null) {
+ return beanFactory;
+ }
+ }
+ return EMPTY_BEAN_FACTORY;
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessor.java
new file mode 100644
index 00000000..bdc70c35
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessor.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
+import org.springframework.webflow.execution.RequestContext;
+import org.springframework.webflow.execution.RequestContextHolder;
+
+/**
+ *
+ * Spring EL PropertyAccessor that enables use of the following reserved variables in expressions:
+ *
+ *
+ *
+ * currentUser
+ * flowRequestContext
+ * resourceBundle
+ *
+ *
+ *
+ * Note that any property of {@link RequestContext} (e.g. flowScope, requestParameters, etc.) may also be used in
+ * expressions. Such properties are already handled by the {@link ReflectivePropertyAccessor}.
+ *
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class FlowVariablePropertyAccessor implements PropertyAccessor {
+
+ private static Map variables = new HashMap();
+
+ static {
+ variables.put("currentUser", new FlowVariableAccessor() {
+ public Object getVariable() {
+ return RequestContextHolder.getRequestContext().getExternalContext().getCurrentUser();
+ }
+ });
+ variables.put("flowRequestContext", new FlowVariableAccessor() {
+ public Object getVariable() {
+ return RequestContextHolder.getRequestContext();
+ }
+ });
+ variables.put("resourceBundle", new FlowVariableAccessor() {
+ public Object getVariable() {
+ return RequestContextHolder.getRequestContext().getActiveFlow().getApplicationContext();
+ }
+ });
+ }
+
+ public Class[] getSpecificTargetClasses() {
+ return null;
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return variables.containsKey(name);
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ FlowVariableAccessor var = (FlowVariableAccessor) variables.get(name);
+ return new TypedValue(var.getVariable());
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return false;
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ throw new AccessException(name + " is a flow reserved word and cannot be set with an expression.");
+ }
+
+ private interface FlowVariableAccessor {
+ Object getVariable();
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MapAdaptablePropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MapAdaptablePropertyAccessor.java
new file mode 100644
index 00000000..e66bd72a
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MapAdaptablePropertyAccessor.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import org.springframework.binding.collection.MapAdaptable;
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.webflow.core.collection.MutableAttributeMap;
+
+/**
+ * Spring EL PropertyAccessor for reading from {@link MapAdaptable} and writing to {@link MutableAttributeMap}.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class MapAdaptablePropertyAccessor implements PropertyAccessor {
+
+ public Class[] getSpecificTargetClasses() {
+ return new Class[] { MapAdaptable.class };
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return true;
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ MapAdaptable map = (MapAdaptable) target;
+ return new TypedValue(map.asMap().get(name));
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return (target instanceof MutableAttributeMap);
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ MutableAttributeMap map = (MutableAttributeMap) target;
+ map.put(name, newValue);
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MessageSourcePropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MessageSourcePropertyAccessor.java
new file mode 100644
index 00000000..6312a480
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/MessageSourcePropertyAccessor.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import java.util.Locale;
+
+import org.springframework.context.MessageSource;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.webflow.execution.RequestContext;
+import org.springframework.webflow.execution.RequestContextHolder;
+
+/**
+ *
+ * Spring EL PropertyAccessor that resolves messages from the {@link MessageSource} of the active Flow. The message
+ * source itself is accessible through the "resourceBundle" variable (see {@link FlowVariablePropertyAccessor}). To
+ * access a specific message use its key in one of the following ways:
+ *
+ *
+ *
+ * resourceBundle.myErrorCode
+ * resourceBundle['myErrorCode']
+ *
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class MessageSourcePropertyAccessor implements PropertyAccessor {
+
+ public Class[] getSpecificTargetClasses() {
+ return new Class[] { MessageSource.class };
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return (getMessage(target, name) != null);
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ return new TypedValue(getMessage(target, name));
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return false;
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ throw new AccessException("The flow MessageSource is not writable.");
+ }
+
+ private String getMessage(Object target, String name) {
+ return ((MessageSource) target).getMessage(name, null, null, getLocale());
+ }
+
+ private Locale getLocale() {
+ RequestContext requestContext = RequestContextHolder.getRequestContext();
+ return (requestContext != null) ? requestContext.getExternalContext().getLocale() : LocaleContextHolder
+ .getLocale();
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessor.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessor.java
new file mode 100644
index 00000000..ec130f12
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessor.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2004-2010 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.expression.spel;
+
+import org.springframework.expression.AccessException;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.PropertyAccessor;
+import org.springframework.expression.TypedValue;
+import org.springframework.webflow.core.collection.MutableAttributeMap;
+import org.springframework.webflow.execution.RequestContext;
+
+/**
+ * Spring EL PropertyAccessor that searches through all Web Flow scopes.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class ScopeSearchingPropertyAccessor implements PropertyAccessor {
+
+ public Class[] getSpecificTargetClasses() {
+ return new Class[] { RequestContext.class };
+ }
+
+ public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
+ return (findScopeForAttribute((RequestContext) target, name) != null);
+ }
+
+ public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
+ MutableAttributeMap scope = findScopeForAttribute((RequestContext) target, name);
+ return (scope != null) ? new TypedValue(scope.get(name)) : null;
+ }
+
+ public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
+ return (findScopeForAttribute((RequestContext) target, name) != null);
+ }
+
+ public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
+ MutableAttributeMap scope = findScopeForAttribute((RequestContext) target, name);
+ if (scope != null) {
+ scope.put(name, newValue);
+ }
+ }
+
+ private MutableAttributeMap findScopeForAttribute(RequestContext requestContext, String name) {
+ if (requestContext.getRequestScope().contains(name)) {
+ return requestContext.getRequestScope();
+ }
+ if (requestContext.getFlashScope().contains(name)) {
+ return requestContext.getFlashScope();
+ }
+ if (requestContext.inViewState() && requestContext.getViewScope().contains(name)) {
+ return requestContext.getViewScope();
+ }
+ if (requestContext.getFlowScope().contains(name)) {
+ return requestContext.getFlowScope();
+ }
+ if (requestContext.getConversationScope().contains(name)) {
+ return requestContext.getConversationScope();
+ }
+ return null;
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParser.java b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParser.java
new file mode 100644
index 00000000..8e6e38c5
--- /dev/null
+++ b/spring-webflow/src/main/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParser.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import org.springframework.binding.expression.spel.SpringELExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+
+/**
+ * A sub-class for {@link SpringELExpressionParser} that registers Web Flow specific Spring EL PropertyAccessors.
+ *
+ * @author Rossen Stoyanchev
+ * @since 2.1
+ */
+public class WebFlowSpringELExpressionParser extends SpringELExpressionParser {
+
+ public WebFlowSpringELExpressionParser(SpelExpressionParser expressionParser) {
+ super(expressionParser);
+ addPropertyAccessor(new MessageSourcePropertyAccessor());
+ addPropertyAccessor(new FlowVariablePropertyAccessor());
+ addPropertyAccessor(new MapAdaptablePropertyAccessor());
+ addPropertyAccessor(new ScopeSearchingPropertyAccessor());
+ addPropertyAccessor(new BeanFactoryPropertyAccessor());
+ addPropertyAccessor(new ActionPropertyAccessor());
+ }
+
+}
diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java b/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java
index 4417f490..ca9ec363 100644
--- a/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java
+++ b/spring-webflow/src/main/java/org/springframework/webflow/test/TestFlowBuilderServicesFactory.java
@@ -2,8 +2,9 @@ package org.springframework.webflow.test;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
/**
* Factory that encapsulates configuration of default flow builder services for a test environment.
@@ -17,7 +18,7 @@ public class TestFlowBuilderServicesFactory {
FlowBuilderServices services = new FlowBuilderServices();
services.setViewFactoryCreator(new MockViewFactoryCreator());
services.setConversionService(new DefaultConversionService());
- services.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ services.setExpressionParser(new WebFlowSpringELExpressionParser(new SpelExpressionParser()));
services.setApplicationContext(createTestApplicationContext());
return services;
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
index 33a603d1..7fc343d9 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowBuilderServicesBeanDefinitionParserTests.java
@@ -12,12 +12,12 @@ import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
+import org.springframework.binding.expression.spel.SpringELExpressionParser;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.webflow.engine.builder.BinderConfiguration;
import org.springframework.webflow.engine.builder.ViewFactoryCreator;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import org.springframework.webflow.execution.ViewFactory;
-import org.springframework.webflow.expression.el.WebFlowELExpressionParser;
import org.springframework.webflow.mvc.builder.MvcViewFactoryCreator;
public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
@@ -32,7 +32,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
public void testFlowBuilderServicesDefaultConfig() {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesDefault");
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof MvcViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof DefaultConversionService);
assertFalse(builderServices.getDevelopment());
@@ -41,7 +41,7 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
public void testFlowBuilderServicesAllCustomized() {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesAllCustom");
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof TestViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
assertTrue(builderServices.getDevelopment());
@@ -51,8 +51,8 @@ public class FlowBuilderServicesBeanDefinitionParserTests extends TestCase {
builderServices = (FlowBuilderServices) context.getBean("flowBuilderServicesConversionServiceCustom");
assertNotNull(builderServices);
assertTrue(builderServices.getConversionService() instanceof TestConversionService);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
- assertTrue(((WebFlowELExpressionParser) builderServices.getExpressionParser()).getConversionService() instanceof TestConversionService);
+ assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
+ assertNotNull(((SpringELExpressionParser) builderServices.getExpressionParser()).getConversionService());
assertTrue(builderServices.getViewFactoryCreator() instanceof MvcViewFactoryCreator);
assertFalse(builderServices.getDevelopment());
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParserTests.java
index e787ee2c..21b482de 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParserTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/config/FlowRegistryBeanDefinitionParserTests.java
@@ -6,13 +6,13 @@ import java.util.Map;
import junit.framework.TestCase;
import org.springframework.binding.convert.service.DefaultConversionService;
+import org.springframework.binding.expression.spel.SpringELExpressionParser;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.webflow.definition.FlowDefinition;
import org.springframework.webflow.definition.registry.FlowDefinitionConstructionException;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.definition.registry.NoSuchFlowDefinitionException;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
-import org.springframework.webflow.expression.el.WebFlowELExpressionParser;
import org.springframework.webflow.mvc.builder.MvcViewFactoryCreator;
public class FlowRegistryBeanDefinitionParserTests extends TestCase {
@@ -63,7 +63,7 @@ public class FlowRegistryBeanDefinitionParserTests extends TestCase {
while (i.hasNext()) {
FlowBuilderServices builderServices = (FlowBuilderServices) i.next();
assertNotNull(builderServices);
- assertTrue(builderServices.getExpressionParser() instanceof WebFlowELExpressionParser);
+ assertTrue(builderServices.getExpressionParser() instanceof SpringELExpressionParser);
assertTrue(builderServices.getViewFactoryCreator() instanceof MvcViewFactoryCreator);
assertTrue(builderServices.getConversionService() instanceof DefaultConversionService);
assertFalse(builderServices.getDevelopment());
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml
index 8999f625..505fb3e2 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml
+++ b/spring-webflow/src/test/java/org/springframework/webflow/config/flow-builder-services.xml
@@ -18,7 +18,11 @@
-
+
+
+
+
+
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/EndStateTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/EndStateTests.java
index f19d4095..53eae243 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/EndStateTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/EndStateTests.java
@@ -24,6 +24,7 @@ import org.springframework.binding.expression.support.AbstractGetValueExpression
import org.springframework.binding.expression.support.FluentParserContext;
import org.springframework.binding.mapping.impl.DefaultMapper;
import org.springframework.binding.mapping.impl.DefaultMapping;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.engine.support.DefaultTargetStateResolver;
import org.springframework.webflow.engine.support.MockTransitionCriteria;
@@ -31,7 +32,7 @@ import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.RequestContext;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
import org.springframework.webflow.test.MockFlowExecutionContext;
import org.springframework.webflow.test.MockFlowSession;
import org.springframework.webflow.test.MockRequestControlContext;
@@ -79,7 +80,7 @@ public class EndStateTests extends TestCase {
};
EndState state = new EndState(flow, "end");
DefaultMapper mapper = new DefaultMapper();
- ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser();
+ ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
Expression x = parser.parseExpression("flowScope.x", new FluentParserContext().evaluate(RequestContext.class));
Expression y = parser.parseExpression("y", new FluentParserContext().evaluate(MutableAttributeMap.class));
mapper.addMapping(new DefaultMapping(x, y));
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/FlowTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/FlowTests.java
index f0267163..da951e8d 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/FlowTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/FlowTests.java
@@ -25,6 +25,7 @@ import org.springframework.binding.expression.support.FluentParserContext;
import org.springframework.binding.mapping.impl.DefaultMapper;
import org.springframework.binding.mapping.impl.DefaultMapping;
import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.webflow.TestException;
import org.springframework.webflow.action.TestMultiAction;
import org.springframework.webflow.core.collection.AttributeMap;
@@ -37,7 +38,7 @@ import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.TestAction;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
import org.springframework.webflow.test.MockRequestControlContext;
/**
@@ -209,7 +210,7 @@ public class FlowTests extends TestCase {
public void testStartWithMapper() {
DefaultMapper attributeMapper = new DefaultMapper();
- ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser();
+ ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
Expression x = parser.parseExpression("attr", new FluentParserContext().evaluate(AttributeMap.class));
Expression y = parser.parseExpression("flowScope.attr", new FluentParserContext()
.evaluate(RequestContext.class));
@@ -224,7 +225,7 @@ public class FlowTests extends TestCase {
public void testStartWithMapperButNoInput() {
DefaultMapper attributeMapper = new DefaultMapper();
- ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser();
+ ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
Expression x = parser.parseExpression("attr", new FluentParserContext().evaluate(AttributeMap.class));
Expression y = parser.parseExpression("flowScope.attr", new FluentParserContext()
.evaluate(RequestContext.class));
@@ -314,7 +315,7 @@ public class FlowTests extends TestCase {
public void testEndWithOutputMapper() {
DefaultMapper attributeMapper = new DefaultMapper();
- ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser();
+ ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
Expression x = parser.parseExpression("flowScope.attr", new FluentParserContext()
.evaluate(RequestContext.class));
Expression y = parser.parseExpression("attr", new FluentParserContext().evaluate(MutableAttributeMap.class));
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
index 30452002..2d159039 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTargetStateResolverTests.java
@@ -40,7 +40,7 @@ public class TextToTargetStateResolverTests extends TestCase {
}
public void testDynamic() throws Exception {
- String expression = "${flowScope.lastState}";
+ String expression = "#{flowScope.lastState}";
TargetStateResolver resolver = (TargetStateResolver) converter.convertSourceToTargetClass(expression,
TargetStateResolver.class);
MockRequestContext context = new MockRequestContext();
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
index 854bb3c3..de6bfb29 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/engine/builder/support/TextToTransitionCriteriaTests.java
@@ -62,7 +62,7 @@ public class TextToTransitionCriteriaTests extends TestCase {
}
public void testTrueEvaluation() throws Exception {
- String expression = "${flowScope.foo == 'bar'}";
+ String expression = "#{flowScope.foo == 'bar'}";
TransitionCriteria criterion = (TransitionCriteria) converter.convertSourceToTargetClass(expression,
TransitionCriteria.class);
RequestContext ctx = getRequestContext();
@@ -70,7 +70,7 @@ public class TextToTransitionCriteriaTests extends TestCase {
}
public void testFalseEvaluation() throws Exception {
- String expression = "${flowScope.foo != 'bar'}";
+ String expression = "#{flowScope.foo != 'bar'}";
TransitionCriteria criterion = (TransitionCriteria) converter.convertSourceToTargetClass(expression,
TransitionCriteria.class);
RequestContext ctx = getRequestContext();
@@ -78,7 +78,7 @@ public class TextToTransitionCriteriaTests extends TestCase {
}
public void testNonStringEvaluation() throws Exception {
- String expression = "${3 + 4}";
+ String expression = "#{3 + 4}";
TransitionCriteria criterion = (TransitionCriteria) converter.convertSourceToTargetClass(expression,
TransitionCriteria.class);
MockRequestContext ctx = getRequestContext();
@@ -87,7 +87,7 @@ public class TextToTransitionCriteriaTests extends TestCase {
}
public void testCurrenEventEval() throws Exception {
- String expression = "${currentEvent == 'submit'}";
+ String expression = "#{currentEvent.id == 'submit'}";
TransitionCriteria criterion = (TransitionCriteria) converter.convertSourceToTargetClass(expression,
TransitionCriteria.class);
MockRequestContext ctx = getRequestContext();
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/DefaultExpressionParserFactoryTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/DefaultExpressionParserFactoryTests.java
deleted file mode 100644
index dab6127e..00000000
--- a/spring-webflow/src/test/java/org/springframework/webflow/expression/DefaultExpressionParserFactoryTests.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.
- * 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.expression;
-
-import junit.framework.TestCase;
-
-import org.springframework.binding.expression.ExpressionParser;
-
-/**
- * Unit tests for {@link DefaultExpressionParserFactory}.
- */
-public class DefaultExpressionParserFactoryTests extends TestCase {
-
- public void testGetDefaultExpressionParser() {
- ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser();
- assertNotNull(parser);
- }
-
- // public void testGetDefaultExpressionParserConversionService() {
- // DefaultConversionService conversionService = new DefaultConversionService();
- // ExpressionParser parser = DefaultExpressionParserFactory.getExpressionParser(conversionService);
- // Expression exp = parser.parseExpression("datum3", new FluentParserContext().expectResult(String.class));
- // TestBean context = new TestBean();
- // Calendar cal = Calendar.getInstance();
- // cal.set(2008, 1, 1);
- // exp.setValue(context, cal.getTime());
- // String string = (String) exp.getValue(context);
- // assertEquals(null, string);
- // }
-}
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
index 24541d9f..f943c0eb 100644
--- 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
@@ -5,8 +5,8 @@ import java.util.Locale;
import junit.framework.TestCase;
+import org.jboss.el.ExpressionFactoryImpl;
import org.springframework.binding.expression.Expression;
-import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils;
import org.springframework.binding.expression.support.FluentParserContext;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.webflow.TestBean;
@@ -24,8 +24,7 @@ import org.springframework.webflow.test.MockRequestContext;
import org.springframework.webflow.test.MockRequestControlContext;
public class WebFlowELExpressionParserTests extends TestCase {
- private WebFlowELExpressionParser parser = new WebFlowELExpressionParser(DefaultExpressionFactoryUtils
- .createExpressionFactory());
+ private WebFlowELExpressionParser parser = new WebFlowELExpressionParser(new ExpressionFactoryImpl());
public void testResolveMap() {
LocalAttributeMap map = new LocalAttributeMap();
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessorTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessorTests.java
new file mode 100644
index 00000000..2d55dd52
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/FlowVariablePropertyAccessorTests.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2002-2010 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.expression.spel;
+
+import junit.framework.TestCase;
+
+import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.expression.AccessException;
+import org.springframework.webflow.engine.Flow;
+import org.springframework.webflow.execution.RequestContextHolder;
+import org.springframework.webflow.test.MockExternalContext;
+import org.springframework.webflow.test.MockRequestContext;
+
+public class FlowVariablePropertyAccessorTests extends TestCase {
+
+ private FlowVariablePropertyAccessor accessor = new FlowVariablePropertyAccessor();
+
+ private MockRequestContext requestContext;
+
+ protected void setUp() throws Exception {
+ requestContext = new MockRequestContext();
+ RequestContextHolder.setRequestContext(requestContext);
+ }
+
+ protected void tearDown() throws Exception {
+ RequestContextHolder.setRequestContext(null);
+ }
+
+ public void testFlowRequestContext() throws Exception {
+ assertTrue(accessor.canRead(null, null, "flowRequestContext"));
+ assertEquals(requestContext, accessor.read(null, null, "flowRequestContext").getValue());
+ }
+
+ public void testCurrentUser() throws Exception {
+ MockExternalContext externalContext = (MockExternalContext) requestContext.getExternalContext();
+ externalContext.setCurrentUser("joe");
+ assertTrue(accessor.canRead(null, null, "currentUser"));
+ assertEquals(externalContext.getCurrentUser(), accessor.read(null, null, "currentUser").getValue());
+ }
+
+ public void testResourceBundle() throws Exception {
+ Flow flow = (Flow) requestContext.getActiveFlow();
+ flow.setApplicationContext(new StaticApplicationContext());
+ assertTrue(accessor.canRead(null, null, "resourceBundle"));
+ assertNotNull(accessor.read(null, null, "resourceBundle").getValue());
+ assertEquals(requestContext.getActiveFlow().getApplicationContext(), accessor
+ .read(null, null, "resourceBundle").getValue());
+ }
+
+ public void testWrite() throws Exception {
+ assertFalse(accessor.canWrite(null, null, "anyName"));
+ try {
+ accessor.write(null, null, "anyName", "anyValue");
+ } catch (AccessException e) {
+ }
+ }
+}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessorTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessorTests.java
new file mode 100644
index 00000000..e340f314
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/ScopeSearchingPropertyAccessorTests.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2004-2010 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.expression.spel;
+
+import junit.framework.TestCase;
+
+import org.springframework.expression.TypedValue;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.webflow.engine.ViewState;
+import org.springframework.webflow.execution.RequestContext;
+import org.springframework.webflow.execution.View;
+import org.springframework.webflow.execution.ViewFactory;
+import org.springframework.webflow.test.MockFlowSession;
+import org.springframework.webflow.test.MockRequestContext;
+
+public class ScopeSearchingPropertyAccessorTests extends TestCase {
+
+ private ScopeSearchingPropertyAccessor accessor = new ScopeSearchingPropertyAccessor();
+
+ private MockRequestContext requestContext;
+
+ protected void setUp() throws Exception {
+ requestContext = new MockRequestContext();
+ }
+
+ public void testGetSpecificTargetClasses() throws Exception {
+ Class[] classes = accessor.getSpecificTargetClasses();
+ assertEquals(1, classes.length);
+ assertEquals(RequestContext.class, classes[0]);
+ }
+
+ public void testGetValue() throws Exception {
+ Object bean = new Object();
+ requestContext.getConversationScope().put("myBean", bean);
+ TypedValue actual = accessor.read(new StandardEvaluationContext(), requestContext, "myBean");
+ assertSame(bean, actual.getValue());
+
+ bean = new Object();
+ requestContext.getFlowScope().put("myBean", bean);
+ actual = accessor.read(new StandardEvaluationContext(), requestContext, "myBean");
+ assertSame(bean, actual.getValue());
+
+ bean = new Object();
+ initView(requestContext);
+ requestContext.getViewScope().put("myBean", bean);
+ actual = accessor.read(new StandardEvaluationContext(), requestContext, "myBean");
+ unsetView(requestContext);
+ assertSame(bean, actual.getValue());
+
+ bean = new Object();
+ requestContext.getFlashScope().put("myBean", bean);
+ actual = accessor.read(new StandardEvaluationContext(), requestContext, "myBean");
+ assertSame(bean, actual.getValue());
+
+ bean = new Object();
+ requestContext.getRequestScope().put("myBean", bean);
+ actual = accessor.read(new StandardEvaluationContext(), requestContext, "myBean");
+ assertSame(bean, actual.getValue());
+ }
+
+ protected void initView(MockRequestContext requestContext) {
+ ((MockFlowSession) requestContext.getFlowExecutionContext().getActiveSession()).setState(new ViewState(
+ requestContext.getRootFlow(), "view", new ViewFactory() {
+ public View getView(RequestContext context) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+ }));
+ }
+
+ protected void unsetView(MockRequestContext requestContext) {
+ ((MockFlowSession) requestContext.getFlowExecutionContext().getActiveSession()).setState(null);
+ }
+
+}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParserTests.java b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParserTests.java
new file mode 100644
index 00000000..cc508fda
--- /dev/null
+++ b/spring-webflow/src/test/java/org/springframework/webflow/expression/spel/WebFlowSpringELExpressionParserTests.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2004-2010 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.expression.spel;
+
+import java.util.Locale;
+
+import junit.framework.TestCase;
+
+import org.springframework.binding.expression.Expression;
+import org.springframework.binding.expression.ExpressionParser;
+import org.springframework.binding.expression.support.FluentParserContext;
+import org.springframework.context.support.StaticApplicationContext;
+import org.springframework.context.support.StaticMessageSource;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.webflow.engine.Flow;
+import org.springframework.webflow.execution.RequestContextHolder;
+import org.springframework.webflow.test.MockExternalContext;
+import org.springframework.webflow.test.MockRequestContext;
+
+public class WebFlowSpringELExpressionParserTests extends TestCase {
+
+ private ExpressionParser parser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
+
+ private MockRequestContext requestContext;
+
+ protected void setUp() throws Exception {
+ requestContext = new MockRequestContext();
+ RequestContextHolder.setRequestContext(requestContext);
+ }
+
+ public void testResourceBundleRead() throws Exception {
+ MockExternalContext externalContext = (MockExternalContext) requestContext.getExternalContext();
+ externalContext.setLocale(Locale.ENGLISH);
+
+ StaticApplicationContext applicationContext = new StaticApplicationContext();
+ StaticMessageSource messageSource = applicationContext.getStaticMessageSource();
+ messageSource.addMessage("myCode", externalContext.getLocale(), "myCode message");
+ messageSource.addMessage("myCode.myCode", externalContext.getLocale(), "myCode myCode message");
+ applicationContext.refresh();
+
+ Flow flow = (Flow) requestContext.getActiveFlow();
+ flow.setApplicationContext(applicationContext);
+
+ String expressionString = "#{resourceBundle.myCode}";
+ Expression exp = parser.parseExpression(expressionString, new FluentParserContext().template());
+ assertEquals("myCode message", exp.getValue(requestContext));
+
+ expressionString = "#{resourceBundle['myCode']}";
+ exp = parser.parseExpression(expressionString, new FluentParserContext().template());
+ assertEquals("myCode message", exp.getValue(requestContext));
+
+ expressionString = "#{resourceBundle['myCode.myCode']}";
+ exp = parser.parseExpression(expressionString, new FluentParserContext().template());
+ assertEquals("myCode myCode message", exp.getValue(requestContext));
+ }
+
+}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java
index 05b27e84..7a28a049 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/portlet/PortletMvcViewTests.java
@@ -7,6 +7,7 @@ import junit.framework.TestCase;
import org.easymock.EasyMock;
import org.springframework.binding.expression.support.StaticExpression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
@@ -14,7 +15,7 @@ import org.springframework.mock.web.portlet.MockPortletContext;
import org.springframework.mock.web.portlet.MockRenderRequest;
import org.springframework.mock.web.portlet.MockRenderResponse;
import org.springframework.web.servlet.ViewRendererServlet;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
import org.springframework.webflow.mvc.view.AbstractMvcView;
import org.springframework.webflow.mvc.view.MvcViewTests.BindBean;
import org.springframework.webflow.test.MockFlowExecutionKey;
@@ -56,7 +57,7 @@ public class PortletMvcViewTests extends TestCase {
org.springframework.web.servlet.View mvcView = (org.springframework.web.servlet.View) EasyMock
.createMock(org.springframework.web.servlet.View.class);
AbstractMvcView view = new PortletMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(new WebFlowSpringELExpressionParser(new SpelExpressionParser()));
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view.processUserEvent();
assertEquals(true, bindBean.getBooleanProperty());
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/DefaultBindingModelTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/DefaultBindingModelTests.java
index d9ee3b29..2240f962 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/DefaultBindingModelTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/DefaultBindingModelTests.java
@@ -1,11 +1,12 @@
package org.springframework.webflow.mvc.view;
import org.springframework.binding.expression.ExpressionParser;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
public class DefaultBindingModelTests extends AbstractBindingModelTests {
protected ExpressionParser getExpressionParser() {
- return DefaultExpressionParserFactory.getExpressionParser();
+ return new WebFlowSpringELExpressionParser(new SpelExpressionParser());
}
}
diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java
index 8bfc404e..ea87f8ea 100644
--- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java
+++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/view/MvcViewTests.java
@@ -21,8 +21,12 @@ import org.springframework.binding.convert.converters.StringToDate;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
+import org.springframework.binding.expression.spel.SpringELExpressionParser;
import org.springframework.binding.expression.support.StaticExpression;
import org.springframework.binding.validation.ValidationContext;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.format.datetime.DateFormatter;
+import org.springframework.format.support.FormattingConversionService;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockMultipartFile;
@@ -37,7 +41,7 @@ import org.springframework.webflow.engine.ViewState;
import org.springframework.webflow.engine.builder.BinderConfiguration;
import org.springframework.webflow.engine.builder.BinderConfiguration.Binding;
import org.springframework.webflow.execution.RequestContext;
-import org.springframework.webflow.expression.DefaultExpressionParserFactory;
+import org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser;
import org.springframework.webflow.test.MockFlowExecutionKey;
import org.springframework.webflow.test.MockRequestContext;
import org.springframework.webflow.test.MockRequestControlContext;
@@ -64,7 +68,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.render();
assertTrue(renderCalled);
assertEquals("bar", model.get("foo"));
@@ -94,7 +98,7 @@ public class MvcViewTests extends TestCase {
context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.render();
assertTrue(renderCalled);
assertEquals("bar", model.get("foo"));
@@ -122,7 +126,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setConversionService(new DefaultConversionService());
view.render();
assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean"));
@@ -185,7 +189,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.processUserEvent();
assertTrue(view.hasFlowEvent());
assertFalse(context.getFlashScope().contains(ViewActionStateHolder.KEY));
@@ -233,7 +237,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
context.setAlwaysRedirectOnPause(true);
view.processUserEvent();
@@ -282,7 +286,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.processUserEvent();
assertTrue(view.hasFlowEvent());
assertFalse(context.getFlashScope().contains(ViewActionStateHolder.KEY));
@@ -305,7 +309,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
context.setAlwaysRedirectOnPause(true);
assertTrue(view.userEventQueued());
@@ -328,7 +332,7 @@ public class MvcViewTests extends TestCase {
context2.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
context2.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
AbstractMvcView view2 = new MockMvcView(mvcView, context2);
- view2.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view2.setExpressionParser(createExpressionParser());
view2.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view2.restoreState((ViewActionStateHolder) viewActionState);
assertFalse(view2.userEventQueued());
@@ -356,7 +360,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
context.setAlwaysRedirectOnPause(true);
assertTrue(view.userEventQueued());
@@ -381,7 +385,7 @@ public class MvcViewTests extends TestCase {
context2.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
context2.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
AbstractMvcView view2 = new MockMvcView(mvcView, context2);
- view2.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view2.setExpressionParser(createExpressionParser());
view2.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view2.restoreState((ViewActionStateHolder) viewActionState);
assertFalse(view2.userEventQueued());
@@ -431,7 +435,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
BinderConfiguration binderConfiguration = new BinderConfiguration();
binderConfiguration.addBinding(new Binding("stringProperty", null, true));
view.setBinderConfiguration(binderConfiguration);
@@ -462,7 +466,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
DefaultConversionService conversionService = new DefaultConversionService();
StringToDate stringToDate = new StringToDate();
stringToDate.setPattern("MM-dd-yyyy");
@@ -496,7 +500,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.processUserEvent();
assertEquals(false, bindBean.getBooleanProperty());
}
@@ -517,7 +521,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
assertTrue(view.userEventQueued());
view.processUserEvent();
assertFalse(view.userEventQueued());
@@ -541,7 +545,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
assertTrue(view.userEventQueued());
view.processUserEvent();
assertFalse(view.userEventQueued());
@@ -567,7 +571,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
assertTrue(view.userEventQueued());
view.processUserEvent();
assertFalse(view.userEventQueued());
@@ -593,7 +597,7 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view.processUserEvent();
assertFalse(view.hasFlowEvent());
@@ -618,13 +622,21 @@ public class MvcViewTests extends TestCase {
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
- view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
+ view.setExpressionParser(createExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view.processUserEvent();
assertFalse(view.hasFlowEvent());
assertFalse(bindBean.validationMethodInvoked);
}
+ private SpringELExpressionParser createExpressionParser() {
+ SpringELExpressionParser expressionParser = new WebFlowSpringELExpressionParser(new SpelExpressionParser());
+ FormattingConversionService conversionService = (FormattingConversionService) expressionParser
+ .getConversionService();
+ conversionService.addFormatterForFieldType(Date.class, new DateFormatter("yyyy-MM-dd"));
+ return expressionParser;
+ }
+
private class MockMvcView extends AbstractMvcView {
public MockMvcView(View view, RequestContext context) {