Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
58b07f58
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,发现更多精彩内容 >>
提交
58b07f58
编写于
8月 07, 2010
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SpEL passes full collection type context to ConversionService (SPR-7410)
上级
7cddb1c5
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
199 addition
and
134 deletion
+199
-134
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
...pringframework/expression/spel/ast/FunctionReference.java
+24
-28
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
...ngframework/expression/spel/support/ReflectionHelper.java
+51
-55
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java
...xpression/spel/support/ReflectiveConstructorExecutor.java
+16
-9
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java
...ork/expression/spel/support/ReflectiveMethodExecutor.java
+17
-5
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java
...ssion/spel/ExpressionTestsUsingCoreConversionService.java
+52
-13
org.springframework.expression/src/test/java/org/springframework/expression/spel/ScenariosForSpringSecurity.java
...framework/expression/spel/ScenariosForSpringSecurity.java
+3
-3
org.springframework.expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java
...mework/expression/spel/support/ReflectionHelperTests.java
+36
-21
未找到文件。
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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,7 +16,6 @@
package
org.springframework.expression.spel.ast
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
...
...
@@ -37,9 +36,10 @@ import org.springframework.util.ReflectionUtils;
* function definition in an expression: "(#max = {|x,y|$x>$y?$x:$y};max(2,3))" Calling context defined function:
* "#isEven(37)". Functions may also be static java methods, registered in the context prior to invocation of the
* expression.
*
* Functions are very simplistic, the arguments are not part of the definition (right now), so the names must be unique.
*
*
* <p>Functions are very simplistic, the arguments are not part of the definition (right now),
* so the names must be unique.
*
* @author Andy Clement
* @since 3.0
*/
...
...
@@ -65,7 +65,8 @@ public class FunctionReference extends SpelNodeImpl {
}
try
{
return
executeFunctionJLRMethod
(
state
,
(
Method
)
o
.
getValue
());
}
catch
(
SpelEvaluationException
se
)
{
}
catch
(
SpelEvaluationException
se
)
{
se
.
setPosition
(
getStartPosition
());
throw
se
;
}
...
...
@@ -79,42 +80,37 @@ public class FunctionReference extends SpelNodeImpl {
* @return the return value of the invoked Java method
* @throws EvaluationException if there is any problem invoking the method
*/
private
TypedValue
executeFunctionJLRMethod
(
ExpressionState
state
,
Method
m
)
throws
EvaluationException
{
private
TypedValue
executeFunctionJLRMethod
(
ExpressionState
state
,
Method
m
ethod
)
throws
EvaluationException
{
Object
[]
functionArgs
=
getArguments
(
state
);
if
(!
m
.
isVarArgs
()
&&
m
.
getParameterTypes
().
length
!=
functionArgs
.
length
)
{
throw
new
SpelEvaluationException
(
SpelMessage
.
INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION
,
functionArgs
.
length
,
m
.
getParameterTypes
().
length
);
if
(!
m
ethod
.
isVarArgs
()
&&
method
.
getParameterTypes
().
length
!=
functionArgs
.
length
)
{
throw
new
SpelEvaluationException
(
SpelMessage
.
INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION
,
functionArgs
.
length
,
method
.
getParameterTypes
().
length
);
}
// Only static methods can be called in this way
if
(!
Modifier
.
isStatic
(
m
.
getModifiers
()))
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
SpelMessage
.
FUNCTION_MUST_BE_STATIC
,
m
if
(!
Modifier
.
isStatic
(
m
ethod
.
getModifiers
()))
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
SpelMessage
.
FUNCTION_MUST_BE_STATIC
,
m
ethod
.
getDeclaringClass
().
getName
()
+
"."
+
m
.
getName
(),
name
);
+
"."
+
m
ethod
.
getName
(),
name
);
}
// Convert arguments if necessary and remap them for varargs if required
if
(
functionArgs
!=
null
)
{
TypeConverter
converter
=
state
.
getEvaluationContext
().
getTypeConverter
();
ReflectionHelper
.
convertAllArguments
(
m
.
getParameterTypes
(),
m
.
isVarArgs
(),
converter
,
functionArgs
);
ReflectionHelper
.
convertAllArguments
(
converter
,
functionArgs
,
method
);
}
if
(
m
.
isVarArgs
())
{
functionArgs
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
m
.
getParameterTypes
(),
functionArgs
);
if
(
m
ethod
.
isVarArgs
())
{
functionArgs
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
m
ethod
.
getParameterTypes
(),
functionArgs
);
}
try
{
ReflectionUtils
.
makeAccessible
(
m
);
Object
result
=
m
.
invoke
(
m
.
getClass
(),
functionArgs
);
return
new
TypedValue
(
result
,
new
TypeDescriptor
(
new
MethodParameter
(
m
,-
1
)));
}
catch
(
IllegalArgumentException
e
)
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
e
,
SpelMessage
.
EXCEPTION_DURING_FUNCTION_CALL
,
name
,
e
.
getMessage
());
}
catch
(
IllegalAccessException
e
)
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
e
,
SpelMessage
.
EXCEPTION_DURING_FUNCTION_CALL
,
name
,
e
.
getMessage
());
}
catch
(
InvocationTargetException
e
)
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
e
,
SpelMessage
.
EXCEPTION_DURING_FUNCTION_CALL
,
name
,
e
.
getMessage
());
ReflectionUtils
.
makeAccessible
(
method
);
Object
result
=
method
.
invoke
(
method
.
getClass
(),
functionArgs
);
return
new
TypedValue
(
result
,
new
TypeDescriptor
(
new
MethodParameter
(
method
,-
1
)));
}
catch
(
Exception
ex
)
{
throw
new
SpelEvaluationException
(
getStartPosition
(),
ex
,
SpelMessage
.
EXCEPTION_DURING_FUNCTION_CALL
,
this
.
name
,
ex
.
getMessage
());
}
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
浏览文件 @
58b07f58
...
...
@@ -17,9 +17,11 @@
package
org.springframework.expression.spel.support
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypeConverter
;
...
...
@@ -29,7 +31,7 @@ import org.springframework.util.Assert;
import
org.springframework.util.ClassUtils
;
/**
* Utility methods used by the reflection resolver code to discover the appropriae
* Utility methods used by the reflection resolver code to discover the appropria
t
e
* methods/constructors and fields that should be used in expressions.
*
* @author Andy Clement
...
...
@@ -39,15 +41,15 @@ import org.springframework.util.ClassUtils;
public
class
ReflectionHelper
{
/**
* Compare argument arrays and return information about whether they match. A supplied type converter
and
*
conversionAllowed flag allow for matches to take into account that a type may be transformed into a different
* type by the converter.
* Compare argument arrays and return information about whether they match. A supplied type converter
*
and conversionAllowed flag allow for matches to take into account that a type may be transformed
*
into a different
type by the converter.
* @param expectedArgTypes the array of types the method/constructor is expecting
* @param suppliedArgTypes the array of types that are being supplied at the point of invocation
* @param typeConverter a registered type converter
* @return a MatchInfo object indicating what kind of match it was or null if it was not a match
*/
public
static
ArgumentsMatchInfo
compareArguments
(
static
ArgumentsMatchInfo
compareArguments
(
Class
[]
expectedArgTypes
,
Class
[]
suppliedArgTypes
,
TypeConverter
typeConverter
)
{
Assert
.
isTrue
(
expectedArgTypes
.
length
==
suppliedArgTypes
.
length
,
...
...
@@ -110,11 +112,13 @@ public class ReflectionHelper {
* @param typeConverter a registered type converter
* @return a MatchInfo object indicating what kind of match it was or null if it was not a match
*/
public
static
ArgumentsMatchInfo
compareArgumentsVarargs
(
static
ArgumentsMatchInfo
compareArgumentsVarargs
(
Class
[]
expectedArgTypes
,
Class
[]
suppliedArgTypes
,
TypeConverter
typeConverter
)
{
Assert
.
isTrue
(
expectedArgTypes
!=
null
&&
expectedArgTypes
.
length
>
0
,
"Expected arguments must at least include one array (the vargargs parameter)"
);
Assert
.
isTrue
(
expectedArgTypes
[
expectedArgTypes
.
length
-
1
].
isArray
(),
"Final expected argument should be array type (the varargs parameter)"
);
Assert
.
isTrue
(
expectedArgTypes
!=
null
&&
expectedArgTypes
.
length
>
0
,
"Expected arguments must at least include one array (the vargargs parameter)"
);
Assert
.
isTrue
(
expectedArgTypes
[
expectedArgTypes
.
length
-
1
].
isArray
(),
"Final expected argument should be array type (the varargs parameter)"
);
ArgsMatchKind
match
=
ArgsMatchKind
.
EXACT
;
List
<
Integer
>
argsRequiringConversion
=
null
;
...
...
@@ -214,76 +218,67 @@ public class ReflectionHelper {
}
/**
* Takes an input set of argument values and, following the positions specified in the int array, it converts
* them to the types specified as the required parameter types. The arguments are converted 'in-place' in the
* input array.
* @param requiredParameterTypes the types that the caller would like to have
* @param isVarargs whether the requiredParameterTypes is a varargs list
* Takes an input set of argument values and, following the positions specified in the int array,
* it converts them to the types specified as the required parameter types. The arguments are
* converted 'in-place' in the input array.
* @param converter the type converter to use for attempting conversions
* @param argumentsRequiringConversion details which of the input arguments need conversion
* @param arguments the actual arguments that need conversion
* @param methodOrCtor the target Method or Constructor
* @param argumentsRequiringConversion details which of the input arguments need conversion
* @param varargsPosition the known position of the varargs argument, if any
* @throws EvaluationException if a problem occurs during conversion
*/
public
static
void
convertArguments
(
Class
[]
requiredParameterTypes
,
boolean
isVarargs
,
TypeConverter
converter
,
int
[]
argumentsRequiringConversion
,
Object
[]
arguments
)
throws
EvaluationException
{
Assert
.
notNull
(
argumentsRequiringConversion
,
"should not be called if no conversions required"
);
Assert
.
notNull
(
arguments
,
"should not be called if no conversions required"
);
Class
varargsType
=
null
;
if
(
isVarargs
)
{
Assert
.
isTrue
(
requiredParameterTypes
[
requiredParameterTypes
.
length
-
1
].
isArray
(),
"if varargs then last parameter type must be array"
);
varargsType
=
requiredParameterTypes
[
requiredParameterTypes
.
length
-
1
].
getComponentType
();
}
for
(
Integer
argPosition
:
argumentsRequiringConversion
)
{
Class
<?>
targetType
=
null
;
if
(
isVarargs
&&
argPosition
>=
(
requiredParameterTypes
.
length
-
1
))
{
targetType
=
varargsType
;
static
void
convertArguments
(
TypeConverter
converter
,
Object
[]
arguments
,
Object
methodOrCtor
,
int
[]
argumentsRequiringConversion
,
Integer
varargsPosition
)
throws
EvaluationException
{
for
(
int
argPosition
:
argumentsRequiringConversion
)
{
TypeDescriptor
targetType
;
if
(
varargsPosition
!=
null
&&
argPosition
>=
varargsPosition
)
{
MethodParameter
methodParam
=
MethodParameter
.
forMethodOrConstructor
(
methodOrCtor
,
varargsPosition
);
targetType
=
new
TypeDescriptor
(
methodParam
,
methodParam
.
getParameterType
().
getComponentType
());
}
else
{
targetType
=
requiredParameterTypes
[
argPosition
]
;
targetType
=
new
TypeDescriptor
(
MethodParameter
.
forMethodOrConstructor
(
methodOrCtor
,
argPosition
))
;
}
arguments
[
argPosition
]
=
converter
.
convertValue
(
arguments
[
argPosition
],
TypeDescriptor
.
forObject
(
arguments
[
argPosition
]),
TypeDescriptor
.
valueOf
(
targetType
));
arguments
[
argPosition
]
=
converter
.
convertValue
(
arguments
[
argPosition
],
TypeDescriptor
.
forObject
(
arguments
[
argPosition
]),
targetType
);
}
}
/**
* Convert a supplied set of arguments into the requested types.
If the parameterTypes are related to
* Convert a supplied set of arguments into the requested types.
If the parameterTypes are related to
* a varargs method then the final entry in the parameterTypes array is going to be an array itself whose
* component type should be used as the conversion target for extraneous arguments. (For example, if the
* parameterTypes are {Integer, String[]} and the input arguments are {Integer, boolean, float} then both
* the boolean and float must be converted to strings).
This method does not repackage the arguments
* the boolean and float must be converted to strings). This method does not repackage the arguments
* into a form suitable for the varargs invocation
* @param parameterTypes the types to be converted to
* @param isVarargs whether parameterTypes relates to a varargs method
* @param converter the converter to use for type conversions
* @param arguments the arguments to convert to the requested parameter types
* @param method the target Method
* @throws SpelEvaluationException if there is a problem with conversion
*/
public
static
void
convertAllArguments
(
Class
[]
parameterTypes
,
boolean
isVarargs
,
TypeConverter
converter
,
Object
[]
arguments
)
throws
SpelEvaluationException
{
Assert
.
notNull
(
arguments
,
"should not be called if nothing to convert"
);
Class
varargsType
=
null
;
if
(
isVarargs
)
{
Assert
.
isTrue
(
parameterTypes
[
parameterTypes
.
length
-
1
].
isArray
(),
"if varargs then last parameter type must be array"
);
varargsType
=
parameterTypes
[
parameterTypes
.
length
-
1
].
getComponentType
();
public
static
void
convertAllArguments
(
TypeConverter
converter
,
Object
[]
arguments
,
Method
method
)
throws
SpelEvaluationException
{
Integer
varargsPosition
=
null
;
if
(
method
.
isVarArgs
())
{
Class
[]
paramTypes
=
method
.
getParameterTypes
();
varargsPosition
=
paramTypes
.
length
-
1
;
}
for
(
int
i
=
0
;
i
<
arguments
.
length
;
i
++)
{
Class
<?>
targetType
=
null
;
if
(
isVarargs
&&
i
>=
(
parameterTypes
.
length
-
1
))
{
targetType
=
varargsType
;
for
(
int
argPosition
=
0
;
argPosition
<
arguments
.
length
;
argPosition
++)
{
TypeDescriptor
targetType
;
if
(
varargsPosition
!=
null
&&
argPosition
>=
varargsPosition
)
{
MethodParameter
methodParam
=
new
MethodParameter
(
method
,
varargsPosition
);
targetType
=
new
TypeDescriptor
(
methodParam
,
methodParam
.
getParameterType
().
getComponentType
());
}
else
{
targetType
=
parameterTypes
[
i
]
;
targetType
=
new
TypeDescriptor
(
new
MethodParameter
(
method
,
argPosition
))
;
}
try
{
if
(
arguments
[
i
]
!=
null
&&
arguments
[
i
].
getClass
()
!=
targetType
)
{
Object
argument
=
arguments
[
argPosition
];
if
(
argument
!=
null
&&
!
targetType
.
getObjectType
().
isInstance
(
argument
))
{
if
(
converter
==
null
)
{
throw
new
SpelEvaluationException
(
SpelMessage
.
TYPE_CONVERSION_ERROR
,
argument
s
[
i
].
getClass
().
getName
(),
targetType
);
throw
new
SpelEvaluationException
(
SpelMessage
.
TYPE_CONVERSION_ERROR
,
argument
.
getClass
().
getName
(),
targetType
);
}
arguments
[
i
]
=
converter
.
convertValue
(
arguments
[
i
],
TypeDescriptor
.
forObject
(
arguments
[
i
]),
TypeDescriptor
.
valueOf
(
targetType
)
);
arguments
[
argPosition
]
=
converter
.
convertValue
(
argument
,
TypeDescriptor
.
forObject
(
argument
),
targetType
);
}
}
catch
(
EvaluationException
ex
)
{
...
...
@@ -292,7 +287,7 @@ public class ReflectionHelper {
throw
(
SpelEvaluationException
)
ex
;
}
else
{
throw
new
SpelEvaluationException
(
ex
,
SpelMessage
.
TYPE_CONVERSION_ERROR
,
arguments
[
i
].
getClass
().
getName
(),
targetType
);
throw
new
SpelEvaluationException
(
ex
,
SpelMessage
.
TYPE_CONVERSION_ERROR
,
arguments
[
argPosition
].
getClass
().
getName
(),
targetType
);
}
}
}
...
...
@@ -313,14 +308,15 @@ public class ReflectionHelper {
int
argumentCount
=
args
.
length
;
// Check if repackaging is needed:
if
(
parameterCount
!=
args
.
length
||
requiredParameterTypes
[
parameterCount
-
1
]
!=
(
args
[
argumentCount
-
1
]
==
null
?
null
:
args
[
argumentCount
-
1
].
getClass
()))
{
if
(
parameterCount
!=
args
.
length
||
requiredParameterTypes
[
parameterCount
-
1
]
!=
(
args
[
argumentCount
-
1
]
==
null
?
null
:
args
[
argumentCount
-
1
].
getClass
()))
{
int
arraySize
=
0
;
// zero size array if nothing to pass as the varargs parameter
if
(
argumentCount
>=
parameterCount
)
{
arraySize
=
argumentCount
-
(
parameterCount
-
1
);
}
Object
[]
repackagedArguments
=
(
Object
[])
Array
.
newInstance
(
requiredParameterTypes
[
parameterCount
-
1
].
getComponentType
(),
arraySize
);
// Copy all but the varargs arguments
for
(
int
i
=
0
;
i
<
arraySize
;
i
++)
{
repackagedArguments
[
i
]
=
args
[
parameterCount
+
i
-
1
];
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -29,12 +29,15 @@ import org.springframework.util.ReflectionUtils;
* A simple ConstructorExecutor implementation that runs a constructor using reflective invocation.
*
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
class
ReflectiveConstructorExecutor
implements
ConstructorExecutor
{
private
final
Constructor
<?>
ctor
;
private
final
Integer
varargsPosition
;
// When the constructor was found, we will have determined if arguments need to be converted for it
// to be invoked. Conversion won't be cheap so let's only do it if necessary.
private
final
int
[]
argsRequiringConversion
;
...
...
@@ -42,23 +45,27 @@ class ReflectiveConstructorExecutor implements ConstructorExecutor {
public
ReflectiveConstructorExecutor
(
Constructor
<?>
ctor
,
int
[]
argsRequiringConversion
)
{
this
.
ctor
=
ctor
;
if
(
ctor
.
isVarArgs
())
{
Class
[]
paramTypes
=
ctor
.
getParameterTypes
();
this
.
varargsPosition
=
paramTypes
.
length
-
1
;
}
else
{
this
.
varargsPosition
=
null
;
}
this
.
argsRequiringConversion
=
argsRequiringConversion
;
}
public
TypedValue
execute
(
EvaluationContext
context
,
Object
...
arguments
)
throws
AccessException
{
try
{
if
(
argsRequiringConversion
!=
null
&&
arguments
!=
null
)
{
ReflectionHelper
.
convertArguments
(
this
.
ctor
.
getParameterTypes
(),
this
.
ctor
.
isVarArgs
(),
context
.
getTypeConverter
(),
this
.
argsRequiringConversion
,
arguments
);
if
(
this
.
argsRequiringConversion
!=
null
&&
arguments
!=
null
)
{
ReflectionHelper
.
convertArguments
(
context
.
getTypeConverter
(),
arguments
,
this
.
ctor
,
this
.
argsRequiringConversion
,
this
.
varargsPosition
);
}
if
(
this
.
ctor
.
isVarArgs
())
{
arguments
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
this
.
ctor
.
getParameterTypes
(),
arguments
);
arguments
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
this
.
ctor
.
getParameterTypes
(),
arguments
);
}
ReflectionUtils
.
makeAccessible
(
this
.
ctor
);
return
new
TypedValue
(
this
.
ctor
.
newInstance
(
arguments
),
TypeDescriptor
.
valueOf
(
this
.
ctor
.
getDeclaringClass
()));
return
new
TypedValue
(
this
.
ctor
.
newInstance
(
arguments
),
TypeDescriptor
.
valueOf
(
this
.
ctor
.
getDeclaringClass
()));
}
catch
(
Exception
ex
)
{
throw
new
AccessException
(
"Problem invoking constructor: "
+
this
.
ctor
,
ex
);
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -28,12 +28,15 @@ import org.springframework.util.ReflectionUtils;
/**
* @author Andy Clement
* @author Juergen Hoeller
* @since 3.0
*/
class
ReflectiveMethodExecutor
implements
MethodExecutor
{
private
final
Method
method
;
private
final
Integer
varargsPosition
;
// When the method was found, we will have determined if arguments need to be converted for it
// to be invoked. Conversion won't be cheap so let's only do it if necessary.
private
final
int
[]
argsRequiringConversion
;
...
...
@@ -41,6 +44,13 @@ class ReflectiveMethodExecutor implements MethodExecutor {
public
ReflectiveMethodExecutor
(
Method
theMethod
,
int
[]
argumentsRequiringConversion
)
{
this
.
method
=
theMethod
;
if
(
theMethod
.
isVarArgs
())
{
Class
[]
paramTypes
=
theMethod
.
getParameterTypes
();
this
.
varargsPosition
=
paramTypes
.
length
-
1
;
}
else
{
this
.
varargsPosition
=
null
;
}
this
.
argsRequiringConversion
=
argumentsRequiringConversion
;
}
...
...
@@ -48,15 +58,17 @@ class ReflectiveMethodExecutor implements MethodExecutor {
public
TypedValue
execute
(
EvaluationContext
context
,
Object
target
,
Object
...
arguments
)
throws
AccessException
{
try
{
if
(
this
.
argsRequiringConversion
!=
null
&&
arguments
!=
null
)
{
ReflectionHelper
.
convertArguments
(
this
.
method
.
getParameterTypes
(),
this
.
method
.
isVarArgs
(),
context
.
getTypeConverter
(),
this
.
argsRequiringConversion
,
arguments
);
ReflectionHelper
.
convertArguments
(
context
.
getTypeConverter
(),
arguments
,
this
.
method
,
this
.
argsRequiringConversion
,
this
.
varargsPosition
);
}
if
(
this
.
method
.
isVarArgs
())
{
arguments
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
this
.
method
.
getParameterTypes
(),
arguments
);
}
ReflectionUtils
.
makeAccessible
(
this
.
method
);
return
new
TypedValue
(
this
.
method
.
invoke
(
target
,
arguments
),
new
TypeDescriptor
(
new
MethodParameter
(
method
,-
1
)));
}
catch
(
Exception
ex
)
{
return
new
TypedValue
(
this
.
method
.
invoke
(
target
,
arguments
),
new
TypeDescriptor
(
new
MethodParameter
(
this
.
method
,
-
1
)));
}
catch
(
Exception
ex
)
{
throw
new
AccessException
(
"Problem invoking method: "
+
this
.
method
,
ex
);
}
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -17,12 +17,14 @@
package
org.springframework.expression.spel
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.List
;
import
junit.framework.Assert
;
import
static
junit
.
framework
.
Assert
.*;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.convert.ConversionService
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.core.convert.support.ConversionServiceFactory
;
...
...
@@ -32,9 +34,11 @@ import org.springframework.expression.TypeConverter;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
/**
* Expression evaluation where the TypeConverter plugged in is the {@link org.springframework.core.convert.support.GenericConversionService}
*
* Expression evaluation where the TypeConverter plugged in is the
* {@link org.springframework.core.convert.support.GenericConversionService}.
*
* @author Andy Clement
* @author Dave Syer
*/
public
class
ExpressionTestsUsingCoreConversionService
extends
ExpressionTestCase
{
...
...
@@ -68,31 +72,66 @@ public class ExpressionTestsUsingCoreConversionService extends ExpressionTestCas
// ArrayList containing List<Integer> to List<String>
Class
<?>
clazz
=
typeDescriptorForListOfString
.
getElementType
();
Assert
.
assertEquals
(
String
.
class
,
clazz
);
assertEquals
(
String
.
class
,
clazz
);
List
l
=
(
List
)
tcs
.
convertValue
(
listOfInteger
,
typeDescriptorForListOfString
);
Assert
.
assertNotNull
(
l
);
assertNotNull
(
l
);
// ArrayList containing List<String> to List<Integer>
clazz
=
typeDescriptorForListOfInteger
.
getElementType
();
Assert
.
assertEquals
(
Integer
.
class
,
clazz
);
assertEquals
(
Integer
.
class
,
clazz
);
l
=
(
List
)
tcs
.
convertValue
(
listOfString
,
typeDescriptorForListOfString
);
Assert
.
assertNotNull
(
l
);
assertNotNull
(
l
);
}
@Test
public
void
testSetParameterizedList
()
throws
Exception
{
StandardEvaluationContext
context
=
TestScenarioCreator
.
getTestEvaluationContext
();
Expression
e
=
parser
.
parseExpression
(
"listOfInteger.size()"
);
Assert
.
assertEquals
(
0
,
e
.
getValue
(
context
,
Integer
.
class
).
intValue
());
assertEquals
(
0
,
e
.
getValue
(
context
,
Integer
.
class
).
intValue
());
context
.
setTypeConverter
(
new
TypeConvertorUsingConversionService
());
// Assign a List<String> to the List<Integer> field - the component elements should be converted
parser
.
parseExpression
(
"listOfInteger"
).
setValue
(
context
,
listOfString
);
Assert
.
assertEquals
(
3
,
e
.
getValue
(
context
,
Integer
.
class
).
intValue
());
// size now 3
assertEquals
(
3
,
e
.
getValue
(
context
,
Integer
.
class
).
intValue
());
// size now 3
Class
clazz
=
parser
.
parseExpression
(
"listOfInteger[1].getClass()"
).
getValue
(
context
,
Class
.
class
);
// element type correctly Integer
Assert
.
assertEquals
(
Integer
.
class
,
clazz
);
assertEquals
(
Integer
.
class
,
clazz
);
}
@Test
public
void
testCoercionToCollectionOfPrimitive
()
throws
Exception
{
class
TestTarget
{
@SuppressWarnings
(
"unused"
)
public
int
sum
(
Collection
<
Integer
>
numbers
)
{
int
total
=
0
;
for
(
int
i
:
numbers
)
{
total
+=
i
;
}
return
total
;
}
}
StandardEvaluationContext
evaluationContext
=
new
StandardEvaluationContext
();
TypeDescriptor
collectionType
=
new
TypeDescriptor
(
new
MethodParameter
(
TestTarget
.
class
.
getDeclaredMethod
(
"sum"
,
Collection
.
class
),
0
));
// The type conversion is possible
assertTrue
(
evaluationContext
.
getTypeConverter
()
.
canConvert
(
TypeDescriptor
.
valueOf
(
String
.
class
),
collectionType
));
// ... and it can be done successfully
assertEquals
(
"[1, 2, 3, 4]"
,
evaluationContext
.
getTypeConverter
().
convertValue
(
"1,2,3,4"
,
TypeDescriptor
.
valueOf
(
String
.
class
),
collectionType
).
toString
());
evaluationContext
.
setVariable
(
"target"
,
new
TestTarget
());
// OK up to here, so the evaluation should be fine...
// ... but this fails
int
result
=
(
Integer
)
parser
.
parseExpression
(
"#target.sum(#root)"
).
getValue
(
evaluationContext
,
"1,2,3,4"
);
assertEquals
(
"Wrong result: "
+
result
,
10
,
result
);
}
/**
* Type converter that uses the core conversion service.
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/ScenariosForSpringSecurity.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -19,8 +19,8 @@ package org.springframework.expression.spel;
import
java.lang.reflect.Method
;
import
junit.framework.Assert
;
import
org.junit.Test
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
...
...
@@ -285,7 +285,7 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
Method
m
=
HasRoleExecutor
.
class
.
getMethod
(
"hasRole"
,
String
[].
class
);
Object
[]
args
=
arguments
;
if
(
args
!=
null
)
{
ReflectionHelper
.
convertAllArguments
(
m
.
getParameterTypes
(),
m
.
isVarArgs
(),
tc
,
args
);
ReflectionHelper
.
convertAllArguments
(
tc
,
args
,
m
);
}
if
(
m
.
isVarArgs
())
{
args
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
m
.
getParameterTypes
(),
args
);
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/HelperTests.java
→
org.springframework.expression/src/test/java/org/springframework/expression/spel/
support/Reflection
HelperTests.java
浏览文件 @
58b07f58
/*
* Copyright 2002-20
09
the original author or authors.
* Copyright 2002-20
10
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.
...
...
@@ -13,27 +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.support
;
import
java.io.ByteArrayOutputStream
;
import
java.io.PrintStream
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
import
junit.framework.Assert
;
import
org.junit.Test
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.ParseException
;
import
org.springframework.expression.PropertyAccessor
;
import
org.springframework.expression.TypedValue
;
import
org.springframework.expression.spel.ExpressionTestCase
;
import
org.springframework.expression.spel.SpelEvaluationException
;
import
org.springframework.expression.spel.SpelMessage
;
import
org.springframework.expression.spel.SpelUtilities
;
import
org.springframework.expression.spel.ast.FormatHelper
;
import
org.springframework.expression.spel.standard.SpelExpression
;
import
org.springframework.expression.spel.support.ReflectionHelper
;
import
org.springframework.expression.spel.support.ReflectivePropertyAccessor
;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
import
org.springframework.expression.spel.support.StandardTypeConverter
;
import
org.springframework.expression.spel.support.ReflectionHelper.ArgsMatchKind
;
/**
...
...
@@ -41,7 +42,7 @@ import org.springframework.expression.spel.support.ReflectionHelper.ArgsMatchKin
*
* @author Andy Clement
*/
public
class
HelperTests
extends
ExpressionTestCase
{
public
class
Reflection
HelperTests
extends
ExpressionTestCase
{
@Test
public
void
testFormatHelperForClassName
()
{
...
...
@@ -199,63 +200,68 @@ public class HelperTests extends ExpressionTestCase {
checkMatch2
(
new
Class
[]{
Integer
.
class
,
Integer
.
class
,
Integer
.
class
},
new
Class
[]{
Integer
.
class
,
String
[].
class
},
tc
,
ArgsMatchKind
.
REQUIRES_CONVERSION
,
1
,
2
);
// what happens on (Integer,String) passed to (Integer[]) ?
}
@Test
public
void
testConvertArguments
()
throws
Exception
{
StandardTypeConverter
tc
=
new
StandardTypeConverter
();
Method
oneArg
=
TestInterface
.
class
.
getMethod
(
"oneArg"
,
String
.
class
);
Method
twoArg
=
TestInterface
.
class
.
getMethod
(
"twoArg"
,
String
.
class
,
String
[].
class
);
// basic conversion int>String
Object
[]
args
=
new
Object
[]{
3
};
ReflectionHelper
.
convertArguments
(
new
Class
[]{
String
.
class
},
false
,
tc
,
new
int
[]{
0
},
args
);
ReflectionHelper
.
convertArguments
(
tc
,
args
,
oneArg
,
new
int
[]{
0
},
null
);
checkArguments
(
args
,
"3"
);
// varargs but nothing to convert
args
=
new
Object
[]{
3
};
ReflectionHelper
.
convertArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
false
,
tc
,
new
int
[]{
0
},
args
);
ReflectionHelper
.
convertArguments
(
tc
,
args
,
twoArg
,
new
int
[]{
0
},
1
);
checkArguments
(
args
,
"3"
);
// varargs with nothing needing conversion
args
=
new
Object
[]{
3
,
"abc"
,
"abc"
};
ReflectionHelper
.
convertArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
true
,
tc
,
new
int
[]{
0
,
1
,
2
},
args
);
ReflectionHelper
.
convertArguments
(
tc
,
args
,
twoArg
,
new
int
[]{
0
,
1
,
2
},
1
);
checkArguments
(
args
,
"3"
,
"abc"
,
"abc"
);
// varargs with conversion required
args
=
new
Object
[]{
3
,
false
,
3.0d
};
ReflectionHelper
.
convertArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
true
,
tc
,
new
int
[]{
0
,
1
,
2
},
args
);
ReflectionHelper
.
convertArguments
(
tc
,
args
,
twoArg
,
new
int
[]{
0
,
1
,
2
},
1
);
checkArguments
(
args
,
"3"
,
"false"
,
"3.0"
);
}
@Test
public
void
testConvertArguments2
()
throws
E
valuationE
xception
{
public
void
testConvertArguments2
()
throws
Exception
{
StandardTypeConverter
tc
=
new
StandardTypeConverter
();
Method
oneArg
=
TestInterface
.
class
.
getMethod
(
"oneArg"
,
String
.
class
);
Method
twoArg
=
TestInterface
.
class
.
getMethod
(
"twoArg"
,
String
.
class
,
String
[].
class
);
// Simple conversion: int to string
Object
[]
args
=
new
Object
[]{
3
};
ReflectionHelper
.
convertAllArguments
(
new
Class
[]{
String
.
class
},
false
,
tc
,
args
);
ReflectionHelper
.
convertAllArguments
(
tc
,
args
,
oneArg
);
checkArguments
(
args
,
"3"
);
// varargs conversion
args
=
new
Object
[]{
3
,
false
,
3.0f
};
ReflectionHelper
.
convertAllArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
true
,
tc
,
args
);
ReflectionHelper
.
convertAllArguments
(
tc
,
args
,
twoArg
);
checkArguments
(
args
,
"3"
,
"false"
,
"3.0"
);
// varargs conversion but no varargs
args
=
new
Object
[]{
3
};
ReflectionHelper
.
convertAllArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
true
,
tc
,
args
);
ReflectionHelper
.
convertAllArguments
(
tc
,
args
,
twoArg
);
checkArguments
(
args
,
"3"
);
// missing converter
args
=
new
Object
[]{
3
,
false
,
3.0f
};
try
{
ReflectionHelper
.
convertAllArguments
(
n
ew
Class
[]{
String
.
class
,
String
[].
class
},
true
,
null
,
args
);
ReflectionHelper
.
convertAllArguments
(
n
ull
,
args
,
twoArg
);
Assert
.
fail
(
"Should have failed because no converter supplied"
);
}
catch
(
SpelEvaluationException
se
)
{
}
catch
(
SpelEvaluationException
se
)
{
Assert
.
assertEquals
(
SpelMessage
.
TYPE_CONVERSION_ERROR
,
se
.
getMessageCode
());
}
// null value
args
=
new
Object
[]{
3
,
null
,
3.0f
};
ReflectionHelper
.
convertAllArguments
(
new
Class
[]{
String
.
class
,
String
[].
class
},
true
,
tc
,
args
);
ReflectionHelper
.
convertAllArguments
(
tc
,
args
,
twoArg
);
checkArguments
(
args
,
"3"
,
null
,
"3.0"
);
}
...
...
@@ -486,4 +492,13 @@ public class HelperTests extends ExpressionTestCase {
private
void
checkArgument
(
Object
expected
,
Object
actual
)
{
Assert
.
assertEquals
(
expected
,
actual
);
}
public
interface
TestInterface
{
void
oneArg
(
String
arg1
);
void
twoArg
(
String
arg1
,
String
...
arg2
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录