SWF-1136 Make Spring EL the default expression language used. The current implementation is functionally equivalent except it ignores the configured Web Flow ConversionService and uses the Spring 3 conversion system instead.

This commit is contained in:
Rossen Stoyanchev
2010-04-27 14:45:39 +00:00
parent afa33607e2
commit 7372b31184
45 changed files with 1113 additions and 352 deletions

View File

@@ -1,76 +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.binding.expression.el;
import javax.el.ExpressionFactory;
import org.springframework.util.ClassUtils;
/**
* A helper for creating a new expression factory instance using the default expression factory class configured for the
* VM.
*
* @author Keith Donald
*/
public class DefaultExpressionFactoryUtils {
// TODO - change default to Spring EL when it becomes available
private static final String DEFAULT_EXPRESSION_FACTORY = "org.jboss.el.ExpressionFactoryImpl";
/**
* Returns the type of ExpressionFactory configured for this VM.
*/
public static String getDefaultExpressionFactoryClassName() {
return DEFAULT_EXPRESSION_FACTORY;
}
/**
* Creates a new instance of the expression factory configured for this VM.
* @throws IllegalStateException if the ExpressionFactory class cannot be instantiated
*/
public static ExpressionFactory createExpressionFactory() throws IllegalStateException {
Class expressionFactoryClass;
try {
expressionFactoryClass = ClassUtils.forName(getDefaultExpressionFactoryClassName(),
DefaultExpressionFactoryUtils.class.getClassLoader());
} catch (ClassNotFoundException e) {
IllegalStateException ise = new IllegalStateException(
"The default ExpressionFactory class '"
+ getDefaultExpressionFactoryClassName()
+ "' could not be found in the classpath. "
+ "Please add this to your classpath or set the default ExpressionFactory class name to something that is in the classpath.");
ise.initCause(e);
throw ise;
} catch (NoClassDefFoundError e) {
IllegalStateException ise = new IllegalStateException(
"The default ExpressionFactory class '"
+ getDefaultExpressionFactoryClassName()
+ "' could not be found in the classpath. "
+ "Please add this to your classpath or set the default ExpressionFactory class name to something that is in the classpath.");
ise.initCause(e);
throw ise;
}
try {
return (ExpressionFactory) expressionFactoryClass.newInstance();
} catch (Exception e) {
IllegalStateException ise = new IllegalStateException("An instance of the default ExpressionFactory '"
+ getDefaultExpressionFactoryClassName()
+ "' could not be instantiated. Check your EL implementation configuration.");
ise.initCause(e);
throw ise;
}
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.PropertyNotFoundException;
import org.springframework.binding.expression.ValueCoercionException;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelMessage;
@@ -76,6 +77,9 @@ public class SpringELExpression implements Expression {
updateEvaluationContext(rootObject);
return expression.getValue(evaluationContext, expectedType);
} catch (SpelEvaluationException e) {
if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE)) {
throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e);
}
if (e.getMessageCode().equals(SpelMessage.TYPE_CONVERSION_ERROR)) {
throw new ValueCoercionException(rootObject.getClass(), getExpressionString(), null, expectedType, e);
}
@@ -86,8 +90,17 @@ public class SpringELExpression implements Expression {
}
public Class getValueType(Object rootObject) throws EvaluationException {
evaluationContext.setRootObject(rootObject);
return expression.getValueType(evaluationContext);
try {
evaluationContext.setRootObject(rootObject);
return expression.getValueType(evaluationContext);
} catch (SpelEvaluationException e) {
if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE)) {
throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e);
}
throw new EvaluationException(rootObject.getClass(), getExpressionString(),
"An ELException occurred getting the value type for expression '" + getExpressionString()
+ "' on context [" + rootObject.getClass() + "]", e);
}
}
public void setValue(Object rootObject, Object value) throws EvaluationException {
@@ -95,6 +108,9 @@ public class SpringELExpression implements Expression {
updateEvaluationContext(rootObject);
expression.setValue(evaluationContext, value);
} catch (SpelEvaluationException e) {
if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE)) {
throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e);
}
if (e.getMessageCode().equals(SpelMessage.EXCEPTION_DURING_PROPERTY_WRITE)) {
throw new ValueCoercionException(rootObject.getClass(), getExpressionString(), value, expectedType, e);
}

View File

@@ -16,6 +16,7 @@
package org.springframework.binding.expression.spel;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -26,6 +27,7 @@ import org.springframework.binding.expression.ExpressionVariable;
import org.springframework.binding.expression.ParserContext;
import org.springframework.binding.expression.ParserException;
import org.springframework.binding.expression.support.NullParserContext;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.convert.ConversionService;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
@@ -33,6 +35,9 @@ import org.springframework.expression.TypeConverter;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.util.Assert;
/**
@@ -47,16 +52,34 @@ public class SpringELExpressionParser implements ExpressionParser {
private SpelExpressionParser expressionParser;
private TypeConverter typeConverter = new StandardTypeConverter();
private ConversionService conversionService;
private List propertyAccessors = new ArrayList();
public SpringELExpressionParser(SpelExpressionParser expressionParser) {
this.expressionParser = expressionParser;
this.propertyAccessors.add(new MapAccessor());
}
public ConversionService getConversionService() {
ensureConversionServiceInitialized();
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
typeConverter = new StandardTypeConverter(conversionService);
this.conversionService = conversionService;
}
private void ensureConversionServiceInitialized() {
if (this.conversionService == null) {
FormattingConversionServiceFactoryBean factoryBean = new FormattingConversionServiceFactoryBean() {
protected void installFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldType(Date.class, new DateFormatter());
}
};
factoryBean.afterPropertiesSet();
this.conversionService = factoryBean.getObject();
}
}
public void addPropertyAccessor(PropertyAccessor propertyAccessor) {
@@ -67,13 +90,17 @@ public class SpringELExpressionParser implements ExpressionParser {
Assert.hasText(expressionString, "The expression string to parse is required and must not be empty");
parserContext = (parserContext == null) ? NullParserContext.INSTANCE : parserContext;
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
evaluationContext.setTypeConverter(typeConverter);
evaluationContext.setTypeConverter(getTypeConverter());
evaluationContext.getPropertyAccessors().addAll(propertyAccessors);
Map spelExpressionVariables = parseSpelExpressionVariables(parserContext.getExpressionVariables());
return new SpringELExpression(parseSpelExpression(expressionString, parserContext), spelExpressionVariables,
parserContext.getExpectedEvaluationResultType(), evaluationContext);
}
private TypeConverter getTypeConverter() {
return (conversionService != null) ? new StandardTypeConverter(conversionService) : new StandardTypeConverter();
}
private org.springframework.expression.Expression parseSpelExpression(String expression, ParserContext parserContext) {
return expressionParser.parseExpression(expression, getSpelParserContext(parserContext));
}

View File

@@ -101,7 +101,7 @@ public class ELExpressionParserCompatibilityTests extends TestCase {
public void testParseEvalExpressionWithContextCustomELVariableResolver() {
String expressionString = "specialProperty";
Expression exp = parser.parseExpression(expressionString, new FluentParserContext().evaluate(TestBean.class));
assertEquals("Custom resolver resolved this special property!", exp.getValue(new TestBean()));
assertEquals("Custom resolver resolved this special property!", exp.getValue(null));
}
public void testParseBeanEvalExpressionInvalidELVariable() {

View File

@@ -7,14 +7,14 @@ import java.util.Map;
import junit.framework.TestCase;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.el.DefaultExpressionFactoryUtils;
import org.springframework.binding.expression.el.ELExpressionParser;
import org.springframework.binding.expression.spel.SpringELExpressionParser;
import org.springframework.binding.mapping.impl.DefaultMapper;
import org.springframework.binding.mapping.impl.DefaultMapping;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class DefaultMapperTests extends TestCase {
private DefaultMapper mapper = new DefaultMapper();
private ExpressionParser parser = new ELExpressionParser(DefaultExpressionFactoryUtils.createExpressionFactory());
private ExpressionParser parser = new SpringELExpressionParser(new SpelExpressionParser());
public void testMapping() {
DefaultMapping mapping1 = new DefaultMapping(parser.parseExpression("foo", null), parser.parseExpression("bar",

View File

@@ -26,6 +26,7 @@
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.beans/3.0.2.RELEASE/org.springframework.beans-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.beans/3.0.2.RELEASE/org.springframework.beans-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.context/3.0.2.RELEASE/org.springframework.context-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.context/3.0.2.RELEASE/org.springframework.context-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.core/3.0.2.RELEASE/org.springframework.core-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.core/3.0.2.RELEASE/org.springframework.core-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.expression/3.0.2.RELEASE/org.springframework.expression-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.expression/3.0.2.RELEASE/org.springframework.expression-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.test/3.0.2.RELEASE/org.springframework.test-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.test/3.0.2.RELEASE/org.springframework.test-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.web/3.0.2.RELEASE/org.springframework.web-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.web/3.0.2.RELEASE/org.springframework.web-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.web.servlet/3.0.2.RELEASE/org.springframework.web.servlet-3.0.2.RELEASE.jar" sourcepath="IVY_CACHE/org.springframework/org.springframework.web.servlet/3.0.2.RELEASE/org.springframework.web.servlet-sources-3.0.2.RELEASE.jar"/>

View File

@@ -30,6 +30,7 @@
<dependency org="org.springframework" name="org.springframework.beans" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.context" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.core" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.expression" rev="3.0.2.RELEASE" conf="compile->runtime" />
<dependency org="org.springframework" name="org.springframework.web" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.web.servlet" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework.webflow" name="org.springframework.binding" rev="latest.integration" conf="compile->runtime"/>

View File

@@ -27,6 +27,11 @@
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>

View File

@@ -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;
}
}

View File

@@ -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;
/**
* <p>
* A Spring EL {@link ExpressionParser} for use with JSF. Adds JSF specific Spring EL PropertyAccessors.
* </p>
*
* @author Rossen Stoyanchev
* @since 2.1
*/
public class FacesSpringELExpressionParser extends WebFlowSpringELExpressionParser {
public FacesSpringELExpressionParser(SpelExpressionParser expressionParser) {
super(expressionParser);
addPropertyAccessor(new JsfManagedBeanPropertyAccessor());
}
}

View File

@@ -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;
/**
* <p>
* 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.
* </p>
* <p>
* 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.
* </p>
* <p>
* Source code adapted from {@link JsfManagedBeanResolver}.
* </p>
*
* @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;
}
}

View File

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

View File

@@ -20,7 +20,11 @@
<faces:flow-builder-services id="flowBuilderServicesConversionServiceCustom"
conversion-service="customConversionService"/>
<bean id="customExpressionParser" class="org.springframework.webflow.expression.DefaultExpressionParserFactory" factory-method="getExpressionParser"/>
<bean id="customExpressionParser" class="org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser">
<constructor-arg>
<bean class="org.springframework.expression.spel.standard.SpelExpressionParser"/>
</constructor-arg>
</bean>
<bean id="customViewFactoryCreator" class="org.springframework.faces.config.FacesFlowBuilderServicesBeanDefinitionParserTests$TestViewFactoryCreator"/>

View File

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

View File

@@ -7,7 +7,7 @@
<view-state id="enterSearchCriteria">
<on-render>
<evaluate expression="bookingService.findBookings(currentUser.name)" result="viewScope.bookings" result-type="dataModel" />
<evaluate expression="bookingService.findBookings(currentUser!=null?currentUser.name:null)" result="viewScope.bookings" result-type="dataModel" />
</on-render>
<transition on="search" to="reviewHotels">
<evaluate expression="searchCriteria.resetPage()" />

View File

@@ -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" %>
<h1>Login Required</h1>

View File

@@ -32,12 +32,13 @@
<classpathentry kind="var" path="IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.2.6.ga/com.springsource.org.hibernate-3.2.6.ga.jar" sourcepath="IVY_CACHE/org.hibernate/com.springsource.org.hibernate/3.2.6.ga/com.springsource.org.hibernate-sources-3.2.6.ga.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.hsqldb/com.springsource.org.hsqldb/1.8.0.9/com.springsource.org.hsqldb-1.8.0.9.jar" sourcepath="IVY_CACHE/org.hsqldb/com.springsource.org.hsqldb/1.8.0.9/com.springsource.org.hsqldb-sources-1.8.0.9.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.jboss.el/com.springsource.org.jboss.el/2.0.0.GA/com.springsource.org.jboss.el-2.0.0.GA.jar" sourcepath="IVY_CACHE/org.jboss.el/com.springsource.org.jboss.el/2.0.0.GA/com.springsource.org.jboss.el-sources-2.0.0.GA.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-3.8.2.jar" sourcepath="IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-sources-3.8.2.ja"/>
<classpathentry kind="var" path="IVY_CACHE/org.ognl/com.springsource.org.ognl/2.6.9/com.springsource.org.ognl-2.6.9.jar" sourcepath="IVY_CACHE/org.ognl/com.springsource.org.ognl/2.6.9/com.springsource.org.ognl-sources-2.6.9.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-3.8.2.jar" sourcepath="IVY_CACHE/org.junit/com.springsource.junit/3.8.2/com.springsource.junit-sources-3.8.2.ja"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.aop/3.0.2.RELEASE/org.springframework.aop-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.aop/3.0.2.RELEASE/org.springframework.aop-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.beans/3.0.2.RELEASE/org.springframework.beans-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.beans/3.0.2.RELEASE/org.springframework.beans-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.context/3.0.2.RELEASE/org.springframework.context-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.context/3.0.2.RELEASE/org.springframework.context-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.core/3.0.2.RELEASE/org.springframework.core-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.core/3.0.2.RELEASE/org.springframework.core-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.expression/3.0.2.RELEASE/org.springframework.expression-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.expression/3.0.2.RELEASE/org.springframework.expression-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.jdbc/3.0.2.RELEASE/org.springframework.jdbc-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.jdbc/3.0.2.RELEASE/org.springframework.jdbc-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.orm/3.0.2.RELEASE/org.springframework.orm-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.orm/3.0.2.RELEASE/org.springframework.orm-sources-3.0.2.RELEASE.jar"/>
<classpathentry kind="var" path="IVY_CACHE/org.springframework/org.springframework.test/3.0.2.RELEASE/org.springframework.test-3.0.2.RELEASE.jar" sourcepath="/IVY_CACHE/org.springframework/org.springframework.test/3.0.2.RELEASE/org.springframework.test-sources-3.0.2.RELEASE.jar"/>

View File

@@ -33,6 +33,7 @@
<dependency org="org.springframework" name="org.springframework.beans" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.context" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.core" rev="3.0.2.RELEASE" conf="compile->runtime"/>
<dependency org="org.springframework" name="org.springframework.expression" rev="3.0.2.RELEASE" conf="compile->runtime" />
<dependency org="org.springframework" name="org.springframework.orm" rev="3.0.2.RELEASE" conf="optional->runtime" />
<dependency org="org.springframework" name="org.springframework.transaction" rev="3.0.2.RELEASE" conf="optional->runtime" />
<dependency org="org.springframework" name="org.springframework.web" rev="3.0.2.RELEASE" conf="compile->runtime"/>

View File

@@ -27,6 +27,11 @@
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>

View File

@@ -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;
}
}

View File

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

View File

@@ -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.
* <p>
* This factory employs the following algorithm when the returned ExpressionParser instance is used for the first time:
* <ul>
* <li>If a Unified EL implementation is configured for the VM, make a {@link WebFlowELExpressionParser} the default.
* <li>If no Unified EL implementation is configured and OGNL is configured, make a {@link WebFlowOgnlExpressionParser}
* the default.
* <li>If neither Unified EL or OGNL are configured, throw an IllegalStateException with a nice error message.
* </ul>
*
* @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;
}
}
}
}

View File

@@ -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;
/**
* <p>
* Spring EL Property Accessor that allows invocation of methods against a resolved Web Flow action, typically a
* {@link MultiAction} in expressions.
* </p>
*
* @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.");
}
}

View File

@@ -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;
}
}

View File

@@ -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;
/**
* <p>
* Spring EL PropertyAccessor that enables use of the following reserved variables in expressions:
* </p>
*
* <pre>
* currentUser
* flowRequestContext
* resourceBundle
* </pre>
*
* <p>
* 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}.
* </p>
*
* @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();
}
}

View File

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

View File

@@ -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;
/**
* <p>
* 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:
* </p>
*
* <pre>
* resourceBundle.myErrorCode
* resourceBundle['myErrorCode']
* </pre>
*
* @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();
}
}

View File

@@ -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;
}
}

View File

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

View File

@@ -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;
}

View File

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

View File

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

View File

@@ -18,7 +18,11 @@
<webflow:flow-builder-services id="flowBuilderServicesConversionServiceCustom"
conversion-service="customConversionService" />
<bean id="customExpressionParser" class="org.springframework.webflow.expression.DefaultExpressionParserFactory" factory-method="getExpressionParser"/>
<bean id="customExpressionParser" class="org.springframework.webflow.expression.spel.WebFlowSpringELExpressionParser">
<constructor-arg>
<bean class="org.springframework.expression.spel.standard.SpelExpressionParser"/>
</constructor-arg>
</bean>
<bean id="customViewFactoryCreator" class="org.springframework.webflow.config.FlowBuilderServicesBeanDefinitionParserTests$TestViewFactoryCreator"/>

View File

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

View File

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

View File

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

View File

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

View File

@@ -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);
// }
}

View File

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

View File

@@ -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) {
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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