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