Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
cfc65b0c
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cfc65b0c
编写于
4月 08, 2009
作者:
A
Andy Clement
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Removed unnecessary code. Increased test coverage from 70>75% - still some way to go
上级
30bed7b5
变更
32
隐藏空白更改
内联
并排
Showing
32 changed file
with
287 addition
and
342 deletion
+287
-342
org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java
.../main/java/org/springframework/expression/TypedValue.java
+7
-1
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Assign.java
.../java/org/springframework/expression/spel/ast/Assign.java
+0
-6
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
...ngframework/expression/spel/ast/ConstructorReference.java
+26
-187
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java
...org/springframework/expression/spel/ast/FormatHelper.java
+5
-7
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
...pringframework/expression/spel/ast/FunctionReference.java
+0
-4
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Literal.java
...java/org/springframework/expression/spel/ast/Literal.java
+1
-8
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java
.../springframework/expression/spel/ast/MethodReference.java
+2
-8
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
...ava/org/springframework/expression/spel/ast/Operator.java
+3
-17
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorNot.java
.../org/springframework/expression/spel/ast/OperatorNot.java
+0
-5
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorPlus.java
...org/springframework/expression/spel/ast/OperatorPlus.java
+2
-13
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Projection.java
...a/org/springframework/expression/spel/ast/Projection.java
+2
-7
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
...amework/expression/spel/ast/PropertyOrFieldReference.java
+1
-0
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java
...ingframework/expression/spel/ast/QualifiedIdentifier.java
+5
-6
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Selection.java
...va/org/springframework/expression/spel/ast/Selection.java
+11
-11
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
...org/springframework/expression/spel/ast/SpelNodeImpl.java
+1
-0
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelTreeAdaptor.java
.../springframework/expression/spel/ast/SpelTreeAdaptor.java
+1
-7
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Ternary.java
...java/org/springframework/expression/spel/ast/Ternary.java
+0
-6
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java
...rg/springframework/expression/spel/ast/TypeReference.java
+0
-6
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java
...ork/expression/spel/support/ReflectiveMethodExecutor.java
+1
-2
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
...mework/expression/spel/support/StandardTypeConverter.java
+25
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
.../org/springframework/expression/spel/EvaluationTests.java
+81
-23
org.springframework.expression/src/test/java/org/springframework/expression/spel/HelperTests.java
...java/org/springframework/expression/spel/HelperTests.java
+40
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/LiteralTests.java
...ava/org/springframework/expression/spel/LiteralTests.java
+11
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/OperatorTests.java
...va/org/springframework/expression/spel/OperatorTests.java
+25
-15
org.springframework.expression/src/test/java/org/springframework/expression/spel/ParserErrorMessagesTests.java
...ngframework/expression/spel/ParserErrorMessagesTests.java
+1
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java
...ngframework/expression/spel/VariableAndFunctionTests.java
+8
-2
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Company.java
...pringframework/expression/spel/testresources/Company.java
+1
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Fruit.java
.../springframework/expression/spel/testresources/Fruit.java
+1
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
...ringframework/expression/spel/testresources/Inventor.java
+23
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Person.java
...springframework/expression/spel/testresources/Person.java
+1
-1
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/PlaceOfBirth.java
...framework/expression/spel/testresources/PlaceOfBirth.java
+1
-0
org.springframework.expression/template.mf
org.springframework.expression/template.mf
+1
-0
未找到文件。
org.springframework.expression/src/main/java/org/springframework/expression/TypedValue.java
浏览文件 @
cfc65b0c
...
...
@@ -57,5 +57,11 @@ public class TypedValue {
public
TypeDescriptor
getTypeDescriptor
()
{
return
this
.
typeDescriptor
;
}
@Override
public
String
toString
()
{
StringBuffer
str
=
new
StringBuffer
();
str
.
append
(
"TypedValue: "
).
append
(
value
).
append
(
" of type "
+
typeDescriptor
.
asString
());
return
str
.
toString
();
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Assign.java
浏览文件 @
cfc65b0c
...
...
@@ -20,7 +20,6 @@ import org.antlr.runtime.Token;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents assignment. An alternative to calling setValue() for an expression is to use an assign.
...
...
@@ -49,9 +48,4 @@ public class Assign extends SpelNodeImpl {
.
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
浏览文件 @
cfc65b0c
...
...
@@ -16,11 +16,9 @@
package
org.springframework.expression.spel.ast
;
import
java.lang.reflect.Array
;
import
java.util.List
;
import
org.antlr.runtime.Token
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.ConstructorExecutor
;
import
org.springframework.expression.ConstructorResolver
;
...
...
@@ -31,6 +29,7 @@ import org.springframework.expression.spel.ExpressionState;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.SpelMessages
;
// TODO asc array constructor call logic has been removed for now
/**
* Represents the invocation of a constructor. Either a constructor on a regular type or construction of an array. When
* an array is constructed, an initializer can be specified.
...
...
@@ -46,201 +45,22 @@ import org.springframework.expression.spel.SpelMessages;
*/
public
class
ConstructorReference
extends
SpelNodeImpl
{
/**
* If true then this is an array constructor, for example, 'new String[]', rather than a simple constructor 'new
* String()'
*/
private
final
boolean
isArrayConstructor
;
// TODO is this caching safe - passing the expression around will mean this executor is also being passed around
/**
* The cached executor that may be reused on subsequent evaluations.
*/
private
ConstructorExecutor
cachedExecutor
;
public
ConstructorReference
(
Token
payload
,
boolean
isArrayConstructor
)
{
public
ConstructorReference
(
Token
payload
)
{
super
(
payload
);
this
.
isArrayConstructor
=
isArrayConstructor
;
}
/**
* Implements getValue() - delegating to the code for building an array or a simple type.
*/
@Override
public
TypedValue
getValueInternal
(
ExpressionState
state
)
throws
EvaluationException
{
if
(
this
.
isArrayConstructor
)
{
return
createArray
(
state
);
}
else
{
return
createNewInstance
(
state
);
}
}
@Override
public
String
toStringAST
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"new "
);
int
index
=
0
;
sb
.
append
(
getChild
(
index
++).
toStringAST
());
if
(!
this
.
isArrayConstructor
)
{
sb
.
append
(
"("
);
for
(
int
i
=
index
;
i
<
getChildCount
();
i
++)
{
if
(
i
>
index
)
sb
.
append
(
","
);
sb
.
append
(
getChild
(
i
).
toStringAST
());
}
sb
.
append
(
")"
);
}
else
{
// Next child is EXPRESSIONLIST token with children that are the
// expressions giving array size
sb
.
append
(
"["
);
SpelNodeImpl
arrayRank
=
getChild
(
index
++);
for
(
int
i
=
0
;
i
<
arrayRank
.
getChildCount
();
i
++)
{
if
(
i
>
0
)
sb
.
append
(
","
);
sb
.
append
(
arrayRank
.
getChild
(
i
).
toStringAST
());
}
sb
.
append
(
"]"
);
if
(
index
<
getChildCount
())
sb
.
append
(
" "
).
append
(
getChild
(
index
).
toStringAST
());
}
return
sb
.
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
/**
* Create an array and return it. The children of this node indicate the type of array, the array ranks and any
* optional initializer that might have been supplied.
* @param state the expression state within which this expression is being evaluated
* @return the new array
* @throws EvaluationException if there is a problem creating the array
*/
private
TypedValue
createArray
(
ExpressionState
state
)
throws
EvaluationException
{
TypedValue
intendedArrayType
=
getChild
(
0
).
getValueInternal
(
state
);
if
(!(
intendedArrayType
.
getValue
()
instanceof
String
))
{
throw
new
SpelException
(
getChild
(
0
).
getCharPositionInLine
(),
SpelMessages
.
TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION
,
FormatHelper
.
formatClassNameForMessage
(
intendedArrayType
.
getClass
()));
}
String
type
=
(
String
)
intendedArrayType
.
getValue
();
Class
<?>
componentType
=
null
;
TypeCode
arrayTypeCode
=
TypeCode
.
forName
(
type
);
if
(
arrayTypeCode
==
TypeCode
.
OBJECT
)
{
componentType
=
state
.
findType
(
type
);
}
else
{
componentType
=
arrayTypeCode
.
getType
();
}
Object
newArray
=
null
;
TypeDescriptor
newArrayTypeDescriptor
=
null
;
if
(
getChild
(
1
).
getChildCount
()
==
0
)
{
// are the array ranks defined?
if
(
getChildCount
()
<
3
)
{
throw
new
SpelException
(
getCharPositionInLine
(),
SpelMessages
.
NO_SIZE_OR_INITIALIZER_FOR_ARRAY_CONSTRUCTION
);
}
// no array ranks so use the size of the initializer to determine array size
int
arraySize
=
getChild
(
2
).
getChildCount
();
newArray
=
Array
.
newInstance
(
componentType
,
arraySize
);
newArrayTypeDescriptor
=
TypeDescriptor
.
valueOf
(
newArray
.
getClass
());
}
else
{
// Array ranks are specified but is it a single or multiple dimension array?
int
dimensions
=
getChild
(
1
).
getChildCount
();
if
(
dimensions
==
1
)
{
Object
o
=
getChild
(
1
).
getValueInternal
(
state
);
int
arraySize
=
state
.
convertValue
(
o
,
INTEGER_TYPE_DESCRIPTOR
);
if
(
getChildCount
()
==
3
)
{
// Check initializer length matches array size length
int
initializerLength
=
getChild
(
2
).
getChildCount
();
if
(
initializerLength
!=
arraySize
)
{
throw
new
SpelException
(
getChild
(
2
).
getCharPositionInLine
(),
SpelMessages
.
INITIALIZER_LENGTH_INCORRECT
,
initializerLength
,
arraySize
);
}
}
newArray
=
Array
.
newInstance
(
componentType
,
arraySize
);
newArrayTypeDescriptor
=
TypeDescriptor
.
valueOf
(
newArray
.
getClass
());
}
else
{
// Multi-dimensional - hold onto your hat !
int
[]
dims
=
new
int
[
dimensions
];
for
(
int
d
=
0
;
d
<
dimensions
;
d
++)
{
dims
[
d
]
=
state
.
convertValue
(
getChild
(
1
).
getChild
(
d
).
getValueInternal
(
state
),
INTEGER_TYPE_DESCRIPTOR
);
}
newArray
=
Array
.
newInstance
(
componentType
,
dims
);
newArrayTypeDescriptor
=
TypeDescriptor
.
valueOf
(
newArray
.
getClass
());
// TODO check any specified initializer for the multidim array matches
}
}
// Populate the array using the initializer if one is specified
if
(
getChildCount
()
==
3
)
{
SpelNodeImpl
initializer
=
getChild
(
2
);
if
(
arrayTypeCode
==
TypeCode
.
OBJECT
)
{
Object
[]
newObjectArray
=
(
Object
[])
newArray
;
for
(
int
i
=
0
;
i
<
newObjectArray
.
length
;
i
++)
{
SpelNodeImpl
elementNode
=
initializer
.
getChild
(
i
);
Object
arrayEntry
=
elementNode
.
getValueInternal
(
state
);
if
(!
componentType
.
isAssignableFrom
(
arrayEntry
.
getClass
()))
{
throw
new
SpelException
(
elementNode
.
getCharPositionInLine
(),
SpelMessages
.
INCORRECT_ELEMENT_TYPE_FOR_ARRAY
,
componentType
.
getName
(),
arrayEntry
.
getClass
().
getName
());
}
newObjectArray
[
i
]
=
arrayEntry
;
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
INT
)
{
int
[]
newIntArray
=
(
int
[])
newArray
;
for
(
int
i
=
0
;
i
<
newIntArray
.
length
;
i
++)
{
newIntArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
INTEGER_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
BOOLEAN
)
{
boolean
[]
newBooleanArray
=
(
boolean
[])
newArray
;
for
(
int
i
=
0
;
i
<
newBooleanArray
.
length
;
i
++)
{
newBooleanArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
BOOLEAN_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
CHAR
)
{
char
[]
newCharArray
=
(
char
[])
newArray
;
for
(
int
i
=
0
;
i
<
newCharArray
.
length
;
i
++)
{
newCharArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
CHARACTER_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
SHORT
)
{
short
[]
newShortArray
=
(
short
[])
newArray
;
for
(
int
i
=
0
;
i
<
newShortArray
.
length
;
i
++)
{
newShortArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
SHORT_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
LONG
)
{
long
[]
newLongArray
=
(
long
[])
newArray
;
for
(
int
i
=
0
;
i
<
newLongArray
.
length
;
i
++)
{
newLongArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
LONG_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
FLOAT
)
{
float
[]
newFloatArray
=
(
float
[])
newArray
;
for
(
int
i
=
0
;
i
<
newFloatArray
.
length
;
i
++)
{
newFloatArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
FLOAT_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
DOUBLE
)
{
double
[]
newDoubleArray
=
(
double
[])
newArray
;
for
(
int
i
=
0
;
i
<
newDoubleArray
.
length
;
i
++)
{
newDoubleArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
DOUBLE_TYPE_DESCRIPTOR
);
}
}
else
if
(
arrayTypeCode
==
TypeCode
.
BYTE
)
{
byte
[]
newByteArray
=
(
byte
[])
newArray
;
for
(
int
i
=
0
;
i
<
newByteArray
.
length
;
i
++)
{
newByteArray
[
i
]
=
state
.
convertValue
(
initializer
.
getChild
(
i
).
getValueInternal
(
state
),
BYTE_TYPE_DESCRIPTOR
);
}
}
}
return
new
TypedValue
(
newArray
,
newArrayTypeDescriptor
);
return
createNewInstance
(
state
);
}
/**
...
...
@@ -274,9 +94,10 @@ public class ConstructorReference extends SpelNodeImpl {
String
typename
=
(
String
)
getChild
(
0
).
getValueInternal
(
state
).
getValue
();
executorToUse
=
findExecutorForConstructor
(
typename
,
argumentTypes
,
state
);
try
{
return
executorToUse
.
execute
(
state
.
getEvaluationContext
(),
arguments
);
}
catch
(
AccessException
ae
)
{
this
.
cachedExecutor
=
executorToUse
;
TypedValue
result
=
executorToUse
.
execute
(
state
.
getEvaluationContext
(),
arguments
);
return
result
;
}
catch
(
AccessException
ae
)
{
throw
new
SpelException
(
ae
,
SpelMessages
.
EXCEPTION_DURING_CONSTRUCTOR_INVOCATION
,
typename
,
ae
.
getMessage
());
}
}
...
...
@@ -314,4 +135,22 @@ public class ConstructorReference extends SpelNodeImpl {
argumentTypes
));
}
@Override
public
String
toStringAST
()
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"new "
);
int
index
=
0
;
sb
.
append
(
getChild
(
index
++).
toStringAST
());
sb
.
append
(
"("
);
for
(
int
i
=
index
;
i
<
getChildCount
();
i
++)
{
if
(
i
>
index
)
sb
.
append
(
","
);
sb
.
append
(
getChild
(
i
).
toStringAST
());
}
sb
.
append
(
")"
);
return
sb
.
toString
();
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FormatHelper.java
浏览文件 @
cfc65b0c
...
...
@@ -21,7 +21,7 @@ package org.springframework.expression.spel.ast;
*
* @author Andy Clement
*/
class
FormatHelper
{
public
class
FormatHelper
{
/**
* Produce a nice string for a given method name with specified arguments.
...
...
@@ -33,13 +33,11 @@ class FormatHelper {
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
name
);
sb
.
append
(
"("
);
if
(
argumentTypes
!=
null
)
{
for
(
int
i
=
0
;
i
<
argumentTypes
.
length
;
i
++)
{
if
(
i
>
0
)
{
sb
.
append
(
","
);
}
sb
.
append
(
argumentTypes
[
i
].
getName
());
for
(
int
i
=
0
;
i
<
argumentTypes
.
length
;
i
++)
{
if
(
i
>
0
)
{
sb
.
append
(
","
);
}
sb
.
append
(
formatClassNameForMessage
(
argumentTypes
[
i
]));
}
sb
.
append
(
")"
);
return
sb
.
toString
();
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
浏览文件 @
cfc65b0c
...
...
@@ -128,10 +128,6 @@ public class FunctionReference extends SpelNodeImpl {
}
// to 'assign' to a function don't use the () suffix and so it is just a variable reference
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
EvaluationException
{
return
false
;
}
/**
* Compute the arguments to the function, they are the children of this expression node.
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Literal.java
浏览文件 @
cfc65b0c
...
...
@@ -52,11 +52,6 @@ public abstract class Literal extends SpelNodeImpl {
return
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
/**
* Process the string form of a number, using the specified base if supplied and return an appropriate literal to
* hold it. Any suffix to indicate a long will be taken into account (either 'l' or 'L' is supported).
...
...
@@ -71,9 +66,7 @@ public abstract class Literal extends SpelNodeImpl {
boolean
isLong
=
false
;
boolean
isHex
=
(
radix
==
16
);
if
(
numberString
.
length
()
>
0
)
{
isLong
=
numberString
.
endsWith
(
"L"
)
||
numberString
.
endsWith
(
"l"
);
}
isLong
=
numberString
.
endsWith
(
"L"
)
||
numberString
.
endsWith
(
"l"
);
if
(
isLong
||
isHex
)
{
// needs to be chopped up a little
int
len
=
numberString
.
length
();
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java
浏览文件 @
cfc65b0c
...
...
@@ -78,10 +78,9 @@ public class MethodReference extends SpelNodeImpl {
try
{
return
executorToUse
.
execute
(
state
.
getEvaluationContext
(),
state
.
getActiveContextObject
().
getValue
(),
arguments
);
}
catch
(
AccessException
ae
)
{
}
catch
(
AccessException
ae
)
{
throw
new
SpelException
(
getCharPositionInLine
(),
ae
,
SpelMessages
.
EXCEPTION_DURING_METHOD_INVOCATION
,
this
.
name
,
state
.
getActiveContextObject
().
getClass
().
getName
(),
ae
.
getMessage
());
this
.
name
,
state
.
getActiveContextObject
().
get
Value
().
get
Class
().
getName
(),
ae
.
getMessage
());
}
}
...
...
@@ -130,11 +129,6 @@ public class MethodReference extends SpelNodeImpl {
return
sb
.
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
protected
MethodExecutor
findAccessorForMethod
(
String
name
,
Class
<?>[]
argumentTypes
,
ExpressionState
state
)
throws
SpelException
{
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
浏览文件 @
cfc65b0c
...
...
@@ -17,8 +17,6 @@
package
org.springframework.expression.spel.ast
;
import
org.antlr.runtime.Token
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.ExpressionState
;
/**
* Common supertype for operators that operate on either one or two operands. In the case of multiply or divide there
...
...
@@ -32,15 +30,7 @@ public abstract class Operator extends SpelNodeImpl {
public
Operator
(
Token
payload
)
{
super
(
payload
);
}
/**
* Operator expressions can never be written to
*/
@Override
public
final
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
public
SpelNodeImpl
getLeftOperand
()
{
return
getChild
(
0
);
}
...
...
@@ -57,17 +47,13 @@ public abstract class Operator extends SpelNodeImpl {
@Override
public
String
toStringAST
()
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
getChildCount
()
>
0
)
{
sb
.
append
(
"("
);
}
sb
.
append
(
"("
);
sb
.
append
(
getChild
(
0
).
toStringAST
());
for
(
int
i
=
1
;
i
<
getChildCount
();
i
++)
{
sb
.
append
(
" "
).
append
(
getOperatorName
()).
append
(
" "
);
sb
.
append
(
getChild
(
i
).
toStringAST
());
}
if
(
getChildCount
()
>
0
)
{
sb
.
append
(
")"
);
}
sb
.
append
(
")"
);
return
sb
.
toString
();
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorNot.java
浏览文件 @
cfc65b0c
...
...
@@ -53,9 +53,4 @@ public class OperatorNot extends SpelNodeImpl { // Not is a unary operator so do
return
sb
.
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorPlus.java
浏览文件 @
cfc65b0c
...
...
@@ -28,11 +28,10 @@ import org.springframework.expression.spel.ExpressionState;
* <li>add doubles (floats are represented as doubles)
* <li>add longs
* <li>add integers
* <li>
add a string of one character and a number (effectively increasing that character), so 'a'+3='d'
* <li>
concatenate strings
* </ul>
* It can be used as a unary operator for numbers (double/long/int). The standard promotions are performed
* when the operand types vary (double+int=double).
* For other options it defers to the registered overloader.
* when the operand types vary (double+int=double). For other options it defers to the registered overloader.
*
* @author Andy Clement
* @since 3.0
...
...
@@ -75,16 +74,6 @@ public class OperatorPlus extends Operator {
}
}
else
if
(
operandOne
instanceof
String
&&
operandTwo
instanceof
String
)
{
return
new
TypedValue
(
new
StringBuilder
((
String
)
operandOne
).
append
((
String
)
operandTwo
).
toString
(),
STRING_TYPE_DESCRIPTOR
);
}
else
if
(
operandOne
instanceof
String
&&
operandTwo
instanceof
Integer
&&
((
String
)
operandOne
).
length
()==
1
)
{
String
theString
=
(
String
)
operandOne
;
Integer
theInteger
=
(
Integer
)
operandTwo
;
// implements character + int (ie. a + 1 = b)
return
new
TypedValue
(
Character
.
toString
((
char
)
(
theString
.
charAt
(
0
)
+
theInteger
)),
STRING_TYPE_DESCRIPTOR
);
}
else
if
(
operandOne
instanceof
Integer
&&
((
operandTwo
instanceof
String
)
&&
((
String
)
operandTwo
).
length
()==
1
))
{
String
theString
=
(
String
)
operandTwo
;
Integer
theInteger
=
(
Integer
)
operandOne
;
// implements character + int (ie. 1 + a = b)
return
new
TypedValue
(
Character
.
toString
((
char
)
(
theString
.
charAt
(
0
)
+
theInteger
)),
STRING_TYPE_DESCRIPTOR
);
}
return
state
.
operate
(
Operation
.
ADD
,
operandOne
,
operandTwo
);
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Projection.java
浏览文件 @
cfc65b0c
...
...
@@ -61,7 +61,7 @@ public class Projection extends SpelNodeImpl {
for
(
Object
k
:
mapdata
.
keySet
())
{
try
{
state
.
pushActiveContextObject
(
new
TypedValue
(
new
KeyValuePair
(
k
,
mapdata
.
get
(
k
)),
TypeDescriptor
.
valueOf
(
KeyValuePair
.
class
)));
result
.
add
(
getChild
(
0
).
getValueInternal
(
state
));
result
.
add
(
getChild
(
0
).
getValueInternal
(
state
)
.
getValue
()
);
}
finally
{
state
.
popActiveContextObject
();
}
...
...
@@ -76,7 +76,7 @@ public class Projection extends SpelNodeImpl {
try
{
state
.
pushActiveContextObject
(
new
TypedValue
(
element
,
TypeDescriptor
.
valueOf
(
op
.
getTypeDescriptor
().
getType
())));
state
.
enterScope
(
"index"
,
idx
);
result
.
add
(
getChild
(
0
).
getValueInternal
(
state
));
result
.
add
(
getChild
(
0
).
getValueInternal
(
state
)
.
getValue
()
);
}
finally
{
state
.
exitScope
();
state
.
popActiveContextObject
();
...
...
@@ -95,9 +95,4 @@ public class Projection extends SpelNodeImpl {
return
sb
.
append
(
"!{"
).
append
(
getChild
(
0
).
toStringAST
()).
append
(
"}"
).
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
浏览文件 @
cfc65b0c
...
...
@@ -145,6 +145,7 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
}
}
}
catch
(
AccessException
ae
)
{
ae
.
printStackTrace
();
throw
new
SpelException
(
getCharPositionInLine
(),
ae
,
SpelMessages
.
EXCEPTION_DURING_PROPERTY_WRITE
,
name
,
ae
.
getMessage
());
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java
浏览文件 @
cfc65b0c
...
...
@@ -31,7 +31,7 @@ import org.springframework.expression.spel.ExpressionState;
*/
public
class
QualifiedIdentifier
extends
SpelNodeImpl
{
private
String
value
;
private
TypedValue
value
;
public
QualifiedIdentifier
(
Token
payload
)
{
super
(
payload
);
...
...
@@ -49,18 +49,17 @@ public class QualifiedIdentifier extends SpelNodeImpl {
}
sb
.
append
(
getChild
(
i
).
getValueInternal
(
state
).
getValue
());
}
this
.
value
=
sb
.
toString
(
);
this
.
value
=
new
TypedValue
(
sb
.
toString
(),
STRING_TYPE_DESCRIPTOR
);
}
return
new
TypedValue
(
this
.
value
,
STRING_TYPE_DESCRIPTOR
)
;
return
this
.
value
;
}
@Override
public
String
toStringAST
()
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
this
.
value
!=
null
)
{
sb
.
append
(
this
.
value
);
}
else
{
sb
.
append
(
this
.
value
.
getValue
());
}
else
{
for
(
int
i
=
0
;
i
<
getChildCount
();
i
++)
{
if
(
i
>
0
)
{
sb
.
append
(
"."
);
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Selection.java
浏览文件 @
cfc65b0c
...
...
@@ -18,6 +18,7 @@ package org.springframework.expression.spel.ast;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -59,17 +60,21 @@ public class Selection extends SpelNodeImpl {
SpelNodeImpl
selectionCriteria
=
getChild
(
0
);
if
(
operand
instanceof
Map
)
{
Map
<?,
?>
mapdata
=
(
Map
<?,
?>)
operand
;
List
<
Object
>
result
=
new
ArrayList
<
Object
>();
// TODO don't lose generic info for the new map
Map
<
Object
,
Object
>
result
=
new
HashMap
<
Object
,
Object
>();
for
(
Object
k
:
mapdata
.
keySet
())
{
try
{
TypedValue
kvpair
=
new
TypedValue
(
new
KeyValuePair
(
k
,
mapdata
.
get
(
k
)),
TypeDescriptor
.
valueOf
(
KeyValuePair
.
class
));
KeyValuePair
kvp
=
new
KeyValuePair
(
k
,
mapdata
.
get
(
k
));
TypedValue
kvpair
=
new
TypedValue
(
kvp
,
TypeDescriptor
.
valueOf
(
KeyValuePair
.
class
));
state
.
pushActiveContextObject
(
kvpair
);
Object
o
=
selectionCriteria
.
getValueInternal
(
state
);
Object
o
=
selectionCriteria
.
getValueInternal
(
state
)
.
getValue
()
;
if
(
o
instanceof
Boolean
)
{
if
(((
Boolean
)
o
).
booleanValue
()
==
true
)
{
if
(
variant
==
FIRST
)
return
kvpair
;
result
.
add
(
kvpair
);
if
(
variant
==
FIRST
)
{
result
.
put
(
kvp
.
key
,
kvp
.
value
);
return
new
TypedValue
(
result
);
}
result
.
put
(
kvp
.
key
,
kvp
.
value
);
}
}
else
{
throw
new
SpelException
(
selectionCriteria
.
getCharPositionInLine
(),
...
...
@@ -142,9 +147,4 @@ public class Selection extends SpelNodeImpl {
return
sb
.
append
(
getChild
(
0
).
toStringAST
()).
append
(
"}"
).
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
浏览文件 @
cfc65b0c
...
...
@@ -55,6 +55,7 @@ public abstract class SpelNodeImpl extends CommonTree implements SpelNode, Seria
}
}
// by default Ast nodes are not writable
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
EvaluationException
{
return
false
;
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelTreeAdaptor.java
浏览文件 @
cfc65b0c
...
...
@@ -18,7 +18,6 @@ package org.springframework.expression.spel.ast;
import
org.antlr.runtime.Token
;
import
org.antlr.runtime.tree.CommonTreeAdaptor
;
import
org.springframework.expression.spel.generated.SpringExpressionsLexer
;
/**
...
...
@@ -95,7 +94,7 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
return
new
CompoundExpression
(
payload
);
case
SpringExpressionsLexer
.
CONSTRUCTOR
:
return
new
ConstructorReference
(
payload
,
false
);
return
new
ConstructorReference
(
payload
);
case
SpringExpressionsLexer
.
VARIABLEREF
:
return
new
VariableReference
(
payload
);
case
SpringExpressionsLexer
.
FUNCTIONREF
:
...
...
@@ -123,11 +122,6 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
case
SpringExpressionsLexer
.
INSTANCEOF
:
return
new
OperatorInstanceof
(
payload
);
case
SpringExpressionsLexer
.
RPAREN
:
return
new
Placeholder
(
payload
);
case
SpringExpressionsLexer
.
COLON
:
return
new
Placeholder
(
payload
);
case
SpringExpressionsLexer
.
DOT
:
return
new
Dot
(
payload
);
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Ternary.java
浏览文件 @
cfc65b0c
...
...
@@ -20,7 +20,6 @@ import org.antlr.runtime.Token;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents a ternary expression, for example: "someCheck()?true:false".
...
...
@@ -57,9 +56,4 @@ public class Ternary extends SpelNodeImpl {
.
append
(
" : "
).
append
(
getChild
(
2
).
toStringAST
()).
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java
浏览文件 @
cfc65b0c
...
...
@@ -20,7 +20,6 @@ import org.antlr.runtime.Token;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents a reference to a type, for example "T(String)" or "T(com.somewhere.Foo)"
...
...
@@ -56,9 +55,4 @@ public class TypeReference extends SpelNodeImpl {
return
sb
.
toString
();
}
@Override
public
boolean
isWritable
(
ExpressionState
expressionState
)
throws
SpelException
{
return
false
;
}
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java
浏览文件 @
cfc65b0c
...
...
@@ -56,8 +56,7 @@ class ReflectiveMethodExecutor implements MethodExecutor {
}
ReflectionUtils
.
makeAccessible
(
this
.
method
);
return
new
TypedValue
(
this
.
method
.
invoke
(
target
,
arguments
),
new
TypeDescriptor
(
new
MethodParameter
(
method
,-
1
)));
}
catch
(
Exception
ex
)
{
}
catch
(
Exception
ex
)
{
throw
new
AccessException
(
"Problem invoking method: "
+
this
.
method
,
ex
);
}
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
浏览文件 @
cfc65b0c
...
...
@@ -17,6 +17,7 @@
package
org.springframework.expression.spel.support
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.core.convert.service.DefaultConversionService
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypeConverter
;
import
org.springframework.expression.spel.SpelException
;
...
...
@@ -31,8 +32,16 @@ import org.springframework.util.NumberUtils;
*/
public
class
StandardTypeConverter
implements
TypeConverter
{
DefaultConversionService
conversionService
;
StandardTypeConverter
()
{
conversionService
=
new
DefaultConversionService
();
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
convertValue
(
Object
value
,
Class
<
T
>
targetType
)
throws
EvaluationException
{
// For activation when conversion service available - this replaces the rest of the method (probably...)
// return (T)convertValue(value,TypeDescriptor.valueOf(targetType));
if
(
ClassUtils
.
isAssignableValue
(
targetType
,
value
))
{
return
(
T
)
value
;
}
...
...
@@ -78,10 +87,20 @@ public class StandardTypeConverter implements TypeConverter {
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
convertValue
(
Object
value
,
TypeDescriptor
typeDescriptor
)
throws
EvaluationException
{
// For activation when conversion service available - this replaces the rest of the method (probably...)
// try {
// return (T)conversionService.executeConversion(value, typeDescriptor);
// } catch (ConversionExecutorNotFoundException cenfe) {
// throw new SpelException(cenfe, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
// } catch (ConversionException ce) {
// throw new SpelException(ce, SpelMessages.TYPE_CONVERSION_ERROR, value.getClass(), typeDescriptor.asString());
// }
return
(
T
)
convertValue
(
value
,
typeDescriptor
.
getType
());
}
public
boolean
canConvert
(
Class
<?>
sourceType
,
Class
<?>
targetType
)
{
// For activation when conversion service available - this replaces the rest of the method (probably...)
// return canConvert(sourceType,TypeDescriptor.valueOf(targetType));
if
(
ClassUtils
.
isAssignable
(
targetType
,
sourceType
)
||
String
.
class
.
equals
(
targetType
))
{
return
true
;
}
...
...
@@ -92,6 +111,12 @@ public class StandardTypeConverter implements TypeConverter {
}
public
boolean
canConvert
(
Class
<?>
sourceType
,
TypeDescriptor
typeDescriptor
)
{
// For activation when conversion service available - this replaces the rest of the method (probably...)
// try {
// return conversionService.getConversionExecutor(sourceType, typeDescriptor)!=null;
// } catch (ConversionExecutorNotFoundException cenfe) {
// return false;
// }
return
canConvert
(
sourceType
,
typeDescriptor
.
getType
());
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
浏览文件 @
cfc65b0c
...
...
@@ -19,6 +19,7 @@ package org.springframework.expression.spel;
import
java.util.ArrayList
;
import
org.springframework.expression.Expression
;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
/**
* Tests the evaluation of real expressions in a real context.
...
...
@@ -208,6 +209,22 @@ public class EvaluationTests extends ExpressionTestCase {
public
void
testConstructorInvocation05
()
{
evaluate
(
"new java.lang.String('foobar')"
,
"foobar"
,
String
.
class
);
}
public
void
testConstructorInvocation06
()
throws
Exception
{
// repeated evaluation to drive use of cached executor
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"new String('wibble')"
);
String
newString
=
expr
.
getValue
(
String
.
class
);
assertEquals
(
"wibble"
,
newString
);
newString
=
expr
.
getValue
(
String
.
class
);
assertEquals
(
"wibble"
,
newString
);
// not writable
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
// ast
assertEquals
(
"new String('wibble')"
,
expr
.
toStringAST
());
}
// array construction
// public void testArrayConstruction01() {
...
...
@@ -275,14 +292,18 @@ public class EvaluationTests extends ExpressionTestCase {
// }
// 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
testProjection01
()
{
evaluate
(
"listOfNumbersUpToTen.!{#this<5?'y':'n'}"
,
"[y, y, y, y, n, n, n, n, n, n]"
,
ArrayList
.
class
);
// inline list creation not supported at the moment
// 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
()
{
// inline map creation not supported at the moment
// evaluate("#{'a':'y','b':'n','c':'y'}.!{value=='y'?key:null}.nonnull().sort()", "[a, c]", ArrayList.class);
evaluate
(
"mapOfNumbersUpToTen.!{key>5?value:null}"
,
"[null, null, null, null, null, six, seven, eight, nine, ten]"
,
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);
...
...
@@ -291,11 +312,21 @@ public class EvaluationTests extends ExpressionTestCase {
// 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
()
{
// inline list creation not supported:
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
public
void
testProjection05
()
{
evaluateAndCheckError
(
"'abc'.!{true}"
,
SpelMessages
.
PROJECTION_NOT_SUPPORTED_ON_TYPE
);
}
public
void
testProjection06
()
throws
Exception
{
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"'abc'.!{true}"
);
assertEquals
(
"'abc'.!{true}"
,
expr
.
toStringAST
());
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
}
//public void testSelection01() {
// inline list creation not supported:
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
//}
public
void
testSelection02
()
{
evaluate
(
"testMap.keySet().?{#this matches '.*o.*'}"
,
"[monday]"
,
ArrayList
.
class
);
...
...
@@ -303,23 +334,40 @@ public class EvaluationTests extends ExpressionTestCase {
evaluate
(
"testMap.keySet().?{#this matches '.*r.*'}.size()"
,
"3"
,
Integer
.
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
(
"listOfNumbersUpToTen
.?{'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
testSelection03
()
{
evaluate
(
"mapOfNumbersUpToTen.?{key>5}.size()"
,
"5"
,
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);
// }
public
void
testSelectionFirst01
()
{
evaluate
(
"listOfNumbersUpToTen.^{#isEven(#this) == 'y'}"
,
"2"
,
Integer
.
class
);
}
public
void
testSelectionLast01
()
{
evaluate
(
"listOfNumbersUpToTen.${#isEven(#this) == 'y'}"
,
"10"
,
Integer
.
class
);
}
public
void
testSelectionAST
()
throws
Exception
{
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"'abc'.^{true}"
);
assertEquals
(
"'abc'.^{true}"
,
expr
.
toStringAST
());
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"'abc'.?{true}"
);
assertEquals
(
"'abc'.?{true}"
,
expr
.
toStringAST
());
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"'abc'.${true}"
);
assertEquals
(
"'abc'.${true}"
,
expr
.
toStringAST
());
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
}
// assignment
public
void
testAssignmentToVariables01
()
{
evaluate
(
"#var1='value1'"
,
"value1"
,
String
.
class
);
...
...
@@ -451,6 +499,16 @@ public class EvaluationTests extends ExpressionTestCase {
public
void
testTypeReferences01
()
{
evaluate
(
"T(java.lang.String)"
,
"class java.lang.String"
,
Class
.
class
);
}
public
void
testTypeReferencesAndQualifiedIdentifierCaching
()
throws
Exception
{
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"T(java.lang.String)"
);
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
assertEquals
(
"T(java.lang.String)"
,
expr
.
toStringAST
());
assertEquals
(
String
.
class
,
expr
.
getValue
(
Class
.
class
));
// use cached QualifiedIdentifier:
assertEquals
(
"T(java.lang.String)"
,
expr
.
toStringAST
());
assertEquals
(
String
.
class
,
expr
.
getValue
(
Class
.
class
));
}
public
void
testTypeReferencesPrimitive
()
{
evaluate
(
"T(int)"
,
"int"
,
Class
.
class
);
...
...
org.springframework.expression/src/
main/java/org/springframework/expression/spel/ast/Placeholder
.java
→
org.springframework.expression/src/
test/java/org/springframework/expression/spel/HelperTests
.java
浏览文件 @
cfc65b0c
...
...
@@ -13,36 +13,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.expression.spel
;
package
org.springframework.expression.spel.ast
;
import
org.antlr.runtime.Token
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.SpelMessages
;
import
org.springframework.expression.spel.ast.FormatHelper
;
/**
* PlaceHolder nodes are created for tokens that come through from the grammar purely to give us additional positional
* information for messages/etc.
* Tests for any helper code.
*
* @author Andy Clement
* @since 3.0
*/
public
class
Placeholder
extends
SpelNodeImpl
{
public
class
HelperTests
extends
ExpressionTestCase
{
public
Placeholder
(
Token
payload
)
{
super
(
payload
);
public
void
testFormatHelperForClassName
()
{
assertEquals
(
"java.lang.String"
,
FormatHelper
.
formatClassNameForMessage
(
String
.
class
));
assertEquals
(
"java.lang.String[]"
,
FormatHelper
.
formatClassNameForMessage
(
new
String
[
1
].
getClass
()));
assertEquals
(
"int[]"
,
FormatHelper
.
formatClassNameForMessage
(
new
int
[
1
].
getClass
()));
assertEquals
(
"int[][]"
,
FormatHelper
.
formatClassNameForMessage
(
new
int
[
1
][
2
].
getClass
()));
assertEquals
(
"null"
,
FormatHelper
.
formatClassNameForMessage
(
null
));
}
@Override
public
TypedValue
getValueInternal
(
ExpressionState
state
)
throws
SpelException
{
throw
new
SpelException
(
getCharPositionInLine
(),
SpelMessages
.
PLACEHOLDER_SHOULD_NEVER_BE_EVALUATED
);
public
void
testFormatHelperForMethod
()
{
assertEquals
(
"foo(java.lang.String)"
,
FormatHelper
.
formatMethodForMessage
(
"foo"
,
String
.
class
));
assertEquals
(
"goo(java.lang.String,int[])"
,
FormatHelper
.
formatMethodForMessage
(
"goo"
,
String
.
class
,
new
int
[
1
].
getClass
()));
assertEquals
(
"boo()"
,
FormatHelper
.
formatMethodForMessage
(
"boo"
));
}
@Override
public
String
toStringAST
()
{
return
getText
();
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/LiteralTests.java
浏览文件 @
cfc65b0c
...
...
@@ -16,6 +16,8 @@
package
org.springframework.expression.spel
;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
/**
* Tests the evaluation of basic literals: boolean, integer, hex integer, long, real, null, date
*
...
...
@@ -134,4 +136,13 @@ public class LiteralTests extends ExpressionTestCase {
evaluate
(
"new Integer(37).byteValue()"
,
(
byte
)
37
,
Byte
.
class
);
// calling byteValue() on Integer.class
evaluateAndAskForReturnType
(
"new Integer(37)"
,
(
byte
)
37
,
Byte
.
class
);
// relying on registered type converters
}
public
void
testNotWritable
()
throws
Exception
{
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"37"
);
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"37L"
);
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"true"
);
assertFalse
(
expr
.
isWritable
(
new
StandardEvaluationContext
()));
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/OperatorTests.java
浏览文件 @
cfc65b0c
...
...
@@ -63,6 +63,8 @@ public class OperatorTests extends ExpressionTestCase {
evaluate
(
"3 == 5"
,
false
,
Boolean
.
class
);
evaluate
(
"5 == 3"
,
false
,
Boolean
.
class
);
evaluate
(
"6 == 6"
,
true
,
Boolean
.
class
);
evaluate
(
"3.0f == 5.0f"
,
false
,
Boolean
.
class
);
evaluate
(
"3.0f == 3.0f"
,
true
,
Boolean
.
class
);
evaluate
(
"'abc' == null"
,
false
,
Boolean
.
class
);
}
...
...
@@ -70,6 +72,8 @@ public class OperatorTests extends ExpressionTestCase {
evaluate
(
"3 != 5"
,
true
,
Boolean
.
class
);
evaluate
(
"5 != 3"
,
true
,
Boolean
.
class
);
evaluate
(
"6 != 6"
,
false
,
Boolean
.
class
);
evaluate
(
"3.0f != 5.0f"
,
true
,
Boolean
.
class
);
evaluate
(
"3.0f != 3.0f"
,
false
,
Boolean
.
class
);
}
public
void
testGreaterThanOrEqual
()
{
...
...
@@ -122,23 +126,36 @@ public class OperatorTests extends ExpressionTestCase {
}
public
void
testPlus
()
throws
Exception
{
evaluate
(
"'a' + 2"
,
"c"
,
String
.
class
);
evaluate
(
"7 + 2"
,
"9"
,
Integer
.
class
);
evaluate
(
"3.0f + 5.0f"
,
8.0d
,
Double
.
class
);
evaluate
(
"3.0d + 5.0d"
,
8.0d
,
Double
.
class
);
evaluateAndCheckError
(
"'ab' + 2"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
evaluate
(
"2+'a' "
,
"c"
,
String
.
class
);
evaluate
AndCheckError
(
"2+'a' "
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
evaluateAndCheckError
(
"2+'ab'"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
// AST:
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"+3"
);
assertEquals
(
"+3"
,
expr
.
toStringAST
());
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"2+3"
);
assertEquals
(
"(2 + 3)"
,
expr
.
toStringAST
());
// use as a unary operator
evaluate
(
"+5d"
,
5
d
,
Double
.
class
);
evaluate
(
"+5L"
,
5L
,
Long
.
class
);
evaluate
(
"+5"
,
5
,
Integer
.
class
);
evaluateAndCheckError
(
"+'abc'"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
// string concatenation
evaluate
(
"'abc'+'def'"
,
"abcdef"
,
String
.
class
);
//
evaluate
(
"5 + new Integer('37')"
,
42
,
Integer
.
class
);
}
public
void
testMinus
()
throws
Exception
{
evaluate
(
"'c' - 2"
,
"a"
,
String
.
class
);
evaluate
(
"3.0f - 5.0f"
,
-
2.0d
,
Double
.
class
);
evaluateAndCheckError
(
"'ab' - 2"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
evaluateAndCheckError
(
"2-'ab'"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
SpelExpression
expr
=
(
SpelExpression
)
parser
.
parseExpression
(
"-3"
);
...
...
@@ -156,11 +173,14 @@ public class OperatorTests extends ExpressionTestCase {
evaluate
(
"3%2"
,
1
,
Integer
.
class
);
evaluate
(
"3L%2L"
,
1L
,
Long
.
class
);
evaluate
(
"3.0d%2.0d"
,
1
d
,
Double
.
class
);
evaluate
(
"5.0f % 3.1f"
,
1.9d
,
Double
.
class
);
evaluateAndCheckError
(
"'abc'%'def'"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
}
public
void
testDivide
()
{
evaluate
(
"3.0f / 5.0f"
,
0.6d
,
Double
.
class
);
evaluate
(
"4L/2L"
,
2L
,
Long
.
class
);
evaluateAndCheckError
(
"'abc'/'def'"
,
SpelMessages
.
OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES
);
}
public
void
testMathOperatorDivide_ConvertToDouble
()
{
...
...
@@ -182,20 +202,8 @@ public class OperatorTests extends ExpressionTestCase {
evaluate
(
"3.0d / 5.0d"
,
0.6d
,
Double
.
class
);
evaluate
(
"6.0d % 3.5d"
,
2.5d
,
Double
.
class
);
}
public
void
testFloats
()
{
evaluate
(
"3.0f == 5.0f"
,
false
,
Boolean
.
class
);
evaluate
(
"3.0f == 3.0f"
,
true
,
Boolean
.
class
);
evaluate
(
"3.0f != 5.0f"
,
true
,
Boolean
.
class
);
evaluate
(
"3.0f != 3.0f"
,
false
,
Boolean
.
class
);
evaluate
(
"3.0f + 5.0f"
,
8.0d
,
Double
.
class
);
evaluate
(
"3.0f - 5.0f"
,
-
2.0d
,
Double
.
class
);
evaluate
(
"3.0f * 5.0f"
,
15.0d
,
Double
.
class
);
evaluate
(
"3.0f / 5.0f"
,
0.6d
,
Double
.
class
);
evaluate
(
"5.0f % 3.1f"
,
1.9d
,
Double
.
class
);
}
public
void
testOperator
String
s
()
throws
Exception
{
public
void
testOperator
Name
s
()
throws
Exception
{
Operator
node
=
getOperatorNode
((
SpelExpression
)
parser
.
parseExpression
(
"1==3"
));
assertEquals
(
"=="
,
node
.
getOperatorName
());
...
...
@@ -266,6 +274,8 @@ public class OperatorTests extends ExpressionTestCase {
evaluate
(
"3L - 50L"
,
-
47L
,
Long
.
class
);
}
// ---
private
Operator
getOperatorNode
(
SpelExpression
e
)
{
SpelNode
node
=
e
.
getAST
();
return
(
Operator
)
findNode
(
node
,
Operator
.
class
);
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/ParserErrorMessagesTests.java
浏览文件 @
cfc65b0c
...
...
@@ -29,6 +29,7 @@ public class ParserErrorMessagesTests extends ExpressionTestCase {
// will not fit into an int, needs L suffix
parseAndCheckError
(
"0xCAFEBABE"
,
SpelMessages
.
NOT_AN_INTEGER
);
evaluate
(
"0xCAFEBABEL"
,
0xCAFEBABE
L
,
Long
.
class
);
parseAndCheckError
(
"0xCAFEBABECAFEBABEL"
,
SpelMessages
.
NOT_A_LONG
);
}
public
void
testBrokenExpression02
()
{
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/VariableAndFunctionTests.java
浏览文件 @
cfc65b0c
...
...
@@ -19,6 +19,7 @@ package org.springframework.expression.spel;
import
org.springframework.expression.spel.antlr.SpelAntlrExpressionParser
;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
/**
* Tests the evaluation of expressions that access variables and functions (lambda/java).
*
...
...
@@ -26,10 +27,15 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
*/
public
class
VariableAndFunctionTests
extends
ExpressionTestCase
{
public
void
testVariableAccess
()
{
public
void
testVariableAccess
01
()
{
evaluate
(
"#answer"
,
"42"
,
Integer
.
class
,
SHOULD_BE_WRITABLE
);
evaluate
(
"#answer / 2"
,
21
,
Integer
.
class
,
SHOULD_NOT_BE_WRITABLE
);
}
public
void
testVariableAccess_WellKnownVariables
()
{
evaluate
(
"#this.getName()"
,
"Nikola Tesla"
,
String
.
class
);
evaluate
(
"#root.getName()"
,
"Nikola Tesla"
,
String
.
class
);
}
public
void
testFunctionAccess01
()
{
evaluate
(
"#reverseInt(1,2,3)"
,
"int[3]{3,2,1}"
,
int
[].
class
);
...
...
@@ -71,7 +77,7 @@ public class VariableAndFunctionTests extends ExpressionTestCase {
}
}
}
// this method is used by the test above
public
void
nonStatic
()
{
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Company.java
浏览文件 @
cfc65b0c
...
...
@@ -3,6 +3,7 @@
*/
package
org.springframework.expression.spel.testresources
;
///CLOVER:OFF
public
class
Company
{
String
address
;
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Fruit.java
浏览文件 @
cfc65b0c
...
...
@@ -5,6 +5,7 @@ package org.springframework.expression.spel.testresources;
import
java.awt.Color
;
///CLOVER:OFF
public
class
Fruit
{
public
String
name
;
// accessible as property field
public
Color
color
;
// accessible as property through getter/setter
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
浏览文件 @
cfc65b0c
...
...
@@ -6,6 +6,7 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Map
;
///CLOVER:OFF
@SuppressWarnings
(
"unused"
)
public
class
Inventor
{
private
String
name
;
...
...
@@ -26,6 +27,8 @@ public class Inventor {
public
List
<
Integer
>
listOfInteger
=
new
ArrayList
<
Integer
>();
public
List
<
Boolean
>
booleanList
=
new
ArrayList
<
Boolean
>();
public
Map
<
String
,
Boolean
>
mapOfStringToBoolean
=
new
HashMap
<
String
,
Boolean
>();
public
Map
<
Integer
,
String
>
mapOfNumbersUpToTen
=
new
HashMap
<
Integer
,
String
>();
public
List
<
Integer
>
listOfNumbersUpToTen
=
new
ArrayList
<
Integer
>();
public
Inventor
(
String
name
,
Date
birthdate
,
String
nationality
)
{
this
.
name
=
name
;
...
...
@@ -42,6 +45,26 @@ public class Inventor {
testMap
.
put
(
"sunday"
,
"sonntag"
);
booleanList
.
add
(
false
);
booleanList
.
add
(
false
);
listOfNumbersUpToTen
.
add
(
1
);
listOfNumbersUpToTen
.
add
(
2
);
listOfNumbersUpToTen
.
add
(
3
);
listOfNumbersUpToTen
.
add
(
4
);
listOfNumbersUpToTen
.
add
(
5
);
listOfNumbersUpToTen
.
add
(
6
);
listOfNumbersUpToTen
.
add
(
7
);
listOfNumbersUpToTen
.
add
(
8
);
listOfNumbersUpToTen
.
add
(
9
);
listOfNumbersUpToTen
.
add
(
10
);
mapOfNumbersUpToTen
.
put
(
1
,
"one"
);
mapOfNumbersUpToTen
.
put
(
2
,
"two"
);
mapOfNumbersUpToTen
.
put
(
3
,
"three"
);
mapOfNumbersUpToTen
.
put
(
4
,
"four"
);
mapOfNumbersUpToTen
.
put
(
5
,
"five"
);
mapOfNumbersUpToTen
.
put
(
6
,
"six"
);
mapOfNumbersUpToTen
.
put
(
7
,
"seven"
);
mapOfNumbersUpToTen
.
put
(
8
,
"eight"
);
mapOfNumbersUpToTen
.
put
(
9
,
"nine"
);
mapOfNumbersUpToTen
.
put
(
10
,
"ten"
);
}
public
void
setPlaceOfBirth
(
PlaceOfBirth
placeOfBirth2
)
{
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Person.java
浏览文件 @
cfc65b0c
package
org.springframework.expression.spel.testresources
;
///CLOVER:OFF
public
class
Person
{
private
String
privateName
;
Company
company
;
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/PlaceOfBirth.java
浏览文件 @
cfc65b0c
package
org.springframework.expression.spel.testresources
;
///CLOVER:OFF
public
class
PlaceOfBirth
{
private
String
city
;
...
...
org.springframework.expression/template.mf
浏览文件 @
cfc65b0c
...
...
@@ -6,6 +6,7 @@ Import-Template:
org.springframework.util;version="[3.0.0, 3.0.1)",
org.springframework.core;version="[3.0.0, 3.0.1)",
org.springframework.core.convert;version="[3.0.0, 3.0.1)",
org.springframework.core.convert.service;version="[3.0.0, 3.0.1)",
org.apache.commons.logging;version="[1.1.1, 2.0.0)",
org.antlr.runtime;version="[3.0.1,4.0.0)",
org.antlr.runtime.tree;version="[3.0.1,4.0.0)"
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录