From c5aa0d12b04f92feeebafa111d3ac98797d26fb0 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 4 Sep 2013 16:44:07 +0200 Subject: [PATCH] Polishing Issue: SPR-9495 (cherry picked from commit baa698e) --- .../expression/EvaluationContext.java | 34 +++++++-------- .../expression/MethodExecutor.java | 23 ++++++----- .../expression/MethodResolver.java | 13 +++--- .../support/StandardEvaluationContext.java | 41 +++++++++---------- 4 files changed, 57 insertions(+), 54 deletions(-) diff --git a/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java index 27a83cab37..9d509c6121 100644 --- a/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/EvaluationContext.java @@ -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"); * you may not use this file except in compliance with the License. @@ -19,12 +19,12 @@ package org.springframework.expression; 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. + * 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, - * {@link org.springframework.expression.spel.support.StandardEvaluationContext} - * that can be extended, rather than having to implement everything. + * {@link org.springframework.expression.spel.support.StandardEvaluationContext} that can + * be extended, rather than having to implement everything. * * @author Andy Clement * @author Juergen Hoeller @@ -33,49 +33,51 @@ import java.util.List; public interface EvaluationContext { /** - * @return the default root context object against which unqualified properties/methods/etc - * should be resolved. This can be overridden when evaluating an expression. + * Return the default root context object against which unqualified + * properties/methods/etc should be resolved. This can be overridden + * when evaluating an expression. */ 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 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 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 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(); /** - * @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(); /** - * @return a type comparator for comparing pairs of objects for equality. + * 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 + * Return an operator overloader that may support mathematical operations + * between more than the standard set of types. */ 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(); diff --git a/spring-expression/src/main/java/org/springframework/expression/MethodExecutor.java b/spring-expression/src/main/java/org/springframework/expression/MethodExecutor.java index bd4dd74516..6b94e4fbac 100644 --- a/spring-expression/src/main/java/org/springframework/expression/MethodExecutor.java +++ b/spring-expression/src/main/java/org/springframework/expression/MethodExecutor.java @@ -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"); * you may not use this file except in compliance with the License. @@ -17,13 +17,15 @@ package org.springframework.expression; /** - * MethodExecutors are built by the resolvers and can be cached by the infrastructure to repeat an operation quickly - * without going back to the resolvers. For example, the particular method to run on an object may be discovered by the - * reflection method 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. + * MethodExecutors are built by the resolvers and can be cached by the infrastructure to + * repeat an operation quickly without going back to the resolvers. For example, the + * particular method to run on an object may be discovered by the reflection method + * 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. * - *

They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go - * back to the resolvers to ask for a new one. + *

They can become stale, and in that case should throw an AccessException: + * This will cause the infrastructure to go back to the resolvers to ask for a new one. * * @author Andy Clement * @since 3.0 @@ -34,10 +36,11 @@ public interface MethodExecutor { * 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 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 - * command will need to run + * @param arguments the arguments to the executor, should match (in terms of number + * and type) whatever the command will need to run * @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; diff --git a/spring-expression/src/main/java/org/springframework/expression/MethodResolver.java b/spring-expression/src/main/java/org/springframework/expression/MethodResolver.java index 75cdc5eab8..e33dc8423f 100644 --- a/spring-expression/src/main/java/org/springframework/expression/MethodResolver.java +++ b/spring-expression/src/main/java/org/springframework/expression/MethodResolver.java @@ -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"); * 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; /** - * A method resolver attempts locate a method and returns a command executor that can be used to invoke that method. - * The command executor will be cached but if it 'goes stale' the resolvers will be called again. + * A method resolver attempts locate a method and returns a command executor that can be + * 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 * @since 3.0 @@ -30,9 +31,9 @@ import org.springframework.core.convert.TypeDescriptor; public interface MethodResolver { /** - * Within the supplied context determine a suitable method on the supplied object that can handle the - * specified arguments. Return a MethodExecutor that can be used to invoke that method - * (or {@code null} if no method could be found). + * Within the supplied context determine a suitable method on the supplied object that + * can handle the specified arguments. Return a {@link MethodExecutor} that can be used + * to invoke that method, or {@code null} if no method could be found. * @param context the current evaluation context * @param targetObject the object upon which the method is being called * @param argumentTypes the arguments that the constructor must be able to handle diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java index c4a4425bed..b001130717 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java @@ -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"); * 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); } - public List getConstructorResolvers() { - ensureConstructorResolversInitialized(); - return this.constructorResolvers; - } - public void setConstructorResolvers(List constructorResolvers) { this.constructorResolvers = constructorResolvers; } + public List getConstructorResolvers() { + ensureConstructorResolversInitialized(); + return this.constructorResolvers; + } public void addMethodResolver(MethodResolver resolver) { ensureMethodResolversInitialized(); @@ -123,6 +122,10 @@ public class StandardEvaluationContext implements EvaluationContext { return this.methodResolvers.remove(methodResolver); } + public void setMethodResolvers(List methodResolvers) { + this.methodResolvers = methodResolvers; + } + public List getMethodResolvers() { ensureMethodResolversInitialized(); return this.methodResolvers; @@ -136,11 +139,6 @@ public class StandardEvaluationContext implements EvaluationContext { return this.beanResolver; } - public void setMethodResolvers(List methodResolvers) { - this.methodResolvers = methodResolvers; - } - - public void addPropertyAccessor(PropertyAccessor accessor) { ensurePropertyAccessorsInitialized(); this.propertyAccessors.add(this.propertyAccessors.size() - 1, accessor); @@ -150,15 +148,14 @@ public class StandardEvaluationContext implements EvaluationContext { return this.propertyAccessors.remove(accessor); } - public List getPropertyAccessors() { - ensurePropertyAccessorsInitialized(); - return this.propertyAccessors; - } - public void setPropertyAccessors(List propertyAccessors) { this.propertyAccessors = propertyAccessors; } + public List getPropertyAccessors() { + ensurePropertyAccessorsInitialized(); + return this.propertyAccessors; + } public void setTypeLocator(TypeLocator typeLocator) { 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 * for the specified type. - * *

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. - * * @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 * @throws IllegalStateException if the {@link ReflectiveMethodResolver} is not in use */ public void registerMethodFilter(Class type, MethodFilter filter) throws IllegalStateException { ensureMethodResolversInitialized(); - if (reflectiveMethodResolver != null) { - reflectiveMethodResolver.registerMethodFilter(type, filter); - } else { + if (this.reflectiveMethodResolver != null) { + this.reflectiveMethodResolver.registerMethodFilter(type, filter); + } + else { 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() { if (this.methodResolvers == null) { List defaultResolvers = new ArrayList(); - defaultResolvers.add(reflectiveMethodResolver = new ReflectiveMethodResolver()); + this.reflectiveMethodResolver = new ReflectiveMethodResolver(); + defaultResolvers.add(this.reflectiveMethodResolver); this.methodResolvers = defaultResolvers; } }