提交 5ff40084 编写于 作者: A Andy Clement

Refactored package structure and made some getValue() methods generic

上级 4c88488c
......@@ -12,8 +12,14 @@
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>structure101.java.eclipse.plugin.JDMEclipseBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>structure101.java.eclipse.plugin.JDMEclipseNature</nature>
</natures>
</projectDescription>
......@@ -41,7 +41,7 @@ public interface Expression {
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
public Object getValue(Class<?> desiredResultType) throws EvaluationException;
public <T> T getValue(Class<T> desiredResultType) throws EvaluationException;
/**
* Evaluate this expression in the provided context and return the result of evaluation.
......@@ -62,7 +62,7 @@ public interface Expression {
* @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation
*/
public Object getValue(EvaluationContext context, Class<?> desiredResultType) throws EvaluationException;
public <T> T getValue(EvaluationContext context, Class<T> desiredResultType) throws EvaluationException;
/**
* Set this expression in the provided context to the value provided.
......
......@@ -62,14 +62,14 @@ public class CompositeStringExpression implements Expression {
throw new EvaluationException(expressionString, "Cannot call setValue() on a composite expression");
}
public Object getValue(EvaluationContext context, Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convert(context, value, expectedResultType);
return (T)ExpressionUtils.convert(context, value, expectedResultType);
}
public Object getValue(Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object value = getValue();
return ExpressionUtils.convert(null, value, expectedResultType);
return (T)ExpressionUtils.convert(null, value, expectedResultType);
}
public boolean isWritable(EvaluationContext context) throws EvaluationException {
......
......@@ -44,14 +44,14 @@ public class LiteralExpression implements Expression {
throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression");
}
public Object getValue(EvaluationContext context, Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Object value = getValue(context);
return ExpressionUtils.convert(context, value, expectedResultType);
return (T)ExpressionUtils.convert(context, value, expectedResultType);
}
public Object getValue(Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object value = getValue();
return ExpressionUtils.convert(null, value, expectedResultType);
return (T)ExpressionUtils.convert(null, value, expectedResultType);
}
public boolean isWritable(EvaluationContext context) throws EvaluationException {
......
......@@ -15,6 +15,7 @@
*/
package org.springframework.expression.spel;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
......@@ -27,7 +28,6 @@ import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypeComparator;
import org.springframework.expression.TypeConverter;
import org.springframework.expression.TypeUtils;
import org.springframework.expression.spel.internal.VariableScope;
/**
* An ExpressionState is for maintaining per-expression-evaluation state, any changes to it are not seen by other
......@@ -199,4 +199,42 @@ public class ExpressionState {
return relatedContext;
}
/**
* 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
* the function is executing. When the function returns the scope is exited.
*
* @author Andy Clement
*
*/
static class VariableScope {
private final Map<String, Object> vars = new HashMap<String, Object>();
public VariableScope() { }
public VariableScope(Map<String, Object> arguments) {
if (arguments!=null) {
vars.putAll(arguments);
}
}
public VariableScope(String name,Object value) {
vars.put(name,value);
}
public Object lookupVariable(String name) {
return vars.get(name);
}
public void setVariable(String name, Object value) {
vars.put(name,value);
}
public boolean definesVariable(String name) {
return vars.containsKey(name);
}
}
}
......@@ -19,8 +19,6 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.common.ExpressionUtils;
import org.springframework.expression.spel.ast.SpelNode;
import org.springframework.expression.spel.standard.StandardEvaluationContext;
/**
* A SpelExpressions represents a parsed (valid) expression that is ready to be evaluated in a specified context. An
......@@ -31,6 +29,7 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
*
*/
public class SpelExpression implements Expression {
private final String expression;
public final SpelNode ast;
......@@ -40,7 +39,7 @@ public class SpelExpression implements Expression {
* @param expression
* @param ast
*/
SpelExpression(String expression, SpelNode ast) {
public SpelExpression(String expression, SpelNode ast) {
this.expression = expression;
this.ast = ast;
}
......@@ -56,8 +55,7 @@ public class SpelExpression implements Expression {
* {@inheritDoc}
*/
public Object getValue() throws EvaluationException {
EvaluationContext eContext = new StandardEvaluationContext();
return ast.getValue(new ExpressionState(eContext));
return ast.getValue(null);
}
/**
......@@ -70,18 +68,17 @@ public class SpelExpression implements Expression {
/**
* {@inheritDoc}
*/
public Object getValue(EvaluationContext context, Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(EvaluationContext context, Class<T> expectedResultType) throws EvaluationException {
Object result = ast.getValue(new ExpressionState(context));
if (result != null && expectedResultType != null) {
Class<?> resultType = result.getClass();
if (expectedResultType.isAssignableFrom(resultType)) {
return result;
if (!expectedResultType.isAssignableFrom(resultType)) {
// Attempt conversion to the requested type, may throw an exception
result = context.getTypeUtils().getTypeConverter().convertValue(result, expectedResultType);
}
// Attempt conversion to the requested type, may throw an exception
return context.getTypeUtils().getTypeConverter().convertValue(result, expectedResultType);
}
return result;
return (T)result;
}
/**
......@@ -145,9 +142,10 @@ public class SpelExpression implements Expression {
/**
* {@inheritDoc}
*/
public Object getValue(Class<?> expectedResultType) throws EvaluationException {
public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object result = getValue();
return ExpressionUtils.convert(null, result, expectedResultType);
// TODO propagate generic-ness into convert
return (T)ExpressionUtils.convert(null, result, expectedResultType);
}
}
......@@ -15,21 +15,12 @@
*/
package org.springframework.expression.spel;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.springframework.expression.Expression;
import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;
import org.springframework.expression.common.DefaultNonTemplateParserContext;
import org.springframework.expression.common.TemplateAwareExpressionParser;
import org.springframework.expression.spel.ast.SpelNode;
import org.springframework.expression.spel.generated.SpringExpressionsLexer;
import org.springframework.expression.spel.generated.SpringExpressionsParser.expr_return;
import org.springframework.expression.spel.internal.InternalELException;
import org.springframework.expression.spel.internal.SpelTreeAdaptor;
import org.springframework.expression.spel.internal.SpringExpressionsLexerExtender;
import org.springframework.expression.spel.internal.SpringExpressionsParserExtender;
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
/**
* Instances of this parser class can process Spring Expression Language format expressions. The result of parsing an
......@@ -40,17 +31,11 @@ import org.springframework.expression.spel.internal.SpringExpressionsParserExten
*/
public class SpelExpressionParser extends TemplateAwareExpressionParser {
private final SpringExpressionsLexer lexer;
private final SpringExpressionsParserExtender parser;
private final SpelInternalParser expressionParser;
/**
* Should be constructed through the SpelParserFactory
*/
public SpelExpressionParser() {
lexer = new SpringExpressionsLexerExtender();
CommonTokenStream tokens = new CommonTokenStream(lexer);
parser = new SpringExpressionsParserExtender(tokens);
parser.setTreeAdaptor(new SpelTreeAdaptor());
// Use an Antlr based expression parser
expressionParser = new SpelAntlrExpressionParser();
}
/**
......@@ -63,22 +48,7 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
*/
@Override
protected Expression doParseExpression(String expressionString, ParserContext context) throws ParseException {
try {
lexer.setCharStream(new ANTLRStringStream(expressionString));
CommonTokenStream tokens = new CommonTokenStream(lexer);
parser.setTokenStream(tokens);
expr_return exprReturn = parser.expr();
SpelExpression newExpression = new SpelExpression(expressionString, (SpelNode) exprReturn.getTree());
return newExpression;
} catch (RecognitionException re) {
ParseException exception = new ParseException(expressionString, "Recognition error at position: "
+ re.charPositionInLine + ": " + re.getMessage(), re);
throw exception;
} catch (InternalELException e) {
SpelException wrappedException = e.getCause();
throw new ParseException(expressionString, "Parsing problem: " + wrappedException.getMessage(),
wrappedException);
}
return expressionParser.doParseExpression(expressionString,context);
}
/**
......@@ -88,4 +58,8 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
public SpelExpression parseExpression(String expressionString) throws ParseException {
return (SpelExpression) super.parseExpression(expressionString, DefaultNonTemplateParserContext.INSTANCE);
}
public interface SpelInternalParser {
Expression doParseExpression(String expressionString, ParserContext context) throws ParseException;
}
}
\ No newline at end of file
......@@ -17,8 +17,6 @@ package org.springframework.expression.spel;
import java.io.PrintStream;
import org.springframework.expression.spel.ast.SpelNode;
/**
* Utilities for working with Spring Expressions.
*
......@@ -45,10 +43,9 @@ public class SpelUtilities {
private static void printAST(PrintStream out, SpelNode t, String indent) {
if (t != null) {
StringBuilder sb = new StringBuilder();
String s = (t.getType() == -1 ? "EOF" : t.getClass().getSimpleName());
sb.append(indent).append(s);
sb.append(" value=").append(t.getText());
sb.append(t.getChildCount() < 2 ? "" : " children=#" + t.getChildCount());
sb.append(indent).append(t.getClass().getSimpleName());
sb.append(" value:").append(t.toStringAST());
sb.append(t.getChildCount() < 2 ? "" : " #children:" + t.getChildCount());
out.println(sb.toString());
for (int i = 0; i < t.getChildCount(); i++) {
printAST(out, t.getChild(i), indent + " ");
......
......@@ -28,15 +28,15 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class Assign extends SpelNode {
public class Assign extends SpelNodeImpl {
public Assign(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object newValue = getChild(1).getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object newValue = getChild(1).getValueInternal(state);
getChild(0).setValue(state, newValue);
return newValue;
}
......
......@@ -26,7 +26,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class CompoundExpression extends SpelNode {
public class CompoundExpression extends SpelNodeImpl {
public CompoundExpression(Token payload) {
super(payload);
......@@ -40,17 +40,17 @@ public class CompoundExpression extends SpelNode {
* @return the final value from the last piece of the compound expression
*/
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object result = null;
SpelNode nextNode = null;
SpelNodeImpl nextNode = null;
try {
nextNode = getChild(0);
result = nextNode.getValue(state);
result = nextNode.getValueInternal(state);
for (int i = 1; i < getChildCount(); i++) {
try {
state.pushActiveContextObject(result);
nextNode = getChild(i);
result = nextNode.getValue(state);
result = nextNode.getValueInternal(state);
} finally {
state.popActiveContextObject();
}
......@@ -69,11 +69,11 @@ public class CompoundExpression extends SpelNode {
getChild(0).setValue(state, value);
return;
}
Object ctx = getChild(0).getValue(state);
Object ctx = getChild(0).getValueInternal(state);
for (int i = 1; i < getChildCount() - 1; i++) {
try {
state.pushActiveContextObject(ctx);
ctx = getChild(i).getValue(state);
ctx = getChild(i).getValueInternal(state);
} finally {
state.popActiveContextObject();
}
......@@ -91,11 +91,11 @@ public class CompoundExpression extends SpelNode {
if (getChildCount() == 1) {
return getChild(0).isWritable(state);
}
Object ctx = getChild(0).getValue(state);
Object ctx = getChild(0).getValueInternal(state);
for (int i = 1; i < getChildCount() - 1; i++) {
try {
state.pushActiveContextObject(ctx);
ctx = getChild(i).getValue(state);
ctx = getChild(i).getValueInternal(state);
} finally {
state.popActiveContextObject();
}
......
......@@ -42,7 +42,7 @@ import org.springframework.expression.spel.internal.Utils;
* @author Andy Clement
*
*/
public class ConstructorReference extends SpelNode {
public class ConstructorReference extends SpelNodeImpl {
/**
* The resolver/executor model {@link ConstructorResolver} supports the caching of executor objects that can run
......@@ -71,7 +71,7 @@ public class ConstructorReference extends SpelNode {
* Implements getValue() - delegating to the code for building an array or a simple type.
*/
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
if (isArrayConstructor) {
return createArray(state);
} else {
......@@ -99,7 +99,7 @@ public class ConstructorReference extends SpelNode {
// Next child is EXPRESSIONLIST token with children that are the
// expressions giving array size
sb.append("[");
SpelNode arrayRank = getChild(index++);
SpelNodeImpl arrayRank = getChild(index++);
for (int i = 0; i < arrayRank.getChildCount(); i++) {
if (i > 0)
sb.append(",");
......@@ -126,7 +126,7 @@ public class ConstructorReference extends SpelNode {
* @throws EvaluationException if there is a problem creating the array
*/
private Object createArray(ExpressionState state) throws EvaluationException {
Object intendedArrayType = getChild(0).getValue(state);
Object intendedArrayType = getChild(0).getValueInternal(state);
if (!(intendedArrayType instanceof String)) {
throw new SpelException(getChild(0).getCharPositionInLine(),
SpelMessages.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, Utils
......@@ -155,7 +155,7 @@ public class ConstructorReference extends SpelNode {
// Array ranks are specified but is it a single or multiple dimension array?
int dimensions = getChild(1).getChildCount();
if (dimensions == 1) {
Object o = getChild(1).getValue(state);
Object o = getChild(1).getValueInternal(state);
int arraySize = state.toInteger(o);
if (getChildCount() == 3) {
// Check initializer length matches array size length
......@@ -170,7 +170,7 @@ public class ConstructorReference extends SpelNode {
// Multi-dimensional - hold onto your hat !
int[] dims = new int[dimensions];
for (int d = 0; d < dimensions; d++) {
dims[d] = state.toInteger(getChild(1).getChild(d).getValue(state));
dims[d] = state.toInteger(getChild(1).getChild(d).getValueInternal(state));
}
newArray = Array.newInstance(componentType, dims);
// TODO check any specified initializer for the multidim array matches
......@@ -179,12 +179,12 @@ public class ConstructorReference extends SpelNode {
// Populate the array using the initializer if one is specified
if (getChildCount() == 3) {
SpelNode initializer = getChild(2);
SpelNodeImpl initializer = getChild(2);
if (arrayTypeCode == TypeCode.OBJECT) {
Object[] newObjectArray = (Object[]) newArray;
for (int i = 0; i < newObjectArray.length; i++) {
SpelNode elementNode = initializer.getChild(i);
Object arrayEntry = elementNode.getValue(state);
SpelNodeImpl elementNode = initializer.getChild(i);
Object arrayEntry = elementNode.getValueInternal(state);
if (!componentType.isAssignableFrom(arrayEntry.getClass())) {
throw new SpelException(elementNode.getCharPositionInLine(),
SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, componentType.getName(), arrayEntry
......@@ -195,42 +195,42 @@ public class ConstructorReference extends SpelNode {
} else if (arrayTypeCode == TypeCode.INT) {
int[] newIntArray = (int[]) newArray;
for (int i = 0; i < newIntArray.length; i++) {
newIntArray[i] = state.toInteger(initializer.getChild(i).getValue(state));
newIntArray[i] = state.toInteger(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.BOOLEAN) {
boolean[] newBooleanArray = (boolean[]) newArray;
for (int i = 0; i < newBooleanArray.length; i++) {
newBooleanArray[i] = state.toBoolean(initializer.getChild(i).getValue(state));
newBooleanArray[i] = state.toBoolean(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.CHAR) {
char[] newCharArray = (char[]) newArray;
for (int i = 0; i < newCharArray.length; i++) {
newCharArray[i] = state.toCharacter(initializer.getChild(i).getValue(state));
newCharArray[i] = state.toCharacter(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.SHORT) {
short[] newShortArray = (short[]) newArray;
for (int i = 0; i < newShortArray.length; i++) {
newShortArray[i] = state.toShort(initializer.getChild(i).getValue(state));
newShortArray[i] = state.toShort(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.LONG) {
long[] newLongArray = (long[]) newArray;
for (int i = 0; i < newLongArray.length; i++) {
newLongArray[i] = state.toLong(initializer.getChild(i).getValue(state));
newLongArray[i] = state.toLong(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.FLOAT) {
float[] newFloatArray = (float[]) newArray;
for (int i = 0; i < newFloatArray.length; i++) {
newFloatArray[i] = state.toFloat(initializer.getChild(i).getValue(state));
newFloatArray[i] = state.toFloat(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.DOUBLE) {
double[] newDoubleArray = (double[]) newArray;
for (int i = 0; i < newDoubleArray.length; i++) {
newDoubleArray[i] = state.toDouble(initializer.getChild(i).getValue(state));
newDoubleArray[i] = state.toDouble(initializer.getChild(i).getValueInternal(state));
}
} else if (arrayTypeCode == TypeCode.BYTE) {
byte[] newByteArray = (byte[]) newArray;
for (int i = 0; i < newByteArray.length; i++) {
newByteArray[i] = state.toByte(initializer.getChild(i).getValue(state));
newByteArray[i] = state.toByte(initializer.getChild(i).getValueInternal(state));
}
}
}
......@@ -249,7 +249,7 @@ public class ConstructorReference extends SpelNode {
Object[] arguments = new Object[getChildCount() - 1];
Class<?>[] argumentTypes = new Class[getChildCount() - 1];
for (int i = 0; i < arguments.length; i++) {
Object childValue = getChild(i + 1).getValue(state);
Object childValue = getChild(i + 1).getValueInternal(state);
arguments[i] = childValue;
argumentTypes[i] = childValue.getClass();
}
......@@ -264,7 +264,7 @@ public class ConstructorReference extends SpelNode {
}
// either there was no accessor or it no longer exists
String typename = (String) getChild(0).getValue(state);
String typename = (String) getChild(0).getValueInternal(state);
cachedExecutor = findExecutorForConstructor(typename, argumentTypes, state);
try {
return cachedExecutor.execute(state.getEvaluationContext(), arguments);
......
......@@ -25,7 +25,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class Dot extends SpelNode {
public class Dot extends SpelNodeImpl {
// TODO Keep Dot for the positional information or remove it?
public Dot(Token payload) {
......@@ -38,7 +38,7 @@ public class Dot extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws SpelException {
public Object getValueInternal(ExpressionState state) throws SpelException {
// This makes Dot a do-nothing operation, but this is not free in terms of computation
return state.getActiveContextObject();
}
......
......@@ -39,7 +39,7 @@ import org.springframework.expression.spel.reflection.ReflectionUtils;
*
* @author Andy Clement
*/
public class FunctionReference extends SpelNode {
public class FunctionReference extends SpelNodeImpl {
private final String name;
......@@ -49,7 +49,7 @@ public class FunctionReference extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object o = state.lookupVariable(name);
if (o == null) {
throw new SpelException(SpelMessages.FUNCTION_NOT_DEFINED, name);
......@@ -139,7 +139,7 @@ public class FunctionReference extends SpelNode {
// Compute arguments to the function
Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = getChild(i).getValue(state);
arguments[i] = getChild(i).getValueInternal(state);
}
return arguments;
}
......
......@@ -19,7 +19,7 @@ import org.antlr.runtime.Token;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
public class Identifier extends SpelNode {
public class Identifier extends SpelNodeImpl {
private final String id;
......@@ -34,7 +34,7 @@ public class Identifier extends SpelNode {
}
@Override
public String getValue(ExpressionState state) throws SpelException {
public String getValueInternal(ExpressionState state) throws SpelException {
return id;
}
......
......@@ -32,16 +32,16 @@ import org.springframework.expression.spel.SpelMessages;
*
* @author Andy Clement
*/
public class Indexer extends SpelNode {
public class Indexer extends SpelNodeImpl {
public Indexer(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object ctx = state.getActiveContextObject();
Object index = getChild(0).getValue(state);
Object index = getChild(0).getValueInternal(state);
// Indexing into a Map
if (ctx instanceof Map) {
......
......@@ -19,7 +19,7 @@ import org.antlr.runtime.Token;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.internal.InternalELException;
import org.springframework.expression.spel.WrappedELException;
/**
* Common superclass for nodes representing literals (boolean, string, number, etc).
......@@ -27,7 +27,7 @@ import org.springframework.expression.spel.internal.InternalELException;
* @author Andy Clement
*
*/
public abstract class Literal extends SpelNode {
public abstract class Literal extends SpelNodeImpl {
public Literal(Token payload) {
super(payload);
......@@ -36,7 +36,7 @@ public abstract class Literal extends SpelNode {
public abstract Object getLiteralValue();
@Override
public final Object getValue(ExpressionState state) throws SpelException {
public final Object getValueInternal(ExpressionState state) throws SpelException {
return getLiteralValue();
}
......@@ -84,7 +84,7 @@ public abstract class Literal extends SpelNode {
long value = Long.parseLong(numberString, radix);
return new LongLiteral(numberToken, value);
} catch (NumberFormatException nfe) {
throw new InternalELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
throw new WrappedELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
SpelMessages.NOT_A_LONG, numberToken.getText()));
}
} else {
......@@ -92,7 +92,7 @@ public abstract class Literal extends SpelNode {
int value = Integer.parseInt(numberString, radix);
return new IntLiteral(numberToken, value);
} catch (NumberFormatException nfe) {
throw new InternalELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
throw new WrappedELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
SpelMessages.NOT_AN_INTEGER, numberToken.getText()));
}
}
......
......@@ -28,7 +28,7 @@ import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.internal.Utils;
public class MethodReference extends SpelNode {
public class MethodReference extends SpelNodeImpl {
private final String name;
private MethodExecutor fastInvocationAccessor;
......@@ -39,11 +39,11 @@ public class MethodReference extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object currentContext = state.getActiveContextObject();
Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = getChild(i).getValue(state);
arguments[i] = getChild(i).getValueInternal(state);
}
if (currentContext == null) {
throw new SpelException(getCharPositionInLine(), SpelMessages.ATTEMPTED_METHOD_CALL_ON_NULL_CONTEXT_OBJECT,
......
......@@ -25,7 +25,7 @@ import org.springframework.expression.spel.ExpressionState;
*
* @author Andy Clement
*/
public abstract class Operator extends SpelNode {
public abstract class Operator extends SpelNodeImpl {
public Operator(Token payload) {
super(payload);
......@@ -39,11 +39,11 @@ public abstract class Operator extends SpelNode {
return false;
}
public SpelNode getLeftOperand() {
public SpelNodeImpl getLeftOperand() {
return getChild(0);
}
public SpelNode getRightOperand() {
public SpelNodeImpl getRightOperand() {
return getChild(1);
}
......
......@@ -37,12 +37,12 @@ public class OperatorAnd extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
boolean leftValue;
boolean rightValue;
try {
leftValue = state.toBoolean(getLeftOperand().getValue(state));
leftValue = state.toBoolean(getLeftOperand().getValueInternal(state));
} catch (SpelException ee) {
ee.setPosition(getLeftOperand().getCharPositionInLine());
throw ee;
......@@ -53,7 +53,7 @@ public class OperatorAnd extends Operator {
}
try {
rightValue = state.toBoolean(getRightOperand().getValue(state));
rightValue = state.toBoolean(getRightOperand().getValueInternal(state));
} catch (SpelException ee) {
ee.setPosition(getRightOperand().getCharPositionInLine());
throw ee;
......
......@@ -51,9 +51,9 @@ public class OperatorBetween extends Operator {
* @throws EvaluationException if there is a problem evaluating the expression
*/
@Override
public Boolean getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (!(right instanceof List) || ((List<?>) right).size() != 2) {
throw new SpelException(getRightOperand().getCharPositionInLine(),
SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST);
......
......@@ -37,9 +37,9 @@ public class OperatorDivide extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state);
Object operandTwo = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
......
......@@ -36,9 +36,9 @@ public class OperatorEquality extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -36,9 +36,9 @@ public class OperatorGreaterThan extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -36,9 +36,9 @@ public class OperatorGreaterThanOrEqual extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -36,9 +36,9 @@ public class OperatorInequality extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -47,9 +47,9 @@ public class OperatorInstanceof extends Operator {
* @throws EvaluationException if there is a problem evaluating the expression
*/
@Override
public Boolean getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left == null) {
return false; // null is not an instanceof anything
}
......
......@@ -36,9 +36,9 @@ public class OperatorLessThan extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -31,9 +31,9 @@ public class OperatorLessThanOrEqual extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -50,11 +50,11 @@ public class OperatorMatches extends Operator {
* @throws EvaluationException if there is a problem evaluating the expression (e.g. the regex is invalid)
*/
@Override
public Boolean getValue(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand();
public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
SpelNodeImpl leftOp = getLeftOperand();
SpelNodeImpl rightOp = getRightOperand();
Object left = leftOp.getValue(state, String.class);
Object right = getRightOperand().getValue(state);
Object right = getRightOperand().getValueInternal(state);
try {
if (!(left instanceof String)) {
throw new SpelException(leftOp.getCharPositionInLine(),
......
......@@ -18,9 +18,9 @@ package org.springframework.expression.spel.ast;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.ExpressionState;
/**
* Implements the minus operator. If there is only one operand it is a unary minus.
......@@ -47,11 +47,11 @@ public class OperatorMinus extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand();
public Object getValueInternal(ExpressionState state) throws EvaluationException {
SpelNodeImpl leftOp = getLeftOperand();
SpelNodeImpl rightOp = getRightOperand();
if (rightOp == null) {// If only one operand, then this is unary minus
Object left = leftOp.getValue(state);
Object left = leftOp.getValueInternal(state);
if (left instanceof Number) {
Number n = (Number) left;
if (left instanceof Double) {
......@@ -70,8 +70,8 @@ public class OperatorMinus extends Operator {
}
throw new SpelException(SpelMessages.CANNOT_NEGATE_TYPE, left.getClass().getName());
} else {
Object left = leftOp.getValue(state);
Object right = rightOp.getValue(state);
Object left = leftOp.getValueInternal(state);
Object right = rightOp.getValueInternal(state);
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
......
......@@ -37,9 +37,9 @@ public class OperatorModulus extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state);
Object operandTwo = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
......
......@@ -48,9 +48,9 @@ public class OperatorMultiply extends Operator {
* </ul>
*/
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state);
Object operandTwo = getRightOperand().getValue(state);
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
......
......@@ -20,16 +20,16 @@ import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
public class OperatorNot extends SpelNode { // Not is a unary operator so do not extend BinaryOperator
public class OperatorNot extends SpelNodeImpl { // Not is a unary operator so do not extend BinaryOperator
public OperatorNot(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
try {
boolean value = state.toBoolean(getChild(0).getValue(state));
boolean value = state.toBoolean(getChild(0).getValueInternal(state));
return !value;
} catch (SpelException see) {
see.setPosition(getChild(0).getCharPositionInLine());
......
......@@ -37,11 +37,11 @@ public class OperatorOr extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
boolean leftValue;
boolean rightValue;
try {
leftValue = state.toBoolean(getLeftOperand().getValue(state));
leftValue = state.toBoolean(getLeftOperand().getValueInternal(state));
} catch (SpelException see) {
see.setPosition(getLeftOperand().getCharPositionInLine());
throw see;
......@@ -51,7 +51,7 @@ public class OperatorOr extends Operator {
return true; // no need to evaluate right operand
try {
rightValue = state.toBoolean(getRightOperand().getValue(state));
rightValue = state.toBoolean(getRightOperand().getValueInternal(state));
} catch (SpelException see) {
see.setPosition(getRightOperand().getCharPositionInLine());
throw see;
......
......@@ -27,18 +27,18 @@ public class OperatorPlus extends Operator {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand();
public Object getValueInternal(ExpressionState state) throws EvaluationException {
SpelNodeImpl leftOp = getLeftOperand();
SpelNodeImpl rightOp = getRightOperand();
if (rightOp == null) { // If only one operand, then this is unary plus
Object operandOne = leftOp.getValue(state);
Object operandOne = leftOp.getValueInternal(state);
if (operandOne instanceof Number) {
return new Integer(((Number) operandOne).intValue());
}
return state.operate(Operation.ADD, operandOne, null);
} else {
Object operandOne = leftOp.getValue(state);
Object operandTwo = rightOp.getValue(state);
Object operandOne = leftOp.getValueInternal(state);
Object operandTwo = rightOp.getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
......
......@@ -27,14 +27,14 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class Placeholder extends SpelNode {
public class Placeholder extends SpelNodeImpl {
public Placeholder(Token payload) {
super(payload);
}
@Override
public String getValue(ExpressionState state) throws SpelException {
public String getValueInternal(ExpressionState state) throws SpelException {
throw new SpelException(getCharPositionInLine(), SpelMessages.PLACEHOLDER_SHOULD_NEVER_BE_EVALUATED);
}
......
......@@ -35,14 +35,14 @@ import org.springframework.expression.spel.internal.KeyValuePair;
* @author Andy Clement
*
*/
public class Projection extends SpelNode {
public class Projection extends SpelNodeImpl {
public Projection(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operand = state.getActiveContextObject();
// When the input is a map, we push a special context object on the stack
......@@ -56,7 +56,7 @@ public class Projection extends SpelNode {
for (Object k : mapdata.keySet()) {
try {
state.pushActiveContextObject(new KeyValuePair(k, mapdata.get(k)));
result.add(getChild(0).getValue(state));
result.add(getChild(0).getValueInternal(state));
} finally {
state.popActiveContextObject();
}
......@@ -71,7 +71,7 @@ public class Projection extends SpelNode {
try {
state.pushActiveContextObject(element);
state.enterScope("index", idx);
result.add(getChild(0).getValue(state));
result.add(getChild(0).getValueInternal(state));
} finally {
state.exitScope();
state.popActiveContextObject();
......
......@@ -35,7 +35,7 @@ import org.springframework.expression.spel.internal.Utils;
*
* @author Andy Clement
*/
public class PropertyOrFieldReference extends SpelNode {
public class PropertyOrFieldReference extends SpelNodeImpl {
public static boolean useCaching = true;
......@@ -49,7 +49,7 @@ public class PropertyOrFieldReference extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws SpelException {
public Object getValueInternal(ExpressionState state) throws SpelException {
return readProperty(state, name);
}
......
......@@ -27,7 +27,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class QualifiedIdentifier extends SpelNode {
public class QualifiedIdentifier extends SpelNodeImpl {
private String value;
......@@ -37,14 +37,14 @@ public class QualifiedIdentifier extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
// Cache the concatenation of child identifiers
if (value == null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < getChildCount(); i++) {
if (i > 0)
sb.append(".");
sb.append(getChild(i).getValue(state));
sb.append(getChild(i).getValueInternal(state));
}
value = sb.toString();
}
......
......@@ -36,7 +36,7 @@ import org.springframework.expression.spel.internal.KeyValuePair;
*
* @author Andy Clement
*/
public class Selection extends SpelNode {
public class Selection extends SpelNodeImpl {
public final static int ALL = 0; // ?{}
public final static int FIRST = 1; // ^{}
......@@ -50,9 +50,9 @@ public class Selection extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operand = state.getActiveContextObject();
SpelNode selectionCriteria = getChild(0);
SpelNodeImpl selectionCriteria = getChild(0);
if (operand instanceof Map) {
Map<?, ?> mapdata = (Map<?, ?>) operand;
List<Object> result = new ArrayList<Object>();
......@@ -60,7 +60,7 @@ public class Selection extends SpelNode {
try {
Object kvpair = new KeyValuePair(k, mapdata.get(k));
state.pushActiveContextObject(kvpair);
Object o = selectionCriteria.getValue(state);
Object o = selectionCriteria.getValueInternal(state);
if (o instanceof Boolean) {
if (((Boolean) o).booleanValue() == true) {
if (variant == FIRST)
......@@ -91,7 +91,7 @@ public class Selection extends SpelNode {
try {
state.pushActiveContextObject(element);
state.enterScope("index", idx);
Object o = selectionCriteria.getValue(state);
Object o = selectionCriteria.getValueInternal(state);
if (o instanceof Boolean) {
if (((Boolean) o).booleanValue() == true) {
if (variant == FIRST)
......
......@@ -25,7 +25,7 @@ import org.springframework.expression.spel.SpelException;
*
* @author Andy Clement
*/
public class Ternary extends SpelNode {
public class Ternary extends SpelNodeImpl {
public Ternary(Token payload) {
super(payload);
......@@ -39,13 +39,13 @@ public class Ternary extends SpelNode {
* executing the chosen alternative
*/
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
Boolean b = (Boolean) getChild(0).getValue(state, Boolean.class);
try {
if (b) {
return getChild(1).getValue(state);
return getChild(1).getValueInternal(state);
} else {
return getChild(2).getValue(state);
return getChild(2).getValueInternal(state);
}
} catch (SpelException ex) {
ex.setPosition(getChild(0).getCharPositionInLine());
......
......@@ -27,16 +27,16 @@ import org.springframework.expression.spel.internal.TypeCode;
* @author Andy Clement
*
*/
public class TypeReference extends SpelNode {
public class TypeReference extends SpelNodeImpl {
public TypeReference(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
public Object getValueInternal(ExpressionState state) throws EvaluationException {
// TODO possible optimization here if we cache the discovered type reference, but can we do that?
String typename = (String) getChild(0).getValue(state);
String typename = (String) getChild(0).getValueInternal(state);
if (typename.indexOf(".") == -1 && Character.isLowerCase(typename.charAt(0))) {
TypeCode tc = TypeCode.forName(typename);
if (tc != TypeCode.OBJECT) {
......
......@@ -26,7 +26,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement
*
*/
public class VariableReference extends SpelNode {
public class VariableReference extends SpelNodeImpl {
// Well known variables:
private final static String THIS = "this"; // currently active context object
......@@ -40,7 +40,7 @@ public class VariableReference extends SpelNode {
}
@Override
public Object getValue(ExpressionState state) throws SpelException {
public Object getValueInternal(ExpressionState state) throws SpelException {
if (name.equals(THIS))
return state.getActiveContextObject();
if (name.equals(ROOT))
......
// $ANTLR 3.0.1 /Users/aclement/el2/spring-framework/trunk/org.springframework.expression/src/main/java/org/springframework/expression/spel/generated/SpringExpressions.g 2008-09-16 19:06:07
package org.springframework.expression.spel.generated;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Stack;
import org.antlr.runtime.tree.*;
import org.antlr.runtime.BitSet;
import org.antlr.runtime.EarlyExitException;
import org.antlr.runtime.MismatchedSetException;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.Parser;
import org.antlr.runtime.ParserRuleReturnScope;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTreeAdaptor;
import org.antlr.runtime.tree.RewriteRuleSubtreeStream;
import org.antlr.runtime.tree.RewriteRuleTokenStream;
import org.antlr.runtime.tree.TreeAdaptor;
public class SpringExpressionsParser extends Parser {
public static final String[] tokenNames = new String[] {
......
......@@ -24,6 +24,8 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
*/
public class ConstructorInvocationTests extends ExpressionTestCase {
// Some tests commented out as language support has been removed for now
// public void testPrimitiveTypeArrayConstructors() {
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
// evaluate("new boolean[]{true,false,true}.count()", 3, Integer.class);
......@@ -46,11 +48,6 @@ public class ConstructorInvocationTests extends ExpressionTestCase {
// evaluate("new byte[]{1,2,3,4}[0]", (byte) 1, Byte.class);
// }
public void testTypeConstructors() {
evaluate("new String('hello world')", "hello world", String.class);
// evaluate("new String(new char[]{'h','e','l','l','o'})", "hello", String.class);
}
// public void testErrorCases() {
// evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
// evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
......@@ -75,6 +72,11 @@ public class ConstructorInvocationTests extends ExpressionTestCase {
// new String[3][4].getClass());
// }
public void testTypeConstructors() {
evaluate("new String('hello world')", "hello world", String.class);
// evaluate("new String(new char[]{'h','e','l','l','o'})", "hello", String.class);
}
/*
* These tests are attempting to call constructors where we need to widen or convert the argument in order to
* satisfy a suitable constructor.
......
......@@ -18,6 +18,8 @@ package org.springframework.expression.spel;
/**
* Tests the evaluation of real expressions in a real context.
*
* Node: Some tests commented out as language support has been removed
*
* @author Andy Clement
*/
public class EvaluationTests extends ExpressionTestCase {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册