提交 e4a926ea 编写于 作者: A Andy Clement 提交者: Sam Brannen

Modify SpEL Tokenizer to support methods on numbers

When attempting to parse an Integer literal expression such as
42.toString(), SpEL currently throws a SpelParseException with a message
similar to: "EL1041E:(pos 3): After parsing a valid expression, there is
still more data in the expression: 'toString'". The problem here is that
'3.' is currently considered a valid number (including the dot).
However, SpEL succeeds at parsing an equivalent expression for a Double
literal such as 3.14.isInfinite().

To address this issue, the SpEL Tokenizer no longer consumes the
trailing '.' on an integer as part of the integer. So '3.foo()' will now
be parsed as '3' '.' 'foo()' and not '3.' 'foo()' -- which was what
prevented parsing of method invocations on integers. To keep the change
simple, the parser will no longer handle real numbers of the form
'3.e4'. From now on they must include the extra 0 (i.e., '3.0e4').

Issue: SPR-9612
上级 015086cb
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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.
......@@ -30,9 +30,10 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.Assert;
/**
* A SpelExpressions represents a parsed (valid) expression that is ready to be evaluated in a specified context. An
* expression can be evaluated standalone or in a specified context. During expression evaluation the context may be
* asked to resolve references to types, beans, properties, methods.
* A {@code SpelExpression} represents a parsed (valid) expression that is ready
* to be evaluated in a specified context. An expression can be evaluated
* standalone or in a specified context. During expression evaluation the context
* may be asked to resolve references to types, beans, properties, and methods.
*
* @author Andy Clement
* @since 3.0
......@@ -103,22 +104,22 @@ public class SpelExpression implements Expression {
return ExpressionUtils.convertTypedValue(context, typedResultValue, expectedResultType);
}
public Class getValueType() throws EvaluationException {
public Class<?> getValueType() throws EvaluationException {
return getValueType(getEvaluationContext());
}
public Class getValueType(Object rootObject) throws EvaluationException {
public Class<?> getValueType(Object rootObject) throws EvaluationException {
return getValueType(getEvaluationContext(), rootObject);
}
public Class getValueType(EvaluationContext context) throws EvaluationException {
public Class<?> getValueType(EvaluationContext context) throws EvaluationException {
Assert.notNull(context, "The EvaluationContext is required");
ExpressionState eState = new ExpressionState(context, configuration);
TypeDescriptor typeDescriptor = ast.getValueInternal(eState).getTypeDescriptor();
return typeDescriptor != null ? typeDescriptor.getType() : null;
}
public Class getValueType(EvaluationContext context, Object rootObject) throws EvaluationException {
public Class<?> getValueType(EvaluationContext context, Object rootObject) throws EvaluationException {
ExpressionState eState = new ExpressionState(context, toTypedValue(rootObject), configuration);
TypeDescriptor typeDescriptor = ast.getValueInternal(eState).getTypeDescriptor();
return typeDescriptor != null ? typeDescriptor.getType() : null;
......
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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.
......@@ -289,10 +289,19 @@ class Tokenizer {
ch = toProcess[pos];
if (ch=='.') {
isReal = true;
int dotpos = pos;
// carry on consuming digits
do {
pos++;
} while (isDigit(toProcess[pos]));
if (pos == dotpos + 1) {
// the number is something like '3.'. It is really an int but may be
// part of something like '3.toString()'. In this case process it as
// an int and leave the dot as a separate token.
pos = dotpos;
pushIntToken(subarray(start, pos), false, start, pos);
return;
}
}
int endOfNumber = pos;
......@@ -307,7 +316,7 @@ class Tokenizer {
pushIntToken(subarray(start, endOfNumber), true, start, endOfNumber);
pos++;
} else if (isExponentChar(toProcess[pos])) {
isReal = true; // if it wasnt before, it is now
isReal = true; // if it wasn't before, it is now
pos++;
char possibleSign = toProcess[pos];
if (isSign(possibleSign)) {
......@@ -502,6 +511,5 @@ class Tokenizer {
flags[ch]|= IS_ALPHA;
}
}
}
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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.
......@@ -16,9 +16,10 @@
package org.springframework.expression.spel.standard;
import junit.framework.Assert;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.ExpressionException;
......@@ -36,323 +37,334 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
public class SpelParserTests {
@Test
public void theMostBasic() throws EvaluationException,ParseException {
public void theMostBasic() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2");
Assert.assertNotNull(expr);
Assert.assertNotNull(expr.getAST());
Assert.assertEquals(2,expr.getValue());
Assert.assertEquals(Integer.class,expr.getValueType());
Assert.assertEquals(2,expr.getAST().getValue(null));
assertNotNull(expr);
assertNotNull(expr.getAST());
assertEquals(2, expr.getValue());
assertEquals(Integer.class, expr.getValueType());
assertEquals(2, expr.getAST().getValue(null));
}
@Test
public void valueType() throws Exception {
SpelExpressionParser parser = new SpelExpressionParser();
EvaluationContext ctx = new StandardEvaluationContext();
Class c = parser.parseRaw("2").getValueType();
Assert.assertEquals(Integer.class,c);
Class<?> c = parser.parseRaw("2").getValueType();
assertEquals(Integer.class, c);
c = parser.parseRaw("12").getValueType(ctx);
Assert.assertEquals(Integer.class,c);
assertEquals(Integer.class, c);
c = parser.parseRaw("null").getValueType();
Assert.assertNull(c);
assertNull(c);
c = parser.parseRaw("null").getValueType(ctx);
Assert.assertNull(c);
Object o = parser.parseRaw("null").getValue(ctx,Integer.class);
Assert.assertNull(o);
assertNull(c);
Object o = parser.parseRaw("null").getValue(ctx, Integer.class);
assertNull(o);
}
@Test
public void whitespace() throws EvaluationException,ParseException {
public void whitespace() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2 + 3");
Assert.assertEquals(5,expr.getValue());
assertEquals(5, expr.getValue());
expr = parser.parseRaw("2 + 3");
Assert.assertEquals(5,expr.getValue());
assertEquals(5, expr.getValue());
expr = parser.parseRaw("2\n+ 3");
Assert.assertEquals(5,expr.getValue());
assertEquals(5, expr.getValue());
expr = parser.parseRaw("2\r\n+\t3");
Assert.assertEquals(5,expr.getValue());
assertEquals(5, expr.getValue());
}
@Test
public void arithmeticPlus1() throws EvaluationException,ParseException {
public void arithmeticPlus1() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+2");
Assert.assertNotNull(expr);
Assert.assertNotNull(expr.getAST());
Assert.assertEquals(4,expr.getValue());
assertNotNull(expr);
assertNotNull(expr.getAST());
assertEquals(4, expr.getValue());
}
@Test
public void arithmeticPlus2() throws EvaluationException,ParseException {
public void arithmeticPlus2() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("37+41");
Assert.assertEquals(78,expr.getValue());
assertEquals(78, expr.getValue());
}
@Test
public void arithmeticMultiply1() throws EvaluationException,ParseException {
public void arithmeticMultiply1() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3");
Assert.assertNotNull(expr);
Assert.assertNotNull(expr.getAST());
// printAst(expr.getAST(),0);
Assert.assertEquals(6,expr.getValue());
assertNotNull(expr);
assertNotNull(expr.getAST());
// printAst(expr.getAST(),0);
assertEquals(6, expr.getValue());
}
@Test
public void arithmeticPrecedence1() throws EvaluationException,ParseException {
public void arithmeticPrecedence1() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2*3+5");
Assert.assertEquals(11,expr.getValue());
assertEquals(11, expr.getValue());
}
@Test
public void generalExpressions() throws Exception {
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.MISSING_CONSTRUCTOR_ARGS,spe.getMessageCode());
Assert.assertEquals(10,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.MISSING_CONSTRUCTOR_ARGS, spe.getMessageCode());
assertEquals(10, spe.getPosition());
}
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3,");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode());
Assert.assertEquals(10,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS, spe.getMessageCode());
assertEquals(10, spe.getPosition());
}
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(3");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode());
Assert.assertEquals(10,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS, spe.getMessageCode());
assertEquals(10, spe.getPosition());
}
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("new String(");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS,spe.getMessageCode());
Assert.assertEquals(10,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.RUN_OUT_OF_ARGUMENTS, spe.getMessageCode());
assertEquals(10, spe.getPosition());
}
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("\"abc");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING,spe.getMessageCode());
Assert.assertEquals(0,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.NON_TERMINATING_DOUBLE_QUOTED_STRING, spe.getMessageCode());
assertEquals(0, spe.getPosition());
}
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw("'abc");
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(SpelMessage.NON_TERMINATING_QUOTED_STRING,spe.getMessageCode());
Assert.assertEquals(0,spe.getPosition());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(SpelMessage.NON_TERMINATING_QUOTED_STRING, spe.getMessageCode());
assertEquals(0, spe.getPosition());
}
}
@Test
public void arithmeticPrecedence2() throws EvaluationException,ParseException {
public void arithmeticPrecedence2() throws EvaluationException, ParseException {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw("2+3*5");
Assert.assertEquals(17,expr.getValue());
assertEquals(17, expr.getValue());
}
@Test
public void arithmeticPrecedence3() throws EvaluationException,ParseException {
public void arithmeticPrecedence3() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("3+10/2");
Assert.assertEquals(8,expr.getValue());
assertEquals(8, expr.getValue());
}
@Test
public void arithmeticPrecedence4() throws EvaluationException,ParseException {
public void arithmeticPrecedence4() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("10/2+3");
Assert.assertEquals(8,expr.getValue());
assertEquals(8, expr.getValue());
}
@Test
public void arithmeticPrecedence5() throws EvaluationException,ParseException {
public void arithmeticPrecedence5() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("(4+10)/2");
Assert.assertEquals(7,expr.getValue());
assertEquals(7, expr.getValue());
}
@Test
public void arithmeticPrecedence6() throws EvaluationException,ParseException {
public void arithmeticPrecedence6() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("(3+2)*2");
Assert.assertEquals(10,expr.getValue());
assertEquals(10, expr.getValue());
}
@Test
public void booleanOperators() throws EvaluationException,ParseException {
public void booleanOperators() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("true");
Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class));
assertEquals(Boolean.TRUE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("false");
Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class));
assertEquals(Boolean.FALSE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("false and false");
Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class));
assertEquals(Boolean.FALSE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("true and (true or false)");
Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class));
assertEquals(Boolean.TRUE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("true and true or false");
Assert.assertEquals(Boolean.TRUE,expr.getValue(Boolean.class));
assertEquals(Boolean.TRUE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("!true");
Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class));
assertEquals(Boolean.FALSE, expr.getValue(Boolean.class));
expr = new SpelExpressionParser().parseRaw("!(false or true)");
Assert.assertEquals(Boolean.FALSE,expr.getValue(Boolean.class));
assertEquals(Boolean.FALSE, expr.getValue(Boolean.class));
}
@Test
public void testStringLiterals() throws EvaluationException,ParseException {
public void stringLiterals() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'");
Assert.assertEquals("howdy",expr.getValue());
assertEquals("howdy", expr.getValue());
expr = new SpelExpressionParser().parseRaw("'hello '' world'");
Assert.assertEquals("hello ' world",expr.getValue());
assertEquals("hello ' world", expr.getValue());
}
@Test
public void testStringLiterals2() throws EvaluationException,ParseException {
public void stringLiterals2() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("'howdy'.substring(0,2)");
Assert.assertEquals("ho",expr.getValue());
assertEquals("ho", expr.getValue());
}
@Test
public void testPositionalInformation() throws EvaluationException, ParseException {
public void positionalInformation() throws EvaluationException, ParseException {
SpelExpression expr = new SpelExpressionParser().parseRaw("true and true or false");
SpelNode rootAst = expr.getAST();
OpOr operatorOr = (OpOr)rootAst;
OpAnd operatorAnd = (OpAnd)operatorOr.getLeftOperand();
OpOr operatorOr = (OpOr) rootAst;
OpAnd operatorAnd = (OpAnd) operatorOr.getLeftOperand();
SpelNode rightOrOperand = operatorOr.getRightOperand();
// check position for final 'false'
Assert.assertEquals(17, rightOrOperand.getStartPosition());
Assert.assertEquals(22, rightOrOperand.getEndPosition());
assertEquals(17, rightOrOperand.getStartPosition());
assertEquals(22, rightOrOperand.getEndPosition());
// check position for first 'true'
Assert.assertEquals(0, operatorAnd.getLeftOperand().getStartPosition());
Assert.assertEquals(4, operatorAnd.getLeftOperand().getEndPosition());
assertEquals(0, operatorAnd.getLeftOperand().getStartPosition());
assertEquals(4, operatorAnd.getLeftOperand().getEndPosition());
// check position for second 'true'
Assert.assertEquals(9, operatorAnd.getRightOperand().getStartPosition());
Assert.assertEquals(13, operatorAnd.getRightOperand().getEndPosition());
assertEquals(9, operatorAnd.getRightOperand().getStartPosition());
assertEquals(13, operatorAnd.getRightOperand().getEndPosition());
// check position for OperatorAnd
Assert.assertEquals(5, operatorAnd.getStartPosition());
Assert.assertEquals(8, operatorAnd.getEndPosition());
assertEquals(5, operatorAnd.getStartPosition());
assertEquals(8, operatorAnd.getEndPosition());
// check position for OperatorOr
Assert.assertEquals(14, operatorOr.getStartPosition());
Assert.assertEquals(16, operatorOr.getEndPosition());
assertEquals(14, operatorOr.getStartPosition());
assertEquals(16, operatorOr.getEndPosition());
}
@Test
public void testTokenKind() {
public void tokenKind() {
TokenKind tk = TokenKind.NOT;
Assert.assertFalse(tk.hasPayload());
Assert.assertEquals("NOT(!)",tk.toString());
assertFalse(tk.hasPayload());
assertEquals("NOT(!)", tk.toString());
tk = TokenKind.MINUS;
Assert.assertFalse(tk.hasPayload());
Assert.assertEquals("MINUS(-)",tk.toString());
assertFalse(tk.hasPayload());
assertEquals("MINUS(-)", tk.toString());
tk = TokenKind.LITERAL_STRING;
Assert.assertEquals("LITERAL_STRING",tk.toString());
Assert.assertTrue(tk.hasPayload());
assertEquals("LITERAL_STRING", tk.toString());
assertTrue(tk.hasPayload());
}
@Test
public void testToken() {
Token token = new Token(TokenKind.NOT,0,3);
Assert.assertEquals(TokenKind.NOT,token.kind);
Assert.assertEquals(0,token.startpos);
Assert.assertEquals(3,token.endpos);
Assert.assertEquals("[NOT(!)](0,3)",token.toString());
token = new Token(TokenKind.LITERAL_STRING,"abc".toCharArray(),0,3);
Assert.assertEquals(TokenKind.LITERAL_STRING,token.kind);
Assert.assertEquals(0,token.startpos);
Assert.assertEquals(3,token.endpos);
Assert.assertEquals("[LITERAL_STRING:abc](0,3)",token.toString());
public void token() {
Token token = new Token(TokenKind.NOT, 0, 3);
assertEquals(TokenKind.NOT, token.kind);
assertEquals(0, token.startpos);
assertEquals(3, token.endpos);
assertEquals("[NOT(!)](0,3)", token.toString());
token = new Token(TokenKind.LITERAL_STRING, "abc".toCharArray(), 0, 3);
assertEquals(TokenKind.LITERAL_STRING, token.kind);
assertEquals(0, token.startpos);
assertEquals(3, token.endpos);
assertEquals("[LITERAL_STRING:abc](0,3)", token.toString());
}
@Test
public void testExceptions() {
public void exceptions() {
ExpressionException exprEx = new ExpressionException("test");
Assert.assertEquals("test", exprEx.getMessage());
Assert.assertEquals("test", exprEx.toDetailedString());
assertEquals("test", exprEx.getMessage());
assertEquals("test", exprEx.toDetailedString());
exprEx = new ExpressionException("wibble","test");
Assert.assertEquals("test", exprEx.getMessage());
Assert.assertEquals("Expression 'wibble': test", exprEx.toDetailedString());
exprEx = new ExpressionException("wibble", "test");
assertEquals("test", exprEx.getMessage());
assertEquals("Expression 'wibble': test", exprEx.toDetailedString());
exprEx = new ExpressionException("wibble",3, "test");
Assert.assertEquals("test", exprEx.getMessage());
Assert.assertEquals("Expression 'wibble' @ 3: test", exprEx.toDetailedString());
exprEx = new ExpressionException("wibble", 3, "test");
assertEquals("test", exprEx.getMessage());
assertEquals("Expression 'wibble' @ 3: test", exprEx.toDetailedString());
}
@Test
public void testNumerics() {
checkNumber("2",2,Integer.class);
checkNumber("22",22,Integer.class);
checkNumber("+22",22,Integer.class);
checkNumber("-22",-22,Integer.class);
public void parseMethodsOnNumbers() {
checkNumber("3.14.toString()", "3.14", String.class);
checkNumber("3.toString()", "3", String.class);
}
checkNumber("2L",2L,Long.class);
checkNumber("22l",22L,Long.class);
checkNumber("0x1",1,Integer.class);
checkNumber("0x1L",1L,Long.class);
checkNumber("0xa",10,Integer.class);
checkNumber("0xAL",10L,Long.class);
@Test
public void numerics() {
checkNumber("2", 2, Integer.class);
checkNumber("22", 22, Integer.class);
checkNumber("+22", 22, Integer.class);
checkNumber("-22", -22, Integer.class);
checkNumberError("0x",SpelMessage.NOT_AN_INTEGER);
checkNumberError("0xL",SpelMessage.NOT_A_LONG);
checkNumber("2L", 2L, Long.class);
checkNumber("22l", 22L, Long.class);
checkNumberError(".324",SpelMessage.UNEXPECTED_DATA_AFTER_DOT);
checkNumber("0x1", 1, Integer.class);
checkNumber("0x1L", 1L, Long.class);
checkNumber("0xa", 10, Integer.class);
checkNumber("0xAL", 10L, Long.class);
checkNumberError("3.4L",SpelMessage.REAL_CANNOT_BE_LONG);
checkNumberError("0x", SpelMessage.NOT_AN_INTEGER);
checkNumberError("0xL", SpelMessage.NOT_A_LONG);
checkNumberError(".324", SpelMessage.UNEXPECTED_DATA_AFTER_DOT);
checkNumberError("3.4L", SpelMessage.REAL_CANNOT_BE_LONG);
// Number is parsed as a float, but immediately promoted to a double
checkNumber("3.5f",3.5d,Double.class);
checkNumber("3.5f", 3.5d, Double.class);
checkNumber("1.2e3", 1.2e3d, Double.class);
checkNumber("1.2e+3", 1.2e3d, Double.class);
checkNumber("1.2e-3", 1.2e-3d, Double.class);
checkNumber("1.2e3", 1.2e3d, Double.class);
checkNumber("1.e+3", 1.e3d, Double.class);
checkNumber("1e+3", 1e3d, Double.class);
}
private void checkNumber(String expression, Object value, Class<?> type) {
try {
SpelExpressionParser parser = new SpelExpressionParser();
SpelExpression expr = parser.parseRaw(expression);
Object o = expr.getValue();
Assert.assertEquals(value,o);
Assert.assertEquals(type,o.getClass());
assertEquals(value, o);
assertEquals(type, o.getClass());
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
fail(e.getMessage());
}
}
......@@ -360,11 +372,12 @@ public class SpelParserTests {
try {
SpelExpressionParser parser = new SpelExpressionParser();
parser.parseRaw(expression);
Assert.fail();
fail();
} catch (ParseException e) {
Assert.assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException)e;
Assert.assertEquals(expectedMessage,spe.getMessageCode());
assertTrue(e instanceof SpelParseException);
SpelParseException spe = (SpelParseException) e;
assertEquals(expectedMessage, spe.getMessageCode());
}
}
}
......@@ -8,6 +8,7 @@ Changes in version 3.2 M2 (2012-08-xx)
* spring-test module now depends on junit:junit-dep (SPR-6966)
* now inferring return type of parameterized factory methods (SPR-9493)
* SpEL Tokenizer now supports methods on integers (SPR-9612)
* now using BufferedInputStream in SimpleMetaDataReader to double performance (SPR-9528)
* introduced "repeatCount" property in Quartz SimpleTriggerFactoryBean (SPR-9521)
* introduced "jtaTransactionManager" property in Hibernate 4 LocalSessionFactoryBean/Builder (SPR-9480)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册