expression parser uses context's ConversionService by default
This commit is contained in:
parent
efaf76b46f
commit
7123e4f81e
|
|
@ -23,11 +23,14 @@ import org.springframework.beans.BeansException;
|
|||
import org.springframework.beans.factory.BeanExpressionException;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
|
@ -96,7 +99,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
|||
|
||||
/**
|
||||
* Specify the EL parser to use for expression parsing.
|
||||
* <p>Default is a {@link org.springframework.expression.spel.SpelExpressionParser},
|
||||
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
|
||||
* compatible with standard Unified EL style expression syntax.
|
||||
*/
|
||||
public void setExpressionParser(ExpressionParser expressionParser) {
|
||||
|
|
@ -119,6 +122,11 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
|||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
|
||||
if (conversionService != null) {
|
||||
sec.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
}
|
||||
customizeEvaluationContext(sec);
|
||||
this.evaluationCache.put(evalContext, sec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ import java.util.List;
|
|||
/**
|
||||
* Expressions are executed in an evaluation context. It is in this context that references
|
||||
* are resolved when encountered during expression evaluation.
|
||||
*
|
||||
* There is a default implementation of the EvaluationContext,
|
||||
*
|
||||
* <p>There is a default implementation of the EvaluationContext,
|
||||
* {@link org.springframework.expression.spel.support.StandardEvaluationContext}
|
||||
* that can be extended, rather than having to implement everything.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
|
|
@ -36,27 +36,6 @@ public interface EvaluationContext {
|
|||
* @return the root context object against which unqualified properties/methods/etc should be resolved
|
||||
*/
|
||||
TypedValue getRootObject();
|
||||
|
||||
|
||||
/**
|
||||
* @param rootObject the root object against which unqualified properties/methods/etc should be resolved
|
||||
*/
|
||||
void setRootObject(Object object);
|
||||
|
||||
|
||||
/**
|
||||
* Set a named variable within this execution context to a specified value.
|
||||
* @param name variable to set
|
||||
* @param value value to be placed in the variable
|
||||
*/
|
||||
void setVariable(String name, Object value);
|
||||
|
||||
/**
|
||||
* Look up a named variable within this execution context.
|
||||
* @param name variable to lookup
|
||||
* @return the value of the variable
|
||||
*/
|
||||
Object lookupVariable(String name);
|
||||
|
||||
/**
|
||||
* @return a list of resolvers that will be asked in turn to locate a constructor
|
||||
|
|
@ -78,20 +57,34 @@ public interface EvaluationContext {
|
|||
*/
|
||||
TypeLocator getTypeLocator();
|
||||
|
||||
/**
|
||||
* @return a type comparator for comparing pairs of objects for equality.
|
||||
*/
|
||||
TypeComparator getTypeComparator();
|
||||
|
||||
/**
|
||||
* @return a type converter that can convert (or coerce) a value from one type to another.
|
||||
*/
|
||||
TypeConverter getTypeConverter();
|
||||
|
||||
/**
|
||||
* @return a type comparator for comparing pairs of objects for equality.
|
||||
*/
|
||||
TypeComparator getTypeComparator();
|
||||
|
||||
/**
|
||||
* @return an operator overloader that may support mathematical operations between more than the standard set of
|
||||
* types
|
||||
*/
|
||||
OperatorOverloader getOperatorOverloader();
|
||||
|
||||
/**
|
||||
* Set a named variable within this evaluation context to a specified value.
|
||||
* @param name variable to set
|
||||
* @param value value to be placed in the variable
|
||||
*/
|
||||
void setVariable(String name, Object value);
|
||||
|
||||
/**
|
||||
* Look up a named variable within this evaluation context.
|
||||
* @param name variable to lookup
|
||||
* @return the value of the variable
|
||||
*/
|
||||
Object lookupVariable(String name);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -36,7 +37,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParserConfigur
|
|||
* communicate state. This is in contrast to the EvaluationContext, which is shared amongst expression evaluations, and
|
||||
* any changes to it will be seen by other expressions or any code that chooses to ask questions of the context.
|
||||
*
|
||||
* It also acts as a place for to define common utility routines that the various Ast nodes might need.
|
||||
* <p>It also acts as a place for to define common utility routines that the various Ast nodes might need.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
|
|
@ -75,7 +76,8 @@ public class ExpressionState {
|
|||
TypedValue rootObject = this.relatedContext.getRootObject();
|
||||
if (rootObject == null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return rootObject;
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +96,8 @@ public class ExpressionState {
|
|||
TypedValue root = this.relatedContext.getRootObject();
|
||||
if (root == null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
@ -105,10 +108,11 @@ public class ExpressionState {
|
|||
|
||||
public TypedValue lookupVariable(String name) {
|
||||
Object value = this.relatedContext.lookupVariable(name);
|
||||
if (value==null) {
|
||||
if (value == null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
return new TypedValue(value,TypeDescriptor.forObject(value));
|
||||
}
|
||||
else {
|
||||
return new TypedValue(value, TypeDescriptor.forObject(value));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,6 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
|
||||
private TypedValue rootObject;
|
||||
|
||||
private final Map<String, Object> variables = new HashMap<String, Object>();
|
||||
|
||||
private final List<ConstructorResolver> constructorResolvers = new ArrayList<ConstructorResolver>();
|
||||
|
||||
private final List<MethodResolver> methodResolvers = new ArrayList<MethodResolver>();
|
||||
|
|
@ -57,12 +55,15 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
|
||||
private TypeLocator typeLocator = new StandardTypeLocator();
|
||||
|
||||
private TypeComparator typeComparator = new StandardTypeComparator();
|
||||
|
||||
private TypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
private TypeComparator typeComparator = new StandardTypeComparator();
|
||||
|
||||
private OperatorOverloader operatorOverloader = new StandardOperatorOverloader();
|
||||
|
||||
private final Map<String, Object> variables = new HashMap<String, Object>();
|
||||
|
||||
|
||||
public StandardEvaluationContext() {
|
||||
this.methodResolvers.add(new ReflectiveMethodResolver());
|
||||
this.constructorResolvers.add(new ReflectiveConstructorResolver());
|
||||
|
|
@ -74,34 +75,19 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
setRootObject(rootObject);
|
||||
}
|
||||
|
||||
|
||||
public void setRootObject(Object rootObject) {
|
||||
this.rootObject = new TypedValue(rootObject,TypeDescriptor.forObject(rootObject));
|
||||
this.rootObject = new TypedValue(rootObject, TypeDescriptor.forObject(rootObject));
|
||||
}
|
||||
|
||||
public void setRootObject(Object rootObject, TypeDescriptor typeDescriptor) {
|
||||
this.rootObject = new TypedValue(rootObject,typeDescriptor);
|
||||
this.rootObject = new TypedValue(rootObject, typeDescriptor);
|
||||
}
|
||||
|
||||
public TypedValue getRootObject() {
|
||||
return this.rootObject;
|
||||
}
|
||||
|
||||
public void setVariable(String name, Object value) {
|
||||
this.variables.put(name, value);
|
||||
}
|
||||
|
||||
public void setVariables(Map<String,Object> variables) {
|
||||
this.variables.putAll(variables);
|
||||
}
|
||||
|
||||
public void registerFunction(String name, Method method) {
|
||||
this.variables.put(name, method);
|
||||
}
|
||||
|
||||
public Object lookupVariable(String name) {
|
||||
return this.variables.get(name);
|
||||
}
|
||||
|
||||
public void addConstructorResolver(ConstructorResolver resolver) {
|
||||
this.constructorResolvers.add(this.constructorResolvers.size() - 1, resolver);
|
||||
}
|
||||
|
|
@ -135,15 +121,6 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
return this.typeLocator;
|
||||
}
|
||||
|
||||
public void setTypeComparator(TypeComparator typeComparator) {
|
||||
Assert.notNull(typeComparator, "TypeComparator must not be null");
|
||||
this.typeComparator = typeComparator;
|
||||
}
|
||||
|
||||
public TypeComparator getTypeComparator() {
|
||||
return this.typeComparator;
|
||||
}
|
||||
|
||||
public void setTypeConverter(TypeConverter typeConverter) {
|
||||
Assert.notNull(typeConverter, "TypeConverter must not be null");
|
||||
this.typeConverter = typeConverter;
|
||||
|
|
@ -153,6 +130,15 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
return this.typeConverter;
|
||||
}
|
||||
|
||||
public void setTypeComparator(TypeComparator typeComparator) {
|
||||
Assert.notNull(typeComparator, "TypeComparator must not be null");
|
||||
this.typeComparator = typeComparator;
|
||||
}
|
||||
|
||||
public TypeComparator getTypeComparator() {
|
||||
return this.typeComparator;
|
||||
}
|
||||
|
||||
public void setOperatorOverloader(OperatorOverloader operatorOverloader) {
|
||||
Assert.notNull(operatorOverloader, "OperatorOverloader must not be null");
|
||||
this.operatorOverloader = operatorOverloader;
|
||||
|
|
@ -162,4 +148,20 @@ public class StandardEvaluationContext implements EvaluationContext {
|
|||
return this.operatorOverloader;
|
||||
}
|
||||
|
||||
public void setVariable(String name, Object value) {
|
||||
this.variables.put(name, value);
|
||||
}
|
||||
|
||||
public void setVariables(Map<String,Object> variables) {
|
||||
this.variables.putAll(variables);
|
||||
}
|
||||
|
||||
public void registerFunction(String name, Method method) {
|
||||
this.variables.put(name, method);
|
||||
}
|
||||
|
||||
public Object lookupVariable(String name) {
|
||||
return this.variables.get(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
@ -29,7 +30,6 @@ import org.springframework.expression.TypedValue;
|
|||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.testresources.Inventor;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the expression state object - some features are not yet exploited in the language (eg nested scopes)
|
||||
*
|
||||
|
|
@ -47,7 +47,6 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
|||
// Local variables are in variable scopes which come and go during evaluation. Normal variables are
|
||||
// accessible through the evaluation context
|
||||
|
||||
|
||||
@Test
|
||||
public void testLocalVariables() {
|
||||
ExpressionState state = getState();
|
||||
|
|
@ -62,7 +61,6 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
|||
state.setLocalVariable("foo",null);
|
||||
value = state.lookupLocalVariable("foo");
|
||||
Assert.assertEquals(null,value);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -119,8 +117,8 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
|||
ExpressionState state = getState();
|
||||
Assert.assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass());
|
||||
|
||||
state.getEvaluationContext().setRootObject(null);
|
||||
Assert.assertEquals(null,state.getRootContextObject().getValue());
|
||||
((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null);
|
||||
Assert.assertEquals(null, state.getRootContextObject().getValue());
|
||||
|
||||
state = new ExpressionState(new StandardEvaluationContext());
|
||||
Assert.assertEquals(TypedValue.NULL_TYPED_VALUE,state.getRootContextObject());
|
||||
|
|
@ -259,4 +257,5 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
|||
ExpressionState state = new ExpressionState(context);
|
||||
return state;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,8 +48,6 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
|||
|
||||
static Inventor tesla ;
|
||||
static Inventor pupin ;
|
||||
|
||||
|
||||
|
||||
static {
|
||||
GregorianCalendar c = new GregorianCalendar();
|
||||
|
|
@ -115,7 +113,7 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
|||
ExpressionParser parser = new SpelExpressionParser();
|
||||
Expression exp = parser.parseExpression("name");
|
||||
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setRootObject(tesla);
|
||||
|
||||
String name = (String) exp.getValue(context);
|
||||
|
|
@ -124,10 +122,9 @@ public class SpelDocumentationTests extends ExpressionTestCase {
|
|||
|
||||
@Test
|
||||
public void testEqualityCheck() throws Exception {
|
||||
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
context.setRootObject(tesla);
|
||||
|
||||
Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
|
||||
|
|
|
|||
Loading…
Reference in New Issue