提交 769e706b 编写于 作者: A Andy Clement

removing: initializers/processors/in operator

上级 afdf54ef
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.ast;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
/**
* Represents a list of expressions of the form "(expression1;expression2;expression3)". The expressions are always
* evaluated from left to right, due to possible side effects that earlier expressions may have that influence the
* evaluation of later expressions (defining functions, setting variables, etc).
*
* @author Andy Clement
*
*/
public class ExpressionListNode extends SpelNode {
public ExpressionListNode(Token payload) {
super(payload);
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object result = null;
for (int i = 0; i < getChildCount(); i++) {
result = getChild(i).getValue(state);
}
return result;
}
@Override
public boolean isWritable(ExpressionState state) throws EvaluationException {
boolean isWritable = false;
if (getChildCount() > 0) {
// Evaluate all but the last one
for (int i = 0; i < getChildCount() - 1; i++) {
getChild(i).getValue(state);
}
isWritable = getChild(getChildCount() - 1).isWritable(state);
}
return isWritable;
}
@Override
public String toStringAST() {
StringBuffer sb = new StringBuffer();
if (getChildCount() == 1) {
sb.append(getChild(0).toStringAST());
} else {
sb.append("(");
for (int i = 0; i < getChildCount(); i++) {
if (i > 0)
sb.append(";");
sb.append(getChild(i).toStringAST());
}
sb.append(")");
}
return sb.toString();
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.ast;
import java.util.ArrayList;
import java.util.List;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
public class ListInitializer extends SpelNode {
public ListInitializer(Token payload) {
super(payload);
}
/**
* Evaluate the list initializer, returning a List<Object>
*/
@Override
public List<Object> getValue(ExpressionState state) throws EvaluationException {
List<Object> result = new ArrayList<Object>();
for (int i = 0; i < getChildCount(); i++) {
Object element = getChild(i).getValue(state);
result.add(element);
}
return result;
}
/**
* Return string form of this node {<child>,<child>,<child>}
*/
@Override
public String toStringAST() {
StringBuilder sb = new StringBuilder();
sb.append("{");
for (int i = 0; i < getChildCount(); i++) {
if (i > 0) {
sb.append(",");
}
sb.append(getChild(i).toStringAST());
}
sb.append("}");
return sb.toString();
}
@Override
public boolean isWritable(ExpressionState expressionState) throws SpelException {
return false;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.ast;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.ExpressionState;
/**
* Represents an entry in a map initializer structure like "#{'a':3,'b':2}" Both "'a':3" and "'b':2" would be MapEntry
* instances.
*
* @author Andy Clement
*
*/
public class MapEntry extends SpelNode {
public MapEntry(Token payload) {
super(payload);
}
@Override
public String toStringAST() {
StringBuilder sb = new StringBuilder();
String k = getChild(0).toStringAST();
String v = getChild(1).toStringAST();
sb.append(k).append(":").append(v);
return sb.toString();
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
throw new SpelException(SpelMessages.MAPENTRY_SHOULD_NOT_BE_EVALUATED);
}
/**
* Return the value of the key for this map entry.
*/
public Object getKeyValue(ExpressionState state) throws EvaluationException {
return getChild(0).getValue(state);
}
/**
* Return the value of the value for this map entry.
*/
public Object getValueValue(ExpressionState state) throws EvaluationException {
return getChild(1).getValue(state);
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.ast;
import java.util.HashMap;
import java.util.Map;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
public class MapInitializer extends SpelNode {
public MapInitializer(Token payload) {
super(payload);
}
@Override
public Map<Object, Object> getValue(ExpressionState state) throws EvaluationException {
Map<Object, Object> result = new HashMap<Object, Object>();
for (int i = 0; i < getChildCount(); i++) {
MapEntry mEntry = (MapEntry) getChild(i);
result.put(mEntry.getKeyValue(state), mEntry.getValueValue(state));
}
return result;
}
/**
* Return string form of this node #{a:b,c:d,...}
*/
@Override
public String toStringAST() {
StringBuilder sb = new StringBuilder();
sb.append("#{");
for (int i = 0; i < getChildCount(); i++) {
if (i > 0)
sb.append(", ");
sb.append(getChild(i).toStringAST());
}
sb.append("}");
return sb.toString();
}
@Override
public boolean isWritable(ExpressionState expressionState) throws SpelException {
return false;
}
}
......@@ -15,13 +15,7 @@
*/
package org.springframework.expression.spel.ast;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.antlr.runtime.Token;
import org.springframework.expression.AccessException;
......@@ -33,173 +27,17 @@ import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.internal.Utils;
import org.springframework.expression.spel.processors.AverageProcessor;
import org.springframework.expression.spel.processors.CountProcessor;
import org.springframework.expression.spel.processors.CutProcessor;
import org.springframework.expression.spel.processors.DataProcessor;
import org.springframework.expression.spel.processors.DistinctProcessor;
import org.springframework.expression.spel.processors.MaxProcessor;
import org.springframework.expression.spel.processors.MinProcessor;
import org.springframework.expression.spel.processors.NonNullProcessor;
import org.springframework.expression.spel.processors.SortProcessor;
public class MethodReference extends SpelNode {
private static Map<String, DataProcessor> registeredProcessers = new HashMap<String, DataProcessor>();
private final String name;
private MethodExecutor fastInvocationAccessor;
static {
registeredProcessers.put("count", new CountProcessor());
registeredProcessers.put("max", new MaxProcessor());
registeredProcessers.put("min", new MinProcessor());
registeredProcessers.put("average", new AverageProcessor());
registeredProcessers.put("sort", new SortProcessor());
registeredProcessers.put("nonnull", new NonNullProcessor());
registeredProcessers.put("distinct", new DistinctProcessor());
registeredProcessers.put("cut", new CutProcessor());
}
public MethodReference(Token payload) {
super(payload);
name = payload.getText();
}
@SuppressWarnings("unchecked")
private Object invokeDataProcessor(Object[] arguments, ExpressionState state) throws EvaluationException {
DataProcessor processor = registeredProcessers.get(name);
Object target = state.getActiveContextObject();
// Prepare the input, translating arrays to lists
boolean wasArray = false;
Class<?> arrayElementType = null;
Collection<Object> dataToProcess = null;
if (target instanceof Collection) {
dataToProcess = (Collection<Object>) target;
} else {
wasArray = true;
arrayElementType = target.getClass().getComponentType();
if (arrayElementType.equals(Integer.TYPE)) {
int[] data = (int[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Byte.TYPE)) {
byte[] data = (byte[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Character.TYPE)) {
char[] data = (char[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Double.TYPE)) {
double[] data = (double[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Long.TYPE)) {
long[] data = (long[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Float.TYPE)) {
float[] data = (float[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Short.TYPE)) {
short[] data = (short[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else if (arrayElementType.equals(Boolean.TYPE)) {
boolean[] data = (boolean[]) target;
dataToProcess = new ArrayList<Object>();
for (int i = 0; i < data.length; i++) {
dataToProcess.add(data[i]);
}
} else {
dataToProcess = Arrays.asList((Object[]) target);
}
}
Object result = processor.process(dataToProcess, arguments, state);
// Convert the result back if necessary
if (wasArray && (result instanceof Collection)) {
Collection c = (Collection) result;
if (arrayElementType.equals(Integer.TYPE)) {
int[] newArray = (int[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Integer) i).intValue();
return newArray;
} else if (arrayElementType.equals(Byte.TYPE)) {
byte[] newArray = (byte[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Byte) i).byteValue();
return newArray;
} else if (arrayElementType.equals(Character.TYPE)) {
char[] newArray = (char[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Character) i).charValue();
return newArray;
} else if (arrayElementType.equals(Double.TYPE)) {
double[] newArray = (double[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Double) i).doubleValue();
return newArray;
} else if (arrayElementType.equals(Long.TYPE)) {
long[] newArray = (long[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Long) i).longValue();
return newArray;
} else if (arrayElementType.equals(Float.TYPE)) {
float[] newArray = (float[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Float) i).floatValue();
return newArray;
} else if (arrayElementType.equals(Short.TYPE)) {
short[] newArray = (short[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Short) i).shortValue();
return newArray;
} else if (arrayElementType.equals(Boolean.TYPE)) {
boolean[] newArray = (boolean[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c)
newArray[idx++] = ((Boolean) i).booleanValue();
return newArray;
} else {
Object[] newArray = (Object[]) Array.newInstance(arrayElementType, c.size());
int idx = 0;
for (Object i : c) {
newArray[idx++] = i;
}
return newArray;
}
}
return result;
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object currentContext = state.getActiveContextObject();
......@@ -212,12 +50,6 @@ public class MethodReference extends SpelNode {
formatMethodForMessage(name, getTypes(arguments)));
}
boolean usingProcessor = registeredProcessers.containsKey(name);
if ((currentContext.getClass().isArray() && usingProcessor)
|| (currentContext instanceof Collection && registeredProcessers.containsKey(name))) {
return invokeDataProcessor(arguments, state);
}
if (fastInvocationAccessor != null) {
try {
return fastInvocationAccessor.execute(state.getEvaluationContext(), state.getActiveContextObject(),
......
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.ast;
import java.util.Collection;
import org.antlr.runtime.Token;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.ExpressionState;
/**
* Represents the 'in' operator and returns true if the left operand can be found within the collection passed as the
* right operand.
*
* @author Andy Clement
*/
public class OperatorIn extends Operator {
public OperatorIn(Token payload) {
super(payload);
}
@Override
public String getOperatorName() {
return "in";
}
@Override
public Object getValue(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValue(state);
Object right = getRightOperand().getValue(state);
if (right instanceof Collection<?>) {
Collection<?> c = (Collection<?>) right;
for (Object element : c) {
if (state.getTypeComparator().compare(left, element) == 0) {
return true;
}
}
return false;
}
throw new SpelException(SpelMessages.OPERATOR_IN_CANNOT_DETERMINE_MEMBERSHIP, left.getClass().getName(), right
.getClass().getName());
}
}
......@@ -7,7 +7,6 @@ options {
}
tokens {
EXPRESSIONLIST;
INTEGER_LITERAL;
EXPRESSION;
QUALIFIED_IDENTIFIER;
......@@ -15,15 +14,10 @@ tokens {
INDEXER;
CONSTRUCTOR;
HOLDER;
CONSTRUCTOR_ARRAY;
NAMED_ARGUMENT;
FUNCTIONREF;
TYPEREF;
RANGE;
VARIABLEREF;
LIST_INITIALIZER;
MAP_INITIALIZER;
MAP_ENTRY;
METHOD;
ADD;
SUBTRACT;
......@@ -94,8 +88,6 @@ startNode
| selection
| firstSelection
| lastSelection
| listInitializer
| mapInitializer
;
node
......@@ -141,10 +133,8 @@ methodArgs : LPAREN! (argument (COMMA! argument)* (COMMA!)?)? RPAREN!;
property: id=ID -> ^(PROPERTY_OR_FIELD[$id]);
//indexer: LBRACKET r1=range (COMMA r2=range)* RBRACKET -> ^(INDEXER $r1 ($r2)*);
indexer: LBRACKET r1=argument (COMMA r2=argument)* RBRACKET -> ^(INDEXER $r1 ($r2)*);
//range: INTEGER_LITERAL UPTO^ INTEGER_LITERAL |
// argument;
// TODO make expression conditional with ? if want completion for when the RCURLY is missing
projection: PROJECT^ expression RCURLY!;
......@@ -162,29 +152,8 @@ type: TYPE qualifiedId RPAREN -> ^(TYPEREF qualifiedId);
constructor
: ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs)
| arrayConstructor
;
arrayConstructor
: 'new' qualifiedId arrayRank (listInitializer)?
-> ^(CONSTRUCTOR_ARRAY qualifiedId arrayRank (listInitializer)?)
;
arrayRank
: LBRACKET (expression (COMMA expression)*)? RBRACKET -> ^(EXPRESSIONLIST expression*);
listInitializer
: LCURLY expression (COMMA expression)* RCURLY -> ^(LIST_INITIALIZER expression*);
//arrayInitializer
// : LCURLY expression (COMMA expression)* RCURLY -> ^(ARRAY_INITIALIZER expression*);
mapInitializer
: POUND LCURLY mapEntry (COMMA mapEntry)* RCURLY -> ^(MAP_INITIALIZER mapEntry*);
mapEntry
: expression COLON expression -> ^(MAP_ENTRY expression*);
ctorArgs
: LPAREN! (namedArgument (COMMA! namedArgument)*)? RPAREN!;
......@@ -223,7 +192,6 @@ relationalOperator
| LESS_THAN_OR_EQUAL
| GREATER_THAN
| GREATER_THAN_OR_EQUAL
| IN
| INSTANCEOF
| BETWEEN
| MATCHES
......@@ -236,7 +204,6 @@ LESS_THAN: '<';
LESS_THAN_OR_EQUAL: '<=';
GREATER_THAN: '>';
GREATER_THAN_OR_EQUAL: '>=';
IN: 'in';
INSTANCEOF: 'instanceof';
BETWEEN:'between';
MATCHES:'matches';
......
GREATER_THAN_OR_EQUAL=68
SELECT_FIRST=49
HOLDER=11
COMMA=43
GREATER_THAN=67
TYPE=51
EXPRESSIONLIST=4
MINUS=34
MAP_ENTRY=20
SELECT_LAST=50
NUMBER=24
LESS_THAN=65
BANG=39
FALSE=59
METHOD=21
PROPERTY_OR_FIELD=8
LBRACKET=44
INDEXER=9
MOD=37
CONSTRUCTOR_ARRAY=12
FUNCTIONREF=14
NULL_LITERAL=55
NAMED_ARGUMENT=13
OR=31
PIPE=74
DOT=40
RCURLY=47
EXPRESSION=6
AND=32
LCURLY=52
REAL_TYPE_SUFFIX=82
STRING_LITERAL=53
SELECT=48
QUALIFIED_IDENTIFIER=7
RBRACKET=45
SUBTRACT=23
ASSIGN=25
INSTANCEOF=70
BETWEEN=71
RPAREN=30
SIGN=83
LPAREN=29
HEX_DIGIT=62
PLUS=33
LIST_INITIALIZER=18
APOS=75
INTEGER_LITERAL=5
AT=79
ID=42
NOT_EQUAL=64
RANGE=16
POWER=38
TYPEREF=15
DECIMAL_DIGIT=60
WS=77
DOLLAR=78
LESS_THAN_OR_EQUAL=66
DQ_STRING_LITERAL=54
HEXADECIMAL_INTEGER_LITERAL=56
MAP_INITIALIZER=19
IN=69
SEMI=73
CONSTRUCTOR=10
INTEGER_TYPE_SUFFIX=61
EQUAL=63
MATCHES=72
DOT_ESCAPED=76
UPTO=80
QMARK=27
PROJECT=46
DEFAULT=26
COLON=28
DIV=36
STAR=35
REAL_LITERAL=57
VARIABLEREF=17
EXPONENT_PART=81
TRUE=58
ADD=22
POUND=41
'new'=84
GREATER_THAN_OR_EQUAL=61
HOLDER=10
COMMA=37
SELECT_FIRST=43
GREATER_THAN=60
TYPE=45
MINUS=28
SELECT_LAST=44
NUMBER=18
LESS_THAN=58
BANG=33
FALSE=52
METHOD=15
PROPERTY_OR_FIELD=7
LBRACKET=38
INDEXER=8
MOD=31
FUNCTIONREF=12
NULL_LITERAL=48
NAMED_ARGUMENT=11
OR=25
PIPE=67
DOT=34
RCURLY=41
EXPRESSION=5
AND=26
LCURLY=66
REAL_TYPE_SUFFIX=75
STRING_LITERAL=46
QUALIFIED_IDENTIFIER=6
SELECT=42
ASSIGN=19
SUBTRACT=17
RBRACKET=39
INSTANCEOF=62
BETWEEN=63
RPAREN=24
SIGN=76
LPAREN=23
HEX_DIGIT=55
PLUS=27
APOS=68
INTEGER_LITERAL=4
AT=72
ID=36
NOT_EQUAL=57
POWER=32
TYPEREF=13
DECIMAL_DIGIT=53
WS=70
DOLLAR=71
LESS_THAN_OR_EQUAL=59
DQ_STRING_LITERAL=47
HEXADECIMAL_INTEGER_LITERAL=49
SEMI=65
CONSTRUCTOR=9
INTEGER_TYPE_SUFFIX=54
EQUAL=56
MATCHES=64
DOT_ESCAPED=69
UPTO=73
QMARK=21
DEFAULT=20
COLON=22
PROJECT=40
DIV=30
STAR=29
REAL_LITERAL=50
VARIABLEREF=14
EXPONENT_PART=74
TRUE=51
ADD=16
POUND=35
'new'=77
......@@ -22,14 +22,10 @@ import org.springframework.expression.spel.ast.BooleanLiteral;
import org.springframework.expression.spel.ast.CompoundExpression;
import org.springframework.expression.spel.ast.ConstructorReference;
import org.springframework.expression.spel.ast.Dot;
import org.springframework.expression.spel.ast.ExpressionListNode;
import org.springframework.expression.spel.ast.FunctionReference;
import org.springframework.expression.spel.ast.Identifier;
import org.springframework.expression.spel.ast.Indexer;
import org.springframework.expression.spel.ast.ListInitializer;
import org.springframework.expression.spel.ast.Literal;
import org.springframework.expression.spel.ast.MapEntry;
import org.springframework.expression.spel.ast.MapInitializer;
import org.springframework.expression.spel.ast.MethodReference;
import org.springframework.expression.spel.ast.NullLiteral;
import org.springframework.expression.spel.ast.OperatorAnd;
......@@ -38,7 +34,6 @@ import org.springframework.expression.spel.ast.OperatorDivide;
import org.springframework.expression.spel.ast.OperatorEquality;
import org.springframework.expression.spel.ast.OperatorGreaterThan;
import org.springframework.expression.spel.ast.OperatorGreaterThanOrEqual;
import org.springframework.expression.spel.ast.OperatorIn;
import org.springframework.expression.spel.ast.OperatorInequality;
import org.springframework.expression.spel.ast.OperatorInstanceof;
import org.springframework.expression.spel.ast.OperatorLessThan;
......@@ -67,8 +62,6 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
public Object create(Token payload) {
if (payload != null) {
switch (payload.getType()) {
case SpringExpressionsLexer.EXPRESSIONLIST:
return new ExpressionListNode(payload);
case SpringExpressionsLexer.TRUE:
return new BooleanLiteral(payload, true);
......@@ -132,17 +125,8 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
case SpringExpressionsLexer.EXPRESSION:
return new CompoundExpression(payload);
case SpringExpressionsLexer.LIST_INITIALIZER:
return new ListInitializer(payload);
case SpringExpressionsLexer.MAP_ENTRY:
return new MapEntry(payload);
case SpringExpressionsLexer.MAP_INITIALIZER:
return new MapInitializer(payload);
case SpringExpressionsLexer.CONSTRUCTOR:
return new ConstructorReference(payload, false);
case SpringExpressionsLexer.CONSTRUCTOR_ARRAY:
return new ConstructorReference(payload, true);
case SpringExpressionsLexer.VARIABLEREF:
return new VariableReference(payload);
case SpringExpressionsLexer.FUNCTIONREF:
......@@ -162,10 +146,7 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
return new Ternary(payload);
case SpringExpressionsLexer.INDEXER:
return new Indexer(payload);
// case SpringExpressionsLexer.UPTO: return new Range(payload);
case SpringExpressionsLexer.IN:
return new OperatorIn(payload);
case SpringExpressionsLexer.BETWEEN:
return new OperatorBetween(payload);
case SpringExpressionsLexer.MATCHES:
......@@ -178,7 +159,6 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
case SpringExpressionsLexer.COLON:
return new Placeholder(payload);
// case SpringExpressionsLexer.EOF: return new ErrorNode(payload);
case SpringExpressionsLexer.DOT:
return new Dot(payload);
......
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.Collection;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
// TODO does it return an element consistent with input? (an int if input is ints, even though the average may be
// X.Y?) yes, for now
/**
* 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 {
// TODO could support average of other types if delegated to OperatorOverloader for addition and division
boolean allIntegerObjects = true;
int total = 0;
int numberOfElements = 0;
for (Object element : input) {
if (element != null) {
if (element instanceof Number) {
allIntegerObjects = allIntegerObjects
&& (element.getClass() == Integer.class || element.getClass() == Integer.TYPE);
total = total + ((Number) element).intValue();
numberOfElements++;
} else {
throw new SpelException(SpelMessages.TYPE_NOT_SUPPORTED_BY_PROCESSOR, "average", element.getClass());
}
}
}
int result = total / numberOfElements;
// if (allIntegerObjects) {
// return new Integer(((Number) result).intValue());
// } else {
return result;
// }
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.Collection;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
/**
* The count processor returns an Integer value representing the number of elements in the collection.
*
* @author Andy Clement
*
*/
public class CountProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
return input.size();
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.SpelMessages;
import org.springframework.expression.spel.ExpressionState;
public class CutProcessor implements DataProcessor {
/** Cut a piece out of a collection - the arguments are from (inclusive) to (exclusive) */
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
if (!(arguments[0] instanceof Integer && arguments[1] instanceof Integer)) {
throw new SpelException(SpelMessages.CUT_ARGUMENTS_MUST_BE_INTS, arguments[0].getClass().getName(),
arguments[1].getClass().getName());
}
int first = ((Integer) arguments[0]).intValue();
int last = ((Integer) arguments[1]).intValue();
List<Object> result = new ArrayList<Object>();
int pos = 0;
if (first < last) {
for (Object o : input) {
if (pos >= first && pos <= last)
result.add(o);
pos++;
}
} else {
for (Object o : input) {
if (pos >= last && pos <= first)
result.add(0, o);
pos++;
}
}
return result;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.Collection;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
/**
* A Data processor takes as input: a collection, an optional set of arguments that configure its behaviour, an
* evaluation context. It returns the result of processing the collection which might be as simple as adding up its
* elements or returning a subset of the non null elements.
*
* @author Andy Clement
*
*/
public interface DataProcessor {
Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws EvaluationException;
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
/**
* The DistinctProcessor returns a new collection containing that is similar to the input collection but with all
* duplicate entries removed.
*
* @author Andy Clement
*
*/
public class DistinctProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
List<Object> result = new ArrayList<Object>();
for (Object o : input) {
if (!result.contains(o))
result.add(o);
}
return result;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.Collection;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeComparator;
import org.springframework.expression.spel.ExpressionState;
/**
* The Max Processor returns the maximum element in the input collection, the maximum is determined using the comparator
* accessible in the evaluation context.
*
* @author Andy Clement
*
*/
public class MaxProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws EvaluationException {
Object max = null;
TypeComparator comparator = state.getTypeComparator();
for (Object element : input) {
if (max == null) {
max = element;
} else {
if (comparator.compare(element, max) > 0)
max = element;
}
}
return max;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.Collection;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeComparator;
import org.springframework.expression.spel.ExpressionState;
/**
* The Min Processor returns the minimum element in the input collection, the minimum is determined using the comparator
* accessible in the evaluation context.
*
* @author Andy Clement
*
*/
public class MinProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws EvaluationException {
Object minimum = null;
TypeComparator elementComparator = state.getTypeComparator();
for (Object element : input) {
if (minimum == null) {
minimum = element;
} else {
if (elementComparator.compare(element, minimum) < 0)
minimum = element;
}
}
return minimum;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.expression.spel.SpelException;
import org.springframework.expression.spel.ExpressionState;
/**
* The NonNull Processor returns a new collection containing all non-null entries from the input collection.
*
* @author Andy Clement
*
*/
public class NonNullProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws SpelException {
List<Object> l = new ArrayList<Object>();
for (Object o : input) {
if (o != null)
l.add(o);
}
return l;
}
}
/*
* Copyright 2004-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.expression.spel.processors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeComparator;
import org.springframework.expression.spel.ExpressionState;
/**
* The Sort Processor will sort an input collection, comparing elements using the comparator accessible in the
* evaluation context.
*
* @author Andy Clement
*
*/
@SuppressWarnings("unchecked")
public class SortProcessor implements DataProcessor {
public Object process(Collection<?> input, Object[] arguments, ExpressionState state) throws EvaluationException {
List<Object> sortedCollection = new ArrayList<Object>();
sortedCollection.addAll(input);
LocalComparator comparator = new LocalComparator(state.getTypeComparator());
Collections.sort(sortedCollection, comparator);
if (comparator.exceptionOccurred != null)
throw comparator.exceptionOccurred;
return sortedCollection;
}
private static class LocalComparator implements java.util.Comparator {
TypeComparator comparator;
EvaluationException exceptionOccurred;
public LocalComparator(TypeComparator comparator) {
this.comparator = comparator;
}
public int compare(Object o1, Object o2) {
try {
return comparator.compare(o1, o2);
} catch (EvaluationException e) {
exceptionOccurred = e;
return 0;
}
}
}
}
<html>
<body>
<p>
Contains the registered collection processors available 'out of the box' with Spring
Expression Language. They are:<ul>
<li>sort() - sorts a collection
<li>nonnull() - returns a new collection containing the non-null elements from the input collection
<li>count() - returns the number of elements in the collection
<li>min() - returns the minimum element from the input collection
<li>max() - returns the maximum element from the input collection
<li>distinct() - returns a new collection where duplicates from the input collection have been removed
</p>
</body>
</html>
\ No newline at end of file
......@@ -24,50 +24,56 @@ import org.springframework.expression.spel.standard.StandardEvaluationContext;
*/
public class ConstructorInvocationTests extends ExpressionTestCase {
public void testPrimitiveTypeArrayConstructors() {
evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
evaluate("new boolean[]{true,false,true}.count()", 3, Integer.class);
evaluate("new char[]{'a','b','c'}.count()", 3, Integer.class);
evaluate("new long[]{1,2,3,4,5}.count()", 5, Integer.class);
evaluate("new short[]{2,3,4,5,6}.count()", 5, Integer.class);
evaluate("new double[]{1d,2d,3d,4d}.count()", 4, Integer.class);
evaluate("new float[]{1f,2f,3f,4f}.count()", 4, Integer.class);
evaluate("new byte[]{1,2,3,4}.count()", 4, Integer.class);
}
// public void testPrimitiveTypeArrayConstructors() {
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
// evaluate("new boolean[]{true,false,true}.count()", 3, Integer.class);
// evaluate("new char[]{'a','b','c'}.count()", 3, Integer.class);
// evaluate("new long[]{1,2,3,4,5}.count()", 5, Integer.class);
// evaluate("new short[]{2,3,4,5,6}.count()", 5, Integer.class);
// evaluate("new double[]{1d,2d,3d,4d}.count()", 4, Integer.class);
// evaluate("new float[]{1f,2f,3f,4f}.count()", 4, Integer.class);
// evaluate("new byte[]{1,2,3,4}.count()", 4, Integer.class);
// }
public void testPrimitiveTypeArrayConstructorsElements() {
evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class);
evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class);
evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class);
evaluate("new long[]{1,2,3,4,5}[0]", 1L, Long.class);
evaluate("new short[]{2,3,4,5,6}[0]", (short) 2, Short.class);
evaluate("new double[]{1d,2d,3d,4d}[0]", (double) 1, Double.class);
evaluate("new float[]{1f,2f,3f,4f}[0]", (float) 1, Float.class);
evaluate("new byte[]{1,2,3,4}[0]", (byte) 1, Byte.class);
}
// public void testPrimitiveTypeArrayConstructorsElements() {
// evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class);
// evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class);
// evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class);
// evaluate("new long[]{1,2,3,4,5}[0]", 1L, Long.class);
// evaluate("new short[]{2,3,4,5,6}[0]", (short) 2, Short.class);
// evaluate("new double[]{1d,2d,3d,4d}[0]", (double) 1, Double.class);
// evaluate("new float[]{1f,2f,3f,4f}[0]", (float) 1, Float.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);
// 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);
evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessages.TYPE_CONVERSION_ERROR);
evaluateAndCheckError("new String('a','c','d')", SpelMessages.CONSTRUCTOR_NOT_FOUND);
}
// 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);
// evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessages.TYPE_CONVERSION_ERROR);
// evaluateAndCheckError("new String('a','c','d')", SpelMessages.CONSTRUCTOR_NOT_FOUND);
// }
public void testTypeArrayConstructors() {
evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class);
evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessages.METHOD_NOT_FOUND, 30, "size()", "java.lang.String[]");
evaluateAndCheckError("new String[]{'a','b','c','d'}.juggernaut", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 30, "juggernaut", "java.lang.String[]");
evaluate("new String[]{'a','b','c','d'}.length", 4, Integer.class);
}
public void testMultiDimensionalArrays() {
evaluate("new String[3,4]","[Ljava.lang.String;[3]{java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null}}",new String[3][4].getClass());
}
// public void testTypeArrayConstructors() {
// evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class);
// evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessages.METHOD_NOT_FOUND, 30, "size()",
// "java.lang.String[]");
// evaluateAndCheckError("new String[]{'a','b','c','d'}.juggernaut", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 30,
// "juggernaut", "java.lang.String[]");
// evaluate("new String[]{'a','b','c','d'}.length", 4, Integer.class);
// }
// public void testMultiDimensionalArrays() {
// evaluate(
// "new String[3,4]",
// "[Ljava.lang.String;[3]{java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null}}"
// ,
// new String[3][4].getClass());
// }
/*
* These tests are attempting to call constructors where we need to widen or convert the argument in order to
......@@ -84,7 +90,7 @@ public class ConstructorInvocationTests extends ExpressionTestCase {
// Closest ctor will be new String(String) and converter supports Double>String
evaluate("new String(3.0d)", "3.0", String.class);
}
public void testVarargsInvocation01() throws Exception {
// Calling 'public TestCode(String... strings)'
SpelExpressionParser parser = new SpelExpressionParser();
......@@ -98,7 +104,7 @@ public class ConstructorInvocationTests extends ExpressionTestCase {
v = parser.parseExpression("new TestType(1,2,3)").getValue(ctx);
v = parser.parseExpression("new TestType(1)").getValue(ctx);
v = parser.parseExpression("new TestType(1,'a',3.0d)").getValue(ctx);
v = parser.parseExpression("new TestType(new String[]{'a','b','c'})").getValue(ctx);
// v = parser.parseExpression("new TestType(new String[]{'a','b','c'})").getValue(ctx);
}
}
......@@ -15,8 +15,6 @@
*/
package org.springframework.expression.spel;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Tests the evaluation of real expressions in a real context.
......@@ -46,42 +44,42 @@ public class EvaluationTests extends ExpressionTestCase {
evaluate("3 >= 3", "true", Boolean.class);
}
public void testRelOperatorsIn01() {
evaluate("3 in {1,2,3,4,5}", "true", Boolean.class);
}
public void testRelOperatorsIn02() {
evaluate("name in {null, \"Nikola Tesla\"}", "true", Boolean.class);
evaluate("name in {null, \"Anonymous\"}", "false", Boolean.class);
}
public void testRelOperatorsBetween01() {
evaluate("1 between {1, 5}", "true", Boolean.class);
}
public void testRelOperatorsBetween02() {
evaluate("'efg' between {'abc', 'xyz'}", "true", Boolean.class);
}
public void testRelOperatorsBetweenErrors01() {
evaluateAndCheckError("1 between T(String)", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 12);
}
// public void testRelOperatorsIn01() {
// evaluate("3 in {1,2,3,4,5}", "true", Boolean.class);
// }
public void testRelOperatorsBetweenErrors02() {
evaluateAndCheckError("'abc' between {5,7}", SpelMessages.NOT_COMPARABLE, 6);
}
// public void testRelOperatorsIn02() {
// evaluate("name in {null, \"Nikola Tesla\"}", "true", Boolean.class);
// evaluate("name in {null, \"Anonymous\"}", "false", Boolean.class);
// }
//
// public void testRelOperatorsBetween01() {
// evaluate("1 between {1, 5}", "true", Boolean.class);
// }
//
// public void testRelOperatorsBetween02() {
// evaluate("'efg' between {'abc', 'xyz'}", "true", Boolean.class);
// }
//
// public void testRelOperatorsBetweenErrors01() {
// evaluateAndCheckError("1 between T(String)", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 12);
// }
//
// public void testRelOperatorsBetweenErrors02() {
// evaluateAndCheckError("'abc' between {5,7}", SpelMessages.NOT_COMPARABLE, 6);
// }
public void testRelOperatorsIs01() {
evaluate("'xyz' instanceof T(int)", "false", Boolean.class);
}
public void testRelOperatorsIs02() {
evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
}
public void testRelOperatorsIs03() {
evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
}
// public void testRelOperatorsIs02() {
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
// }
//
// public void testRelOperatorsIs03() {
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
// }
public void testRelOperatorsIs04() {
evaluate("null instanceof T(String)", "false", Boolean.class);
......@@ -148,70 +146,70 @@ public class EvaluationTests extends ExpressionTestCase {
}
// inline list creation
public void testInlineListCreation01() {
evaluate("{1, 2, 3, 4, 5}", "[1, 2, 3, 4, 5]", ArrayList.class);
}
public void testInlineListCreation02() {
evaluate("{'abc', 'xyz'}", "[abc, xyz]", ArrayList.class);
}
// inline map creation
public void testInlineMapCreation01() {
evaluate("#{'key1':'Value 1', 'today':'Monday'}", "{key1=Value 1, today=Monday}", HashMap.class);
}
public void testInlineMapCreation02() {
evaluate("#{1:'January', 2:'February', 3:'March'}.size()", 3, Integer.class);// "{2=February, 1=January,
// 3=March}", HashMap.class);
}
public void testInlineMapCreation03() {
evaluate("#{'key1':'Value 1', 'today':'Monday'}['key1']", "Value 1", String.class);
}
public void testInlineMapCreation04() {
evaluate("#{1:'January', 2:'February', 3:'March'}[3]", "March", String.class);
}
public void testInlineMapCreation05() {
evaluate("#{1:'January', 2:'February', 3:'March'}.get(2)", "February", String.class);
}
// set construction
public void testSetConstruction01() {
evaluate("new HashSet().addAll({'a','b','c'})", "true", Boolean.class);
}
// public void testInlineListCreation01() {
// evaluate("{1, 2, 3, 4, 5}", "[1, 2, 3, 4, 5]", ArrayList.class);
// }
//
// public void testInlineListCreation02() {
// evaluate("{'abc', 'xyz'}", "[abc, xyz]", ArrayList.class);
// }
//
// // inline map creation
// public void testInlineMapCreation01() {
// evaluate("#{'key1':'Value 1', 'today':'Monday'}", "{key1=Value 1, today=Monday}", HashMap.class);
// }
//
// public void testInlineMapCreation02() {
// evaluate("#{1:'January', 2:'February', 3:'March'}.size()", 3, Integer.class);// "{2=February, 1=January,
// // 3=March}", HashMap.class);
// }
//
// public void testInlineMapCreation03() {
// evaluate("#{'key1':'Value 1', 'today':'Monday'}['key1']", "Value 1", String.class);
// }
//
// public void testInlineMapCreation04() {
// evaluate("#{1:'January', 2:'February', 3:'March'}[3]", "March", String.class);
// }
//
// public void testInlineMapCreation05() {
// evaluate("#{1:'January', 2:'February', 3:'March'}.get(2)", "February", String.class);
// }
//
// // set construction
// public void testSetConstruction01() {
// evaluate("new HashSet().addAll({'a','b','c'})", "true", Boolean.class);
// }
// constructors
public void testConstructorInvocation01() {
evaluate("new String('hello')", "hello", String.class);
}
public void testConstructorInvocation02() {
evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class);
}
// public void testConstructorInvocation02() {
// evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class);
// }
public void testConstructorInvocation03() {
evaluateAndCheckError("new String[]", SpelMessages.NO_SIZE_OR_INITIALIZER_FOR_ARRAY_CONSTRUCTION, 4);
}
// public void testConstructorInvocation03() {
// evaluateAndCheckError("new String[]", SpelMessages.NO_SIZE_OR_INITIALIZER_FOR_ARRAY_CONSTRUCTION, 4);
// }
public void testConstructorInvocation04() {
evaluateAndCheckError("new String[3]{'abc',3,'def'}", SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4);
}
// public void testConstructorInvocation04() {
// evaluateAndCheckError("new String[3]{'abc',3,'def'}", SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4);
// }
public void testConstructorInvocation05() {
evaluate("new java.lang.String('foobar')", "foobar", String.class);
}
// array construction
public void testArrayConstruction01() {
evaluate("new int[] {1, 2, 3, 4, 5}", "int[5]{1,2,3,4,5}", int[].class);
}
// public void testArrayConstruction01() {
// evaluate("new int[] {1, 2, 3, 4, 5}", "int[5]{1,2,3,4,5}", int[].class);
// }
public void testArrayConstruction02() {
evaluate("new String[] {'abc', 'xyz'}", "java.lang.String[2]{abc,xyz}", String[].class);
}
// public void testArrayConstruction02() {
// evaluate("new String[] {'abc', 'xyz'}", "java.lang.String[2]{abc,xyz}", String[].class);
// }
// unary expressions
public void testUnaryMinus01() {
......@@ -228,85 +226,85 @@ public class EvaluationTests extends ExpressionTestCase {
// collection processors
// from spring.net: count,sum,max,min,average,sort,orderBy,distinct,nonNull
public void testProcessorsCount01() {
evaluate("new String[] {'abc','def','xyz'}.count()", "3", Integer.class);
}
public void testProcessorsCount02() {
evaluate("new int[] {1,2,3}.count()", "3", Integer.class);
}
public void testProcessorsMax01() {
evaluate("new int[] {1,2,3}.max()", "3", Integer.class);
}
public void testProcessorsMin01() {
evaluate("new int[] {1,2,3}.min()", "1", Integer.class);
}
public void testProcessorsKeys01() {
evaluate("#{1:'January', 2:'February', 3:'March'}.keySet().sort()", "[1, 2, 3]", ArrayList.class);
}
public void testProcessorsValues01() {
evaluate("#{1:'January', 2:'February', 3:'March'}.values().sort()", "[February, January, March]",
ArrayList.class);
}
public void testProcessorsAverage01() {
evaluate("new int[] {1,2,3}.average()", "2", Integer.class);
}
public void testProcessorsSort01() {
evaluate("new int[] {3,2,1}.sort()", "int[3]{1,2,3}", int[].class);
}
public void testCollectionProcessorsNonNull01() {
evaluate("{'a','b',null,'d',null}.nonnull()", "[a, b, d]", ArrayList.class);
}
public void testCollectionProcessorsDistinct01() {
evaluate("{'a','b','a','d','e'}.distinct()", "[a, b, d, e]", ArrayList.class);
}
// public void testProcessorsCount01() {
// evaluate("new String[] {'abc','def','xyz'}.count()", "3", Integer.class);
// }
//
// public void testProcessorsCount02() {
// evaluate("new int[] {1,2,3}.count()", "3", Integer.class);
// }
//
// public void testProcessorsMax01() {
// evaluate("new int[] {1,2,3}.max()", "3", Integer.class);
// }
//
// public void testProcessorsMin01() {
// evaluate("new int[] {1,2,3}.min()", "1", Integer.class);
// }
//
// public void testProcessorsKeys01() {
// evaluate("#{1:'January', 2:'February', 3:'March'}.keySet().sort()", "[1, 2, 3]", ArrayList.class);
// }
//
// public void testProcessorsValues01() {
// evaluate("#{1:'January', 2:'February', 3:'March'}.values().sort()", "[February, January, March]",
// ArrayList.class);
// }
//
// public void testProcessorsAverage01() {
// evaluate("new int[] {1,2,3}.average()", "2", Integer.class);
// }
//
// public void testProcessorsSort01() {
// evaluate("new int[] {3,2,1}.sort()", "int[3]{1,2,3}", int[].class);
// }
//
// public void testCollectionProcessorsNonNull01() {
// evaluate("{'a','b',null,'d',null}.nonnull()", "[a, b, d]", ArrayList.class);
// }
//
// public void testCollectionProcessorsDistinct01() {
// evaluate("{'a','b','a','d','e'}.distinct()", "[a, b, d, e]", ArrayList.class);
// }
// projection and selection
public void testProjection01() {
evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#isEven(#this)}", "[n, y, n, y, n, y, n, y, n, y]", ArrayList.class);
}
public void testProjection02() {
evaluate("#{'a':'y','b':'n','c':'y'}.!{value=='y'?key:null}.nonnull().sort()", "[a, c]", ArrayList.class);
}
public void testProjection03() {
evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#this>5}",
"[false, false, false, false, false, true, true, true, true, true]", ArrayList.class);
}
// public void testProjection01() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#isEven(#this)}", "[n, y, n, y, n, y, n, y, n, y]", ArrayList.class);
// }
//
// public void testProjection02() {
// evaluate("#{'a':'y','b':'n','c':'y'}.!{value=='y'?key:null}.nonnull().sort()", "[a, c]", ArrayList.class);
// }
//
// public void testProjection03() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#this>5}",
// "[false, false, false, false, false, true, true, true, true, true]", ArrayList.class);
// }
// public void testProjection04() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{$index>5?'y':'n'}", "[n, n, n, n, n, n, y, y, y, y]", ArrayList.class);
// }
public void testSelection01() {
evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
}
// public void testSelection01() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
// }
public void testSelectionError_NonBooleanSelectionCriteria() {
evaluateAndCheckError("{1,2,3,4,5,6,7,8,9,10}.?{'nonboolean'}",
SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
}
// public void testSelectionError_NonBooleanSelectionCriteria() {
// evaluateAndCheckError("{1,2,3,4,5,6,7,8,9,10}.?{'nonboolean'}",
// SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
// }
// public void testSelectionUsingIndex() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{$index > 5 }", "[7, 8, 9, 10]", ArrayList.class);
// }
public void testSelectionFirst01() {
evaluate("{1,2,3,4,5,6,7,8,9,10}.^{#isEven(#this) == 'y'}", "2", Integer.class);
}
public void testSelectionLast01() {
evaluate("{1,2,3,4,5,6,7,8,9,10}.${#isEven(#this) == 'y'}", "10", Integer.class);
}
// public void testSelectionFirst01() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.^{#isEven(#this) == 'y'}", "2", Integer.class);
// }
//
// public void testSelectionLast01() {
// evaluate("{1,2,3,4,5,6,7,8,9,10}.${#isEven(#this) == 'y'}", "10", Integer.class);
// }
// assignment
public void testAssignmentToVariables01() {
......@@ -314,13 +312,13 @@ public class EvaluationTests extends ExpressionTestCase {
}
// Ternary operator
public void testTernaryOperator01() {
evaluate("{1}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is odd", String.class);
}
public void testTernaryOperator02() {
evaluate("{2}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is even", String.class);
}
// public void testTernaryOperator01() {
// evaluate("{1}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is odd", String.class);
// }
//
// public void testTernaryOperator02() {
// evaluate("{2}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is even", String.class);
// }
public void testTernaryOperator03() {
evaluateAndCheckError("'hello'?1:2", SpelMessages.TYPE_CONVERSION_ERROR); // cannot convert String to boolean
......@@ -333,13 +331,13 @@ public class EvaluationTests extends ExpressionTestCase {
}
// Indexer
public void testCutProcessor01() {
evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
}
public void testCutProcessor02() {
evaluate("{1,2,3,4,5}.cut(3,1)", "[4, 3, 2]", ArrayList.class);
}
// public void testCutProcessor01() {
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
// }
//
// public void testCutProcessor02() {
// evaluate("{1,2,3,4,5}.cut(3,1)", "[4, 3, 2]", ArrayList.class);
// }
public void testIndexer03() {
evaluate("'christian'[8]", "n", String.class);
......
......@@ -30,16 +30,16 @@ public class MethodInvocationTests extends ExpressionTestCase {
evaluate("getPlaceOfBirth().getCity()", "SmilJan", String.class);
}
public void testBuiltInProcessors() {
evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
evaluate("new int[]{4,3,2,1}.sort()[3]", 4, Integer.class);
evaluate("new int[]{4,3,2,1}.average()", 2, Integer.class);
evaluate("new int[]{4,3,2,1}.max()", 4, Integer.class);
evaluate("new int[]{4,3,2,1}.min()", 1, Integer.class);
evaluate("new int[]{4,3,2,1,2,3}.distinct().count()", 4, Integer.class);
evaluate("{1,2,3,null}.nonnull().count()", 3, Integer.class);
evaluate("new int[]{4,3,2,1,2,3}.distinct().count()", 4, Integer.class);
}
// public void testBuiltInProcessors() {
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
// evaluate("new int[]{4,3,2,1}.sort()[3]", 4, Integer.class);
// evaluate("new int[]{4,3,2,1}.average()", 2, Integer.class);
// evaluate("new int[]{4,3,2,1}.max()", 4, Integer.class);
// evaluate("new int[]{4,3,2,1}.min()", 1, Integer.class);
// evaluate("new int[]{4,3,2,1,2,3}.distinct().count()", 4, Integer.class);
// evaluate("{1,2,3,null}.nonnull().count()", 3, Integer.class);
// evaluate("new int[]{4,3,2,1,2,3}.distinct().count()", 4, Integer.class);
// }
public void testStringClass() {
evaluate("new java.lang.String('hello').charAt(2)", 'l', Character.class);
......@@ -74,7 +74,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
evaluate("aVarargsMethod(1,2,3)", 3, Integer.class); // all need converting to strings
evaluate("aVarargsMethod(1)", 1, Integer.class); // needs string conversion
evaluate("aVarargsMethod(1,'a',3.0d)", 3, Integer.class); // first and last need conversion
evaluate("aVarargsMethod(new String[]{'a','b','c'})", 3, Integer.class);
// evaluate("aVarargsMethod(new String[]{'a','b','c'})", 3, Integer.class);
}
public void testVarargsInvocation02() {
......@@ -85,7 +85,7 @@ public class MethodInvocationTests extends ExpressionTestCase {
evaluate("aVarargsMethod2(8,2,3)", 10, Integer.class);
evaluate("aVarargsMethod2(9)", 9, Integer.class);
evaluate("aVarargsMethod2(2,'a',3.0d)", 4, Integer.class);
evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class);
// evaluate("aVarargsMethod2(8,new String[]{'a','b','c'})", 11, Integer.class);
}
// Due to conversion there are two possible methods to call ...
......
......@@ -133,25 +133,25 @@ public class ParsingTests extends TestCase {
parseCheck("3>=3", "(3 >= 3)");
}
public void testRelOperatorsIn01() {
parseCheck("3 in {1,2,3,4,5}", "(3 in {1,2,3,4,5})");
}
public void testRelOperatorsBetween01() {
parseCheck("1 between {1, 5}", "(1 between {1,5})");
}
// public void testRelOperatorsIn01() {
// parseCheck("3 in {1,2,3,4,5}", "(3 in {1,2,3,4,5})");
// }
//
// public void testRelOperatorsBetween01() {
// parseCheck("1 between {1, 5}", "(1 between {1,5})");
// }
public void testRelOperatorsBetween02() {
parseCheck("'efg' between {'abc', 'xyz'}", "('efg' between {'abc','xyz'})");
}// true
// public void testRelOperatorsBetween02() {
// parseCheck("'efg' between {'abc', 'xyz'}", "('efg' between {'abc','xyz'})");
// }// true
public void testRelOperatorsIs01() {
parseCheck("'xyz' instanceof int", "('xyz' instanceof int)");
}// false
public void testRelOperatorsIs02() {
parseCheck("{1, 2, 3, 4, 5} instanceof List", "({1,2,3,4,5} instanceof List)");
}// true
// public void testRelOperatorsIs02() {
// parseCheck("{1, 2, 3, 4, 5} instanceof List", "({1,2,3,4,5} instanceof List)");
// }// true
public void testRelOperatorsMatches01() {
parseCheck("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'", "('5.0067' matches '^-?\\d+(\\.\\d{2})?$')");
......@@ -196,37 +196,37 @@ public class ParsingTests extends TestCase {
}
// collection processors
public void testCollectionProcessorsCount01() {
parseCheck("new String[] {'abc','def','xyz'}.count()");
}
public void testCollectionProcessorsCount02() {
parseCheck("new int[] {1,2,3}.count()");
}
public void testCollectionProcessorsMax01() {
parseCheck("new int[] {1,2,3}.max()");
}
public void testCollectionProcessorsMin01() {
parseCheck("new int[] {1,2,3}.min()");
}
public void testCollectionProcessorsAverage01() {
parseCheck("new int[] {1,2,3}.average()");
}
public void testCollectionProcessorsSort01() {
parseCheck("new int[] {3,2,1}.sort()");
}
public void testCollectionProcessorsNonNull01() {
parseCheck("{'a','b',null,'d',null}.nonNull()");
}
// public void testCollectionProcessorsCount01() {
// parseCheck("new String[] {'abc','def','xyz'}.count()");
// }
public void testCollectionProcessorsDistinct01() {
parseCheck("{'a','b','a','d','e'}.distinct()");
}
// public void testCollectionProcessorsCount02() {
// parseCheck("new int[] {1,2,3}.count()");
// }
//
// public void testCollectionProcessorsMax01() {
// parseCheck("new int[] {1,2,3}.max()");
// }
//
// public void testCollectionProcessorsMin01() {
// parseCheck("new int[] {1,2,3}.min()");
// }
//
// public void testCollectionProcessorsAverage01() {
// parseCheck("new int[] {1,2,3}.average()");
// }
//
// public void testCollectionProcessorsSort01() {
// parseCheck("new int[] {3,2,1}.sort()");
// }
//
// public void testCollectionProcessorsNonNull01() {
// parseCheck("{'a','b',null,'d',null}.nonNull()");
// }
//
// public void testCollectionProcessorsDistinct01() {
// parseCheck("{'a','b','a','d','e'}.distinct()");
// }
// // references
// public void testReferences01() {
......@@ -255,30 +255,30 @@ public class ParsingTests extends TestCase {
}
// inline list creation
public void testInlineListCreation01() {
parseCheck("{1, 2, 3, 4, 5}", "{1,2,3,4,5}");
}
public void testInlineListCreation02() {
parseCheck("{'abc','xyz'}", "{'abc','xyz'}");
}
// inline map creation
public void testInlineMapCreation01() {
parseCheck("#{'key1':'Value 1', 'today':DateTime.Today}");
}
public void testInlineMapCreation02() {
parseCheck("#{1:'January', 2:'February', 3:'March'}");
}
public void testInlineMapCreation03() {
parseCheck("#{'key1':'Value 1', 'today':'Monday'}['key1']");
}
// public void testInlineListCreation01() {
// parseCheck("{1, 2, 3, 4, 5}", "{1,2,3,4,5}");
// }
//
// public void testInlineListCreation02() {
// parseCheck("{'abc','xyz'}", "{'abc','xyz'}");
// }
public void testInlineMapCreation04() {
parseCheck("#{1:'January', 2:'February', 3:'March'}[3]");
}
// // inline map creation
// public void testInlineMapCreation01() {
// parseCheck("#{'key1':'Value 1', 'today':DateTime.Today}");
// }
//
// public void testInlineMapCreation02() {
// parseCheck("#{1:'January', 2:'February', 3:'March'}");
// }
//
// public void testInlineMapCreation03() {
// parseCheck("#{'key1':'Value 1', 'today':'Monday'}['key1']");
// }
//
// public void testInlineMapCreation04() {
// parseCheck("#{1:'January', 2:'February', 3:'March'}[3]");
// }
// methods
public void testMethods01() {
......@@ -298,18 +298,18 @@ public class ParsingTests extends TestCase {
parseCheck("new String('hello')");
}
public void testConstructors02() {
parseCheck("new String[3]");
}
// public void testConstructors02() {
// parseCheck("new String[3]");
// }
// array construction
public void testArrayConstruction01() {
parseCheck("new int[] {1, 2, 3, 4, 5}", "new int[] {1,2,3,4,5}");
}
public void testArrayConstruction02() {
parseCheck("new String[] {'abc','xyz'}", "new String[] {'abc','xyz'}");
}
// public void testArrayConstruction01() {
// parseCheck("new int[] {1, 2, 3, 4, 5}", "new int[] {1,2,3,4,5}");
// }
//
// public void testArrayConstruction02() {
// parseCheck("new String[] {'abc','xyz'}", "new String[] {'abc','xyz'}");
// }
// variables and functions
public void testVariables01() {
......@@ -325,24 +325,24 @@ public class ParsingTests extends TestCase {
}
// projections and selections
public void testProjections01() {
parseCheck("{1,2,3,4,5,6,7,8,9,10}.!{#isEven()}");
}
// public void testProjections01() {
// parseCheck("{1,2,3,4,5,6,7,8,9,10}.!{#isEven()}");
// }
public void testSelections01() {
parseCheck("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}",
"{1,2,3,4,5,6,7,8,9,10}.?{(#isEven(#this) == 'y')}");
}
// public void testSelections01() {
// parseCheck("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}",
// "{1,2,3,4,5,6,7,8,9,10}.?{(#isEven(#this) == 'y')}");
// }
public void testSelectionsFirst01() {
parseCheck("{1,2,3,4,5,6,7,8,9,10}.^{#isEven(#this) == 'y'}",
"{1,2,3,4,5,6,7,8,9,10}.^{(#isEven(#this) == 'y')}");
}
// public void testSelectionsFirst01() {
// parseCheck("{1,2,3,4,5,6,7,8,9,10}.^{#isEven(#this) == 'y'}",
// "{1,2,3,4,5,6,7,8,9,10}.^{(#isEven(#this) == 'y')}");
// }
public void testSelectionsLast01() {
parseCheck("{1,2,3,4,5,6,7,8,9,10}.${#isEven(#this) == 'y'}",
"{1,2,3,4,5,6,7,8,9,10}.${(#isEven(#this) == 'y')}");
}
// public void testSelectionsLast01() {
// parseCheck("{1,2,3,4,5,6,7,8,9,10}.${#isEven(#this) == 'y'}",
// "{1,2,3,4,5,6,7,8,9,10}.${(#isEven(#this) == 'y')}");
// }
// assignment
public void testAssignmentToVariables01() {
......@@ -350,10 +350,10 @@ public class ParsingTests extends TestCase {
}
// ternary operator
public void testTernaryOperator01() {
parseCheck("{1}.#isEven(#this) == 'y'?'it is even':'it is odd'",
"({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd'");
}
// public void testTernaryOperator01() {
// parseCheck("{1}.#isEven(#this) == 'y'?'it is even':'it is odd'",
// "({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd'");
// }
//
// public void testLambdaMax() {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册