parent
6de67cc2df
commit
c5aa0d12b0
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,12 +19,12 @@ package org.springframework.expression;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expressions are executed in an evaluation context. It is in this context that references
|
* Expressions are executed in an evaluation context. It is in this context that
|
||||||
* are resolved when encountered during expression evaluation.
|
* references are resolved when encountered during expression evaluation.
|
||||||
*
|
*
|
||||||
* <p>There is a default implementation of the EvaluationContext,
|
* <p>There is a default implementation of the EvaluationContext,
|
||||||
* {@link org.springframework.expression.spel.support.StandardEvaluationContext}
|
* {@link org.springframework.expression.spel.support.StandardEvaluationContext} that can
|
||||||
* that can be extended, rather than having to implement everything.
|
* be extended, rather than having to implement everything.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -33,49 +33,51 @@ import java.util.List;
|
||||||
public interface EvaluationContext {
|
public interface EvaluationContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the default root context object against which unqualified properties/methods/etc
|
* Return the default root context object against which unqualified
|
||||||
* should be resolved. This can be overridden when evaluating an expression.
|
* properties/methods/etc should be resolved. This can be overridden
|
||||||
|
* when evaluating an expression.
|
||||||
*/
|
*/
|
||||||
TypedValue getRootObject();
|
TypedValue getRootObject();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a list of resolvers that will be asked in turn to locate a constructor
|
* Return a list of resolvers that will be asked in turn to locate a constructor.
|
||||||
*/
|
*/
|
||||||
List<ConstructorResolver> getConstructorResolvers();
|
List<ConstructorResolver> getConstructorResolvers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a list of resolvers that will be asked in turn to locate a method
|
* Return a list of resolvers that will be asked in turn to locate a method.
|
||||||
*/
|
*/
|
||||||
List<MethodResolver> getMethodResolvers();
|
List<MethodResolver> getMethodResolvers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a list of accessors that will be asked in turn to read/write a property
|
* Return a list of accessors that will be asked in turn to read/write a property.
|
||||||
*/
|
*/
|
||||||
List<PropertyAccessor> getPropertyAccessors();
|
List<PropertyAccessor> getPropertyAccessors();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a type locator that can be used to find types, either by short or fully qualified name.
|
* Return a type locator that can be used to find types, either by short or
|
||||||
|
* fully qualified name.
|
||||||
*/
|
*/
|
||||||
TypeLocator getTypeLocator();
|
TypeLocator getTypeLocator();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a type converter that can convert (or coerce) a value from one type to another.
|
* Return a type converter that can convert (or coerce) a value from one type to another.
|
||||||
*/
|
*/
|
||||||
TypeConverter getTypeConverter();
|
TypeConverter getTypeConverter();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a type comparator for comparing pairs of objects for equality.
|
* Return a type comparator for comparing pairs of objects for equality.
|
||||||
*/
|
*/
|
||||||
TypeComparator getTypeComparator();
|
TypeComparator getTypeComparator();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an operator overloader that may support mathematical operations
|
* Return an operator overloader that may support mathematical operations
|
||||||
* between more than the standard set of types
|
* between more than the standard set of types.
|
||||||
*/
|
*/
|
||||||
OperatorOverloader getOperatorOverloader();
|
OperatorOverloader getOperatorOverloader();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a bean resolver that can look up beans by name
|
* Return a bean resolver that can look up beans by name.
|
||||||
*/
|
*/
|
||||||
BeanResolver getBeanResolver();
|
BeanResolver getBeanResolver();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,13 +17,15 @@
|
||||||
package org.springframework.expression;
|
package org.springframework.expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MethodExecutors are built by the resolvers and can be cached by the infrastructure to repeat an operation quickly
|
* MethodExecutors are built by the resolvers and can be cached by the infrastructure to
|
||||||
* without going back to the resolvers. For example, the particular method to run on an object may be discovered by the
|
* repeat an operation quickly without going back to the resolvers. For example, the
|
||||||
* reflection method resolver - it will then build a MethodExecutor that executes that method and the MethodExecutor can
|
* particular method to run on an object may be discovered by the reflection method
|
||||||
* be reused without needing to go back to the resolver to discover the method again.
|
* resolver - it will then build a MethodExecutor that executes that method and the
|
||||||
|
* MethodExecutor can be reused without needing to go back to the resolver to discover
|
||||||
|
* the method again.
|
||||||
*
|
*
|
||||||
* <p>They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go
|
* <p>They can become stale, and in that case should throw an AccessException:
|
||||||
* back to the resolvers to ask for a new one.
|
* This will cause the infrastructure to go back to the resolvers to ask for a new one.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -34,10 +36,11 @@ public interface MethodExecutor {
|
||||||
* Execute a command using the specified arguments, and using the specified expression state.
|
* Execute a command using the specified arguments, and using the specified expression state.
|
||||||
* @param context the evaluation context in which the command is being executed
|
* @param context the evaluation context in which the command is being executed
|
||||||
* @param target the target object of the call - null for static methods
|
* @param target the target object of the call - null for static methods
|
||||||
* @param arguments the arguments to the executor, should match (in terms of number and type) whatever the
|
* @param arguments the arguments to the executor, should match (in terms of number
|
||||||
* command will need to run
|
* and type) whatever the command will need to run
|
||||||
* @return the value returned from execution
|
* @return the value returned from execution
|
||||||
* @throws AccessException if there is a problem executing the command or the MethodExecutor is no longer valid
|
* @throws AccessException if there is a problem executing the command or the
|
||||||
|
* MethodExecutor is no longer valid
|
||||||
*/
|
*/
|
||||||
TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException;
|
TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -21,8 +21,9 @@ import java.util.List;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A method resolver attempts locate a method and returns a command executor that can be used to invoke that method.
|
* A method resolver attempts locate a method and returns a command executor that can be
|
||||||
* The command executor will be cached but if it 'goes stale' the resolvers will be called again.
|
* used to invoke that method. The command executor will be cached but if it 'goes stale'
|
||||||
|
* the resolvers will be called again.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
@ -30,9 +31,9 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||||
public interface MethodResolver {
|
public interface MethodResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Within the supplied context determine a suitable method on the supplied object that can handle the
|
* Within the supplied context determine a suitable method on the supplied object that
|
||||||
* specified arguments. Return a MethodExecutor that can be used to invoke that method
|
* can handle the specified arguments. Return a {@link MethodExecutor} that can be used
|
||||||
* (or {@code null} if no method could be found).
|
* to invoke that method, or {@code null} if no method could be found.
|
||||||
* @param context the current evaluation context
|
* @param context the current evaluation context
|
||||||
* @param targetObject the object upon which the method is being called
|
* @param targetObject the object upon which the method is being called
|
||||||
* @param argumentTypes the arguments that the constructor must be able to handle
|
* @param argumentTypes the arguments that the constructor must be able to handle
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2013 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -103,15 +103,14 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
return this.constructorResolvers.remove(resolver);
|
return this.constructorResolvers.remove(resolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ConstructorResolver> getConstructorResolvers() {
|
|
||||||
ensureConstructorResolversInitialized();
|
|
||||||
return this.constructorResolvers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConstructorResolvers(List<ConstructorResolver> constructorResolvers) {
|
public void setConstructorResolvers(List<ConstructorResolver> constructorResolvers) {
|
||||||
this.constructorResolvers = constructorResolvers;
|
this.constructorResolvers = constructorResolvers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ConstructorResolver> getConstructorResolvers() {
|
||||||
|
ensureConstructorResolversInitialized();
|
||||||
|
return this.constructorResolvers;
|
||||||
|
}
|
||||||
|
|
||||||
public void addMethodResolver(MethodResolver resolver) {
|
public void addMethodResolver(MethodResolver resolver) {
|
||||||
ensureMethodResolversInitialized();
|
ensureMethodResolversInitialized();
|
||||||
|
@ -123,6 +122,10 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
return this.methodResolvers.remove(methodResolver);
|
return this.methodResolvers.remove(methodResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setMethodResolvers(List<MethodResolver> methodResolvers) {
|
||||||
|
this.methodResolvers = methodResolvers;
|
||||||
|
}
|
||||||
|
|
||||||
public List<MethodResolver> getMethodResolvers() {
|
public List<MethodResolver> getMethodResolvers() {
|
||||||
ensureMethodResolversInitialized();
|
ensureMethodResolversInitialized();
|
||||||
return this.methodResolvers;
|
return this.methodResolvers;
|
||||||
|
@ -136,11 +139,6 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
return this.beanResolver;
|
return this.beanResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMethodResolvers(List<MethodResolver> methodResolvers) {
|
|
||||||
this.methodResolvers = methodResolvers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addPropertyAccessor(PropertyAccessor accessor) {
|
public void addPropertyAccessor(PropertyAccessor accessor) {
|
||||||
ensurePropertyAccessorsInitialized();
|
ensurePropertyAccessorsInitialized();
|
||||||
this.propertyAccessors.add(this.propertyAccessors.size() - 1, accessor);
|
this.propertyAccessors.add(this.propertyAccessors.size() - 1, accessor);
|
||||||
|
@ -150,15 +148,14 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
return this.propertyAccessors.remove(accessor);
|
return this.propertyAccessors.remove(accessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PropertyAccessor> getPropertyAccessors() {
|
|
||||||
ensurePropertyAccessorsInitialized();
|
|
||||||
return this.propertyAccessors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
|
public void setPropertyAccessors(List<PropertyAccessor> propertyAccessors) {
|
||||||
this.propertyAccessors = propertyAccessors;
|
this.propertyAccessors = propertyAccessors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<PropertyAccessor> getPropertyAccessors() {
|
||||||
|
ensurePropertyAccessorsInitialized();
|
||||||
|
return this.propertyAccessors;
|
||||||
|
}
|
||||||
|
|
||||||
public void setTypeLocator(TypeLocator typeLocator) {
|
public void setTypeLocator(TypeLocator typeLocator) {
|
||||||
Assert.notNull(typeLocator, "TypeLocator must not be null");
|
Assert.notNull(typeLocator, "TypeLocator must not be null");
|
||||||
|
@ -221,19 +218,18 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
/**
|
/**
|
||||||
* Register a {@code MethodFilter} which will be called during method resolution
|
* Register a {@code MethodFilter} which will be called during method resolution
|
||||||
* for the specified type.
|
* for the specified type.
|
||||||
*
|
|
||||||
* <p>The {@code MethodFilter} may remove methods and/or sort the methods which
|
* <p>The {@code MethodFilter} may remove methods and/or sort the methods which
|
||||||
* will then be used by SpEL as the candidates to look through for a match.
|
* will then be used by SpEL as the candidates to look through for a match.
|
||||||
*
|
|
||||||
* @param type the type for which the filter should be called
|
* @param type the type for which the filter should be called
|
||||||
* @param filter a {@code MethodFilter}, or {@code null} to unregister a filter for the type
|
* @param filter a {@code MethodFilter}, or {@code null} to unregister a filter for the type
|
||||||
* @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use
|
* @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use
|
||||||
*/
|
*/
|
||||||
public void registerMethodFilter(Class<?> type, MethodFilter filter) throws IllegalStateException {
|
public void registerMethodFilter(Class<?> type, MethodFilter filter) throws IllegalStateException {
|
||||||
ensureMethodResolversInitialized();
|
ensureMethodResolversInitialized();
|
||||||
if (reflectiveMethodResolver != null) {
|
if (this.reflectiveMethodResolver != null) {
|
||||||
reflectiveMethodResolver.registerMethodFilter(type, filter);
|
this.reflectiveMethodResolver.registerMethodFilter(type, filter);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
throw new IllegalStateException("Method filter cannot be set as the reflective method resolver is not in use");
|
throw new IllegalStateException("Method filter cannot be set as the reflective method resolver is not in use");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +257,8 @@ public class StandardEvaluationContext implements EvaluationContext {
|
||||||
private synchronized void initializeMethodResolvers() {
|
private synchronized void initializeMethodResolvers() {
|
||||||
if (this.methodResolvers == null) {
|
if (this.methodResolvers == null) {
|
||||||
List<MethodResolver> defaultResolvers = new ArrayList<MethodResolver>();
|
List<MethodResolver> defaultResolvers = new ArrayList<MethodResolver>();
|
||||||
defaultResolvers.add(reflectiveMethodResolver = new ReflectiveMethodResolver());
|
this.reflectiveMethodResolver = new ReflectiveMethodResolver();
|
||||||
|
defaultResolvers.add(this.reflectiveMethodResolver);
|
||||||
this.methodResolvers = defaultResolvers;
|
this.methodResolvers = defaultResolvers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue