changed tabs to spaces
parent
5ce9a8a5d4
commit
bf09c40c7f
|
@ -24,7 +24,7 @@ final class ExtensionFunctions {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <K,V> Map<K,V> map(final List<? extends K> keys,
|
public static <K,V> Map<K,V> map(final List<? extends K> keys,
|
||||||
final List<? extends V> values) {
|
final List<? extends V> values) {
|
||||||
Assert.isTrue(keys.size() == values.size(),
|
Assert.isTrue(keys.size() == values.size(),
|
||||||
"There should equal number of keys and values");
|
"There should equal number of keys and values");
|
||||||
Map<K,V> map = new HashMap<K,V>();
|
Map<K,V> map = new HashMap<K,V>();
|
||||||
|
|
|
@ -17,18 +17,18 @@ final class ImplicitConstructorResolver implements
|
||||||
|
|
||||||
private final ReflectiveConstructorResolver delegate = new ReflectiveConstructorResolver();
|
private final ReflectiveConstructorResolver delegate = new ReflectiveConstructorResolver();
|
||||||
|
|
||||||
public ConstructorExecutor resolve(final EvaluationContext context,
|
public ConstructorExecutor resolve(final EvaluationContext context,
|
||||||
final String typeName, final Class<?>[] argumentTypes) throws AccessException {
|
final String typeName, final Class<?>[] argumentTypes) throws AccessException {
|
||||||
try {
|
try {
|
||||||
return delegate.resolve(context, typeName, argumentTypes);
|
return delegate.resolve(context, typeName, argumentTypes);
|
||||||
} catch (AccessException ex) {
|
} catch (AccessException ex) {
|
||||||
Object variable = ((SpelHelper) context.lookupVariable(SpelHelper.CONTEXT_LOOKUP_KEY))
|
Object variable = ((SpelHelper) context.lookupVariable(SpelHelper.CONTEXT_LOOKUP_KEY))
|
||||||
.lookupImplicitConstructor(typeName + Arrays.toString(argumentTypes));
|
.lookupImplicitConstructor(typeName + Arrays.toString(argumentTypes));
|
||||||
if (variable instanceof Constructor<?>) {
|
if (variable instanceof Constructor<?>) {
|
||||||
Constructor<?> constructor = (Constructor<?>) variable;
|
Constructor<?> constructor = (Constructor<?>) variable;
|
||||||
return delegate.resolve(context, constructor.getDeclaringClass().getName(), argumentTypes);
|
return delegate.resolve(context, constructor.getDeclaringClass().getName(), argumentTypes);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,83 +16,83 @@ import org.springframework.expression.spel.support.ReflectiveMethodResolver;
|
||||||
|
|
||||||
public final class ImplicitMethodResolver implements MethodResolver {
|
public final class ImplicitMethodResolver implements MethodResolver {
|
||||||
|
|
||||||
private static final ConcurrentHashMap<String, MethodExecutor> cache =
|
private static final ConcurrentHashMap<String, MethodExecutor> cache =
|
||||||
new ConcurrentHashMap<String, MethodExecutor>();
|
new ConcurrentHashMap<String, MethodExecutor>();
|
||||||
|
|
||||||
private static final MethodExecutor NULL_ME = new MethodExecutor() {
|
private static final MethodExecutor NULL_ME = new MethodExecutor() {
|
||||||
public TypedValue execute(final EvaluationContext context, final Object target,
|
public TypedValue execute(final EvaluationContext context, final Object target,
|
||||||
final Object... arguments) throws AccessException {
|
final Object... arguments) throws AccessException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final class ImplicitMethodExecutor implements
|
private static final class ImplicitMethodExecutor implements
|
||||||
MethodExecutor {
|
MethodExecutor {
|
||||||
private final MethodExecutor executor;
|
private final MethodExecutor executor;
|
||||||
|
|
||||||
private ImplicitMethodExecutor(final MethodExecutor executor) {
|
private ImplicitMethodExecutor(final MethodExecutor executor) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedValue execute(final EvaluationContext context, final Object target,
|
public TypedValue execute(final EvaluationContext context, final Object target,
|
||||||
final Object... arguments) throws AccessException {
|
final Object... arguments) throws AccessException {
|
||||||
Object[] modifiedArguments = new Object[arguments.length + 1];
|
Object[] modifiedArguments = new Object[arguments.length + 1];
|
||||||
modifiedArguments[0] = target;
|
modifiedArguments[0] = target;
|
||||||
System.arraycopy(arguments, 0, modifiedArguments, 1, arguments.length);
|
System.arraycopy(arguments, 0, modifiedArguments, 1, arguments.length);
|
||||||
return executor.execute(context, null, modifiedArguments);
|
return executor.execute(context, null, modifiedArguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodExecutor resolve(final EvaluationContext context,
|
public MethodExecutor resolve(final EvaluationContext context,
|
||||||
final Object targetObject, final String name, final Class<?>[] argumentTypes)
|
final Object targetObject, final String name, final Class<?>[] argumentTypes)
|
||||||
throws AccessException {
|
throws AccessException {
|
||||||
if (targetObject == null) {
|
if (targetObject == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Class<?> type = targetObject.getClass();
|
Class<?> type = targetObject.getClass();
|
||||||
String cacheKey = type.getName() + "." + name;
|
String cacheKey = type.getName() + "." + name;
|
||||||
if (cache.containsKey(cacheKey)) {
|
if (cache.containsKey(cacheKey)) {
|
||||||
MethodExecutor executor = cache.get(cacheKey);
|
MethodExecutor executor = cache.get(cacheKey);
|
||||||
return executor == NULL_ME ? null : executor;
|
return executor == NULL_ME ? null : executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
Method method = lookupMethod(context, type, name);
|
Method method = lookupMethod(context, type, name);
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
int modifiers = method.getModifiers();
|
int modifiers = method.getModifiers();
|
||||||
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)) {
|
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)) {
|
||||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||||
Class<?> firstParameterType = parameterTypes[0];
|
Class<?> firstParameterType = parameterTypes[0];
|
||||||
if (parameterTypes.length > 0
|
if (parameterTypes.length > 0
|
||||||
&& firstParameterType.isAssignableFrom(type)) {
|
&& firstParameterType.isAssignableFrom(type)) {
|
||||||
|
|
||||||
Class<?>[] modifiedArgumentTypes = new Class[argumentTypes.length + 1];
|
Class<?>[] modifiedArgumentTypes = new Class[argumentTypes.length + 1];
|
||||||
modifiedArgumentTypes[0] = firstParameterType;
|
modifiedArgumentTypes[0] = firstParameterType;
|
||||||
System.arraycopy(argumentTypes, 0, modifiedArgumentTypes,
|
System.arraycopy(argumentTypes, 0, modifiedArgumentTypes,
|
||||||
1, argumentTypes.length);
|
1, argumentTypes.length);
|
||||||
MethodExecutor executor = new ReflectiveMethodResolver()
|
MethodExecutor executor = new ReflectiveMethodResolver()
|
||||||
.resolve(context, method.getDeclaringClass(), name,
|
.resolve(context, method.getDeclaringClass(), name,
|
||||||
modifiedArgumentTypes);
|
modifiedArgumentTypes);
|
||||||
MethodExecutor wrappedExecutor = executor == null ? null
|
MethodExecutor wrappedExecutor = executor == null ? null
|
||||||
: new ImplicitMethodExecutor(executor);
|
: new ImplicitMethodExecutor(executor);
|
||||||
cache.putIfAbsent(cacheKey, wrappedExecutor);
|
cache.putIfAbsent(cacheKey, wrappedExecutor);
|
||||||
return wrappedExecutor;
|
return wrappedExecutor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cache.putIfAbsent(cacheKey, NULL_ME);
|
cache.putIfAbsent(cacheKey, NULL_ME);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method lookupMethod(final EvaluationContext context,
|
private static Method lookupMethod(final EvaluationContext context,
|
||||||
final Class<?> type, final String name) {
|
final Class<?> type, final String name) {
|
||||||
for (Class<?> clazz : InheritenceUtil.getInheritance(type)) {
|
for (Class<?> clazz : InheritenceUtil.getInheritance(type)) {
|
||||||
Object variable = ((SpelHelper) context.lookupVariable(SpelHelper.CONTEXT_LOOKUP_KEY))
|
Object variable = ((SpelHelper) context.lookupVariable(SpelHelper.CONTEXT_LOOKUP_KEY))
|
||||||
.lookupImplicitMethod(clazz.getName() + "." + name);
|
.lookupImplicitMethod(clazz.getName() + "." + name);
|
||||||
if (variable instanceof Method) {
|
if (variable instanceof Method) {
|
||||||
return (Method) variable;
|
return (Method) variable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -12,28 +12,28 @@ import java.util.Set;
|
||||||
final class ImplicitMethods {
|
final class ImplicitMethods {
|
||||||
|
|
||||||
public static <T> Set<T> distinct(final List<? extends T> list) {
|
public static <T> Set<T> distinct(final List<? extends T> list) {
|
||||||
return unmodifiableSet(new HashSet<T>(list));
|
return unmodifiableSet(new HashSet<T>(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Comparable<? super T>> List<T> sorted(
|
public static <T extends Comparable<? super T>> List<T> sorted(
|
||||||
final List<? extends T> list) {
|
final List<? extends T> list) {
|
||||||
List<T> temp = new ArrayList<T>(list);
|
List<T> temp = new ArrayList<T>(list);
|
||||||
Collections.sort(temp);
|
Collections.sort(temp);
|
||||||
return unmodifiableList(temp);
|
return unmodifiableList(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> reversed(final List<? extends T> list) {
|
public static <T> List<T> reversed(final List<? extends T> list) {
|
||||||
List<T> temp = new ArrayList<T>(list);
|
List<T> temp = new ArrayList<T>(list);
|
||||||
Collections.reverse(temp);
|
Collections.reverse(temp);
|
||||||
return unmodifiableList(temp);
|
return unmodifiableList(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> take(final List<T> list, final int n) {
|
public static <T> List<T> take(final List<T> list, final int n) {
|
||||||
return unmodifiableList(list.subList(0, n));
|
return unmodifiableList(list.subList(0, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> drop(final List<T> list, final int n) {
|
public static <T> List<T> drop(final List<T> list, final int n) {
|
||||||
return unmodifiableList(list.subList(n, list.size()));
|
return unmodifiableList(list.subList(n, list.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,39 +15,39 @@ import org.springframework.util.Assert;
|
||||||
|
|
||||||
public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAccessor {
|
public final class ImplicitPropertyAccessor extends ReadOnlyGenericPropertyAccessor {
|
||||||
|
|
||||||
private static final ConcurrentHashMap<String, MethodExecutor> cache =
|
private static final ConcurrentHashMap<String, MethodExecutor> cache =
|
||||||
new ConcurrentHashMap<String, MethodExecutor>();
|
new ConcurrentHashMap<String, MethodExecutor>();
|
||||||
|
|
||||||
public boolean canRead(final EvaluationContext context,
|
public boolean canRead(final EvaluationContext context,
|
||||||
final Object target, final String name)
|
final Object target, final String name)
|
||||||
throws AccessException {
|
throws AccessException {
|
||||||
Assert.notNull(target, "target is null");
|
Assert.notNull(target, "target is null");
|
||||||
String cacheKey = target.getClass().getName() + "." + name;
|
String cacheKey = target.getClass().getName() + "." + name;
|
||||||
if (cache.containsKey(cacheKey)) {
|
if (cache.containsKey(cacheKey)) {
|
||||||
return cache.get(cacheKey) != null;
|
return cache.get(cacheKey) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MethodResolver mr : context.getMethodResolvers()) {
|
for (MethodResolver mr : context.getMethodResolvers()) {
|
||||||
MethodExecutor me = mr.resolve(context, target, name, new Class[0]);
|
MethodExecutor me = mr.resolve(context, target, name, new Class[0]);
|
||||||
if (me != null) {
|
if (me != null) {
|
||||||
cache.putIfAbsent(cacheKey, me);
|
cache.putIfAbsent(cacheKey, me);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.putIfAbsent(cacheKey, null);
|
cache.putIfAbsent(cacheKey, null);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedValue read(final EvaluationContext context,
|
public TypedValue read(final EvaluationContext context,
|
||||||
final Object target, final String name)
|
final Object target, final String name)
|
||||||
throws AccessException {
|
throws AccessException {
|
||||||
if (canRead(context, target, name)) {
|
if (canRead(context, target, name)) {
|
||||||
String cacheKey = target.getClass().getName() + "." + name;
|
String cacheKey = target.getClass().getName() + "." + name;
|
||||||
return cache.get(cacheKey).execute(context, target, new Object[0]);
|
return cache.get(cacheKey).execute(context, target, new Object[0]);
|
||||||
}
|
}
|
||||||
throw new AccessException(MessageFormat.format(
|
throw new AccessException(MessageFormat.format(
|
||||||
"Cannot read property: {0} of target: {1}", name, target));
|
"Cannot read property: {0} of target: {1}", name, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,62 +5,62 @@ import java.util.Set;
|
||||||
|
|
||||||
final class InheritenceUtil {
|
final class InheritenceUtil {
|
||||||
|
|
||||||
public static Set<Class<?>> getInheritance(final Class<?> in) {
|
public static Set<Class<?>> getInheritance(final Class<?> in) {
|
||||||
LinkedHashSet<Class<?>> result = new LinkedHashSet<Class<?>>();
|
LinkedHashSet<Class<?>> result = new LinkedHashSet<Class<?>>();
|
||||||
result.add(in);
|
result.add(in);
|
||||||
getInheritance(in, result);
|
getInheritance(in, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get inheritance of type.
|
* Get inheritance of type.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
private static void getInheritance(final Class<?> in, final Set<Class<?>> result) {
|
private static void getInheritance(final Class<?> in, final Set<Class<?>> result) {
|
||||||
Class<?> superclass = getSuperclass(in);
|
Class<?> superclass = getSuperclass(in);
|
||||||
|
|
||||||
if (superclass != null) {
|
if (superclass != null) {
|
||||||
result.add(superclass);
|
result.add(superclass);
|
||||||
getInheritance(superclass, result);
|
getInheritance(superclass, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
getInterfaceInheritance(in, result);
|
getInterfaceInheritance(in, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get interfaces that the type inherits from.
|
* Get interfaces that the type inherits from.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
private static void getInterfaceInheritance(final Class<?> in,
|
private static void getInterfaceInheritance(final Class<?> in,
|
||||||
final Set<Class<?>> result) {
|
final Set<Class<?>> result) {
|
||||||
for (Class<?> c : in.getInterfaces()) {
|
for (Class<?> c : in.getInterfaces()) {
|
||||||
result.add(c);
|
result.add(c);
|
||||||
getInterfaceInheritance(c, result);
|
getInterfaceInheritance(c, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get superclass of class.
|
* Get superclass of class.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static Class<?> getSuperclass(final Class<?> in) {
|
private static Class<?> getSuperclass(final Class<?> in) {
|
||||||
if (in == null) {
|
if (in == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (in.isArray() && in != Object[].class) {
|
if (in.isArray() && in != Object[].class) {
|
||||||
Class<?> type = in.getComponentType();
|
Class<?> type = in.getComponentType();
|
||||||
while (type.isArray()) {
|
while (type.isArray()) {
|
||||||
type = type.getComponentType();
|
type = type.getComponentType();
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
return in.getSuperclass();
|
return in.getSuperclass();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,22 +7,22 @@ import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.PropertyAccessor;
|
import org.springframework.expression.PropertyAccessor;
|
||||||
|
|
||||||
public abstract class ReadOnlyGenericPropertyAccessor implements
|
public abstract class ReadOnlyGenericPropertyAccessor implements
|
||||||
PropertyAccessor {
|
PropertyAccessor {
|
||||||
|
|
||||||
public final boolean canWrite(final EvaluationContext context,
|
public final boolean canWrite(final EvaluationContext context,
|
||||||
final Object target, final String name) throws AccessException {
|
final Object target, final String name) throws AccessException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final Class[] getSpecificTargetClasses() {
|
public final Class[] getSpecificTargetClasses() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void write(final EvaluationContext context, final Object target,
|
public final void write(final EvaluationContext context, final Object target,
|
||||||
final String name, final Object newValue) throws AccessException {
|
final String name, final Object newValue) throws AccessException {
|
||||||
throw new AccessException(MessageFormat.format(
|
throw new AccessException(MessageFormat.format(
|
||||||
"Cannot write property: {0} of target: {1}", name, target));
|
"Cannot write property: {0} of target: {1}", name, target));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,110 +22,110 @@ import org.springframework.util.Assert;
|
||||||
|
|
||||||
public final class SpelHelper {
|
public final class SpelHelper {
|
||||||
|
|
||||||
public static final String CONTEXT_LOOKUP_KEY = SpelHelper.class.getName();
|
public static final String CONTEXT_LOOKUP_KEY = SpelHelper.class.getName();
|
||||||
|
|
||||||
private static final ExpressionParser PARSER = new SpelExpressionParser();
|
private static final ExpressionParser PARSER = new SpelExpressionParser();
|
||||||
private static final ThreadLocal<EvaluationContext> currentContext =
|
private static final ThreadLocal<EvaluationContext> currentContext =
|
||||||
new ThreadLocal<EvaluationContext>();
|
new ThreadLocal<EvaluationContext>();
|
||||||
|
|
||||||
private volatile EvaluationContext context;
|
private volatile EvaluationContext context;
|
||||||
private final Set<Method> registeredFunctions = new HashSet<Method>();
|
private final Set<Method> registeredFunctions = new HashSet<Method>();
|
||||||
private final Map<String,Method> registeredMethods =
|
private final Map<String,Method> registeredMethods =
|
||||||
new ConcurrentHashMap<String, Method>();
|
new ConcurrentHashMap<String, Method>();
|
||||||
private final Map<String,Constructor<?>> registeredConstructors =
|
private final Map<String,Constructor<?>> registeredConstructors =
|
||||||
new ConcurrentHashMap<String, Constructor<?>>();
|
new ConcurrentHashMap<String, Constructor<?>>();
|
||||||
|
|
||||||
{
|
{
|
||||||
registerFunctionsFromClass(ExtensionFunctions.class);
|
registerFunctionsFromClass(ExtensionFunctions.class);
|
||||||
registerImplicitMethodsFromClass(ImplicitMethods.class);
|
registerImplicitMethodsFromClass(ImplicitMethods.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpelHelper registerImplicitMethodsFromClass(final Class<?> clazz) {
|
public SpelHelper registerImplicitMethodsFromClass(final Class<?> clazz) {
|
||||||
for (Method method : filterMethods(clazz)) {
|
for (Method method : filterMethods(clazz)) {
|
||||||
registeredMethods.put(String.format(
|
registeredMethods.put(String.format(
|
||||||
"%s.%s", method.getParameterTypes()[0].getName(), method.getName()),
|
"%s.%s", method.getParameterTypes()[0].getName(), method.getName()),
|
||||||
method);
|
method);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpelHelper registerFunctionsFromClass(final Class<?> clazz) {
|
public SpelHelper registerFunctionsFromClass(final Class<?> clazz) {
|
||||||
registeredFunctions.addAll(filterMethods(clazz));
|
registeredFunctions.addAll(filterMethods(clazz));
|
||||||
context = null;
|
context = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpelHelper registerImplicitConstructorsFromClass(final Class<?> clazz) {
|
public SpelHelper registerImplicitConstructorsFromClass(final Class<?> clazz) {
|
||||||
for (Constructor<?> constructor : asList(clazz.getConstructors())) {
|
for (Constructor<?> constructor : asList(clazz.getConstructors())) {
|
||||||
registeredConstructors.put(
|
registeredConstructors.put(
|
||||||
constructor.getDeclaringClass().getSimpleName()
|
constructor.getDeclaringClass().getSimpleName()
|
||||||
+ Arrays.toString(constructor.getParameterTypes()),
|
+ Arrays.toString(constructor.getParameterTypes()),
|
||||||
constructor);
|
constructor);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T evalExpression(final String expressionString,
|
public <T> T evalExpression(final String expressionString,
|
||||||
final Object rootElement, final Class<T> desiredType) {
|
final Object rootElement, final Class<T> desiredType) {
|
||||||
EvaluationContext evaluationContext = getEvaluationContext(rootElement);
|
EvaluationContext evaluationContext = getEvaluationContext(rootElement);
|
||||||
currentContext.set(evaluationContext);
|
currentContext.set(evaluationContext);
|
||||||
T value = evalExpression(expressionString, evaluationContext, desiredType);
|
T value = evalExpression(expressionString, evaluationContext, desiredType);
|
||||||
currentContext.set(null);
|
currentContext.set(null);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T evalExpression(final String expressionString,
|
public <T> T evalExpression(final String expressionString,
|
||||||
final EvaluationContext evaluationContext, final Class<T> desiredType) {
|
final EvaluationContext evaluationContext, final Class<T> desiredType) {
|
||||||
return PARSER.parseExpression(expressionString)
|
return PARSER.parseExpression(expressionString)
|
||||||
.getValue(evaluationContext, desiredType);
|
.getValue(evaluationContext, desiredType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T evalExpressions(final String[] expressionStrings,
|
public <T> T evalExpressions(final String[] expressionStrings,
|
||||||
final Object rootElement, final Class<T> desiredType) {
|
final Object rootElement, final Class<T> desiredType) {
|
||||||
int length = expressionStrings.length;
|
int length = expressionStrings.length;
|
||||||
Assert.isTrue(length > 0,
|
Assert.isTrue(length > 0,
|
||||||
"expressionStrings should have length more than 0");
|
"expressionStrings should have length more than 0");
|
||||||
for (int i = 0; i < length - 1; i++) {
|
for (int i = 0; i < length - 1; i++) {
|
||||||
evalExpression(expressionStrings[i], rootElement, Object.class);
|
evalExpression(expressionStrings[i], rootElement, Object.class);
|
||||||
}
|
}
|
||||||
return evalExpression(expressionStrings[length - 1],
|
return evalExpression(expressionStrings[length - 1],
|
||||||
rootElement, desiredType);
|
rootElement, desiredType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EvaluationContext getEvaluationContext(final Object rootObject) {
|
private EvaluationContext getEvaluationContext(final Object rootObject) {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
synchronized (PARSER) {
|
synchronized (PARSER) {
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
StandardEvaluationContext newContext = new StandardEvaluationContext(rootObject);
|
StandardEvaluationContext newContext = new StandardEvaluationContext(rootObject);
|
||||||
newContext.getMethodResolvers().add(new ImplicitMethodResolver());
|
newContext.getMethodResolvers().add(new ImplicitMethodResolver());
|
||||||
newContext.getPropertyAccessors().add(new ImplicitPropertyAccessor());
|
newContext.getPropertyAccessors().add(new ImplicitPropertyAccessor());
|
||||||
newContext.setConstructorResolvers(
|
newContext.setConstructorResolvers(
|
||||||
asList((ConstructorResolver) new ImplicitConstructorResolver()));
|
asList((ConstructorResolver) new ImplicitConstructorResolver()));
|
||||||
for (Method method : registeredFunctions) {
|
for (Method method : registeredFunctions) {
|
||||||
newContext.setVariable(method.getName(), method);
|
newContext.setVariable(method.getName(), method);
|
||||||
}
|
}
|
||||||
newContext.setVariable(CONTEXT_LOOKUP_KEY, this);
|
newContext.setVariable(CONTEXT_LOOKUP_KEY, this);
|
||||||
context = newContext;
|
context = newContext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
|
||||||
|
|
||||||
public Method lookupImplicitMethod(final String lookup) {
|
|
||||||
Assert.notNull(lookup);
|
|
||||||
return registeredMethods.get(lookup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Constructor<?> lookupImplicitConstructor(final String lookup) {
|
public Method lookupImplicitMethod(final String lookup) {
|
||||||
Assert.notNull(lookup);
|
Assert.notNull(lookup);
|
||||||
return registeredConstructors.get(lookup);
|
return registeredMethods.get(lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EvaluationContext getCurrentContext() {
|
public Constructor<?> lookupImplicitConstructor(final String lookup) {
|
||||||
return currentContext.get();
|
Assert.notNull(lookup);
|
||||||
}
|
return registeredConstructors.get(lookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EvaluationContext getCurrentContext() {
|
||||||
|
return currentContext.get();
|
||||||
|
}
|
||||||
|
|
||||||
private static List<Method> filterMethods(final Class<?> clazz) {
|
private static List<Method> filterMethods(final Class<?> clazz) {
|
||||||
List<Method> allowedMethods = new ArrayList<Method>();
|
List<Method> allowedMethods = new ArrayList<Method>();
|
||||||
|
|
|
@ -8,36 +8,36 @@ import org.junit.Test;
|
||||||
|
|
||||||
public class SpelHelperTest {
|
public class SpelHelperTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRegisteredFunction() {
|
public void testRegisteredFunction() {
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
Arrays.asList("abhinav", "mini", "dan"),
|
Arrays.asList("abhinav", "mini", "dan"),
|
||||||
new SpelHelper().evalExpression(
|
new SpelHelper().evalExpression(
|
||||||
"#list('abhinav','mini','dan')", new Object(), List.class));
|
"#list('abhinav','mini','dan')", new Object(), List.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImplicitMethod() {
|
public void testImplicitMethod() {
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
Arrays.asList("abhinav", "dan", "mini"),
|
Arrays.asList("abhinav", "dan", "mini"),
|
||||||
new SpelHelper().evalExpression(
|
new SpelHelper().evalExpression(
|
||||||
"#list('abhinav','mini','dan').sorted", new Object(), List.class));
|
"#list('abhinav','mini','dan').sorted", new Object(), List.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ConstructorTest {
|
public static final class ConstructorTest {
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object o) {
|
public boolean equals(final Object o) {
|
||||||
return o instanceof ConstructorTest;
|
return o instanceof ConstructorTest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testImplicitConstructor() {
|
public void testImplicitConstructor() {
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
new ConstructorTest(),
|
new ConstructorTest(),
|
||||||
new SpelHelper()
|
new SpelHelper()
|
||||||
.registerImplicitConstructorsFromClass(ConstructorTest.class)
|
.registerImplicitConstructorsFromClass(ConstructorTest.class)
|
||||||
.evalExpression("new ConstructorTest()", new Object(), ConstructorTest.class));
|
.evalExpression("new ConstructorTest()", new Object(), ConstructorTest.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue