diff --git a/spring-expression/src/main/java/org/springframework/expression/ConstructorExecutor.java b/spring-expression/src/main/java/org/springframework/expression/ConstructorExecutor.java
index bb04735237..71efb3039a 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ConstructorExecutor.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ConstructorExecutor.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.
@@ -19,13 +19,15 @@ package org.springframework.expression;
// TODO Is the resolver/executor model too pervasive in this package?
/**
- * Executors are built by resolvers and can be cached by the infrastructure to repeat an operation quickly without going
- * back to the resolvers. For example, the particular constructor to run on a class may be discovered by the reflection
- * constructor resolver - it will then build a ConstructorExecutor that executes that constructor and the
- * ConstructorExecutor can be reused without needing to go back to the resolver to discover the constructor again.
+ * Executors are built by resolvers and can be cached by the infrastructure to repeat an
+ * operation quickly without going back to the resolvers. For example, the particular
+ * constructor to run on a class may be discovered by the reflection constructor resolver
+ * - it will then build a ConstructorExecutor that executes that constructor and the
+ * ConstructorExecutor can be reused without needing to go back to the resolver to
+ * discover the constructor 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,11 +36,13 @@ public interface ConstructorExecutor {
/**
* Execute a constructor in the specified context using the specified arguments.
+ *
* @param context the evaluation context in which the command is being executed
- * @param arguments the arguments to the constructor call, should match (in terms of number and type) whatever the
- * command will need to run
+ * @param arguments the arguments to the constructor call, should match (in terms of
+ * number and type) whatever the command will need to run
* @return the new object
- * @throws AccessException if there is a problem executing the command or the CommandExecutor is no longer valid
+ * @throws AccessException if there is a problem executing the command or the
+ * CommandExecutor is no longer valid
*/
TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException;
diff --git a/spring-expression/src/main/java/org/springframework/expression/ConstructorResolver.java b/spring-expression/src/main/java/org/springframework/expression/ConstructorResolver.java
index e1892d86c0..d942978af9 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ConstructorResolver.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ConstructorResolver.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,18 +21,19 @@ import java.util.List;
import org.springframework.core.convert.TypeDescriptor;
/**
- * A constructor resolver attempts locate a constructor and returns a ConstructorExecutor that can be used to invoke
- * that constructor. The ConstructorExecutor will be cached but if it 'goes stale' the resolvers will be called again.
- *
+ * A constructor resolver attempts locate a constructor and returns a ConstructorExecutor
+ * that can be used to invoke that constructor. The ConstructorExecutor will be cached but
+ * if it 'goes stale' the resolvers will be called again.
+ *
* @author Andy Clement
* @since 3.0
*/
public interface ConstructorResolver {
/**
- * Within the supplied context determine a suitable constructor on the supplied type that can handle the
- * specified arguments. Return a ConstructorExecutor that can be used to invoke that constructor
- * (or {@code null} if no constructor could be found).
+ * Within the supplied context determine a suitable constructor on the supplied type
+ * that can handle the specified arguments. Return a ConstructorExecutor that can be
+ * used to invoke that constructor (or {@code null} if no constructor could be found).
* @param context the current evaluation context
* @param typeName the type upon which to look for the constructor
* @param argumentTypes the arguments that the constructor must be able to handle
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..a4953fe06d 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,8 +33,9 @@ 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();
@@ -54,7 +55,8 @@ public interface EvaluationContext {
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();
diff --git a/spring-expression/src/main/java/org/springframework/expression/Expression.java b/spring-expression/src/main/java/org/springframework/expression/Expression.java
index fdad75b17f..b72a353d70 100644
--- a/spring-expression/src/main/java/org/springframework/expression/Expression.java
+++ b/spring-expression/src/main/java/org/springframework/expression/Expression.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.
@@ -19,10 +19,9 @@ package org.springframework.expression;
import org.springframework.core.convert.TypeDescriptor;
/**
- * An expression capable of evaluating itself against context objects.
- * Encapsulates the details of a previously parsed expression string.
- * Provides a common abstraction for expression evaluation independent
- * of any language like OGNL or the Unified EL.
+ * An expression capable of evaluating itself against context objects. Encapsulates the
+ * details of a previously parsed expression string. Provides a common abstraction for
+ * expression evaluation independent of any language like OGNL or the Unified EL.
*
* @author Keith Donald
* @author Andy Clement
diff --git a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java
index ecea713cad..240c8053be 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.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.
@@ -16,7 +16,6 @@
package org.springframework.expression;
-
/**
* Super class for exceptions that can occur whilst processing expressions
*
@@ -27,8 +26,10 @@ package org.springframework.expression;
public class ExpressionException extends RuntimeException {
protected String expressionString;
+
protected int position; // -1 if not known - but should be known in all reasonable cases
+
/**
* Creates a new expression exception.
* @param expressionString the expression string
@@ -85,15 +86,16 @@ public class ExpressionException extends RuntimeException {
super(message,cause);
}
+
public String toDetailedString() {
StringBuilder output = new StringBuilder();
- if (expressionString!=null) {
+ if (this.expressionString!=null) {
output.append("Expression '");
- output.append(expressionString);
+ output.append(this.expressionString);
output.append("'");
- if (position!=-1) {
+ if (this.position!=-1) {
output.append(" @ ");
- output.append(position);
+ output.append(this.position);
}
output.append(": ");
}
@@ -106,7 +108,7 @@ public class ExpressionException extends RuntimeException {
}
public final int getPosition() {
- return position;
+ return this.position;
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java b/spring-expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java
index a6b11fb26a..30a4e00843 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ExpressionInvocationTargetException.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.
@@ -13,13 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.expression;
/**
- * This exception wraps (as cause) a checked exception thrown by some method that SpEL invokes.
- * It differs from a SpelEvaluationException because this indicates the occurrence of a checked exception
- * that the invoked method was defined to throw. SpelEvaluationExceptions are for handling (and wrapping)
- * unexpected exceptions.
+ * This exception wraps (as cause) a checked exception thrown by some method that SpEL
+ * invokes. It differs from a SpelEvaluationException because this indicates the
+ * occurrence of a checked exception that the invoked method was defined to throw.
+ * SpelEvaluationExceptions are for handling (and wrapping) unexpected exceptions.
*
* @author Andy Clement
* @since 3.0.3
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..1506f98630 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
@@ -31,13 +33,15 @@ package org.springframework.expression;
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 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/MethodFilter.java b/spring-expression/src/main/java/org/springframework/expression/MethodFilter.java
index 50992dd798..d7c6e20cbd 100644
--- a/spring-expression/src/main/java/org/springframework/expression/MethodFilter.java
+++ b/spring-expression/src/main/java/org/springframework/expression/MethodFilter.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.
@@ -13,18 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.expression;
import java.lang.reflect.Method;
import java.util.List;
/**
- * MethodFilter instances allow SpEL users to fine tune the behaviour of the method resolution
- * process. Method resolution (which translates from a method name in an expression to a real
- * method to invoke) will normally retrieve candidate methods for invocation via a simple call
- * to 'Class.getMethods()' and will choose the first one that is suitable for the
- * input parameters. By registering a MethodFilter the user can receive a callback
- * and change the methods that will be considered suitable.
+ * MethodFilter instances allow SpEL users to fine tune the behaviour of the method
+ * resolution process. Method resolution (which translates from a method name in an
+ * expression to a real method to invoke) will normally retrieve candidate methods for
+ * invocation via a simple call to 'Class.getMethods()' and will choose the first one that
+ * is suitable for the input parameters. By registering a MethodFilter the user can
+ * receive a callback and change the methods that will be considered suitable.
*
* @author Andy Clement
* @since 3.0.1
@@ -32,12 +33,11 @@ import java.util.List;
public interface MethodFilter {
/**
- * Called by the method resolver to allow the SpEL user to organize the list of candidate
- * methods that may be invoked. The filter can remove methods that should not be
- * considered candidates and it may sort the results. The resolver will then search
- * through the methods as returned from the filter when looking for a suitable
+ * Called by the method resolver to allow the SpEL user to organize the list of
+ * candidate methods that may be invoked. The filter can remove methods that should
+ * not be considered candidates and it may sort the results. The resolver will then
+ * search through the methods as returned from the filter when looking for a suitable
* candidate to invoke.
- *
* @param methods the full list of methods the resolver was going to choose from
* @return a possible subset of input methods that may be sorted by order of relevance
*/
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..d3bdb78c96 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,13 +31,14 @@ 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 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
- * @return a MethodExecutor that can invoke the method, or null if the method cannot be found
+ * @return a MethodExecutor that can invoke the method, or null if the method cannot
+ * be found
*/
MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
List argumentTypes) throws AccessException;
diff --git a/spring-expression/src/main/java/org/springframework/expression/Operation.java b/spring-expression/src/main/java/org/springframework/expression/Operation.java
index 01b805905b..f4b9673704 100644
--- a/spring-expression/src/main/java/org/springframework/expression/Operation.java
+++ b/spring-expression/src/main/java/org/springframework/expression/Operation.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.
@@ -17,13 +17,24 @@
package org.springframework.expression;
/**
- * Supported operations that an {@link OperatorOverloader} can implement for any pair of operands.
+ * Supported operations that an {@link OperatorOverloader} can implement for any pair of
+ * operands.
*
* @author Andy Clement
* @since 3.0
*/
public enum Operation {
- ADD, SUBTRACT, DIVIDE, MULTIPLY, MODULUS, POWER
+ ADD,
+
+ SUBTRACT,
+
+ DIVIDE,
+
+ MULTIPLY,
+
+ MODULUS,
+
+ POWER
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/OperatorOverloader.java b/spring-expression/src/main/java/org/springframework/expression/OperatorOverloader.java
index 29c165111b..7291575c9c 100644
--- a/spring-expression/src/main/java/org/springframework/expression/OperatorOverloader.java
+++ b/spring-expression/src/main/java/org/springframework/expression/OperatorOverloader.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.
@@ -17,8 +17,9 @@
package org.springframework.expression;
/**
- * By default the mathematical operators {@link Operation} support simple types like numbers. By providing an
- * implementation of OperatorOverloader, a user of the expression language can support these operations on other types.
+ * By default the mathematical operators {@link Operation} support simple types like
+ * numbers. By providing an implementation of OperatorOverloader, a user of the expression
+ * language can support these operations on other types.
*
* @author Andy Clement
* @since 3.0
@@ -26,20 +27,21 @@ package org.springframework.expression;
public interface OperatorOverloader {
/**
- * Return true if the operator overloader supports the specified operation
- * between the two operands and so should be invoked to handle it.
+ * Return true if the operator overloader supports the specified operation between the
+ * two operands and so should be invoked to handle it.
* @param operation the operation to be performed
* @param leftOperand the left operand
* @param rightOperand the right operand
- * @return true if the OperatorOverloader supports the specified operation between the two operands
+ * @return true if the OperatorOverloader supports the specified operation between the
+ * two operands
* @throws EvaluationException if there is a problem performing the operation
*/
boolean overridesOperation(Operation operation, Object leftOperand, Object rightOperand)
throws EvaluationException;
/**
- * Execute the specified operation on two operands, returning a result.
- * See {@link Operation} for supported operations.
+ * Execute the specified operation on two operands, returning a result. See
+ * {@link Operation} for supported operations.
* @param operation the operation to be performed
* @param leftOperand the left operand
* @param rightOperand the right operand
diff --git a/spring-expression/src/main/java/org/springframework/expression/ParserContext.java b/spring-expression/src/main/java/org/springframework/expression/ParserContext.java
index 87a442c6b3..9617feb247 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ParserContext.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ParserContext.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.
@@ -17,7 +17,8 @@
package org.springframework.expression;
/**
- * Input provided to an expression parser that can influence an expression parsing/compilation routine.
+ * Input provided to an expression parser that can influence an expression
+ * parsing/compilation routine.
*
* @author Keith Donald
* @author Andy Clement
@@ -26,38 +27,35 @@ package org.springframework.expression;
public interface ParserContext {
/**
- * Whether or not the expression being parsed is a template. A template expression consists of literal text that can
- * be mixed with evaluatable blocks. Some examples:
- *
+ * Whether or not the expression being parsed is a template. A template expression
+ * consists of literal text that can be mixed with evaluatable blocks. Some examples:
*
* Some literal text
* Hello #{name.firstName}!
* #{3 + 4}
*
- *
* @return true if the expression is a template, false otherwise
*/
boolean isTemplate();
/**
- * For template expressions, returns the prefix that identifies the start of an expression block within a string.
- * For example: "${"
- *
+ * For template expressions, returns the prefix that identifies the start of an
+ * expression block within a string. For example: "${"
* @return the prefix that identifies the start of an expression
*/
String getExpressionPrefix();
/**
- * For template expressions, return the prefix that identifies the end of an expression block within a string.
- * For example: "}"
- *
+ * For template expressions, return the prefix that identifies the end of an
+ * expression block within a string. For example: "}"
* @return the suffix that identifies the end of an expression
*/
String getExpressionSuffix();
+
/**
- * The default ParserContext implementation that enables template expression parsing mode.
- * The expression prefix is #{ and the expression suffix is }.
+ * The default ParserContext implementation that enables template expression parsing
+ * mode. The expression prefix is #{ and the expression suffix is }.
* @see #isTemplate()
*/
public static final ParserContext TEMPLATE_EXPRESSION = new ParserContext() {
diff --git a/spring-expression/src/main/java/org/springframework/expression/PropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/PropertyAccessor.java
index e14c30ba68..a8222c25ab 100644
--- a/spring-expression/src/main/java/org/springframework/expression/PropertyAccessor.java
+++ b/spring-expression/src/main/java/org/springframework/expression/PropertyAccessor.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.
@@ -18,13 +18,15 @@ package org.springframework.expression;
/**
- * A property accessor is able to read (and possibly write) to object properties. The interface places no restrictions
- * and so implementors are free to access properties directly as fields or through getters or in any other way they see
- * as appropriate. A resolver can optionally specify an array of target classes for which it should be called - but if
- * it returns null from getSpecificTargetClasses() then it will be called for all property references and given a chance
- * to determine if it can read or write them. Property resolvers are considered to be ordered and each will be called in
- * turn. The only rule that affects the call order is that any naming the target class directly in
- * getSpecifiedTargetClasses() will be called first, before the general resolvers.
+ * A property accessor is able to read (and possibly write) to object properties. The
+ * interface places no restrictions and so implementors are free to access properties
+ * directly as fields or through getters or in any other way they see as appropriate. A
+ * resolver can optionally specify an array of target classes for which it should be
+ * called - but if it returns null from getSpecificTargetClasses() then it will be called
+ * for all property references and given a chance to determine if it can read or write
+ * them. Property resolvers are considered to be ordered and each will be called in turn.
+ * The only rule that affects the call order is that any naming the target class directly
+ * in getSpecifiedTargetClasses() will be called first, before the general resolvers.
*
* @author Andy Clement
* @since 3.0
@@ -32,19 +34,23 @@ package org.springframework.expression;
public interface PropertyAccessor {
/**
- * Return an array of classes for which this resolver should be called. Returning null indicates this is a general
- * resolver that can be called in an attempt to resolve a property on any type.
- * @return an array of classes that this resolver is suitable for (or null if a general resolver)
+ * Return an array of classes for which this resolver should be called. Returning null
+ * indicates this is a general resolver that can be called in an attempt to resolve a
+ * property on any type.
+ * @return an array of classes that this resolver is suitable for (or null if a
+ * general resolver)
*/
Class[] getSpecificTargetClasses();
/**
- * Called to determine if a resolver instance is able to access a specified property on a specified target object.
+ * Called to determine if a resolver instance is able to access a specified property
+ * on a specified target object.
* @param context the evaluation context in which the access is being attempted
* @param target the target object upon which the property is being accessed
* @param name the name of the property being accessed
* @return true if this resolver is able to read the property
- * @throws AccessException if there is any problem determining whether the property can be read
+ * @throws AccessException if there is any problem determining whether the property
+ * can be read
*/
boolean canRead(EvaluationContext context, Object target, String name) throws AccessException;
@@ -59,17 +65,20 @@ public interface PropertyAccessor {
TypedValue read(EvaluationContext context, Object target, String name) throws AccessException;
/**
- * Called to determine if a resolver instance is able to write to a specified property on a specified target object.
+ * Called to determine if a resolver instance is able to write to a specified property
+ * on a specified target object.
* @param context the evaluation context in which the access is being attempted
* @param target the target object upon which the property is being accessed
* @param name the name of the property being accessed
* @return true if this resolver is able to write to the property
- * @throws AccessException if there is any problem determining whether the property can be written to
+ * @throws AccessException if there is any problem determining whether the property
+ * can be written to
*/
boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException;
/**
- * Called to write to a property on a specified target object. Should only succeed if canWrite() also returns true.
+ * Called to write to a property on a specified target object. Should only succeed if
+ * canWrite() also returns true.
* @param context the evaluation context in which the access is being attempted
* @param target the target object upon which the property is being accessed
* @param name the name of the property being accessed
diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java
index 1dfb41adc7..c939fcab11 100644
--- a/spring-expression/src/main/java/org/springframework/expression/TypeComparator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/TypeComparator.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.
@@ -17,8 +17,8 @@
package org.springframework.expression;
/**
- * Instances of a type comparator should be able to compare pairs of objects for equality, the specification of the
- * return value is the same as for {@link Comparable}.
+ * Instances of a type comparator should be able to compare pairs of objects for equality,
+ * the specification of the return value is the same as for {@link Comparable}.
*
* @author Andy Clement
* @since 3.0
@@ -29,9 +29,10 @@ public interface TypeComparator {
* Compare two objects.
* @param firstObject the first object
* @param secondObject the second object
- * @return 0 if they are equal, <0 if the first is smaller than the second, or >0 if the first is larger than the
- * second
- * @throws EvaluationException if a problem occurs during comparison (or they are not comparable)
+ * @return 0 if they are equal, <0 if the first is smaller than the second, or >0 if
+ * the first is larger than the second
+ * @throws EvaluationException if a problem occurs during comparison (or they are not
+ * comparable)
*/
int compare(Object firstObject, Object secondObject) throws EvaluationException;
diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java
index e6145ab20e..bb7b26b386 100644
--- a/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java
+++ b/spring-expression/src/main/java/org/springframework/expression/TypeConverter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 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,10 +19,10 @@ package org.springframework.expression;
import org.springframework.core.convert.TypeDescriptor;
/**
- * A type converter can convert values between different types encountered
- * during expression evaluation. This is an SPI for the expression parser;
- * see {@link org.springframework.core.convert.ConversionService} for the
- * primary user API to Spring's conversion facilities.
+ * A type converter can convert values between different types encountered during
+ * expression evaluation. This is an SPI for the expression parser; see
+ * {@link org.springframework.core.convert.ConversionService} for the primary user API to
+ * Spring's conversion facilities.
*
* @author Andy Clement
* @author Juergen Hoeller
@@ -31,7 +31,8 @@ import org.springframework.core.convert.TypeDescriptor;
public interface TypeConverter {
/**
- * Return true if the type converter can convert the specified type to the desired target type.
+ * Return true if the type converter can convert the specified type to the desired
+ * target type.
* @param sourceType a type descriptor that describes the source type
* @param targetType a type descriptor that describes the requested result type
* @return true if that conversion can be performed
@@ -39,12 +40,15 @@ public interface TypeConverter {
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
/**
- * Convert (may coerce) a value from one type to another, for example from a boolean to a string.
- * The typeDescriptor parameter enables support for typed collections - if the caller really wishes they
- * can have a List<Integer> for example, rather than simply a List.
+ * Convert (may coerce) a value from one type to another, for example from a boolean
+ * to a string. The typeDescriptor parameter enables support for typed collections -
+ * if the caller really wishes they can have a List<Integer> for example, rather
+ * than simply a List.
* @param value the value to be converted
- * @param sourceType a type descriptor that supplies extra information about the source object
- * @param targetType a type descriptor that supplies extra information about the requested result type
+ * @param sourceType a type descriptor that supplies extra information about the
+ * source object
+ * @param targetType a type descriptor that supplies extra information about the
+ * requested result type
* @return the converted value
* @throws EvaluationException if conversion is not possible
*/
diff --git a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java
index 4a22a82c19..7fade5cb7b 100644
--- a/spring-expression/src/main/java/org/springframework/expression/TypeLocator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/TypeLocator.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,9 +17,11 @@
package org.springframework.expression;
/**
- * Implementors of this interface are expected to be able to locate types. They may use custom classloaders
- * or the and deal with common package prefixes (java.lang, etc) however they wish. See
- * {@link org.springframework.expression.spel.support.StandardTypeLocator} for an example implementation.
+ * Implementors of this interface are expected to be able to locate types. They may use
+ * custom classloaders or the and deal with common package prefixes (java.lang, etc)
+ * however they wish. See
+ * {@link org.springframework.expression.spel.support.StandardTypeLocator} for an example
+ * implementation.
*
* @author Andy Clement
* @since 3.0
@@ -27,7 +29,8 @@ package org.springframework.expression;
public interface TypeLocator {
/**
- * Find a type by name. The name may or may not be fully qualified (eg. String or java.lang.String)
+ * Find a type by name. The name may or may not be fully qualified (eg. String or
+ * java.lang.String)
* @param typename the type to be located
* @return the class object representing that type
* @throws EvaluationException if there is a problem finding it
diff --git a/spring-expression/src/main/java/org/springframework/expression/TypedValue.java b/spring-expression/src/main/java/org/springframework/expression/TypedValue.java
index 67ecb99ad2..12fb458293 100644
--- a/spring-expression/src/main/java/org/springframework/expression/TypedValue.java
+++ b/spring-expression/src/main/java/org/springframework/expression/TypedValue.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.
@@ -19,9 +19,9 @@ package org.springframework.expression;
import org.springframework.core.convert.TypeDescriptor;
/**
- * Encapsulates an object and a type descriptor that describes it.
- * The type descriptor can hold generic information that would not be
- * accessible through a simple {@code getClass()} call on the object.
+ * Encapsulates an object and a type descriptor that describes it. The type descriptor can
+ * hold generic information that would not be accessible through a simple
+ * {@code getClass()} call on the object.
*
* @author Andy Clement
* @author Juergen Hoeller
diff --git a/spring-expression/src/main/java/org/springframework/expression/common/CompositeStringExpression.java b/spring-expression/src/main/java/org/springframework/expression/common/CompositeStringExpression.java
index a24a545479..1ddd5f9143 100644
--- a/spring-expression/src/main/java/org/springframework/expression/common/CompositeStringExpression.java
+++ b/spring-expression/src/main/java/org/springframework/expression/common/CompositeStringExpression.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.
@@ -20,18 +20,21 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
+import org.springframework.expression.TypedValue;
/**
- * Represents a template expression broken into pieces. Each piece will be an Expression but pure text parts to the
- * template will be represented as LiteralExpression objects. An example of a template expression might be:
- *
+ * Represents a template expression broken into pieces. Each piece will be an Expression
+ * but pure text parts to the template will be represented as LiteralExpression objects.
+ * An example of a template expression might be:
+ *
*
- * "Hello ${getName()}"
- *
- * which will be represented as a CompositeStringExpression of two parts. The first part being a
- * LiteralExpression representing 'Hello ' and the second part being a real expression that will
- * call {@code getName()} when invoked.
- *
+ * "Hello ${getName()}"
+ *
+ *
+ * which will be represented as a CompositeStringExpression of two parts. The first part
+ * being a LiteralExpression representing 'Hello ' and the second part being a real
+ * expression that will call {@code getName()} when invoked.
+ *
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
@@ -131,13 +134,13 @@ public class CompositeStringExpression implements Expression {
@Override
public T getValue(EvaluationContext context, Class expectedResultType) throws EvaluationException {
Object value = getValue(context);
- return ExpressionUtils.convert(context, value, expectedResultType);
+ return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
}
@Override
public T getValue(Class expectedResultType) throws EvaluationException {
Object value = getValue();
- return ExpressionUtils.convert(null, value, expectedResultType);
+ return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType);
}
@Override
@@ -146,21 +149,21 @@ public class CompositeStringExpression implements Expression {
}
public Expression[] getExpressions() {
- return expressions;
+ return this.expressions;
}
@Override
public T getValue(Object rootObject, Class desiredResultType) throws EvaluationException {
Object value = getValue(rootObject);
- return ExpressionUtils.convert(null, value, desiredResultType);
+ return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
public T getValue(EvaluationContext context, Object rootObject, Class desiredResultType)
throws EvaluationException {
Object value = getValue(context,rootObject);
- return ExpressionUtils.convert(context, value, desiredResultType);
+ return ExpressionUtils.convertTypedValue(context, new TypedValue(value), desiredResultType);
}
@Override
diff --git a/spring-expression/src/main/java/org/springframework/expression/common/ExpressionUtils.java b/spring-expression/src/main/java/org/springframework/expression/common/ExpressionUtils.java
index cc959c799e..696d1eedf9 100644
--- a/spring-expression/src/main/java/org/springframework/expression/common/ExpressionUtils.java
+++ b/spring-expression/src/main/java/org/springframework/expression/common/ExpressionUtils.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.
@@ -33,29 +33,32 @@ import org.springframework.util.ClassUtils;
public abstract class ExpressionUtils {
/**
- * Determines if there is a type converter available in the specified context and attempts to use it to convert the
- * supplied value to the specified type. Throws an exception if conversion is not possible.
+ * Determines if there is a type converter available in the specified context and
+ * attempts to use it to convert the supplied value to the specified type. Throws an
+ * exception if conversion is not possible.
* @param context the evaluation context that may define a type converter
* @param value the value to convert (may be null)
* @param targetType the type to attempt conversion to
* @return the converted value
- * @throws EvaluationException if there is a problem during conversion or conversion of the value to the specified
- * type is not supported
+ * @throws EvaluationException if there is a problem during conversion or conversion
+ * of the value to the specified type is not supported
+ * @deprecated use {@link #convertTypedValue(EvaluationContext, TypedValue, Class)}
*/
+ @Deprecated
public static T convert(EvaluationContext context, Object value, Class targetType) throws EvaluationException {
- // TODO remove this function over time and use the one it delegates to
- return convertTypedValue(context,new TypedValue(value),targetType);
+ return convertTypedValue(context, new TypedValue(value), targetType);
}
/**
- * Determines if there is a type converter available in the specified context and attempts to use it to convert the
- * supplied value to the specified type. Throws an exception if conversion is not possible.
+ * Determines if there is a type converter available in the specified context and
+ * attempts to use it to convert the supplied value to the specified type. Throws an
+ * exception if conversion is not possible.
* @param context the evaluation context that may define a type converter
* @param typedValue the value to convert and a type descriptor describing it
* @param targetType the type to attempt conversion to
* @return the converted value
- * @throws EvaluationException if there is a problem during conversion or conversion of the value to the specified
- * type is not supported
+ * @throws EvaluationException if there is a problem during conversion or conversion
+ * of the value to the specified type is not supported
*/
@SuppressWarnings("unchecked")
public static T convertTypedValue(EvaluationContext context, TypedValue typedValue, Class targetType) {
diff --git a/spring-expression/src/main/java/org/springframework/expression/common/LiteralExpression.java b/spring-expression/src/main/java/org/springframework/expression/common/LiteralExpression.java
index ea6742ae07..c9b1878ff3 100644
--- a/spring-expression/src/main/java/org/springframework/expression/common/LiteralExpression.java
+++ b/spring-expression/src/main/java/org/springframework/expression/common/LiteralExpression.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.
@@ -20,13 +20,14 @@ import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
+import org.springframework.expression.TypedValue;
/**
- * A very simple hardcoded implementation of the Expression interface that represents a string literal.
- * It is used with CompositeStringExpression when representing a template expression which is made up
- * of pieces - some being real expressions to be handled by an EL implementation like Spel, and some
- * being just textual elements.
- *
+ * A very simple hardcoded implementation of the Expression interface that represents a
+ * string literal. It is used with CompositeStringExpression when representing a template
+ * expression which is made up of pieces - some being real expressions to be handled by an
+ * EL implementation like Spel, and some being just textual elements.
+ *
* @author Andy Clement
* @since 3.0
*/
@@ -78,19 +79,19 @@ public class LiteralExpression implements Expression {
@Override
public void setValue(EvaluationContext context, Object value) throws EvaluationException {
- throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression");
+ throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
@Override
public T getValue(EvaluationContext context, Class expectedResultType) throws EvaluationException {
Object value = getValue(context);
- return ExpressionUtils.convert(context, value, expectedResultType);
+ return ExpressionUtils.convertTypedValue(context, new TypedValue(value), expectedResultType);
}
@Override
public T getValue(Class expectedResultType) throws EvaluationException {
Object value = getValue();
- return ExpressionUtils.convert(null, value, expectedResultType);
+ return ExpressionUtils.convertTypedValue(null, new TypedValue(value), expectedResultType);
}
@Override
@@ -106,7 +107,7 @@ public class LiteralExpression implements Expression {
@Override
public T getValue(Object rootObject, Class desiredResultType) throws EvaluationException {
Object value = getValue(rootObject);
- return ExpressionUtils.convert(null, value, desiredResultType);
+ return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
@@ -117,7 +118,7 @@ public class LiteralExpression implements Expression {
@Override
public T getValue(EvaluationContext context, Object rootObject, Class desiredResultType) throws EvaluationException {
Object value = getValue(context, rootObject);
- return ExpressionUtils.convert(null, value, desiredResultType);
+ return ExpressionUtils.convertTypedValue(null, new TypedValue(value), desiredResultType);
}
@Override
@@ -147,7 +148,7 @@ public class LiteralExpression implements Expression {
@Override
public void setValue(EvaluationContext context, Object rootObject, Object value) throws EvaluationException {
- throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression");
+ throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
@Override
@@ -157,7 +158,7 @@ public class LiteralExpression implements Expression {
@Override
public void setValue(Object rootObject, Object value) throws EvaluationException {
- throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression");
+ throw new EvaluationException(this.literalValue, "Cannot call setValue() on a LiteralExpression");
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java b/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java
index 82b6ab07bb..c74371e998 100644
--- a/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.java
+++ b/spring-expression/src/main/java/org/springframework/expression/common/TemplateAwareExpressionParser.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.
@@ -26,9 +26,9 @@ import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;
/**
- * An expression parser that understands templates. It can be subclassed
- * by expression parsers that do not offer first class support for templating.
- *
+ * An expression parser that understands templates. It can be subclassed by expression
+ * parsers that do not offer first class support for templating.
+ *
* @author Keith Donald
* @author Juergen Hoeller
* @author Andy Clement
@@ -40,102 +40,124 @@ public abstract class TemplateAwareExpressionParser implements ExpressionParser
* Default ParserContext instance for non-template expressions.
*/
private static final ParserContext NON_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
+
@Override
public String getExpressionPrefix() {
return null;
}
+
@Override
public String getExpressionSuffix() {
return null;
}
+
@Override
public boolean isTemplate() {
return false;
}
};
-
@Override
public Expression parseExpression(String expressionString) throws ParseException {
return parseExpression(expressionString, NON_TEMPLATE_PARSER_CONTEXT);
}
@Override
- public Expression parseExpression(String expressionString, ParserContext context) throws ParseException {
+ public Expression parseExpression(String expressionString, ParserContext context)
+ throws ParseException {
if (context == null) {
context = NON_TEMPLATE_PARSER_CONTEXT;
}
+
if (context.isTemplate()) {
return parseTemplate(expressionString, context);
- } else {
+ }
+ else {
return doParseExpression(expressionString, context);
}
}
- private Expression parseTemplate(String expressionString, ParserContext context) throws ParseException {
+ private Expression parseTemplate(String expressionString, ParserContext context)
+ throws ParseException {
if (expressionString.length() == 0) {
return new LiteralExpression("");
}
Expression[] expressions = parseExpressions(expressionString, context);
if (expressions.length == 1) {
return expressions[0];
- } else {
+ }
+ else {
return new CompositeStringExpression(expressionString, expressions);
}
}
-
/**
- * Helper that parses given expression string using the configured parser. The expression string can contain any
- * number of expressions all contained in "${...}" markers. For instance: "foo${expr0}bar${expr1}". The static
- * pieces of text will also be returned as Expressions that just return that static piece of text. As a result,
- * evaluating all returned expressions and concatenating the results produces the complete evaluated string.
- * Unwrapping is only done of the outermost delimiters found, so the string 'hello ${foo${abc}}' would break into
- * the pieces 'hello ' and 'foo${abc}'. This means that expression languages that used ${..} as part of their
- * functionality are supported without any problem.
- * The parsing is aware of the structure of an embedded expression. It assumes that parentheses '(',
- * square brackets '[' and curly brackets '}' must be in pairs within the expression unless they are within a
- * string literal and a string literal starts and terminates with a single quote '.
- *
+ * Helper that parses given expression string using the configured parser. The
+ * expression string can contain any number of expressions all contained in "${...}"
+ * markers. For instance: "foo${expr0}bar${expr1}". The static pieces of text will
+ * also be returned as Expressions that just return that static piece of text. As a
+ * result, evaluating all returned expressions and concatenating the results produces
+ * the complete evaluated string. Unwrapping is only done of the outermost delimiters
+ * found, so the string 'hello ${foo${abc}}' would break into the pieces 'hello ' and
+ * 'foo${abc}'. This means that expression languages that used ${..} as part of their
+ * functionality are supported without any problem. The parsing is aware of the
+ * structure of an embedded expression. It assumes that parentheses '(', square
+ * brackets '[' and curly brackets '}' must be in pairs within the expression unless
+ * they are within a string literal and a string literal starts and terminates with a
+ * single quote '.
* @param expressionString the expression string
* @return the parsed expressions
* @throws ParseException when the expressions cannot be parsed
*/
- private Expression[] parseExpressions(String expressionString, ParserContext context) throws ParseException {
+ private Expression[] parseExpressions(String expressionString, ParserContext context)
+ throws ParseException {
List expressions = new LinkedList();
String prefix = context.getExpressionPrefix();
String suffix = context.getExpressionSuffix();
int startIdx = 0;
while (startIdx < expressionString.length()) {
- int prefixIndex = expressionString.indexOf(prefix,startIdx);
+ int prefixIndex = expressionString.indexOf(prefix, startIdx);
if (prefixIndex >= startIdx) {
// an inner expression was found - this is a composite
if (prefixIndex > startIdx) {
- expressions.add(createLiteralExpression(context,expressionString.substring(startIdx, prefixIndex)));
+ expressions.add(createLiteralExpression(context,
+ expressionString.substring(startIdx, prefixIndex)));
}
int afterPrefixIndex = prefixIndex + prefix.length();
- int suffixIndex = skipToCorrectEndSuffix(prefix,suffix,expressionString,afterPrefixIndex);
+ int suffixIndex = skipToCorrectEndSuffix(prefix, suffix,
+ expressionString, afterPrefixIndex);
+
if (suffixIndex == -1) {
- throw new ParseException(expressionString, prefixIndex, "No ending suffix '" + suffix +
- "' for expression starting at character " + prefixIndex + ": " +
- expressionString.substring(prefixIndex));
+ throw new ParseException(expressionString, prefixIndex,
+ "No ending suffix '" + suffix
+ + "' for expression starting at character "
+ + prefixIndex + ": "
+ + expressionString.substring(prefixIndex));
}
+
if (suffixIndex == afterPrefixIndex) {
- throw new ParseException(expressionString, prefixIndex, "No expression defined within delimiter '" +
- prefix + suffix + "' at character " + prefixIndex);
- } else {
- String expr = expressionString.substring(prefixIndex + prefix.length(), suffixIndex);
- expr = expr.trim();
- if (expr.length()==0) {
- throw new ParseException(expressionString, prefixIndex, "No expression defined within delimiter '" +
- prefix + suffix + "' at character " + prefixIndex);
- }
- expressions.add(doParseExpression(expr, context));
- startIdx = suffixIndex + suffix.length();
+ throw new ParseException(expressionString, prefixIndex,
+ "No expression defined within delimiter '" + prefix + suffix
+ + "' at character " + prefixIndex);
}
- } else {
+
+ String expr = expressionString.substring(prefixIndex + prefix.length(),
+ suffixIndex);
+ expr = expr.trim();
+
+ if (expr.length() == 0) {
+ throw new ParseException(expressionString, prefixIndex,
+ "No expression defined within delimiter '" + prefix + suffix
+ + "' at character " + prefixIndex);
+ }
+
+ expressions.add(doParseExpression(expr, context));
+ startIdx = suffixIndex + suffix.length();
+ }
+ else {
// no more ${expressions} found in string, add rest as static text
- expressions.add(createLiteralExpression(context,expressionString.substring(startIdx)));
+ expressions.add(createLiteralExpression(context,
+ expressionString.substring(startIdx)));
startIdx = expressionString.length();
}
}
@@ -147,19 +169,20 @@ public abstract class TemplateAwareExpressionParser implements ExpressionParser
}
/**
- * Return true if the specified suffix can be found at the supplied position in the supplied expression string.
+ * Return true if the specified suffix can be found at the supplied position in the
+ * supplied expression string.
* @param expressionString the expression string which may contain the suffix
* @param pos the start position at which to check for the suffix
* @param suffix the suffix string
*/
- private boolean isSuffixHere(String expressionString,int pos,String suffix) {
+ private boolean isSuffixHere(String expressionString, int pos, String suffix) {
int suffixPosition = 0;
- for (int i=0;i stack = new Stack();
- while (posIt also acts as a place for to define common utility routines that the various Ast nodes might need.
+ *
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
@@ -138,7 +141,8 @@ public class ExpressionState {
}
public Object convertValue(Object value, TypeDescriptor targetTypeDescriptor) throws EvaluationException {
- return this.relatedContext.getTypeConverter().convertValue(value, TypeDescriptor.forObject(value), targetTypeDescriptor);
+ return this.relatedContext.getTypeConverter().convertValue(value,
+ TypeDescriptor.forObject(value), targetTypeDescriptor);
}
public TypeConverter getTypeConverter() {
@@ -147,7 +151,8 @@ public class ExpressionState {
public Object convertValue(TypedValue value, TypeDescriptor targetTypeDescriptor) throws EvaluationException {
Object val = value.getValue();
- return this.relatedContext.getTypeConverter().convertValue(val, TypeDescriptor.forObject(val), targetTypeDescriptor);
+ return this.relatedContext.getTypeConverter().convertValue(val,
+ TypeDescriptor.forObject(val), targetTypeDescriptor);
}
/*
@@ -210,6 +215,7 @@ public class ExpressionState {
return this.configuration;
}
+
/**
* A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names
* of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst
@@ -221,6 +227,7 @@ public class ExpressionState {
public VariableScope() { }
+
public VariableScope(Map arguments) {
if (arguments != null) {
this.vars.putAll(arguments);
@@ -231,6 +238,7 @@ public class ExpressionState {
this.vars.put(name,value);
}
+
public Object lookupVariable(String name) {
return this.vars.get(name);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java
index 7c7a3f6f1c..80a604f690 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelEvaluationException.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.
@@ -18,9 +18,9 @@ package org.springframework.expression.spel;
import org.springframework.expression.EvaluationException;
/**
- * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it
- * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages
- * that can occur.
+ * Root exception for Spring EL related exceptions. Rather than holding a hard coded
+ * string indicating the problem, it records a message key and the inserts for the
+ * message. See {@link SpelMessage} for the list of all possible messages that can occur.
*
* @author Andy Clement
* @since 3.0
@@ -28,8 +28,10 @@ import org.springframework.expression.EvaluationException;
@SuppressWarnings("serial")
public class SpelEvaluationException extends EvaluationException {
- private SpelMessage message;
- private Object[] inserts;
+ private final SpelMessage message;
+
+ private final Object[] inserts;
+
public SpelEvaluationException(SpelMessage message, Object... inserts) {
super(message.formatMessage(0, inserts)); // TODO poor position information, can the callers not really supply something?
@@ -56,15 +58,18 @@ public class SpelEvaluationException extends EvaluationException {
this.inserts = inserts;
}
+
/**
* @return a formatted message with inserts applied
*/
@Override
public String getMessage() {
- if (message != null)
- return message.formatMessage(position, inserts);
- else
+ if (this.message != null) {
+ return this.message.formatMessage(this.position, this.inserts);
+ }
+ else {
return super.getMessage();
+ }
}
/**
@@ -87,7 +92,7 @@ public class SpelEvaluationException extends EvaluationException {
* @return the message inserts
*/
public Object[] getInserts() {
- return inserts;
+ return this.inserts;
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
index c6d95a9413..b61125af33 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
@@ -19,98 +19,249 @@ package org.springframework.expression.spel;
import java.text.MessageFormat;
/**
- * Contains all the messages that can be produced by the Spring Expression Language. Each message has a kind (info,
- * warn, error) and a code number. Tests can be written to expect particular code numbers rather than particular text,
- * enabling the message text to more easily be modified and the tests to run successfully in different locales.
- *
- * When a message is formatted, it will have this kind of form
+ * Contains all the messages that can be produced by the Spring Expression Language. Each
+ * message has a kind (info, warn, error) and a code number. Tests can be written to
+ * expect particular code numbers rather than particular text, enabling the message text
+ * to more easily be modified and the tests to run successfully in different locales.
+ *
+ *
When a message is formatted, it will have this kind of form
*
*
* EL1004E: (pos 34): Type cannot be found 'String'
*
*
- * The prefix captures the code and the error kind, whilst the position is included if it is known.
+ * The prefix captures the code and the error kind, whilst the position is
+ * included if it is known.
*
* @author Andy Clement
* @since 3.0
*/
public enum SpelMessage {
- TYPE_CONVERSION_ERROR(Kind.ERROR, 1001, "Type conversion problem, cannot convert from {0} to {1}"), //
- CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002, "Constructor call: No suitable constructor found on type {0} for arguments {1}"), //
- CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003, "A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"), //
- METHOD_NOT_FOUND(Kind.ERROR, 1004, "Method call: Method {0} cannot be found on {1} type"), //
- TYPE_NOT_FOUND(Kind.ERROR, 1005, "Type cannot be found ''{0}''"), //
- FUNCTION_NOT_DEFINED(Kind.ERROR, 1006, "The function ''{0}'' could not be found"), //
- PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007, "Field or property ''{0}'' cannot be found on null"), //
- PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008, "Field or property ''{0}'' cannot be found on object of type ''{1}''"), //
- PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009, "Field or property ''{0}'' cannot be set on null"), //
- PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010, "Field or property ''{0}'' cannot be set on object of type ''{1}''"), //
- METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011, "Method call: Attempted to call method {0} on null context object"), //
- CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012, "Cannot index into a null value"),
- NOT_COMPARABLE(Kind.ERROR, 1013, "Cannot compare instances of {0} and {1}"), //
- INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014, "Incorrect number of arguments for function, {0} supplied but function takes {1}"), //
- INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015, "Cannot perform selection on input data of type ''{0}''"), //
- RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016, "Result of selection criteria is not boolean"), //
- BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017, "Right operand for the 'between' operator has to be a two-element list"), //
- INVALID_PATTERN(Kind.ERROR, 1018, "Pattern is not valid ''{0}''"), //
- PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019, "Projection is not supported on the type ''{0}''"), //
- ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020, "The argument list of a lambda expression should never have getValue() called upon it"), //
- EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021, "A problem occurred whilst attempting to access the property ''{0}'': ''{1}''"), //
- FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022, "The function ''{0}'' mapped to an object of type ''{1}'' which cannot be invoked"), //
- EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023, "A problem occurred whilst attempting to invoke the function ''{0}'': ''{1}''"), //
- ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024, "The array has ''{0}'' elements, index ''{1}'' is invalid"), //
- COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025, "The collection has ''{0}'' elements, index ''{1}'' is invalid"), //
- STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026, "The string has ''{0}'' characters, index ''{1}'' is invalid"), //
- INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027, "Indexing into type ''{0}'' is not supported"), //
- INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028, "The operator 'instanceof' needs the right operand to be a class, not a ''{0}''"), //
- EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029, "A problem occurred when trying to execute method ''{0}'' on object of type ''{1}'': ''{2}''"), //
- OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030, "The operator ''{0}'' is not supported between objects of type ''{1}'' and ''{2}''"), //
- PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031, "Problem locating method {0} cannot on type {1}"),
- SETVALUE_NOT_SUPPORTED( Kind.ERROR, 1032, "setValue(ExpressionState, Object) not supported for ''{0}''"), //
- MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033, "Method call of ''{0}'' is ambiguous, supported type conversions allow multiple variants to match"), //
- EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034, "A problem occurred whilst attempting to set the property ''{0}'': {1}"), //
- NOT_AN_INTEGER(Kind.ERROR, 1035, "The value ''{0}'' cannot be parsed as an int"), //
- NOT_A_LONG(Kind.ERROR, 1036, "The value ''{0}'' cannot be parsed as a long"), //
- INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037, "First operand to matches operator must be a string. ''{0}'' is not"), //
- INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038, "Second operand to matches operator must be a string. ''{0}'' is not"), //
- FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039, "Only static methods can be called via function references. The method ''{0}'' referred to by name ''{1}'' is not static."),//
- NOT_A_REAL(Kind.ERROR, 1040, "The value ''{0}'' cannot be parsed as a double"), //
- MORE_INPUT(Kind.ERROR,1041, "After parsing a valid expression, there is still more data in the expression: ''{0}''"),
- RIGHT_OPERAND_PROBLEM(Kind.ERROR,1042, "Problem parsing right operand"),
- NOT_EXPECTED_TOKEN(Kind.ERROR,1043,"Unexpected token. Expected ''{0}'' but was ''{1}''"),
- OOD(Kind.ERROR,1044,"Unexpectedly ran out of input"), //
- NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR,1045,"Cannot find terminating \" for string"),//
- NON_TERMINATING_QUOTED_STRING(Kind.ERROR,1046,"Cannot find terminating ' for string"), //
- MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR,1047,"A real number must be prefixed by zero, it cannot start with just ''.''"), //
- REAL_CANNOT_BE_LONG(Kind.ERROR,1048,"Real number cannot be suffixed with a long (L or l) suffix"),//
- UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR,1049,"Unexpected data after ''.'': ''{0}''"),//
- MISSING_CONSTRUCTOR_ARGS(Kind.ERROR,1050,"The arguments '(...)' for the constructor call are missing"),//
- RUN_OUT_OF_ARGUMENTS(Kind.ERROR,1051,"Unexpected ran out of arguments"),//
- UNABLE_TO_GROW_COLLECTION(Kind.ERROR,1052,"Unable to grow collection"),//
- UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR,1053,"Unable to grow collection: unable to determine list element type"),//
- UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR,1054,"Unable to dynamically create a List to replace a null value"),//
- UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR,1055,"Unable to dynamically create a Map to replace a null value"),//
- UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR,1056,"Unable to dynamically create instance of ''{0}'' to replace a null value"),//
- NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR,1057,"No bean resolver registered in the context to resolve access to bean ''{0}''"),//
- EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058, "A problem occurred when trying to resolve bean ''{0}'':''{1}''"), //
- INVALID_BEAN_REFERENCE(Kind.ERROR,1059,"@ can only be followed by an identifier or a quoted name"),//
+ TYPE_CONVERSION_ERROR(Kind.ERROR, 1001,
+ "Type conversion problem, cannot convert from {0} to {1}"),
+
+ CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002,
+ "Constructor call: No suitable constructor found on type {0} for " +
+ "arguments {1}"),
+
+ CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003,
+ "A problem occurred whilst attempting to construct an object of type " +
+ "''{0}'' using arguments ''{1}''"),
+
+ METHOD_NOT_FOUND(Kind.ERROR, 1004,
+ "Method call: Method {0} cannot be found on {1} type"),
+
+ TYPE_NOT_FOUND(Kind.ERROR, 1005,
+ "Type cannot be found ''{0}''"),
+
+ FUNCTION_NOT_DEFINED(Kind.ERROR, 1006,
+ "The function ''{0}'' could not be found"),
+
+ PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007,
+ "Field or property ''{0}'' cannot be found on null"),
+
+ PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008,
+ "Field or property ''{0}'' cannot be found on object of type ''{1}''"),
+
+ PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009,
+ "Field or property ''{0}'' cannot be set on null"),
+
+ PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010,
+ "Field or property ''{0}'' cannot be set on object of type ''{1}''"),
+
+ METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011,
+ "Method call: Attempted to call method {0} on null context object"),
+
+ CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012,
+ "Cannot index into a null value"),
+
+ NOT_COMPARABLE(Kind.ERROR, 1013,
+ "Cannot compare instances of {0} and {1}"),
+
+ INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014,
+ "Incorrect number of arguments for function, {0} supplied but " +
+ "function takes {1}"),
+
+ INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015,
+ "Cannot perform selection on input data of type ''{0}''"),
+
+ RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016,
+ "Result of selection criteria is not boolean"),
+
+ BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017,
+ "Right operand for the 'between' operator has to be a two-element list"),
+
+ INVALID_PATTERN(Kind.ERROR, 1018,
+ "Pattern is not valid ''{0}''"),
+
+ PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019,
+ "Projection is not supported on the type ''{0}''"),
+
+ ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020,
+ "The argument list of a lambda expression should never have getValue() " +
+ "called upon it"),
+
+ EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021,
+ "A problem occurred whilst attempting to access the property " +
+ "''{0}'': ''{1}''"),
+
+ FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022,
+ "The function ''{0}'' mapped to an object of type ''{1}'' which " +
+ "cannot be invoked"),
+
+ EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023,
+ "A problem occurred whilst attempting to invoke the " +
+ "function ''{0}'': ''{1}''"),
+
+ ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024,
+ "The array has ''{0}'' elements, index ''{1}'' is invalid"),
+
+ COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025,
+ "The collection has ''{0}'' elements, index ''{1}'' is invalid"),
+
+ STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026,
+ "The string has ''{0}'' characters, index ''{1}'' is invalid"),
+
+ INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027,
+ "Indexing into type ''{0}'' is not supported"),
+
+ INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028,
+ "The operator 'instanceof' needs the right operand to be a class, " +
+ "not a ''{0}''"),
+
+ EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029,
+ "A problem occurred when trying to execute method ''{0}'' on object " +
+ "of type ''{1}'': ''{2}''"),
+
+ OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030,
+ "The operator ''{0}'' is not supported between objects of type " +
+ "''{1}'' and ''{2}''"),
+
+ PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031,
+ "Problem locating method {0} cannot on type {1}"),
+
+ SETVALUE_NOT_SUPPORTED( Kind.ERROR, 1032,
+ "setValue(ExpressionState, Object) not supported for ''{0}''"),
+
+ MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033,
+ "Method call of ''{0}'' is ambiguous, supported type conversions " +
+ "allow multiple variants to match"),
+
+ EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034,
+ "A problem occurred whilst attempting to set the property ''{0}'': {1}"),
+
+ NOT_AN_INTEGER(Kind.ERROR, 1035,
+ "The value ''{0}'' cannot be parsed as an int"),
+
+ NOT_A_LONG(Kind.ERROR, 1036,
+ "The value ''{0}'' cannot be parsed as a long"),
+
+ INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037,
+ "First operand to matches operator must be a string. ''{0}'' is not"),
+
+ INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038,
+ "Second operand to matches operator must be a string. ''{0}'' is not"),
+
+ FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039,
+ "Only static methods can be called via function references. " +
+ "The method ''{0}'' referred to by name ''{1}'' is not static."),
+
+ NOT_A_REAL(Kind.ERROR, 1040,
+ "The value ''{0}'' cannot be parsed as a double"),
+
+ MORE_INPUT(Kind.ERROR,1041,
+ "After parsing a valid expression, there is still more data in " +
+ "the expression: ''{0}''"),
+
+ RIGHT_OPERAND_PROBLEM(Kind.ERROR, 1042,
+ "Problem parsing right operand"),
+
+ NOT_EXPECTED_TOKEN(Kind.ERROR, 1043,
+ "Unexpected token. Expected ''{0}'' but was ''{1}''"),
+
+ OOD(Kind.ERROR, 1044,
+ "Unexpectedly ran out of input"),
+
+ NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR, 1045,
+ "Cannot find terminating \" for string"),
+
+ NON_TERMINATING_QUOTED_STRING(Kind.ERROR, 1046,
+ "Cannot find terminating ' for string"),
+
+ MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR, 1047,
+ "A real number must be prefixed by zero, it cannot start with just ''.''"),
+
+ REAL_CANNOT_BE_LONG(Kind.ERROR, 1048,
+ "Real number cannot be suffixed with a long (L or l) suffix"),
+
+ UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR, 1049,
+ "Unexpected data after ''.'': ''{0}''"),
+
+ MISSING_CONSTRUCTOR_ARGS(Kind.ERROR, 1050,
+ "The arguments '(...)' for the constructor call are missing"),
+
+ RUN_OUT_OF_ARGUMENTS(Kind.ERROR, 1051,
+ "Unexpected ran out of arguments"),
+
+ UNABLE_TO_GROW_COLLECTION(Kind.ERROR, 1052,
+ "Unable to grow collection"),
+
+ UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR, 1053,
+ "Unable to grow collection: unable to determine list element type"),
+
+ UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR, 1054,
+ "Unable to dynamically create a List to replace a null value"),
+
+ UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR, 1055,
+ "Unable to dynamically create a Map to replace a null value"),
+
+ UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR, 1056,
+ "Unable to dynamically create instance of ''{0}'' to replace a null value"),
+
+ NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR, 1057,
+ "No bean resolver registered in the context to resolve access to bean ''{0}''"),
+
+ EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058,
+ "A problem occurred when trying to resolve bean ''{0}'':''{1}''"),
+
+ INVALID_BEAN_REFERENCE(Kind.ERROR, 1059,
+ "@ can only be followed by an identifier or a quoted name"),
+
TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION(Kind.ERROR, 1060,
- "Expected the type of the new array to be specified as a String but found ''{0}''"), //
+ "Expected the type of the new array to be specified as a String but found ''{0}''"),
+
INCORRECT_ELEMENT_TYPE_FOR_ARRAY(Kind.ERROR, 1061,
- "The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"), //
+ "The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"),
+
MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED(Kind.ERROR, 1062,
- "Using an initializer to build a multi-dimensional array is not currently supported"), //
- MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063, "A required array dimension has not been specified"), //
- INITIALIZER_LENGTH_INCORRECT(
- Kind.ERROR, 1064, "array initializer size does not match array dimensions"), //
- UNEXPECTED_ESCAPE_CHAR(Kind.ERROR,1065,"unexpected escape character."), //
- OPERAND_NOT_INCREMENTABLE(Kind.ERROR,1066,"the expression component ''{0}'' does not support increment"), //
- OPERAND_NOT_DECREMENTABLE(Kind.ERROR,1067,"the expression component ''{0}'' does not support decrement"), //
- NOT_ASSIGNABLE(Kind.ERROR,1068,"the expression component ''{0}'' is not assignable"), //
- MISSING_CHARACTER(Kind.ERROR,1069,"missing expected character ''{0}''"),
- LEFT_OPERAND_PROBLEM(Kind.ERROR,1070, "Problem parsing left operand"),
- MISSING_SELECTION_EXPRESSION(Kind.ERROR, 1071, "A required selection expression has not been specified");
+ "Using an initializer to build a multi-dimensional array is not currently supported"),
+
+ MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063,
+ "A required array dimension has not been specified"),
+
+ INITIALIZER_LENGTH_INCORRECT(Kind.ERROR, 1064,
+ "array initializer size does not match array dimensions"),
+
+ UNEXPECTED_ESCAPE_CHAR(Kind.ERROR, 1065, "unexpected escape character."),
+
+ OPERAND_NOT_INCREMENTABLE(Kind.ERROR, 1066,
+ "the expression component ''{0}'' does not support increment"),
+
+ OPERAND_NOT_DECREMENTABLE(Kind.ERROR, 1067,
+ "the expression component ''{0}'' does not support decrement"),
+
+ NOT_ASSIGNABLE(Kind.ERROR, 1068,
+ "the expression component ''{0}'' is not assignable"),
+
+ MISSING_CHARACTER(Kind.ERROR, 1069,
+ "missing expected character ''{0}''"),
+
+ LEFT_OPERAND_PROBLEM(Kind.ERROR, 1070,
+ "Problem parsing left operand"),
+
+ MISSING_SELECTION_EXPRESSION(Kind.ERROR, 1071,
+ "A required selection expression has not been specified");
private Kind kind;
private int code;
@@ -134,23 +285,17 @@ public enum SpelMessage {
*/
public String formatMessage(int pos, Object... inserts) {
StringBuilder formattedMessage = new StringBuilder();
- formattedMessage.append("EL").append(code);
- switch (kind) {
-// case WARNING:
-// formattedMessage.append("W");
-// break;
-// case INFO:
-// formattedMessage.append("I");
-// break;
- case ERROR:
- formattedMessage.append("E");
- break;
+ formattedMessage.append("EL").append(this.code);
+ switch (this.kind) {
+ case ERROR:
+ formattedMessage.append("E");
+ break;
}
formattedMessage.append(":");
if (pos != -1) {
formattedMessage.append("(pos ").append(pos).append("): ");
}
- formattedMessage.append(MessageFormat.format(message, inserts));
+ formattedMessage.append(MessageFormat.format(this.message, inserts));
return formattedMessage.toString();
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelNode.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelNode.java
index 6e2ba93f3f..0699445702 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelNode.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelNode.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.
@@ -28,14 +28,16 @@ import org.springframework.expression.TypedValue;
public interface SpelNode {
/**
- * Evaluate the expression node in the context of the supplied expression state and return the value.
+ * Evaluate the expression node in the context of the supplied expression state and
+ * return the value.
* @param expressionState the current expression state (includes the context)
* @return the value of this node evaluated against the specified state
*/
Object getValue(ExpressionState expressionState) throws EvaluationException;
/**
- * Evaluate the expression node in the context of the supplied expression state and return the typed value.
+ * Evaluate the expression node in the context of the supplied expression state and
+ * return the typed value.
* @param expressionState the current expression state (includes the context)
* @return the type value of this node evaluated against the specified state
*/
@@ -51,11 +53,13 @@ public interface SpelNode {
boolean isWritable(ExpressionState expressionState) throws EvaluationException;
/**
- * Evaluate the expression to a node and then set the new value on that node. For example, if the expression
- * evaluates to a property reference then the property will be set to the new value.
+ * Evaluate the expression to a node and then set the new value on that node. For
+ * example, if the expression evaluates to a property reference then the property will
+ * be set to the new value.
* @param expressionState the current expression state (includes the context)
* @param newValue the new value
- * @throws EvaluationException if any problem occurs evaluating the expression or setting the new value
+ * @throws EvaluationException if any problem occurs evaluating the expression or
+ * setting the new value
*/
void setValue(ExpressionState expressionState, Object newValue) throws EvaluationException;
@@ -78,7 +82,8 @@ public interface SpelNode {
/**
* Determine the class of the object passed in, unless it is already a class object.
* @param obj the object that the caller wants the class of
- * @return the class of the object if it is not already a class object, or null if the object is null
+ * @return the class of the object if it is not already a class object, or null if the
+ * object is null
*/
Class> getObjectClass(Object obj);
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelParseException.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelParseException.java
index 1935b3ba61..2a623ddccc 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelParseException.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelParseException.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.
@@ -19,24 +19,20 @@ import org.springframework.expression.ParseException;
/**
- * Root exception for Spring EL related exceptions. Rather than holding a hard coded string indicating the problem, it
- * records a message key and the inserts for the message. See {@link SpelMessage} for the list of all possible messages
- * that can occur.
- *
+ * Root exception for Spring EL related exceptions. Rather than holding a hard coded
+ * string indicating the problem, it records a message key and the inserts for the
+ * message. See {@link SpelMessage} for the list of all possible messages that can occur.
+ *
* @author Andy Clement
* @since 3.0
*/
@SuppressWarnings("serial")
public class SpelParseException extends ParseException {
- private SpelMessage message;
- private Object[] inserts;
+ private final SpelMessage message;
+
+ private final Object[] inserts;
-// public SpelParseException(String expressionString, int position, Throwable cause, SpelMessages message, Object... inserts) {
-// super(expressionString, position, message.formatMessage(position,inserts), cause);
-// this.message = message;
-// this.inserts = inserts;
-// }
public SpelParseException(String expressionString, int position, SpelMessage message, Object... inserts) {
super(expressionString, position, message.formatMessage(position,inserts));
@@ -59,36 +55,14 @@ public class SpelParseException extends ParseException {
this.inserts = inserts;
}
-//
-// public SpelException(Throwable cause, SpelMessages message, Object... inserts) {
-// super(cause);
-// this.message = message;
-// this.inserts = inserts;
-// }
-//
-// public SpelException(int position, SpelMessages message, Object... inserts) {
-// super((Throwable)null);
-// this.position = position;
-// this.message = message;
-// this.inserts = inserts;
-// }
-//
-// public SpelException(SpelMessages message, Object... inserts) {
-// super((Throwable)null);
-// this.message = message;
-// this.inserts = inserts;
-// }
-
/**
* @return a formatted message with inserts applied
*/
@Override
public String getMessage() {
- if (message != null)
- return message.formatMessage(position, inserts);
- else
- return super.getMessage();
+ return (this.message != null ? this.message.formatMessage(this.position, this.inserts)
+ : super.getMessage());
}
/**
@@ -102,7 +76,7 @@ public class SpelParseException extends ParseException {
* @return the message inserts
*/
public Object[] getInserts() {
- return inserts;
+ return this.inserts;
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java
index ccadb93061..20932fa9b2 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelParserConfiguration.java
@@ -30,7 +30,7 @@ public class SpelParserConfiguration {
private final boolean autoGrowCollections;
- private int maximumAutoGrowSize;
+ private final int maximumAutoGrowSize;
/**
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java
index c472ed6393..7d2c045121 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Assign.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.
@@ -21,7 +21,8 @@ import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
/**
- * Represents assignment. An alternative to calling setValue() for an expression is to use an assign.
+ * Represents assignment. An alternative to calling setValue() for an expression is to use
+ * an assign.
*
*
Example: 'someNumberProperty=42'
*
@@ -30,21 +31,23 @@ import org.springframework.expression.spel.ExpressionState;
*/
public class Assign extends SpelNodeImpl {
+
public Assign(int pos,SpelNodeImpl... operands) {
super(pos,operands);
}
+
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- TypedValue newValue = children[1].getValueInternal(state);
+ TypedValue newValue = this.children[1].getValueInternal(state);
getChild(0).setValue(state, newValue.getValue());
return newValue;
}
@Override
public String toStringAST() {
- return new StringBuilder().append(getChild(0).toStringAST()).append("=").append(getChild(1).toStringAST())
- .toString();
+ return new StringBuilder().append(getChild(0).toStringAST()).append("=").append(
+ getChild(1).toStringAST()).toString();
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java
index 92eb3036fa..98cccc4985 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/AstUtils.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.
@@ -30,13 +30,15 @@ import org.springframework.expression.PropertyAccessor;
public class AstUtils {
/**
- * Determines the set of property resolvers that should be used to try and access a property on the specified target
- * type. The resolvers are considered to be in an ordered list, however in the returned list any that are exact
- * matches for the input target type (as opposed to 'general' resolvers that could work for any type) are placed at
- * the start of the list. In addition, there are specific resolvers that exactly name the class in question and
- * resolvers that name a specific class but it is a supertype of the class we have. These are put at the end of the
- * specific resolvers set and will be tried after exactly matching accessors but before generic accessors.
- *
+ * Determines the set of property resolvers that should be used to try and access a
+ * property on the specified target type. The resolvers are considered to be in an
+ * ordered list, however in the returned list any that are exact matches for the input
+ * target type (as opposed to 'general' resolvers that could work for any type) are
+ * placed at the start of the list. In addition, there are specific resolvers that
+ * exactly name the class in question and resolvers that name a specific class but it
+ * is a supertype of the class we have. These are put at the end of the specific
+ * resolvers set and will be tried after exactly matching accessors but before generic
+ * accessors.
* @param targetType the type upon which property access is being attempted
* @return a list of resolvers that should be tried in order to access the property
*/
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java
index 35636fe806..b0be644e1f 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.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.
@@ -31,25 +31,31 @@ import org.springframework.expression.spel.SpelMessage;
*/
public class BeanReference extends SpelNodeImpl {
- private String beanname;
+ private final String beanname;
+
public BeanReference(int pos,String beanname) {
super(pos);
this.beanname = beanname;
}
+
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
BeanResolver beanResolver = state.getEvaluationContext().getBeanResolver();
if (beanResolver==null) {
- throw new SpelEvaluationException(getStartPosition(),SpelMessage.NO_BEAN_RESOLVER_REGISTERED, beanname);
+ throw new SpelEvaluationException(getStartPosition(),
+ SpelMessage.NO_BEAN_RESOLVER_REGISTERED, this.beanname);
}
+
try {
- TypedValue bean = new TypedValue(beanResolver.resolve(state.getEvaluationContext(),beanname));
+ TypedValue bean = new TypedValue(beanResolver.resolve(
+ state.getEvaluationContext(), this.beanname));
return bean;
- } catch (AccessException ae) {
+ }
+ catch (AccessException ae) {
throw new SpelEvaluationException( getStartPosition(), ae, SpelMessage.EXCEPTION_DURING_BEAN_RESOLUTION,
- beanname, ae.getMessage());
+ this.beanname, ae.getMessage());
}
}
@@ -57,10 +63,11 @@ public class BeanReference extends SpelNodeImpl {
public String toStringAST() {
StringBuilder sb = new StringBuilder();
sb.append("@");
- if (beanname.indexOf('.')==-1) {
- sb.append(beanname);
- } else {
- sb.append("'").append(beanname).append("'");
+ if (this.beanname.indexOf('.') == -1) {
+ sb.append(this.beanname);
+ }
+ else {
+ sb.append("'").append(this.beanname).append("'");
}
return sb.toString();
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BooleanLiteral.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BooleanLiteral.java
index 84878ee131..5aa748c8c0 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BooleanLiteral.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BooleanLiteral.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.
@@ -27,11 +27,13 @@ public class BooleanLiteral extends Literal {
private final BooleanTypedValue value;
+
public BooleanLiteral(String payload, int pos, boolean value) {
super(payload, pos);
this.value = BooleanTypedValue.forValue(value);
}
+
@Override
public BooleanTypedValue getLiteralValue() {
return this.value;
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java
index b632adec5e..688670c142 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.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.
@@ -39,32 +39,35 @@ public class CompoundExpression extends SpelNodeImpl {
@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
- if (getChildCount()==1) {
- return children[0].getValueRef(state);
+ if (getChildCount() == 1) {
+ return this.children[0].getValueRef(state);
}
TypedValue result = null;
SpelNodeImpl nextNode = null;
try {
- nextNode = children[0];
+ nextNode = this.children[0];
result = nextNode.getValueInternal(state);
int cc = getChildCount();
- for (int i = 1; i < cc-1; i++) {
+ for (int i = 1; i < cc - 1; i++) {
try {
state.pushActiveContextObject(result);
- nextNode = children[i];
+ nextNode = this.children[i];
result = nextNode.getValueInternal(state);
- } finally {
+ }
+ finally {
state.popActiveContextObject();
}
}
try {
state.pushActiveContextObject(result);
- nextNode = children[cc-1];
+ nextNode = this.children[cc-1];
return nextNode.getValueRef(state);
- } finally {
+ }
+ finally {
state.popActiveContextObject();
}
- } catch (SpelEvaluationException ee) {
+ }
+ catch (SpelEvaluationException ee) {
// Correct the position for the error before re-throwing
ee.setPosition(nextNode.getStartPosition());
throw ee;
@@ -96,7 +99,9 @@ public class CompoundExpression extends SpelNodeImpl {
public String toStringAST() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < getChildCount(); i++) {
- if (i>0) { sb.append("."); }
+ if (i > 0) {
+ sb.append(".");
+ }
sb.append(getChild(i).toStringAST());
}
return sb.toString();
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
index c6a25931fb..a16cc55788 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.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.
@@ -132,7 +132,8 @@ public class ConstructorReference extends SpelNodeImpl {
Throwable rootCause = ae.getCause().getCause();
if (rootCause instanceof RuntimeException) {
throw (RuntimeException) rootCause;
- } else {
+ }
+ else {
String typename = (String) this.children[0].getValueInternal(state).getValue();
throw new SpelEvaluationException(getStartPosition(), rootCause,
SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typename, FormatHelper
@@ -153,9 +154,9 @@ public class ConstructorReference extends SpelNodeImpl {
return executorToUse.execute(state.getEvaluationContext(), arguments);
}
catch (AccessException ae) {
- throw new SpelEvaluationException(getStartPosition(), ae, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM,
- typename, FormatHelper.formatMethodForMessage("", argumentTypes));
-
+ throw new SpelEvaluationException(getStartPosition(), ae,
+ SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typename,
+ FormatHelper.formatMethodForMessage("", argumentTypes));
}
}
@@ -168,8 +169,9 @@ public class ConstructorReference extends SpelNodeImpl {
* @return a reusable ConstructorExecutor that can be invoked to run the constructor or null
* @throws SpelEvaluationException if there is a problem locating the constructor
*/
- private ConstructorExecutor findExecutorForConstructor(String typename, List argumentTypes,
- ExpressionState state) throws SpelEvaluationException {
+ private ConstructorExecutor findExecutorForConstructor(String typename,
+ List argumentTypes, ExpressionState state)
+ throws SpelEvaluationException {
EvaluationContext eContext = state.getEvaluationContext();
List cResolvers = eContext.getConstructorResolvers();
@@ -202,8 +204,9 @@ public class ConstructorReference extends SpelNodeImpl {
sb.append(getChild(index++).toStringAST());
sb.append("(");
for (int i = index; i < getChildCount(); i++) {
- if (i > index)
+ if (i > index) {
sb.append(",");
+ }
sb.append(getChild(i).toStringAST());
}
sb.append(")");
@@ -221,8 +224,8 @@ public class ConstructorReference extends SpelNodeImpl {
Object intendedArrayType = getChild(0).getValue(state);
if (!(intendedArrayType instanceof String)) {
throw new SpelEvaluationException(getChild(0).getStartPosition(),
- SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, FormatHelper
- .formatClassNameForMessage(intendedArrayType.getClass()));
+ SpelMessage.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION,
+ FormatHelper.formatClassNameForMessage(intendedArrayType.getClass()));
}
String type = (String) intendedArrayType;
Class> componentType;
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Elvis.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Elvis.java
index b37548a5a2..7c44d0635c 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Elvis.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Elvis.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.
@@ -21,8 +21,8 @@ import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
/**
- * Represents the elvis operator ?:. For an expression "a?:b" if a is not null, the value of the expression
- * is "a", if a is null then the value of the expression is "b".
+ * Represents the elvis operator ?:. For an expression "a?:b" if a is not null, the value
+ * of the expression is "a", if a is null then the value of the expression is "b".
*
* @author Andy Clement
* @since 3.0
@@ -33,25 +33,30 @@ public class Elvis extends SpelNodeImpl {
super(pos,args);
}
+
/**
- * Evaluate the condition and if not null, return it. If it is null return the other value.
+ * Evaluate the condition and if not null, return it. If it is null return the other
+ * value.
* @param state the expression state
- * @throws EvaluationException if the condition does not evaluate correctly to a boolean or there is a problem
- * executing the chosen alternative
+ * @throws EvaluationException if the condition does not evaluate correctly to a
+ * boolean or there is a problem executing the chosen alternative
*/
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- TypedValue value = children[0].getValueInternal(state);
- if (value.getValue()!=null && !((value.getValue() instanceof String) && ((String)value.getValue()).length()==0)) {
+ TypedValue value = this.children[0].getValueInternal(state);
+ if ((value.getValue() != null) && !((value.getValue() instanceof String) &&
+ ((String) value.getValue()).length() == 0)) {
return value;
- } else {
- return children[1].getValueInternal(state);
+ }
+ else {
+ return this.children[1].getValueInternal(state);
}
}
@Override
public String toStringAST() {
- return new StringBuilder().append(getChild(0).toStringAST()).append(" ?: ").append(getChild(1).toStringAST()).toString();
+ return new StringBuilder().append(getChild(0).toStringAST()).append(" ?: ").append(
+ getChild(1).toStringAST()).toString();
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FloatLiteral.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FloatLiteral.java
index c63ee9a8ce..6d7be2b481 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FloatLiteral.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FloatLiteral.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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.expression.spel.ast;
import org.springframework.expression.TypedValue;
@@ -24,6 +25,7 @@ import org.springframework.expression.TypedValue;
* @since 3.2
*/
public class FloatLiteral extends Literal {
+
private final TypedValue value;
FloatLiteral(String payload, int pos, float value) {
@@ -31,6 +33,7 @@ public class FloatLiteral extends Literal {
this.value = new TypedValue(value);
}
+
@Override
public TypedValue getLiteralValue() {
return this.value;
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java
index 1d3b853e29..8719f49526 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.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.
@@ -75,7 +75,8 @@ public class FormatHelper {
for (int i = 0; i < dims; i++) {
fmtd.append("[]");
}
- } else {
+ }
+ else {
fmtd.append(clazz.getName());
}
return fmtd.toString();
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
index db69a05945..642c4497ee 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.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.
@@ -31,14 +31,15 @@ import org.springframework.expression.spel.support.ReflectionHelper;
import org.springframework.util.ReflectionUtils;
/**
- * A function reference is of the form "#someFunction(a,b,c)". Functions may be defined in the context prior to the
- * expression being evaluated or within the expression itself using a lambda function definition. For example: Lambda
- * function definition in an expression: "(#max = {|x,y|$x>$y?$x:$y};max(2,3))" Calling context defined function:
- * "#isEven(37)". Functions may also be static java methods, registered in the context prior to invocation of the
- * expression.
+ * A function reference is of the form "#someFunction(a,b,c)". Functions may be defined in
+ * the context prior to the expression being evaluated or within the expression itself
+ * using a lambda function definition. For example: Lambda function definition in an
+ * expression: "(#max = {|x,y|$x>$y?$x:$y};max(2,3))" Calling context defined function:
+ * "#isEven(37)". Functions may also be static java methods, registered in the context
+ * prior to invocation of the expression.
*
- *
Functions are very simplistic, the arguments are not part of the definition (right now),
- * so the names must be unique.
+ *
Functions are very simplistic, the arguments are not part of the definition (right
+ * now), so the names must be unique.
*
* @author Andy Clement
* @since 3.0
@@ -47,21 +48,23 @@ public class FunctionReference extends SpelNodeImpl {
private final String name;
+
public FunctionReference(String functionName, int pos, SpelNodeImpl... arguments) {
super(pos,arguments);
- name = functionName;
+ this.name = functionName;
}
+
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- TypedValue o = state.lookupVariable(name);
+ TypedValue o = state.lookupVariable(this.name);
if (o == null) {
- throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_NOT_DEFINED, name);
+ throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_NOT_DEFINED, this.name);
}
// Two possibilities: a lambda function or a Java static method registered as a function
if (!(o.getValue() instanceof Method)) {
- throw new SpelEvaluationException(SpelMessage.FUNCTION_REFERENCE_CANNOT_BE_INVOKED, name, o.getClass());
+ throw new SpelEvaluationException(SpelMessage.FUNCTION_REFERENCE_CANNOT_BE_INVOKED, this.name, o.getClass());
}
try {
return executeFunctionJLRMethod(state, (Method) o.getValue());
@@ -89,9 +92,9 @@ public class FunctionReference extends SpelNodeImpl {
}
// Only static methods can be called in this way
if (!Modifier.isStatic(method.getModifiers())) {
- throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_MUST_BE_STATIC, method
- .getDeclaringClass().getName()
- + "." + method.getName(), name);
+ throw new SpelEvaluationException(getStartPosition(),
+ SpelMessage.FUNCTION_MUST_BE_STATIC,
+ method.getDeclaringClass().getName() + "." + method.getName(), this.name);
}
// Convert arguments if necessary and remap them for varargs if required
@@ -100,7 +103,8 @@ public class FunctionReference extends SpelNodeImpl {
ReflectionHelper.convertAllArguments(converter, functionArgs, method);
}
if (method.isVarArgs()) {
- functionArgs = ReflectionHelper.setupArgumentsForVarargsInvocation(method.getParameterTypes(), functionArgs);
+ functionArgs = ReflectionHelper.setupArgumentsForVarargsInvocation(
+ method.getParameterTypes(), functionArgs);
}
try {
@@ -116,11 +120,12 @@ public class FunctionReference extends SpelNodeImpl {
@Override
public String toStringAST() {
- StringBuilder sb = new StringBuilder("#").append(name);
+ StringBuilder sb = new StringBuilder("#").append(this.name);
sb.append("(");
for (int i = 0; i < getChildCount(); i++) {
- if (i > 0)
+ if (i > 0) {
sb.append(",");
+ }
sb.append(getChild(i).toStringAST());
}
sb.append(")");
@@ -137,7 +142,7 @@ public class FunctionReference extends SpelNodeImpl {
// Compute arguments to the function
Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) {
- arguments[i] = children[i].getValueInternal(state).getValue();
+ arguments[i] = this.children[i].getValueInternal(state).getValue();
}
return arguments;
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Identifier.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Identifier.java
index e174535301..d258fbb993 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Identifier.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Identifier.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.
@@ -27,14 +27,16 @@ public class Identifier extends SpelNodeImpl {
private final TypedValue id;
+
public Identifier(String payload,int pos) {
super(pos);
this.id = new TypedValue(payload);
}
+
@Override
public String toStringAST() {
- return (String)this.id.getValue();
+ return (String) this.id.getValue();
}
@Override
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
index 4f919beec2..82e7db4259 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
@@ -33,9 +33,8 @@ import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.ReflectivePropertyAccessor;
/**
- * An Indexer can index into some proceeding structure to access a particular
- * piece of it. Supported structures are: strings/collections
- * (lists/sets)/arrays
+ * An Indexer can index into some proceeding structure to access a particular piece of it.
+ * Supported structures are: strings/collections (lists/sets)/arrays
*
* @author Andy Clement
* @author Phillip Webb
@@ -95,26 +94,28 @@ public class Indexer extends SpelNodeImpl {
private final Object array;
- private final int idx;
+ private final int index;
private final TypeDescriptor typeDescriptor;
- ArrayIndexingValueRef(TypeConverter typeConverter, Object array, int idx, TypeDescriptor typeDescriptor) {
+
+ ArrayIndexingValueRef(TypeConverter typeConverter, Object array, int index, TypeDescriptor typeDescriptor) {
this.typeConverter = typeConverter;
this.array = array;
- this.idx = idx;
+ this.index = index;
this.typeDescriptor = typeDescriptor;
}
+
@Override
public TypedValue getValue() {
- Object arrayElement = accessArrayElement(this.array, this.idx);
+ Object arrayElement = accessArrayElement(this.array, this.index);
return new TypedValue(arrayElement, this.typeDescriptor.elementTypeDescriptor(arrayElement));
}
@Override
public void setValue(Object newValue) {
- setArrayElement(this.typeConverter, this.array, this.idx, newValue,
+ setArrayElement(this.typeConverter, this.array, this.index, newValue,
this.typeDescriptor.getElementTypeDescriptor().getType());
}
@@ -136,17 +137,21 @@ public class Indexer extends SpelNodeImpl {
private final TypeDescriptor mapEntryTypeDescriptor;
- MapIndexingValueRef(TypeConverter typeConverter, Map map, Object key, TypeDescriptor mapEntryTypeDescriptor) {
+
+ MapIndexingValueRef(TypeConverter typeConverter, Map map, Object key,
+ TypeDescriptor mapEntryTypeDescriptor) {
this.typeConverter = typeConverter;
this.map = map;
this.key = key;
this.mapEntryTypeDescriptor = mapEntryTypeDescriptor;
}
+
@Override
public TypedValue getValue() {
Object value = this.map.get(this.key);
- return new TypedValue(value, this.mapEntryTypeDescriptor.getMapValueTypeDescriptor(value));
+ return new TypedValue(value,
+ this.mapEntryTypeDescriptor.getMapValueTypeDescriptor(value));
}
@Override
@@ -171,71 +176,75 @@ public class Indexer extends SpelNodeImpl {
private final String name;
- private final EvaluationContext eContext;
+ private final EvaluationContext evaluationContext;
+
+ private final TypeDescriptor targetObjectTypeDescriptor;
- private final TypeDescriptor td;
public PropertyIndexingValueRef(Object targetObject, String value, EvaluationContext evaluationContext,
TypeDescriptor targetObjectTypeDescriptor) {
this.targetObject = targetObject;
this.name = value;
- this.eContext = evaluationContext;
- this.td = targetObjectTypeDescriptor;
+ this.evaluationContext = evaluationContext;
+ this.targetObjectTypeDescriptor = targetObjectTypeDescriptor;
}
+
@Override
public TypedValue getValue() {
- Class> targetObjectRuntimeClass = getObjectClass(targetObject);
+ Class> targetObjectRuntimeClass = getObjectClass(this.targetObject);
try {
- if (cachedReadName != null && cachedReadName.equals(name) && cachedReadTargetType != null &&
- cachedReadTargetType.equals(targetObjectRuntimeClass)) {
+ if (Indexer.this.cachedReadName != null && Indexer.this.cachedReadName.equals(this.name) && Indexer.this.cachedReadTargetType != null &&
+ Indexer.this.cachedReadTargetType.equals(targetObjectRuntimeClass)) {
// it is OK to use the cached accessor
- return cachedReadAccessor.read(this.eContext, this.targetObject, this.name);
+ return Indexer.this.cachedReadAccessor.read(this.evaluationContext, this.targetObject, this.name);
}
- List accessorsToTry =
- AstUtils.getPropertyAccessorsToTry(targetObjectRuntimeClass, eContext.getPropertyAccessors());
+
+ List accessorsToTry = AstUtils.getPropertyAccessorsToTry(
+ targetObjectRuntimeClass, this.evaluationContext.getPropertyAccessors());
+
if (accessorsToTry != null) {
for (PropertyAccessor accessor : accessorsToTry) {
- if (accessor.canRead(this.eContext, this.targetObject, this.name)) {
+ if (accessor.canRead(this.evaluationContext, this.targetObject, this.name)) {
if (accessor instanceof ReflectivePropertyAccessor) {
accessor = ((ReflectivePropertyAccessor) accessor).createOptimalAccessor(
- this.eContext, this.targetObject, this.name);
+ this.evaluationContext, this.targetObject, this.name);
}
- cachedReadAccessor = accessor;
- cachedReadName = this.name;
- cachedReadTargetType = targetObjectRuntimeClass;
- return accessor.read(this.eContext, this.targetObject, this.name);
+ Indexer.this.cachedReadAccessor = accessor;
+ Indexer.this.cachedReadName = this.name;
+ Indexer.this.cachedReadTargetType = targetObjectRuntimeClass;
+ return accessor.read(this.evaluationContext, this.targetObject, this.name);
}
}
}
}
catch (AccessException ex) {
throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE,
- this.td.toString());
+ this.targetObjectTypeDescriptor.toString());
}
throw new SpelEvaluationException(getStartPosition(), SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE,
- this.td.toString());
+ this.targetObjectTypeDescriptor.toString());
}
@Override
public void setValue(Object newValue) {
- Class> contextObjectClass = getObjectClass(targetObject);
+ Class> contextObjectClass = getObjectClass(this.targetObject);
try {
- if (cachedWriteName != null && cachedWriteName.equals(name) && cachedWriteTargetType != null &&
- cachedWriteTargetType.equals(contextObjectClass)) {
+ if (Indexer.this.cachedWriteName != null && Indexer.this.cachedWriteName.equals(this.name) && Indexer.this.cachedWriteTargetType != null &&
+ Indexer.this.cachedWriteTargetType.equals(contextObjectClass)) {
// it is OK to use the cached accessor
- cachedWriteAccessor.write(this.eContext, this.targetObject, this.name, newValue);
+ Indexer.this.cachedWriteAccessor.write(this.evaluationContext, this.targetObject, this.name, newValue);
return;
}
List accessorsToTry =
- AstUtils.getPropertyAccessorsToTry(contextObjectClass, this.eContext.getPropertyAccessors());
+ AstUtils.getPropertyAccessorsToTry(contextObjectClass, this.evaluationContext.getPropertyAccessors());
if (accessorsToTry != null) {
for (PropertyAccessor accessor : accessorsToTry) {
- if (accessor.canWrite(this.eContext, this.targetObject, this.name)) {
- cachedWriteName = this.name;
- cachedWriteTargetType = contextObjectClass;
- cachedWriteAccessor = accessor;
- accessor.write(this.eContext, this.targetObject, this.name, newValue);
+ if (accessor.canWrite(this.evaluationContext, this.targetObject, this.name)) {
+ Indexer.this.cachedWriteName = this.name;
+ Indexer.this.cachedWriteTargetType = contextObjectClass;
+ Indexer.this.cachedWriteAccessor = accessor;
+ accessor.write(this.evaluationContext, this.targetObject, this.name, newValue);
return;
}
}
@@ -267,7 +276,8 @@ public class Indexer extends SpelNodeImpl {
private final boolean growCollection;
- private int maximumSize;
+ private final int maximumSize;
+
CollectionIndexingValueRef(Collection collection, int index, TypeDescriptor collectionEntryTypeDescriptor,
TypeConverter typeConverter, boolean growCollection, int maximumSize) {
@@ -279,6 +289,7 @@ public class Indexer extends SpelNodeImpl {
this.maximumSize = maximumSize;
}
+
@Override
public TypedValue getValue() {
growCollectionIfNecessary();
@@ -356,19 +367,21 @@ public class Indexer extends SpelNodeImpl {
private final int index;
- private final TypeDescriptor td;
+ private final TypeDescriptor typeDescriptor;
- public StringIndexingLValue(String target, int index, TypeDescriptor td) {
+
+ public StringIndexingLValue(String target, int index, TypeDescriptor typeDescriptor) {
this.target = target;
this.index = index;
- this.td = td;
+ this.typeDescriptor = typeDescriptor;
}
+
@Override
public TypedValue getValue() {
if (this.index >= this.target.length()) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.STRING_INDEX_OUT_OF_BOUNDS,
- this.target.length(), index);
+ this.target.length(), this.index);
}
return new TypedValue(String.valueOf(this.target.charAt(this.index)));
}
@@ -376,7 +389,7 @@ public class Indexer extends SpelNodeImpl {
@Override
public void setValue(Object newValue) {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE,
- this.td.toString());
+ this.typeDescriptor.toString());
}
@Override
@@ -387,6 +400,7 @@ public class Indexer extends SpelNodeImpl {
@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
+
TypedValue context = state.getActiveContextObject();
Object targetObject = context.getValue();
TypeDescriptor targetObjectTypeDescriptor = context.getTypeDescriptor();
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java
index 1839d203c4..cae9002f40 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineList.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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.expression.spel.ast;
import java.util.ArrayList;
@@ -35,11 +36,13 @@ public class InlineList extends SpelNodeImpl {
// if the list is purely literals, it is a constant value and can be computed and cached
TypedValue constant = null; // TODO must be immutable list
+
public InlineList(int pos, SpelNodeImpl... args) {
super(pos, args);
checkIfConstant();
}
+
/**
* If all the components of the list are constants, or lists that themselves contain constants, then a constant list
* can be built to represent this node. This will speed up later getValue calls and reduce the amount of garbage
@@ -55,7 +58,8 @@ public class InlineList extends SpelNodeImpl {
if (!inlineList.isConstant()) {
isConstant = false;
}
- } else {
+ }
+ else {
isConstant = false;
}
}
@@ -67,7 +71,8 @@ public class InlineList extends SpelNodeImpl {
SpelNode child = getChild(c);
if ((child instanceof Literal)) {
constantList.add(((Literal) child).getLiteralValue().getValue());
- } else if (child instanceof InlineList) {
+ }
+ else if (child instanceof InlineList) {
constantList.add(((InlineList) child).getConstantValue());
}
}
@@ -77,9 +82,10 @@ public class InlineList extends SpelNodeImpl {
@Override
public TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException {
- if (constant != null) {
- return constant;
- } else {
+ if (this.constant != null) {
+ return this.constant;
+ }
+ else {
List