Skip to content

Commit 026ee84

Browse files
committed
Merge pull request spring-projects#112 from aclement/SPR-9612
* SPR-9612: Modify SpEL Tokenizer to support methods on numbers
2 parents 015086c + e4a926e commit 026ee84

File tree

4 files changed

+197
-174
lines changed

4 files changed

+197
-174
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/standard/SpelExpression.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,9 +30,10 @@
3030
import org.springframework.util.Assert;
3131

3232
/**
33-
* A SpelExpressions represents a parsed (valid) expression that is ready to be evaluated in a specified context. An
34-
* expression can be evaluated standalone or in a specified context. During expression evaluation the context may be
35-
* asked to resolve references to types, beans, properties, methods.
33+
* A {@code SpelExpression} represents a parsed (valid) expression that is ready
34+
* to be evaluated in a specified context. An expression can be evaluated
35+
* standalone or in a specified context. During expression evaluation the context
36+
* may be asked to resolve references to types, beans, properties, and methods.
3637
*
3738
* @author Andy Clement
3839
* @since 3.0
@@ -103,22 +104,22 @@ public <T> T getValue(EvaluationContext context, Object rootObject, Class<T> exp
103104
return ExpressionUtils.convertTypedValue(context, typedResultValue, expectedResultType);
104105
}
105106

106-
public Class getValueType() throws EvaluationException {
107+
public Class<?> getValueType() throws EvaluationException {
107108
return getValueType(getEvaluationContext());
108109
}
109110

110-
public Class getValueType(Object rootObject) throws EvaluationException {
111+
public Class<?> getValueType(Object rootObject) throws EvaluationException {
111112
return getValueType(getEvaluationContext(), rootObject);
112113
}
113114

114-
public Class getValueType(EvaluationContext context) throws EvaluationException {
115+
public Class<?> getValueType(EvaluationContext context) throws EvaluationException {
115116
Assert.notNull(context, "The EvaluationContext is required");
116117
ExpressionState eState = new ExpressionState(context, configuration);
117118
TypeDescriptor typeDescriptor = ast.getValueInternal(eState).getTypeDescriptor();
118119
return typeDescriptor != null ? typeDescriptor.getType() : null;
119120
}
120121

121-
public Class getValueType(EvaluationContext context, Object rootObject) throws EvaluationException {
122+
public Class<?> getValueType(EvaluationContext context, Object rootObject) throws EvaluationException {
122123
ExpressionState eState = new ExpressionState(context, toTypedValue(rootObject), configuration);
123124
TypeDescriptor typeDescriptor = ast.getValueInternal(eState).getTypeDescriptor();
124125
return typeDescriptor != null ? typeDescriptor.getType() : null;

spring-expression/src/main/java/org/springframework/expression/spel/standard/Tokenizer.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -289,10 +289,19 @@ private void lexNumericLiteral(boolean firstCharIsZero) {
289289
ch = toProcess[pos];
290290
if (ch=='.') {
291291
isReal = true;
292+
int dotpos = pos;
292293
// carry on consuming digits
293294
do {
294295
pos++;
295296
} while (isDigit(toProcess[pos]));
297+
if (pos == dotpos + 1) {
298+
// the number is something like '3.'. It is really an int but may be
299+
// part of something like '3.toString()'. In this case process it as
300+
// an int and leave the dot as a separate token.
301+
pos = dotpos;
302+
pushIntToken(subarray(start, pos), false, start, pos);
303+
return;
304+
}
296305
}
297306

298307
int endOfNumber = pos;
@@ -307,7 +316,7 @@ private void lexNumericLiteral(boolean firstCharIsZero) {
307316
pushIntToken(subarray(start, endOfNumber), true, start, endOfNumber);
308317
pos++;
309318
} else if (isExponentChar(toProcess[pos])) {
310-
isReal = true; // if it wasnt before, it is now
319+
isReal = true; // if it wasn't before, it is now
311320
pos++;
312321
char possibleSign = toProcess[pos];
313322
if (isSign(possibleSign)) {
@@ -502,6 +511,5 @@ private boolean isHexadecimalDigit(char ch) {
502511
flags[ch]|= IS_ALPHA;
503512
}
504513
}
505-
506514

507515
}

0 commit comments

Comments
 (0)