Final commit before the great 'stripdown'. Used clover to determine coverage and added tests as necessary.

This commit is contained in:
Andy Clement
2008-09-15 20:14:36 +00:00
parent 23db8b58da
commit 59a4427525
14 changed files with 270 additions and 54 deletions

View File

@@ -24,14 +24,15 @@ public class LiteralExpression implements Expression {
}
public String getExpressionString() {
return new StringBuilder().append("'").append(literalValue).append("'").toString();
return literalValue;
// return new StringBuilder().append("'").append(literalValue).append("'").toString();
}
public Object getValue() throws EvaluationException {
public String getValue() throws EvaluationException {
return literalValue;
}
public Object getValue(EvaluationContext context) throws EvaluationException {
public String getValue(EvaluationContext context) throws EvaluationException {
return literalValue;
}

View File

@@ -25,6 +25,7 @@ import org.springframework.expression.Operation;
import org.springframework.expression.OperatorOverloader;
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;
@@ -42,21 +43,21 @@ public class ExpressionState {
private EvaluationContext relatedContext;
private final Stack<VariableScope> environment = new Stack<VariableScope>();
private final Stack<VariableScope> variableScopes = new Stack<VariableScope>();
private final Stack<Object> contextObjects = new Stack<Object>();
public ExpressionState(EvaluationContext context) {
this.relatedContext = context;
createEnvironment();
relatedContext = context;
createVariableScope();
}
public ExpressionState() {
createEnvironment();
createVariableScope();
}
private void createEnvironment() {
environment.add(new VariableScope()); // create an empty top level VariableScope
private void createVariableScope() {
variableScopes.add(new VariableScope()); // create an empty top level VariableScope
}
/**
@@ -97,37 +98,42 @@ public class ExpressionState {
return getTypeUtilities().getTypeLocator().findType(type);
}
// TODO all these methods that grab the type converter will fail badly if there isn't one...
public boolean toBoolean(Object value) throws EvaluationException {
// TODO cache TypeConverter when it is set/changed?
return ((Boolean) getTypeUtilities().getTypeConverter().convertValue(value, Boolean.TYPE)).booleanValue();
return ((Boolean) getTypeConverter().convertValue(value, Boolean.TYPE)).booleanValue();
}
public char toCharacter(Object value) throws EvaluationException {
return ((Character) getTypeUtilities().getTypeConverter().convertValue(value, Character.TYPE)).charValue();
return ((Character) getTypeConverter().convertValue(value, Character.TYPE)).charValue();
}
public short toShort(Object value) throws EvaluationException {
return ((Short) getTypeUtilities().getTypeConverter().convertValue(value, Short.TYPE)).shortValue();
return ((Short) getTypeConverter().convertValue(value, Short.TYPE)).shortValue();
}
public int toInteger(Object value) throws EvaluationException {
return ((Integer) getTypeUtilities().getTypeConverter().convertValue(value, Integer.TYPE)).intValue();
return ((Integer) getTypeConverter().convertValue(value, Integer.TYPE)).intValue();
}
public double toDouble(Object value) throws EvaluationException {
return ((Double) getTypeUtilities().getTypeConverter().convertValue(value, Double.TYPE)).doubleValue();
return ((Double) getTypeConverter().convertValue(value, Double.TYPE)).doubleValue();
}
public float toFloat(Object value) throws EvaluationException {
return ((Float) getTypeUtilities().getTypeConverter().convertValue(value, Float.TYPE)).floatValue();
return ((Float) getTypeConverter().convertValue(value, Float.TYPE)).floatValue();
}
public long toLong(Object value) throws EvaluationException {
return ((Long) getTypeUtilities().getTypeConverter().convertValue(value, Long.TYPE)).longValue();
return ((Long) getTypeConverter().convertValue(value, Long.TYPE)).longValue();
}
public byte toByte(Object value) throws EvaluationException {
return ((Byte) getTypeUtilities().getTypeConverter().convertValue(value, Byte.TYPE)).byteValue();
return ((Byte) getTypeConverter().convertValue(value, Byte.TYPE)).byteValue();
}
public TypeConverter getTypeConverter() {
// TODO cache TypeConverter when it is set/changed?
return getTypeUtilities().getTypeConverter();
}
public void setVariable(String name, Object value) {
@@ -142,26 +148,26 @@ public class ExpressionState {
* A new scope is entered when a function is invoked
*/
public void enterScope(Map<String, Object> argMap) {
environment.push(new VariableScope(argMap));
variableScopes.push(new VariableScope(argMap));
}
public void enterScope(String name, Object value) {
environment.push(new VariableScope(name, value));
variableScopes.push(new VariableScope(name, value));
}
public void exitScope() {
environment.pop();
variableScopes.pop();
}
public void setLocalVariable(String name, Object value) {
environment.peek().setVariable(name, value);
variableScopes.peek().setVariable(name, value);
}
public Object lookupLocalVariable(String name) {
int scopeNumber = environment.size() - 1;
int scopeNumber = variableScopes.size() - 1;
for (int i = scopeNumber; i >= 0; i--) {
if (environment.get(i).definesVariable(name)) {
return environment.get(i).lookupVariable(name);
if (variableScopes.get(i).definesVariable(name)) {
return variableScopes.get(i).lookupVariable(name);
}
}
return null;

View File

@@ -45,13 +45,10 @@ public class SpelUtilities {
private static void printAST(PrintStream out, SpelNode t, String indent) {
if (t != null) {
StringBuffer sb = new StringBuffer();
String s = null;
if (t.getType() == -1)
s = "EOF";
else {
s = t.getClass().getSimpleName();
}
sb.append(indent + s + (t.getChildCount() < 2 ? "" : " #" + t.getChildCount()));
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());
out.println(sb.toString());
for (int i = 0; i < t.getChildCount(); i++) {
printAST(out, t.getChild(i), indent + " ");

View File

@@ -27,11 +27,13 @@ import org.springframework.expression.spel.SpelMessages;
* The AverageProcessor operates upon an input collection and computes the average value of the elements within it. It
* will currently only operate upon Numbers and its return value type is an Integer if the input values were integers,
* otherwise it is a double.
*
* @author Andy Clement
*/
public class AverageProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
// TypeUtilities typeUtilities = state.getTypeUtilities();
// TODO could support average of other types if delegated to OperatorOverloader for addition and division
boolean allIntegerObjects = true;
int total = 0;
int numberOfElements = 0;