Refactored package structure and made some getValue() methods generic

This commit is contained in:
Andy Clement 2008-12-12 23:07:08 +00:00
parent 4c88488c5a
commit 5ff4008423
46 changed files with 237 additions and 212 deletions

View File

@ -12,8 +12,14 @@
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand>
<name>structure101.java.eclipse.plugin.JDMEclipseBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
<nature>structure101.java.eclipse.plugin.JDMEclipseNature</nature>
</natures> </natures>
</projectDescription> </projectDescription>

View File

@ -41,7 +41,7 @@ public interface Expression {
* @return the evaluation result * @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation * @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. * Evaluate this expression in the provided context and return the result of evaluation.
@ -62,7 +62,7 @@ public interface Expression {
* @return the evaluation result * @return the evaluation result
* @throws EvaluationException if there is a problem during evaluation * @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. * Set this expression in the provided context to the value provided.

View File

@ -62,14 +62,14 @@ public class CompositeStringExpression implements Expression {
throw new EvaluationException(expressionString, "Cannot call setValue() on a composite 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); 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(); Object value = getValue();
return ExpressionUtils.convert(null, value, expectedResultType); return (T)ExpressionUtils.convert(null, value, expectedResultType);
} }
public boolean isWritable(EvaluationContext context) throws EvaluationException { public boolean isWritable(EvaluationContext context) throws EvaluationException {

View File

@ -44,14 +44,14 @@ public class LiteralExpression implements Expression {
throw new EvaluationException(literalValue, "Cannot call setValue() on a LiteralExpression"); 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); 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(); Object value = getValue();
return ExpressionUtils.convert(null, value, expectedResultType); return (T)ExpressionUtils.convert(null, value, expectedResultType);
} }
public boolean isWritable(EvaluationContext context) throws EvaluationException { public boolean isWritable(EvaluationContext context) throws EvaluationException {

View File

@ -15,6 +15,7 @@
*/ */
package org.springframework.expression.spel; package org.springframework.expression.spel;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
@ -27,7 +28,6 @@ import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypeComparator; import org.springframework.expression.TypeComparator;
import org.springframework.expression.TypeConverter; import org.springframework.expression.TypeConverter;
import org.springframework.expression.TypeUtils; 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 * 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; 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);
}
}
} }

View File

@ -19,8 +19,6 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException; import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.common.ExpressionUtils; 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 * 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 { public class SpelExpression implements Expression {
private final String expression; private final String expression;
public final SpelNode ast; public final SpelNode ast;
@ -40,7 +39,7 @@ public class SpelExpression implements Expression {
* @param expression * @param expression
* @param ast * @param ast
*/ */
SpelExpression(String expression, SpelNode ast) { public SpelExpression(String expression, SpelNode ast) {
this.expression = expression; this.expression = expression;
this.ast = ast; this.ast = ast;
} }
@ -56,8 +55,7 @@ public class SpelExpression implements Expression {
* {@inheritDoc} * {@inheritDoc}
*/ */
public Object getValue() throws EvaluationException { public Object getValue() throws EvaluationException {
EvaluationContext eContext = new StandardEvaluationContext(); return ast.getValue(null);
return ast.getValue(new ExpressionState(eContext));
} }
/** /**
@ -70,18 +68,17 @@ public class SpelExpression implements Expression {
/** /**
* {@inheritDoc} * {@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)); Object result = ast.getValue(new ExpressionState(context));
if (result != null && expectedResultType != null) { if (result != null && expectedResultType != null) {
Class<?> resultType = result.getClass(); Class<?> resultType = result.getClass();
if (expectedResultType.isAssignableFrom(resultType)) { if (!expectedResultType.isAssignableFrom(resultType)) {
return result; // 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} * {@inheritDoc}
*/ */
public Object getValue(Class<?> expectedResultType) throws EvaluationException { public <T> T getValue(Class<T> expectedResultType) throws EvaluationException {
Object result = getValue(); Object result = getValue();
return ExpressionUtils.convert(null, result, expectedResultType); // TODO propagate generic-ness into convert
return (T)ExpressionUtils.convert(null, result, expectedResultType);
} }
} }

View File

@ -15,21 +15,12 @@
*/ */
package org.springframework.expression.spel; 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.Expression;
import org.springframework.expression.ParseException; import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext; import org.springframework.expression.ParserContext;
import org.springframework.expression.common.DefaultNonTemplateParserContext; import org.springframework.expression.common.DefaultNonTemplateParserContext;
import org.springframework.expression.common.TemplateAwareExpressionParser; import org.springframework.expression.common.TemplateAwareExpressionParser;
import org.springframework.expression.spel.ast.SpelNode; import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
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;
/** /**
* Instances of this parser class can process Spring Expression Language format expressions. The result of parsing an * 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 { public class SpelExpressionParser extends TemplateAwareExpressionParser {
private final SpringExpressionsLexer lexer; private final SpelInternalParser expressionParser;
private final SpringExpressionsParserExtender parser;
/**
* Should be constructed through the SpelParserFactory
*/
public SpelExpressionParser() { public SpelExpressionParser() {
lexer = new SpringExpressionsLexerExtender(); // Use an Antlr based expression parser
CommonTokenStream tokens = new CommonTokenStream(lexer); expressionParser = new SpelAntlrExpressionParser();
parser = new SpringExpressionsParserExtender(tokens);
parser.setTreeAdaptor(new SpelTreeAdaptor());
} }
/** /**
@ -63,22 +48,7 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
*/ */
@Override @Override
protected Expression doParseExpression(String expressionString, ParserContext context) throws ParseException { protected Expression doParseExpression(String expressionString, ParserContext context) throws ParseException {
try { return expressionParser.doParseExpression(expressionString,context);
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);
}
} }
/** /**
@ -88,4 +58,8 @@ public class SpelExpressionParser extends TemplateAwareExpressionParser {
public SpelExpression parseExpression(String expressionString) throws ParseException { public SpelExpression parseExpression(String expressionString) throws ParseException {
return (SpelExpression) super.parseExpression(expressionString, DefaultNonTemplateParserContext.INSTANCE); return (SpelExpression) super.parseExpression(expressionString, DefaultNonTemplateParserContext.INSTANCE);
} }
public interface SpelInternalParser {
Expression doParseExpression(String expressionString, ParserContext context) throws ParseException;
}
} }

View File

@ -17,8 +17,6 @@ package org.springframework.expression.spel;
import java.io.PrintStream; import java.io.PrintStream;
import org.springframework.expression.spel.ast.SpelNode;
/** /**
* Utilities for working with Spring Expressions. * Utilities for working with Spring Expressions.
* *
@ -45,10 +43,9 @@ public class SpelUtilities {
private static void printAST(PrintStream out, SpelNode t, String indent) { private static void printAST(PrintStream out, SpelNode t, String indent) {
if (t != null) { if (t != null) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
String s = (t.getType() == -1 ? "EOF" : t.getClass().getSimpleName()); sb.append(indent).append(t.getClass().getSimpleName());
sb.append(indent).append(s); sb.append(" value:").append(t.toStringAST());
sb.append(" value=").append(t.getText()); sb.append(t.getChildCount() < 2 ? "" : " #children:" + t.getChildCount());
sb.append(t.getChildCount() < 2 ? "" : " children=#" + t.getChildCount());
out.println(sb.toString()); out.println(sb.toString());
for (int i = 0; i < t.getChildCount(); i++) { for (int i = 0; i < t.getChildCount(); i++) {
printAST(out, t.getChild(i), indent + " "); printAST(out, t.getChild(i), indent + " ");

View File

@ -28,15 +28,15 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class Assign extends SpelNode { public class Assign extends SpelNodeImpl {
public Assign(Token payload) { public Assign(Token payload) {
super(payload); super(payload);
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object newValue = getChild(1).getValue(state); Object newValue = getChild(1).getValueInternal(state);
getChild(0).setValue(state, newValue); getChild(0).setValue(state, newValue);
return newValue; return newValue;
} }

View File

@ -26,7 +26,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class CompoundExpression extends SpelNode { public class CompoundExpression extends SpelNodeImpl {
public CompoundExpression(Token payload) { public CompoundExpression(Token payload) {
super(payload); super(payload);
@ -40,17 +40,17 @@ public class CompoundExpression extends SpelNode {
* @return the final value from the last piece of the compound expression * @return the final value from the last piece of the compound expression
*/ */
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object result = null; Object result = null;
SpelNode nextNode = null; SpelNodeImpl nextNode = null;
try { try {
nextNode = getChild(0); nextNode = getChild(0);
result = nextNode.getValue(state); result = nextNode.getValueInternal(state);
for (int i = 1; i < getChildCount(); i++) { for (int i = 1; i < getChildCount(); i++) {
try { try {
state.pushActiveContextObject(result); state.pushActiveContextObject(result);
nextNode = getChild(i); nextNode = getChild(i);
result = nextNode.getValue(state); result = nextNode.getValueInternal(state);
} finally { } finally {
state.popActiveContextObject(); state.popActiveContextObject();
} }
@ -69,11 +69,11 @@ public class CompoundExpression extends SpelNode {
getChild(0).setValue(state, value); getChild(0).setValue(state, value);
return; return;
} }
Object ctx = getChild(0).getValue(state); Object ctx = getChild(0).getValueInternal(state);
for (int i = 1; i < getChildCount() - 1; i++) { for (int i = 1; i < getChildCount() - 1; i++) {
try { try {
state.pushActiveContextObject(ctx); state.pushActiveContextObject(ctx);
ctx = getChild(i).getValue(state); ctx = getChild(i).getValueInternal(state);
} finally { } finally {
state.popActiveContextObject(); state.popActiveContextObject();
} }
@ -91,11 +91,11 @@ public class CompoundExpression extends SpelNode {
if (getChildCount() == 1) { if (getChildCount() == 1) {
return getChild(0).isWritable(state); 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++) { for (int i = 1; i < getChildCount() - 1; i++) {
try { try {
state.pushActiveContextObject(ctx); state.pushActiveContextObject(ctx);
ctx = getChild(i).getValue(state); ctx = getChild(i).getValueInternal(state);
} finally { } finally {
state.popActiveContextObject(); state.popActiveContextObject();
} }

View File

@ -42,7 +42,7 @@ import org.springframework.expression.spel.internal.Utils;
* @author Andy Clement * @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 * 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. * Implements getValue() - delegating to the code for building an array or a simple type.
*/ */
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
if (isArrayConstructor) { if (isArrayConstructor) {
return createArray(state); return createArray(state);
} else { } else {
@ -99,7 +99,7 @@ public class ConstructorReference extends SpelNode {
// Next child is EXPRESSIONLIST token with children that are the // Next child is EXPRESSIONLIST token with children that are the
// expressions giving array size // expressions giving array size
sb.append("["); sb.append("[");
SpelNode arrayRank = getChild(index++); SpelNodeImpl arrayRank = getChild(index++);
for (int i = 0; i < arrayRank.getChildCount(); i++) { for (int i = 0; i < arrayRank.getChildCount(); i++) {
if (i > 0) if (i > 0)
sb.append(","); sb.append(",");
@ -126,7 +126,7 @@ public class ConstructorReference extends SpelNode {
* @throws EvaluationException if there is a problem creating the array * @throws EvaluationException if there is a problem creating the array
*/ */
private Object createArray(ExpressionState state) throws EvaluationException { private Object createArray(ExpressionState state) throws EvaluationException {
Object intendedArrayType = getChild(0).getValue(state); Object intendedArrayType = getChild(0).getValueInternal(state);
if (!(intendedArrayType instanceof String)) { if (!(intendedArrayType instanceof String)) {
throw new SpelException(getChild(0).getCharPositionInLine(), throw new SpelException(getChild(0).getCharPositionInLine(),
SpelMessages.TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION, Utils 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? // Array ranks are specified but is it a single or multiple dimension array?
int dimensions = getChild(1).getChildCount(); int dimensions = getChild(1).getChildCount();
if (dimensions == 1) { if (dimensions == 1) {
Object o = getChild(1).getValue(state); Object o = getChild(1).getValueInternal(state);
int arraySize = state.toInteger(o); int arraySize = state.toInteger(o);
if (getChildCount() == 3) { if (getChildCount() == 3) {
// Check initializer length matches array size length // Check initializer length matches array size length
@ -170,7 +170,7 @@ public class ConstructorReference extends SpelNode {
// Multi-dimensional - hold onto your hat ! // Multi-dimensional - hold onto your hat !
int[] dims = new int[dimensions]; int[] dims = new int[dimensions];
for (int d = 0; d < dimensions; d++) { 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); newArray = Array.newInstance(componentType, dims);
// TODO check any specified initializer for the multidim array matches // 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 // Populate the array using the initializer if one is specified
if (getChildCount() == 3) { if (getChildCount() == 3) {
SpelNode initializer = getChild(2); SpelNodeImpl initializer = getChild(2);
if (arrayTypeCode == TypeCode.OBJECT) { if (arrayTypeCode == TypeCode.OBJECT) {
Object[] newObjectArray = (Object[]) newArray; Object[] newObjectArray = (Object[]) newArray;
for (int i = 0; i < newObjectArray.length; i++) { for (int i = 0; i < newObjectArray.length; i++) {
SpelNode elementNode = initializer.getChild(i); SpelNodeImpl elementNode = initializer.getChild(i);
Object arrayEntry = elementNode.getValue(state); Object arrayEntry = elementNode.getValueInternal(state);
if (!componentType.isAssignableFrom(arrayEntry.getClass())) { if (!componentType.isAssignableFrom(arrayEntry.getClass())) {
throw new SpelException(elementNode.getCharPositionInLine(), throw new SpelException(elementNode.getCharPositionInLine(),
SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, componentType.getName(), arrayEntry SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, componentType.getName(), arrayEntry
@ -195,42 +195,42 @@ public class ConstructorReference extends SpelNode {
} else if (arrayTypeCode == TypeCode.INT) { } else if (arrayTypeCode == TypeCode.INT) {
int[] newIntArray = (int[]) newArray; int[] newIntArray = (int[]) newArray;
for (int i = 0; i < newIntArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.BOOLEAN) {
boolean[] newBooleanArray = (boolean[]) newArray; boolean[] newBooleanArray = (boolean[]) newArray;
for (int i = 0; i < newBooleanArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.CHAR) {
char[] newCharArray = (char[]) newArray; char[] newCharArray = (char[]) newArray;
for (int i = 0; i < newCharArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.SHORT) {
short[] newShortArray = (short[]) newArray; short[] newShortArray = (short[]) newArray;
for (int i = 0; i < newShortArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.LONG) {
long[] newLongArray = (long[]) newArray; long[] newLongArray = (long[]) newArray;
for (int i = 0; i < newLongArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.FLOAT) {
float[] newFloatArray = (float[]) newArray; float[] newFloatArray = (float[]) newArray;
for (int i = 0; i < newFloatArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.DOUBLE) {
double[] newDoubleArray = (double[]) newArray; double[] newDoubleArray = (double[]) newArray;
for (int i = 0; i < newDoubleArray.length; i++) { 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) { } else if (arrayTypeCode == TypeCode.BYTE) {
byte[] newByteArray = (byte[]) newArray; byte[] newByteArray = (byte[]) newArray;
for (int i = 0; i < newByteArray.length; i++) { 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]; Object[] arguments = new Object[getChildCount() - 1];
Class<?>[] argumentTypes = new Class[getChildCount() - 1]; Class<?>[] argumentTypes = new Class[getChildCount() - 1];
for (int i = 0; i < arguments.length; i++) { 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; arguments[i] = childValue;
argumentTypes[i] = childValue.getClass(); argumentTypes[i] = childValue.getClass();
} }
@ -264,7 +264,7 @@ public class ConstructorReference extends SpelNode {
} }
// either there was no accessor or it no longer exists // 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); cachedExecutor = findExecutorForConstructor(typename, argumentTypes, state);
try { try {
return cachedExecutor.execute(state.getEvaluationContext(), arguments); return cachedExecutor.execute(state.getEvaluationContext(), arguments);

View File

@ -25,7 +25,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class Dot extends SpelNode { public class Dot extends SpelNodeImpl {
// TODO Keep Dot for the positional information or remove it? // TODO Keep Dot for the positional information or remove it?
public Dot(Token payload) { public Dot(Token payload) {
@ -38,7 +38,7 @@ public class Dot extends SpelNode {
} }
@Override @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 // This makes Dot a do-nothing operation, but this is not free in terms of computation
return state.getActiveContextObject(); return state.getActiveContextObject();
} }

View File

@ -39,7 +39,7 @@ import org.springframework.expression.spel.reflection.ReflectionUtils;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public class FunctionReference extends SpelNode { public class FunctionReference extends SpelNodeImpl {
private final String name; private final String name;
@ -49,7 +49,7 @@ public class FunctionReference extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object o = state.lookupVariable(name); Object o = state.lookupVariable(name);
if (o == null) { if (o == null) {
throw new SpelException(SpelMessages.FUNCTION_NOT_DEFINED, name); throw new SpelException(SpelMessages.FUNCTION_NOT_DEFINED, name);
@ -139,7 +139,7 @@ public class FunctionReference extends SpelNode {
// Compute arguments to the function // Compute arguments to the function
Object[] arguments = new Object[getChildCount()]; Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) { for (int i = 0; i < arguments.length; i++) {
arguments[i] = getChild(i).getValue(state); arguments[i] = getChild(i).getValueInternal(state);
} }
return arguments; return arguments;
} }

View File

@ -19,7 +19,7 @@ import org.antlr.runtime.Token;
import org.springframework.expression.spel.SpelException; import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.ExpressionState;
public class Identifier extends SpelNode { public class Identifier extends SpelNodeImpl {
private final String id; private final String id;
@ -34,7 +34,7 @@ public class Identifier extends SpelNode {
} }
@Override @Override
public String getValue(ExpressionState state) throws SpelException { public String getValueInternal(ExpressionState state) throws SpelException {
return id; return id;
} }

View File

@ -32,16 +32,16 @@ import org.springframework.expression.spel.SpelMessages;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public class Indexer extends SpelNode { public class Indexer extends SpelNodeImpl {
public Indexer(Token payload) { public Indexer(Token payload) {
super(payload); super(payload);
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object ctx = state.getActiveContextObject(); Object ctx = state.getActiveContextObject();
Object index = getChild(0).getValue(state); Object index = getChild(0).getValueInternal(state);
// Indexing into a Map // Indexing into a Map
if (ctx instanceof Map) { if (ctx instanceof Map) {

View File

@ -19,7 +19,7 @@ import org.antlr.runtime.Token;
import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException; import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages; 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). * Common superclass for nodes representing literals (boolean, string, number, etc).
@ -27,7 +27,7 @@ import org.springframework.expression.spel.internal.InternalELException;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public abstract class Literal extends SpelNode { public abstract class Literal extends SpelNodeImpl {
public Literal(Token payload) { public Literal(Token payload) {
super(payload); super(payload);
@ -36,7 +36,7 @@ public abstract class Literal extends SpelNode {
public abstract Object getLiteralValue(); public abstract Object getLiteralValue();
@Override @Override
public final Object getValue(ExpressionState state) throws SpelException { public final Object getValueInternal(ExpressionState state) throws SpelException {
return getLiteralValue(); return getLiteralValue();
} }
@ -84,7 +84,7 @@ public abstract class Literal extends SpelNode {
long value = Long.parseLong(numberString, radix); long value = Long.parseLong(numberString, radix);
return new LongLiteral(numberToken, value); return new LongLiteral(numberToken, value);
} catch (NumberFormatException nfe) { } 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())); SpelMessages.NOT_A_LONG, numberToken.getText()));
} }
} else { } else {
@ -92,7 +92,7 @@ public abstract class Literal extends SpelNode {
int value = Integer.parseInt(numberString, radix); int value = Integer.parseInt(numberString, radix);
return new IntLiteral(numberToken, value); return new IntLiteral(numberToken, value);
} catch (NumberFormatException nfe) { } 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())); SpelMessages.NOT_AN_INTEGER, numberToken.getText()));
} }
} }

View File

@ -28,7 +28,7 @@ import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages; import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.internal.Utils; import org.springframework.expression.spel.internal.Utils;
public class MethodReference extends SpelNode { public class MethodReference extends SpelNodeImpl {
private final String name; private final String name;
private MethodExecutor fastInvocationAccessor; private MethodExecutor fastInvocationAccessor;
@ -39,11 +39,11 @@ public class MethodReference extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object currentContext = state.getActiveContextObject(); Object currentContext = state.getActiveContextObject();
Object[] arguments = new Object[getChildCount()]; Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) { for (int i = 0; i < arguments.length; i++) {
arguments[i] = getChild(i).getValue(state); arguments[i] = getChild(i).getValueInternal(state);
} }
if (currentContext == null) { if (currentContext == null) {
throw new SpelException(getCharPositionInLine(), SpelMessages.ATTEMPTED_METHOD_CALL_ON_NULL_CONTEXT_OBJECT, throw new SpelException(getCharPositionInLine(), SpelMessages.ATTEMPTED_METHOD_CALL_ON_NULL_CONTEXT_OBJECT,

View File

@ -25,7 +25,7 @@ import org.springframework.expression.spel.ExpressionState;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public abstract class Operator extends SpelNode { public abstract class Operator extends SpelNodeImpl {
public Operator(Token payload) { public Operator(Token payload) {
super(payload); super(payload);
@ -39,11 +39,11 @@ public abstract class Operator extends SpelNode {
return false; return false;
} }
public SpelNode getLeftOperand() { public SpelNodeImpl getLeftOperand() {
return getChild(0); return getChild(0);
} }
public SpelNode getRightOperand() { public SpelNodeImpl getRightOperand() {
return getChild(1); return getChild(1);
} }

View File

@ -37,12 +37,12 @@ public class OperatorAnd extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
boolean leftValue; boolean leftValue;
boolean rightValue; boolean rightValue;
try { try {
leftValue = state.toBoolean(getLeftOperand().getValue(state)); leftValue = state.toBoolean(getLeftOperand().getValueInternal(state));
} catch (SpelException ee) { } catch (SpelException ee) {
ee.setPosition(getLeftOperand().getCharPositionInLine()); ee.setPosition(getLeftOperand().getCharPositionInLine());
throw ee; throw ee;
@ -53,7 +53,7 @@ public class OperatorAnd extends Operator {
} }
try { try {
rightValue = state.toBoolean(getRightOperand().getValue(state)); rightValue = state.toBoolean(getRightOperand().getValueInternal(state));
} catch (SpelException ee) { } catch (SpelException ee) {
ee.setPosition(getRightOperand().getCharPositionInLine()); ee.setPosition(getRightOperand().getCharPositionInLine());
throw ee; throw ee;

View File

@ -51,9 +51,9 @@ public class OperatorBetween extends Operator {
* @throws EvaluationException if there is a problem evaluating the expression * @throws EvaluationException if there is a problem evaluating the expression
*/ */
@Override @Override
public Boolean getValue(ExpressionState state) throws EvaluationException { public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (!(right instanceof List) || ((List<?>) right).size() != 2) { if (!(right instanceof List) || ((List<?>) right).size() != 2) {
throw new SpelException(getRightOperand().getCharPositionInLine(), throw new SpelException(getRightOperand().getCharPositionInLine(),
SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST); SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST);

View File

@ -37,9 +37,9 @@ public class OperatorDivide extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state); Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValue(state); Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) { if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne; Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo; Number op2 = (Number) operandTwo;

View File

@ -36,9 +36,9 @@ public class OperatorEquality extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -36,9 +36,9 @@ public class OperatorGreaterThan extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -36,9 +36,9 @@ public class OperatorGreaterThanOrEqual extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -36,9 +36,9 @@ public class OperatorInequality extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -47,9 +47,9 @@ public class OperatorInstanceof extends Operator {
* @throws EvaluationException if there is a problem evaluating the expression * @throws EvaluationException if there is a problem evaluating the expression
*/ */
@Override @Override
public Boolean getValue(ExpressionState state) throws EvaluationException { public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left == null) { if (left == null) {
return false; // null is not an instanceof anything return false; // null is not an instanceof anything
} }

View File

@ -36,9 +36,9 @@ public class OperatorLessThan extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -31,9 +31,9 @@ public class OperatorLessThanOrEqual extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state); Object left = getLeftOperand().getValueInternal(state);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -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) * @throws EvaluationException if there is a problem evaluating the expression (e.g. the regex is invalid)
*/ */
@Override @Override
public Boolean getValue(ExpressionState state) throws EvaluationException { public Boolean getValueInternal(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand(); SpelNodeImpl leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand(); SpelNodeImpl rightOp = getRightOperand();
Object left = leftOp.getValue(state, String.class); Object left = leftOp.getValue(state, String.class);
Object right = getRightOperand().getValue(state); Object right = getRightOperand().getValueInternal(state);
try { try {
if (!(left instanceof String)) { if (!(left instanceof String)) {
throw new SpelException(leftOp.getCharPositionInLine(), throw new SpelException(leftOp.getCharPositionInLine(),

View File

@ -18,9 +18,9 @@ package org.springframework.expression.spel.ast;
import org.antlr.runtime.Token; import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException; import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation; import org.springframework.expression.Operation;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException; import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages; 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. * 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 @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand(); SpelNodeImpl leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand(); SpelNodeImpl rightOp = getRightOperand();
if (rightOp == null) {// If only one operand, then this is unary minus 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) { if (left instanceof Number) {
Number n = (Number) left; Number n = (Number) left;
if (left instanceof Double) { if (left instanceof Double) {
@ -70,8 +70,8 @@ public class OperatorMinus extends Operator {
} }
throw new SpelException(SpelMessages.CANNOT_NEGATE_TYPE, left.getClass().getName()); throw new SpelException(SpelMessages.CANNOT_NEGATE_TYPE, left.getClass().getName());
} else { } else {
Object left = leftOp.getValue(state); Object left = leftOp.getValueInternal(state);
Object right = rightOp.getValue(state); Object right = rightOp.getValueInternal(state);
if (left instanceof Number && right instanceof Number) { if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left; Number op1 = (Number) left;
Number op2 = (Number) right; Number op2 = (Number) right;

View File

@ -37,9 +37,9 @@ public class OperatorModulus extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state); Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValue(state); Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) { if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne; Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo; Number op2 = (Number) operandTwo;

View File

@ -48,9 +48,9 @@ public class OperatorMultiply extends Operator {
* </ul> * </ul>
*/ */
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operandOne = getLeftOperand().getValue(state); Object operandOne = getLeftOperand().getValueInternal(state);
Object operandTwo = getRightOperand().getValue(state); Object operandTwo = getRightOperand().getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) { if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne; Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo; Number op2 = (Number) operandTwo;

View File

@ -20,16 +20,16 @@ import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException; import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState; 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) { public OperatorNot(Token payload) {
super(payload); super(payload);
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
try { try {
boolean value = state.toBoolean(getChild(0).getValue(state)); boolean value = state.toBoolean(getChild(0).getValueInternal(state));
return !value; return !value;
} catch (SpelException see) { } catch (SpelException see) {
see.setPosition(getChild(0).getCharPositionInLine()); see.setPosition(getChild(0).getCharPositionInLine());

View File

@ -37,11 +37,11 @@ public class OperatorOr extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
boolean leftValue; boolean leftValue;
boolean rightValue; boolean rightValue;
try { try {
leftValue = state.toBoolean(getLeftOperand().getValue(state)); leftValue = state.toBoolean(getLeftOperand().getValueInternal(state));
} catch (SpelException see) { } catch (SpelException see) {
see.setPosition(getLeftOperand().getCharPositionInLine()); see.setPosition(getLeftOperand().getCharPositionInLine());
throw see; throw see;
@ -51,7 +51,7 @@ public class OperatorOr extends Operator {
return true; // no need to evaluate right operand return true; // no need to evaluate right operand
try { try {
rightValue = state.toBoolean(getRightOperand().getValue(state)); rightValue = state.toBoolean(getRightOperand().getValueInternal(state));
} catch (SpelException see) { } catch (SpelException see) {
see.setPosition(getRightOperand().getCharPositionInLine()); see.setPosition(getRightOperand().getCharPositionInLine());
throw see; throw see;

View File

@ -27,18 +27,18 @@ public class OperatorPlus extends Operator {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
SpelNode leftOp = getLeftOperand(); SpelNodeImpl leftOp = getLeftOperand();
SpelNode rightOp = getRightOperand(); SpelNodeImpl rightOp = getRightOperand();
if (rightOp == null) { // If only one operand, then this is unary plus 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) { if (operandOne instanceof Number) {
return new Integer(((Number) operandOne).intValue()); return new Integer(((Number) operandOne).intValue());
} }
return state.operate(Operation.ADD, operandOne, null); return state.operate(Operation.ADD, operandOne, null);
} else { } else {
Object operandOne = leftOp.getValue(state); Object operandOne = leftOp.getValueInternal(state);
Object operandTwo = rightOp.getValue(state); Object operandTwo = rightOp.getValueInternal(state);
if (operandOne instanceof Number && operandTwo instanceof Number) { if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne; Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo; Number op2 = (Number) operandTwo;

View File

@ -27,14 +27,14 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class Placeholder extends SpelNode { public class Placeholder extends SpelNodeImpl {
public Placeholder(Token payload) { public Placeholder(Token payload) {
super(payload); super(payload);
} }
@Override @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); throw new SpelException(getCharPositionInLine(), SpelMessages.PLACEHOLDER_SHOULD_NEVER_BE_EVALUATED);
} }

View File

@ -35,14 +35,14 @@ import org.springframework.expression.spel.internal.KeyValuePair;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class Projection extends SpelNode { public class Projection extends SpelNodeImpl {
public Projection(Token payload) { public Projection(Token payload) {
super(payload); super(payload);
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operand = state.getActiveContextObject(); Object operand = state.getActiveContextObject();
// When the input is a map, we push a special context object on the stack // 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()) { for (Object k : mapdata.keySet()) {
try { try {
state.pushActiveContextObject(new KeyValuePair(k, mapdata.get(k))); state.pushActiveContextObject(new KeyValuePair(k, mapdata.get(k)));
result.add(getChild(0).getValue(state)); result.add(getChild(0).getValueInternal(state));
} finally { } finally {
state.popActiveContextObject(); state.popActiveContextObject();
} }
@ -71,7 +71,7 @@ public class Projection extends SpelNode {
try { try {
state.pushActiveContextObject(element); state.pushActiveContextObject(element);
state.enterScope("index", idx); state.enterScope("index", idx);
result.add(getChild(0).getValue(state)); result.add(getChild(0).getValueInternal(state));
} finally { } finally {
state.exitScope(); state.exitScope();
state.popActiveContextObject(); state.popActiveContextObject();

View File

@ -35,7 +35,7 @@ import org.springframework.expression.spel.internal.Utils;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public class PropertyOrFieldReference extends SpelNode { public class PropertyOrFieldReference extends SpelNodeImpl {
public static boolean useCaching = true; public static boolean useCaching = true;
@ -49,7 +49,7 @@ public class PropertyOrFieldReference extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws SpelException { public Object getValueInternal(ExpressionState state) throws SpelException {
return readProperty(state, name); return readProperty(state, name);
} }

View File

@ -27,7 +27,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class QualifiedIdentifier extends SpelNode { public class QualifiedIdentifier extends SpelNodeImpl {
private String value; private String value;
@ -37,14 +37,14 @@ public class QualifiedIdentifier extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
// Cache the concatenation of child identifiers // Cache the concatenation of child identifiers
if (value == null) { if (value == null) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < getChildCount(); i++) { for (int i = 0; i < getChildCount(); i++) {
if (i > 0) if (i > 0)
sb.append("."); sb.append(".");
sb.append(getChild(i).getValue(state)); sb.append(getChild(i).getValueInternal(state));
} }
value = sb.toString(); value = sb.toString();
} }

View File

@ -36,7 +36,7 @@ import org.springframework.expression.spel.internal.KeyValuePair;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public class Selection extends SpelNode { public class Selection extends SpelNodeImpl {
public final static int ALL = 0; // ?{} public final static int ALL = 0; // ?{}
public final static int FIRST = 1; // ^{} public final static int FIRST = 1; // ^{}
@ -50,9 +50,9 @@ public class Selection extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Object operand = state.getActiveContextObject(); Object operand = state.getActiveContextObject();
SpelNode selectionCriteria = getChild(0); SpelNodeImpl selectionCriteria = getChild(0);
if (operand instanceof Map) { if (operand instanceof Map) {
Map<?, ?> mapdata = (Map<?, ?>) operand; Map<?, ?> mapdata = (Map<?, ?>) operand;
List<Object> result = new ArrayList<Object>(); List<Object> result = new ArrayList<Object>();
@ -60,7 +60,7 @@ public class Selection extends SpelNode {
try { try {
Object kvpair = new KeyValuePair(k, mapdata.get(k)); Object kvpair = new KeyValuePair(k, mapdata.get(k));
state.pushActiveContextObject(kvpair); state.pushActiveContextObject(kvpair);
Object o = selectionCriteria.getValue(state); Object o = selectionCriteria.getValueInternal(state);
if (o instanceof Boolean) { if (o instanceof Boolean) {
if (((Boolean) o).booleanValue() == true) { if (((Boolean) o).booleanValue() == true) {
if (variant == FIRST) if (variant == FIRST)
@ -91,7 +91,7 @@ public class Selection extends SpelNode {
try { try {
state.pushActiveContextObject(element); state.pushActiveContextObject(element);
state.enterScope("index", idx); state.enterScope("index", idx);
Object o = selectionCriteria.getValue(state); Object o = selectionCriteria.getValueInternal(state);
if (o instanceof Boolean) { if (o instanceof Boolean) {
if (((Boolean) o).booleanValue() == true) { if (((Boolean) o).booleanValue() == true) {
if (variant == FIRST) if (variant == FIRST)

View File

@ -25,7 +25,7 @@ import org.springframework.expression.spel.SpelException;
* *
* @author Andy Clement * @author Andy Clement
*/ */
public class Ternary extends SpelNode { public class Ternary extends SpelNodeImpl {
public Ternary(Token payload) { public Ternary(Token payload) {
super(payload); super(payload);
@ -39,13 +39,13 @@ public class Ternary extends SpelNode {
* executing the chosen alternative * executing the chosen alternative
*/ */
@Override @Override
public Object getValue(ExpressionState state) throws EvaluationException { public Object getValueInternal(ExpressionState state) throws EvaluationException {
Boolean b = (Boolean) getChild(0).getValue(state, Boolean.class); Boolean b = (Boolean) getChild(0).getValue(state, Boolean.class);
try { try {
if (b) { if (b) {
return getChild(1).getValue(state); return getChild(1).getValueInternal(state);
} else { } else {
return getChild(2).getValue(state); return getChild(2).getValueInternal(state);
} }
} catch (SpelException ex) { } catch (SpelException ex) {
ex.setPosition(getChild(0).getCharPositionInLine()); ex.setPosition(getChild(0).getCharPositionInLine());

View File

@ -27,16 +27,16 @@ import org.springframework.expression.spel.internal.TypeCode;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class TypeReference extends SpelNode { public class TypeReference extends SpelNodeImpl {
public TypeReference(Token payload) { public TypeReference(Token payload) {
super(payload); super(payload);
} }
@Override @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? // 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))) { if (typename.indexOf(".") == -1 && Character.isLowerCase(typename.charAt(0))) {
TypeCode tc = TypeCode.forName(typename); TypeCode tc = TypeCode.forName(typename);
if (tc != TypeCode.OBJECT) { if (tc != TypeCode.OBJECT) {

View File

@ -26,7 +26,7 @@ import org.springframework.expression.spel.ExpressionState;
* @author Andy Clement * @author Andy Clement
* *
*/ */
public class VariableReference extends SpelNode { public class VariableReference extends SpelNodeImpl {
// Well known variables: // Well known variables:
private final static String THIS = "this"; // currently active context object private final static String THIS = "this"; // currently active context object
@ -40,7 +40,7 @@ public class VariableReference extends SpelNode {
} }
@Override @Override
public Object getValue(ExpressionState state) throws SpelException { public Object getValueInternal(ExpressionState state) throws SpelException {
if (name.equals(THIS)) if (name.equals(THIS))
return state.getActiveContextObject(); return state.getActiveContextObject();
if (name.equals(ROOT)) if (name.equals(ROOT))

View File

@ -1,14 +1,22 @@
// $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 // $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; 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.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 class SpringExpressionsParser extends Parser {
public static final String[] tokenNames = new String[] { public static final String[] tokenNames = new String[] {

View File

@ -24,6 +24,8 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
*/ */
public class ConstructorInvocationTests extends ExpressionTestCase { public class ConstructorInvocationTests extends ExpressionTestCase {
// Some tests commented out as language support has been removed for now
// public void testPrimitiveTypeArrayConstructors() { // public void testPrimitiveTypeArrayConstructors() {
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class); // evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
// evaluate("new boolean[]{true,false,true}.count()", 3, 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); // 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() { // public void testErrorCases() {
// evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT); // evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
// evaluateAndCheckError("new char[3]{'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()); // 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 * These tests are attempting to call constructors where we need to widen or convert the argument in order to
* satisfy a suitable constructor. * satisfy a suitable constructor.

View File

@ -18,6 +18,8 @@ package org.springframework.expression.spel;
/** /**
* Tests the evaluation of real expressions in a real context. * Tests the evaluation of real expressions in a real context.
* *
* Node: Some tests commented out as language support has been removed
*
* @author Andy Clement * @author Andy Clement
*/ */
public class EvaluationTests extends ExpressionTestCase { public class EvaluationTests extends ExpressionTestCase {