diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpression.java b/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpression.java index cd59e347..a3cde964 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpression.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpression.java @@ -18,15 +18,19 @@ package org.springframework.binding.expression.spel; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; 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.core.convert.ConversionService; +import org.springframework.expression.PropertyAccessor; import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelMessage; import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.expression.spel.support.StandardTypeConverter; import org.springframework.util.Assert; /** @@ -42,12 +46,14 @@ public class SpringELExpression implements Expression { private org.springframework.expression.Expression expression; - private StandardEvaluationContext evaluationContext; - - private Class expectedType; + private Class expectedType; private Map expressionVariables; + private ConversionService conversionService; + + private List propertyAccessors; + /** * Constructor for SpringELExpression. * @@ -56,16 +62,17 @@ public class SpringELExpression implements Expression { * This parameter is optional (may be null). * @param expectedType the target type expected from the evaluation of the expression or null. This parameter is * optional (may be null). - * @param evaluationContext a Spring EL evaluation context. + * @param conversionService the Spring ConversionService instance to use for type conversion + * @param propertyAccessors propertyAccessors for Spring EL to use when evaluating expressions */ public SpringELExpression(org.springframework.expression.Expression expression, Map expressionVariables, - Class expectedType, StandardEvaluationContext evaluationContext) { + Class expectedType, ConversionService conversionService, List propertyAccessors) { Assert.notNull(expression, "The SpelExpression is required for evaluation"); - Assert.notNull(evaluationContext, "The StandardEvaluationContext is required for evaluation"); this.expression = expression; this.expressionVariables = expressionVariables; this.expectedType = expectedType; - this.evaluationContext = evaluationContext; + this.conversionService = conversionService; + this.propertyAccessors = propertyAccessors; } public String getExpressionString() { @@ -74,8 +81,7 @@ public class SpringELExpression implements Expression { public Object getValue(Object rootObject) throws EvaluationException { try { - updateEvaluationContext(rootObject); - return expression.getValue(evaluationContext, expectedType); + return expression.getValue(newEvaluationContext(rootObject), expectedType); } catch (SpelEvaluationException e) { if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE)) { throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e); @@ -91,8 +97,7 @@ public class SpringELExpression implements Expression { public Class getValueType(Object rootObject) throws EvaluationException { try { - evaluationContext.setRootObject(rootObject); - return expression.getValueType(evaluationContext); + return expression.getValueType(newEvaluationContext(rootObject)); } catch (SpelEvaluationException e) { if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE)) { throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e); @@ -105,8 +110,7 @@ public class SpringELExpression implements Expression { public void setValue(Object rootObject, Object value) throws EvaluationException { try { - updateEvaluationContext(rootObject); - expression.setValue(evaluationContext, value); + expression.setValue(newEvaluationContext(rootObject), value); } catch (SpelEvaluationException e) { if (e.getMessageCode().equals(SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE)) { throw new PropertyNotFoundException(rootObject.getClass(), getExpressionString(), e); @@ -124,10 +128,14 @@ public class SpringELExpression implements Expression { * Updates the Spring EL evaluation context to reflect the given rootObject. * * @param rootObject the object for the evaluation. + * @return */ - private void updateEvaluationContext(Object rootObject) { - evaluationContext.setRootObject(rootObject); - evaluationContext.setVariables(getVariableValues(rootObject)); + private StandardEvaluationContext newEvaluationContext(Object rootObject) { + StandardEvaluationContext context = new StandardEvaluationContext(rootObject); + context.setVariables(getVariableValues(rootObject)); + context.setTypeConverter(new StandardTypeConverter(conversionService)); + context.getPropertyAccessors().addAll(propertyAccessors); + return context; } /** @@ -137,14 +145,14 @@ public class SpringELExpression implements Expression { * @param rootObject the Object to evaluate variable expressions against. * @return a mapping between variables names and plain Object's. */ - private Map getVariableValues(Object rootObject) { + private Map getVariableValues(Object rootObject) { if (expressionVariables == null) { - return Collections.EMPTY_MAP; + return Collections.emptyMap(); } - Map variableValues = new HashMap(expressionVariables.size()); + Map variableValues = new HashMap(expressionVariables.size()); for (Iterator iterator = expressionVariables.entrySet().iterator(); iterator.hasNext();) { Map.Entry var = (Map.Entry) iterator.next(); - variableValues.put(var.getKey(), ((Expression) var.getValue()).getValue(rootObject)); + variableValues.put((String) var.getKey(), ((Expression) var.getValue()).getValue(rootObject)); } return variableValues; } diff --git a/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpressionParser.java b/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpressionParser.java index 34eb8663..97c37bab 100644 --- a/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpressionParser.java +++ b/spring-binding/src/main/java/org/springframework/binding/expression/spel/SpringELExpressionParser.java @@ -32,8 +32,6 @@ import org.springframework.context.expression.MapAccessor; import org.springframework.expression.EvaluationContext; import org.springframework.expression.PropertyAccessor; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.expression.spel.support.StandardTypeConverter; import org.springframework.util.Assert; /** @@ -50,7 +48,7 @@ public class SpringELExpressionParser implements ExpressionParser { private ConversionService conversionService; - private List propertyAccessors = new ArrayList(); + private List propertyAccessors = new ArrayList(); public SpringELExpressionParser(SpelExpressionParser expressionParser) { this(expressionParser, new DefaultConversionService()); @@ -73,12 +71,10 @@ public class SpringELExpressionParser implements ExpressionParser { public Expression parseExpression(String expressionString, ParserContext parserContext) throws ParserException { 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(new StandardTypeConverter(conversionService.getDelegateConversionService())); - evaluationContext.getPropertyAccessors().addAll(propertyAccessors); Map spelExpressionVariables = parseSpelExpressionVariables(parserContext.getExpressionVariables()); return new SpringELExpression(parseSpelExpression(expressionString, parserContext), spelExpressionVariables, - parserContext.getExpectedEvaluationResultType(), evaluationContext); + parserContext.getExpectedEvaluationResultType(), conversionService.getDelegateConversionService(), + propertyAccessors); } private org.springframework.expression.Expression parseSpelExpression(String expression, ParserContext parserContext) {