use of org.springframework.expression.spel.ast.SpelNodeImpl in project spring-framework by spring-projects.
the class SpelCompilationCoverageTests method compiledExpressionShouldWorkWhenUsingCustomFunctionWithVarargs.
@Test
public void compiledExpressionShouldWorkWhenUsingCustomFunctionWithVarargs() throws Exception {
StandardEvaluationContext context = null;
// Here the target method takes Object... and we are passing a string
expression = parser.parseExpression("#doFormat('hey %s', 'there')");
context = new StandardEvaluationContext();
context.registerFunction("doFormat", DelegatingStringFormat.class.getDeclaredMethod("format", String.class, Object[].class));
((SpelExpression) expression).setEvaluationContext(context);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
expression = parser.parseExpression("#doFormat([0], 'there')");
context = new StandardEvaluationContext(new Object[] { "hey %s" });
context.registerFunction("doFormat", DelegatingStringFormat.class.getDeclaredMethod("format", String.class, Object[].class));
((SpelExpression) expression).setEvaluationContext(context);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
expression = parser.parseExpression("#doFormat([0], #arg)");
context = new StandardEvaluationContext(new Object[] { "hey %s" });
context.registerFunction("doFormat", DelegatingStringFormat.class.getDeclaredMethod("format", String.class, Object[].class));
context.setVariable("arg", "there");
((SpelExpression) expression).setEvaluationContext(context);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(String.class)).isEqualTo("hey there");
}
use of org.springframework.expression.spel.ast.SpelNodeImpl in project spring-framework by spring-projects.
the class SpelCompilationCoverageTests method functionReferenceVarargs_SPR12359.
@Test
public void functionReferenceVarargs_SPR12359() throws Exception {
StandardEvaluationContext context = new StandardEvaluationContext();
context.registerFunction("append", SomeCompareMethod2.class.getDeclaredMethod("append", String[].class));
context.registerFunction("append2", SomeCompareMethod2.class.getDeclaredMethod("append2", Object[].class));
context.registerFunction("append3", SomeCompareMethod2.class.getDeclaredMethod("append3", String[].class));
context.registerFunction("append4", SomeCompareMethod2.class.getDeclaredMethod("append4", String.class, String[].class));
context.registerFunction("appendChar", SomeCompareMethod2.class.getDeclaredMethod("appendChar", char[].class));
context.registerFunction("sum", SomeCompareMethod2.class.getDeclaredMethod("sum", int[].class));
context.registerFunction("sumDouble", SomeCompareMethod2.class.getDeclaredMethod("sumDouble", double[].class));
context.registerFunction("sumFloat", SomeCompareMethod2.class.getDeclaredMethod("sumFloat", float[].class));
context.setVariable("stringArray", new String[] { "x", "y", "z" });
context.setVariable("intArray", new int[] { 5, 6, 9 });
context.setVariable("doubleArray", new double[] { 5.0d, 6.0d, 9.0d });
context.setVariable("floatArray", new float[] { 5.0f, 6.0f, 9.0f });
expression = parser.parseExpression("#append('a','b','c')");
assertThat(expression.getValue(context).toString()).isEqualTo("abc");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("abc");
expression = parser.parseExpression("#append('a')");
assertThat(expression.getValue(context).toString()).isEqualTo("a");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("a");
expression = parser.parseExpression("#append()");
assertThat(expression.getValue(context).toString()).isEqualTo("");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("");
expression = parser.parseExpression("#append(#stringArray)");
assertThat(expression.getValue(context).toString()).isEqualTo("xyz");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("xyz");
// This is a methodreference invocation, to compare with functionreference
expression = parser.parseExpression("append(#stringArray)");
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("xyz");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("xyz");
expression = parser.parseExpression("#append2('a','b','c')");
assertThat(expression.getValue(context).toString()).isEqualTo("abc");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("abc");
expression = parser.parseExpression("append2('a','b')");
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("ab");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("ab");
expression = parser.parseExpression("#append2('a','b')");
assertThat(expression.getValue(context).toString()).isEqualTo("ab");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("ab");
expression = parser.parseExpression("#append2()");
assertThat(expression.getValue(context).toString()).isEqualTo("");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("");
expression = parser.parseExpression("#append3(#stringArray)");
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("xyz");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context, new SomeCompareMethod2()).toString()).isEqualTo("xyz");
// TODO fails due to conversionservice handling of String[] to Object...
// expression = parser.parseExpression("#append2(#stringArray)");
// assertEquals("xyz", expression.getValue(context).toString());
// assertTrue(((SpelNodeImpl)((SpelExpression) expression).getAST()).isCompilable());
// assertCanCompile(expression);
// assertEquals("xyz", expression.getValue(context).toString());
expression = parser.parseExpression("#sum(1,2,3)");
assertThat(expression.getValue(context)).isEqualTo(6);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(6);
expression = parser.parseExpression("#sum(2)");
assertThat(expression.getValue(context)).isEqualTo(2);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(2);
expression = parser.parseExpression("#sum()");
assertThat(expression.getValue(context)).isEqualTo(0);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(0);
expression = parser.parseExpression("#sum(#intArray)");
assertThat(expression.getValue(context)).isEqualTo(20);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(20);
expression = parser.parseExpression("#sumDouble(1.0d,2.0d,3.0d)");
assertThat(expression.getValue(context)).isEqualTo(6);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(6);
expression = parser.parseExpression("#sumDouble(2.0d)");
assertThat(expression.getValue(context)).isEqualTo(2);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(2);
expression = parser.parseExpression("#sumDouble()");
assertThat(expression.getValue(context)).isEqualTo(0);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(0);
expression = parser.parseExpression("#sumDouble(#doubleArray)");
assertThat(expression.getValue(context)).isEqualTo(20);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(20);
expression = parser.parseExpression("#sumFloat(1.0f,2.0f,3.0f)");
assertThat(expression.getValue(context)).isEqualTo(6);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(6);
expression = parser.parseExpression("#sumFloat(2.0f)");
assertThat(expression.getValue(context)).isEqualTo(2);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(2);
expression = parser.parseExpression("#sumFloat()");
assertThat(expression.getValue(context)).isEqualTo(0);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(0);
expression = parser.parseExpression("#sumFloat(#floatArray)");
assertThat(expression.getValue(context)).isEqualTo(20);
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo(20);
expression = parser.parseExpression("#appendChar('abc'.charAt(0),'abc'.charAt(1))");
assertThat(expression.getValue(context)).isEqualTo("ab");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context)).isEqualTo("ab");
expression = parser.parseExpression("#append4('a','b','c')");
assertThat(expression.getValue(context).toString()).isEqualTo("a::bc");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("a::bc");
expression = parser.parseExpression("#append4('a','b')");
assertThat(expression.getValue(context).toString()).isEqualTo("a::b");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("a::b");
expression = parser.parseExpression("#append4('a')");
assertThat(expression.getValue(context).toString()).isEqualTo("a::");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("a::");
expression = parser.parseExpression("#append4('a',#stringArray)");
assertThat(expression.getValue(context).toString()).isEqualTo("a::xyz");
assertThat(((SpelNodeImpl) ((SpelExpression) expression).getAST()).isCompilable()).isTrue();
assertCanCompile(expression);
assertThat(expression.getValue(context).toString()).isEqualTo("a::xyz");
}
use of org.springframework.expression.spel.ast.SpelNodeImpl in project spring-framework by spring-projects.
the class InternalSpelExpressionParser method maybeEatInlineListOrMap.
// list = LCURLY (element (COMMA element)*) RCURLY
// map = LCURLY (key ':' value (COMMA key ':' value)*) RCURLY
private boolean maybeEatInlineListOrMap() {
Token t = peekToken();
if (!peekToken(TokenKind.LCURLY, true)) {
return false;
}
Assert.state(t != null, "No token");
SpelNodeImpl expr = null;
Token closingCurly = peekToken();
if (peekToken(TokenKind.RCURLY, true)) {
// empty list '{}'
Assert.state(closingCurly != null, "No token");
expr = new InlineList(t.startPos, closingCurly.endPos);
} else if (peekToken(TokenKind.COLON, true)) {
closingCurly = eatToken(TokenKind.RCURLY);
// empty map '{:}'
expr = new InlineMap(t.startPos, closingCurly.endPos);
} else {
SpelNodeImpl firstExpression = eatExpression();
// ':' - this is a map!
if (peekToken(TokenKind.RCURLY)) {
// list with one item in it
List<SpelNodeImpl> elements = new ArrayList<>();
elements.add(firstExpression);
closingCurly = eatToken(TokenKind.RCURLY);
expr = new InlineList(t.startPos, closingCurly.endPos, elements.toArray(new SpelNodeImpl[0]));
} else if (peekToken(TokenKind.COMMA, true)) {
// multi-item list
List<SpelNodeImpl> elements = new ArrayList<>();
elements.add(firstExpression);
do {
elements.add(eatExpression());
} while (peekToken(TokenKind.COMMA, true));
closingCurly = eatToken(TokenKind.RCURLY);
expr = new InlineList(t.startPos, closingCurly.endPos, elements.toArray(new SpelNodeImpl[0]));
} else if (peekToken(TokenKind.COLON, true)) {
// map!
List<SpelNodeImpl> elements = new ArrayList<>();
elements.add(firstExpression);
elements.add(eatExpression());
while (peekToken(TokenKind.COMMA, true)) {
elements.add(eatExpression());
eatToken(TokenKind.COLON);
elements.add(eatExpression());
}
closingCurly = eatToken(TokenKind.RCURLY);
expr = new InlineMap(t.startPos, closingCurly.endPos, elements.toArray(new SpelNodeImpl[0]));
} else {
throw internalException(t.startPos, SpelMessage.OOD);
}
}
this.constructedNodes.push(expr);
return true;
}
use of org.springframework.expression.spel.ast.SpelNodeImpl in project spring-framework by spring-projects.
the class InternalSpelExpressionParser method maybeEatMethodOrProperty.
// This is complicated due to the support for dollars in identifiers.
// Dollars are normally separate tokens but there we want to combine
// a series of identifiers and dollars into a single identifier.
private boolean maybeEatMethodOrProperty(boolean nullSafeNavigation) {
if (peekToken(TokenKind.IDENTIFIER)) {
Token methodOrPropertyName = takeToken();
SpelNodeImpl[] args = maybeEatMethodArgs();
if (args == null) {
// property
push(new PropertyOrFieldReference(nullSafeNavigation, methodOrPropertyName.stringValue(), methodOrPropertyName.startPos, methodOrPropertyName.endPos));
return true;
}
// method reference
push(new MethodReference(nullSafeNavigation, methodOrPropertyName.stringValue(), methodOrPropertyName.startPos, methodOrPropertyName.endPos, args));
// TODO what is the end position for a method reference? the name or the last arg?
return true;
}
return false;
}
use of org.springframework.expression.spel.ast.SpelNodeImpl in project spring-framework by spring-projects.
the class InternalSpelExpressionParser method maybeEatConstructorReference.
// constructor
// : ('new' qualifiedId LPAREN) => 'new' qualifiedId ctorArgs -> ^(CONSTRUCTOR qualifiedId ctorArgs)
private boolean maybeEatConstructorReference() {
if (peekIdentifierToken("new")) {
Token newToken = takeToken();
// It looks like a constructor reference but is NEW being used as a map key?
if (peekToken(TokenKind.RSQUARE)) {
// looks like 'NEW]' (so NEW used as map key)
push(new PropertyOrFieldReference(false, newToken.stringValue(), newToken.startPos, newToken.endPos));
return true;
}
SpelNodeImpl possiblyQualifiedConstructorName = eatPossiblyQualifiedId();
List<SpelNodeImpl> nodes = new ArrayList<>();
nodes.add(possiblyQualifiedConstructorName);
if (peekToken(TokenKind.LSQUARE)) {
// array initializer
List<SpelNodeImpl> dimensions = new ArrayList<>();
while (peekToken(TokenKind.LSQUARE, true)) {
if (!peekToken(TokenKind.RSQUARE)) {
dimensions.add(eatExpression());
} else {
dimensions.add(null);
}
eatToken(TokenKind.RSQUARE);
}
if (maybeEatInlineListOrMap()) {
nodes.add(pop());
}
push(new ConstructorReference(newToken.startPos, newToken.endPos, dimensions.toArray(new SpelNodeImpl[0]), nodes.toArray(new SpelNodeImpl[0])));
} else {
// regular constructor invocation
eatConstructorArgs(nodes);
// TODO correct end position?
push(new ConstructorReference(newToken.startPos, newToken.endPos, nodes.toArray(new SpelNodeImpl[0])));
}
return true;
}
return false;
}
Aggregations