Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
54865c0c
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,发现更多精彩内容 >>
提交
54865c0c
编写于
4月 01, 2009
作者:
A
Andy Clement
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
initial typeDescriptor awareness in the EL. some basic testing of using GenericConversionService
上级
65afc808
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
328 addition
and
29 deletion
+328
-29
org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java
...java/org/springframework/expression/PropertyAccessor.java
+11
-0
org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java
...in/java/org/springframework/expression/TypeConverter.java
+22
-0
org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java
.../org/springframework/expression/spel/ExpressionState.java
+5
-0
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
...java/org/springframework/expression/spel/ast/Indexer.java
+3
-2
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorAnd.java
.../org/springframework/expression/spel/ast/OperatorAnd.java
+3
-3
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorNot.java
.../org/springframework/expression/spel/ast/OperatorNot.java
+2
-2
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorOr.java
...a/org/springframework/expression/spel/ast/OperatorOr.java
+3
-3
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
...amework/expression/spel/ast/PropertyOrFieldReference.java
+31
-3
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
...org/springframework/expression/spel/ast/SpelNodeImpl.java
+4
-1
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyResolver.java
...k/expression/spel/support/ReflectivePropertyResolver.java
+37
-7
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
...mework/expression/spel/support/StandardTypeConverter.java
+11
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java
...work/expression/spel/ExpressionLanguageScenarioTests.java
+10
-2
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java
...ssion/spel/ExpressionTestsUsingCoreConversionService.java
+121
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java
...a/org/springframework/expression/spel/MapAccessTests.java
+7
-1
org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java
.../springframework/expression/spel/PropertyAccessTests.java
+5
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/ScenariosForSpringSecurity.java
...framework/expression/spel/ScenariosForSpringSecurity.java
+10
-0
org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java
...va/org/springframework/expression/spel/SetValueTests.java
+33
-5
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
...ringframework/expression/spel/testresources/Inventor.java
+10
-0
未找到文件。
org.springframework.expression/src/main/java/org/springframework/expression/PropertyAccessor.java
浏览文件 @
54865c0c
...
...
@@ -16,6 +16,8 @@
package
org.springframework.expression
;
import
org.springframework.core.convert.TypeDescriptor
;
/**
* A property accessor is able to read (and possibly write) to object properties. The interface places no restrictions
* and so implementors are free to access properties directly as fields or through getters or in any other way they see
...
...
@@ -41,6 +43,15 @@ public interface PropertyAccessor {
* @return an array of classes that this resolver is suitable for (or null if a general resolver)
*/
Class
[]
getSpecificTargetClasses
();
/**
* Called to retrieve a type descriptor that describes the type of the property.
* @param context the evaluation context in which the access is being attempted
* @param target the target object upon which the property is being accessed
* @param name the name of the property being accessed
* @return a type descriptor that describes the type of this property.
*/
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
);
/**
* Called to determine if a resolver instance is able to access a specified property on a specified target object.
...
...
org.springframework.expression/src/main/java/org/springframework/expression/TypeConverter.java
浏览文件 @
54865c0c
...
...
@@ -16,6 +16,8 @@
package
org.springframework.expression
;
import
org.springframework.core.convert.TypeDescriptor
;
/**
* A type converter can convert values between different types encountered
* during expression evaluation.
...
...
@@ -26,6 +28,7 @@ package org.springframework.expression;
public
interface
TypeConverter
{
// TODO replace this stuff with Keiths spring-binding conversion code
// TODO should ExpressionException be thrown for lost precision in the case of coercion?
// TODO could remove the methods where the target is Class and just keep the TypeDescriptor variants
/**
* Convert (may coerce) a value from one type to another, for example from a boolean to a string.
...
...
@@ -36,6 +39,17 @@ public interface TypeConverter {
*/
<
T
>
T
convertValue
(
Object
value
,
Class
<
T
>
targetType
)
throws
EvaluationException
;
/**
* Convert (may coerce) a value from one type to another, for example from a boolean to a string.
* The typeDescriptor parameter enables support for typed collections - if the caller really wishes they
* can have a List<Integer> for example, rather than simply a List.
* @param value the value to be converted
* @param typeDescriptor a type descriptor that supplies extra information about the requested result type
* @return the converted value
* @throws EvaluationException if conversion is not possible
*/
<
T
>
T
convertValue
(
Object
value
,
TypeDescriptor
typeDescriptor
)
throws
EvaluationException
;
/**
* Return true if the type converter can convert the specified type to the desired target type.
* @param sourceType the type to be converted from
...
...
@@ -44,4 +58,12 @@ public interface TypeConverter {
*/
boolean
canConvert
(
Class
<?>
sourceType
,
Class
<?>
targetType
);
/**
* Return true if the type converter can convert the specified type to the desired target type.
* @param sourceType the type to be converted from
* @param typeDescriptor a type descriptor that supplies extra information about the requested result type
* @return true if that conversion can be performed
*/
boolean
canConvert
(
Class
<?>
sourceType
,
TypeDescriptor
typeDescriptor
);
}
org.springframework.expression/src/main/java/org/springframework/expression/spel/ExpressionState.java
浏览文件 @
54865c0c
...
...
@@ -20,6 +20,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Stack
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.Operation
;
...
...
@@ -99,6 +100,10 @@ public class ExpressionState {
return
this
.
relatedContext
.
getTypeLocator
().
findType
(
type
);
}
public
<
T
>
T
convertValue
(
Object
value
,
TypeDescriptor
targetTypeDescriptor
)
throws
EvaluationException
{
return
this
.
relatedContext
.
getTypeConverter
().
convertValue
(
value
,
targetTypeDescriptor
);
}
public
<
T
>
T
convertValue
(
Object
value
,
Class
<
T
>
targetType
)
throws
EvaluationException
{
return
this
.
relatedContext
.
getTypeConverter
().
convertValue
(
value
,
targetType
);
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
浏览文件 @
54865c0c
...
...
@@ -21,6 +21,7 @@ import java.util.List;
import
java.util.Map
;
import
org.antlr.runtime.Token
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
...
...
@@ -51,7 +52,7 @@ public class Indexer extends SpelNodeImpl {
return
((
Map
<?,
?>)
ctx
).
get
(
index
);
}
int
idx
=
state
.
convertValue
(
index
,
I
nteger
.
class
);
int
idx
=
state
.
convertValue
(
index
,
I
NTEGER_TYPE_DESCRIPTOR
);
if
(
ctx
.
getClass
().
isArray
())
{
return
accessArrayElement
(
ctx
,
idx
);
...
...
@@ -109,7 +110,7 @@ public class Indexer extends SpelNodeImpl {
return
;
}
int
idx
=
state
.
convertValue
(
index
,
I
nteger
.
class
);
int
idx
=
state
.
convertValue
(
index
,
I
NTEGER_TYPE_DESCRIPTOR
);
if
(
ctx
.
getClass
().
isArray
())
{
setArrayElement
(
state
,
ctx
,
idx
,
newValue
);
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorAnd.java
浏览文件 @
54865c0c
...
...
@@ -18,8 +18,8 @@ package org.springframework.expression.spel.ast;
import
org.antlr.runtime.Token
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents the boolean AND operation.
...
...
@@ -44,7 +44,7 @@ public class OperatorAnd extends Operator {
boolean
rightValue
;
try
{
leftValue
=
state
.
convertValue
(
getLeftOperand
().
getValueInternal
(
state
),
B
oolean
.
class
);
leftValue
=
state
.
convertValue
(
getLeftOperand
().
getValueInternal
(
state
),
B
OOLEAN_TYPE_DESCRIPTOR
);
}
catch
(
SpelException
ee
)
{
ee
.
setPosition
(
getLeftOperand
().
getCharPositionInLine
());
...
...
@@ -56,7 +56,7 @@ public class OperatorAnd extends Operator {
}
try
{
rightValue
=
state
.
convertValue
(
getRightOperand
().
getValueInternal
(
state
),
B
oolean
.
class
);
rightValue
=
state
.
convertValue
(
getRightOperand
().
getValueInternal
(
state
),
B
OOLEAN_TYPE_DESCRIPTOR
);
}
catch
(
SpelException
ee
)
{
ee
.
setPosition
(
getRightOperand
().
getCharPositionInLine
());
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorNot.java
浏览文件 @
54865c0c
...
...
@@ -18,8 +18,8 @@ package org.springframework.expression.spel.ast;
import
org.antlr.runtime.Token
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents a NOT operation.
...
...
@@ -36,7 +36,7 @@ public class OperatorNot extends SpelNodeImpl { // Not is a unary operator so do
@Override
public
Object
getValueInternal
(
ExpressionState
state
)
throws
EvaluationException
{
try
{
boolean
value
=
state
.
convertValue
(
getChild
(
0
).
getValueInternal
(
state
),
B
oolean
.
class
);
boolean
value
=
state
.
convertValue
(
getChild
(
0
).
getValueInternal
(
state
),
B
OOLEAN_TYPE_DESCRIPTOR
);
return
!
value
;
}
catch
(
SpelException
see
)
{
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/OperatorOr.java
浏览文件 @
54865c0c
...
...
@@ -18,8 +18,8 @@ package org.springframework.expression.spel.ast;
import
org.antlr.runtime.Token
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.spel.SpelException
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
/**
* Represents the boolean OR operation.
...
...
@@ -43,7 +43,7 @@ public class OperatorOr extends Operator {
boolean
leftValue
;
boolean
rightValue
;
try
{
leftValue
=
state
.
convertValue
(
getLeftOperand
().
getValueInternal
(
state
),
B
oolean
.
class
);
leftValue
=
state
.
convertValue
(
getLeftOperand
().
getValueInternal
(
state
),
B
OOLEAN_TYPE_DESCRIPTOR
);
}
catch
(
SpelException
see
)
{
see
.
setPosition
(
getLeftOperand
().
getCharPositionInLine
());
...
...
@@ -55,7 +55,7 @@ public class OperatorOr extends Operator {
}
try
{
rightValue
=
state
.
convertValue
(
getRightOperand
().
getValueInternal
(
state
),
B
oolean
.
class
);
rightValue
=
state
.
convertValue
(
getRightOperand
().
getValueInternal
(
state
),
B
OOLEAN_TYPE_DESCRIPTOR
);
}
catch
(
SpelException
see
)
{
see
.
setPosition
(
getRightOperand
().
getCharPositionInLine
());
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/PropertyOrFieldReference.java
浏览文件 @
54865c0c
...
...
@@ -20,8 +20,10 @@ import java.util.ArrayList;
import
java.util.List
;
import
org.antlr.runtime.Token
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.PropertyAccessor
;
import
org.springframework.expression.spel.ExpressionState
;
import
org.springframework.expression.spel.SpelException
;
...
...
@@ -41,6 +43,8 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
private
volatile
PropertyAccessor
cachedReadAccessor
;
private
volatile
PropertyAccessor
cachedWriteAccessor
;
private
volatile
TypeDescriptor
cachedTypeDescriptor
;
public
PropertyOrFieldReference
(
Token
payload
)
{
...
...
@@ -121,8 +125,20 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
PropertyAccessor
accessorToUse
=
this
.
cachedWriteAccessor
;
if
(
accessorToUse
!=
null
)
{
try
{
accessorToUse
.
write
(
state
.
getEvaluationContext
(),
contextObject
,
name
,
newValue
);
try
{
Object
possiblyConvertedValue
=
newValue
;
if
(
cachedTypeDescriptor
==
null
)
{
cachedTypeDescriptor
=
accessorToUse
.
getTypeDescriptor
(
eContext
,
contextObject
,
name
);
}
if
(
cachedTypeDescriptor
!=
null
)
{
try
{
possiblyConvertedValue
=
state
.
convertValue
(
newValue
,
cachedTypeDescriptor
.
getType
());
}
catch
(
EvaluationException
evaluationException
)
{
throw
new
SpelException
(
getCharPositionInLine
(),
evaluationException
,
SpelMessages
.
TYPE_CONVERSION_ERROR
,
newValue
.
getClass
(),
cachedTypeDescriptor
.
getType
());
}
}
accessorToUse
.
write
(
state
.
getEvaluationContext
(),
contextObject
,
name
,
possiblyConvertedValue
);
return
;
}
catch
(
AccessException
ae
)
{
...
...
@@ -140,7 +156,19 @@ public class PropertyOrFieldReference extends SpelNodeImpl {
for
(
PropertyAccessor
accessor
:
accessorsToTry
)
{
if
(
accessor
.
canWrite
(
eContext
,
contextObject
,
name
))
{
this
.
cachedWriteAccessor
=
accessor
;
accessor
.
write
(
eContext
,
contextObject
,
name
,
newValue
);
// TODO missing conversion of newValue to the type of the property
Object
possiblyConvertedValue
=
newValue
;
if
(
cachedTypeDescriptor
==
null
)
{
cachedTypeDescriptor
=
accessor
.
getTypeDescriptor
(
eContext
,
contextObject
,
name
);
}
if
(
cachedTypeDescriptor
!=
null
)
{
try
{
possiblyConvertedValue
=
state
.
convertValue
(
newValue
,
cachedTypeDescriptor
);
}
catch
(
EvaluationException
evaluationException
)
{
throw
new
SpelException
(
getCharPositionInLine
(),
evaluationException
,
SpelMessages
.
TYPE_CONVERSION_ERROR
,
newValue
.
getClass
(),
cachedTypeDescriptor
.
getType
());
}
}
accessor
.
write
(
eContext
,
contextObject
,
name
,
possiblyConvertedValue
);
return
;
}
}
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
浏览文件 @
54865c0c
...
...
@@ -20,7 +20,7 @@ import java.io.Serializable;
import
org.antlr.runtime.Token
;
import
org.antlr.runtime.tree.CommonTree
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.common.ExpressionUtils
;
import
org.springframework.expression.spel.ExpressionState
;
...
...
@@ -38,6 +38,9 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
*/
public
abstract
class
SpelNodeImpl
extends
CommonTree
implements
SpelNode
,
Serializable
{
protected
static
TypeDescriptor
BOOLEAN_TYPE_DESCRIPTOR
=
TypeDescriptor
.
valueOf
(
Boolean
.
class
);
protected
static
TypeDescriptor
INTEGER_TYPE_DESCRIPTOR
=
TypeDescriptor
.
valueOf
(
Integer
.
class
);
/**
* The Antlr parser uses this constructor to build SpelNodes.
* @param payload the token for the node that has been parsed
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyResolver.java
浏览文件 @
54865c0c
...
...
@@ -24,6 +24,8 @@ import java.lang.reflect.Modifier;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.PropertyAccessor
;
...
...
@@ -32,9 +34,7 @@ import org.springframework.util.StringUtils;
/**
* Simple PropertyResolver that uses reflection to access properties for reading and writing. A property can be accessed
* if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written). This
* implementation currently follows the Resolver/Executor model (it extends CacheablePropertyAccessor) - the code that
* would be used if it were a simple property accessor is shown at the end.
* if it is accessible as a field on the object or through a getter (if being read) or a setter (if being written).
*
* @author Andy Clement
* @author Juergen Hoeller
...
...
@@ -42,10 +42,11 @@ import org.springframework.util.StringUtils;
*/
public
class
ReflectivePropertyResolver
implements
PropertyAccessor
{
private
final
Map
<
CacheKey
,
Member
>
readerCache
=
new
ConcurrentHashMap
<
CacheKey
,
Member
>();
private
final
Map
<
CacheKey
,
Member
>
writerCache
=
new
ConcurrentHashMap
<
CacheKey
,
Member
>();
protected
final
Map
<
CacheKey
,
Member
>
readerCache
=
new
ConcurrentHashMap
<
CacheKey
,
Member
>();
protected
final
Map
<
CacheKey
,
Member
>
writerCache
=
new
ConcurrentHashMap
<
CacheKey
,
Member
>();
protected
final
Map
<
CacheKey
,
TypeDescriptor
>
typeDescriptorCache
=
new
ConcurrentHashMap
<
CacheKey
,
TypeDescriptor
>();
/**
* @return null which means this is a general purpose accessor
...
...
@@ -69,12 +70,14 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
Method
method
=
findGetterForProperty
(
name
,
type
,
target
instanceof
Class
);
if
(
method
!=
null
)
{
this
.
readerCache
.
put
(
cacheKey
,
method
);
this
.
typeDescriptorCache
.
put
(
cacheKey
,
new
TypeDescriptor
(
new
MethodParameter
(
method
,
0
)));
return
true
;
}
else
{
Field
field
=
findField
(
name
,
type
,
target
instanceof
Class
);
if
(
field
!=
null
)
{
this
.
readerCache
.
put
(
cacheKey
,
field
);
this
.
readerCache
.
put
(
cacheKey
,
field
);
this
.
typeDescriptorCache
.
put
(
cacheKey
,
new
TypeDescriptor
(
field
));
return
true
;
}
}
...
...
@@ -152,12 +155,14 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
Method
method
=
findSetterForProperty
(
name
,
type
,
target
instanceof
Class
);
if
(
method
!=
null
)
{
this
.
writerCache
.
put
(
cacheKey
,
method
);
this
.
typeDescriptorCache
.
put
(
cacheKey
,
new
TypeDescriptor
(
new
MethodParameter
(
method
,
0
)));
return
true
;
}
else
{
Field
field
=
findField
(
name
,
type
,
target
instanceof
Class
);
if
(
field
!=
null
)
{
this
.
writerCache
.
put
(
cacheKey
,
field
);
this
.
typeDescriptorCache
.
put
(
cacheKey
,
new
TypeDescriptor
(
field
));
return
true
;
}
}
...
...
@@ -217,7 +222,32 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
throw
new
AccessException
(
"Neither setter nor field found for property '"
+
name
+
"'"
);
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
if
(
target
==
null
)
{
return
null
;
}
Class
<?>
type
=
(
target
instanceof
Class
?
(
Class
<?>)
target
:
target
.
getClass
());
if
(
type
.
isArray
()
&&
name
.
equals
(
"length"
))
{
return
TypeDescriptor
.
valueOf
(
Integer
.
TYPE
);
}
CacheKey
cacheKey
=
new
CacheKey
(
type
,
name
);
TypeDescriptor
typeDescriptor
=
this
.
typeDescriptorCache
.
get
(
cacheKey
);
if
(
typeDescriptor
==
null
)
{
// attempt to populate the cache entry
try
{
if
(
canRead
(
context
,
target
,
name
))
{
typeDescriptor
=
this
.
typeDescriptorCache
.
get
(
cacheKey
);
}
else
if
(
canWrite
(
context
,
target
,
name
))
{
typeDescriptor
=
this
.
typeDescriptorCache
.
get
(
cacheKey
);
}
}
catch
(
AccessException
e
)
{
// continue with null typeDescriptor
}
}
return
typeDescriptor
;
}
/**
* Find a getter method for the specified property. A getter is defined as a method whose name start with the prefix
...
...
org.springframework.expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java
浏览文件 @
54865c0c
...
...
@@ -16,6 +16,7 @@
package
org.springframework.expression.spel.support
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.TypeConverter
;
import
org.springframework.expression.spel.SpelException
;
...
...
@@ -25,6 +26,7 @@ import org.springframework.util.NumberUtils;
/**
* @author Juergen Hoeller
* @author Andy Clement
* @since 3.0
*/
public
class
StandardTypeConverter
implements
TypeConverter
{
...
...
@@ -74,6 +76,11 @@ public class StandardTypeConverter implements TypeConverter {
throw
new
SpelException
(
SpelMessages
.
TYPE_CONVERSION_ERROR
,
value
.
getClass
(),
targetType
);
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
convertValue
(
Object
value
,
TypeDescriptor
typeDescriptor
)
throws
EvaluationException
{
return
(
T
)
convertValue
(
value
,
typeDescriptor
.
getType
());
}
public
boolean
canConvert
(
Class
<?>
sourceType
,
Class
<?>
targetType
)
{
if
(
ClassUtils
.
isAssignable
(
targetType
,
sourceType
)
||
String
.
class
.
equals
(
targetType
))
{
return
true
;
...
...
@@ -84,4 +91,8 @@ public class StandardTypeConverter implements TypeConverter {
(
Boolean
.
class
.
equals
(
actualTargetType
)
&&
String
.
class
.
equals
(
sourceType
)));
}
public
boolean
canConvert
(
Class
<?>
sourceType
,
TypeDescriptor
typeDescriptor
)
{
return
canConvert
(
sourceType
,
typeDescriptor
.
getType
());
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionLanguageScenarioTests.java
浏览文件 @
54865c0c
...
...
@@ -16,13 +16,14 @@
package
org.springframework.expression.spel
;
import
java.awt.
*
;
import
java.awt.
Color
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
...
...
@@ -264,6 +265,10 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
public
void
write
(
EvaluationContext
context
,
Object
target
,
String
name
,
Object
newValue
)
throws
AccessException
{
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
null
;
}
}
...
...
@@ -301,6 +306,9 @@ public class ExpressionLanguageScenarioTests extends ExpressionTestCase {
public
void
write
(
EvaluationContext
context
,
Object
target
,
String
name
,
Object
newValue
)
throws
AccessException
{
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
null
;
}
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/ExpressionTestsUsingCoreConversionService.java
0 → 100644
浏览文件 @
54865c0c
/*
* Copyright 2002-2009 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.expression.spel
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.springframework.core.convert.ConversionExecutor
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.core.convert.service.DefaultConversionService
;
import
org.springframework.core.convert.service.GenericConversionService
;
import
org.springframework.expression.EvaluationException
;
import
org.springframework.expression.Expression
;
import
org.springframework.expression.TypeConverter
;
import
org.springframework.expression.spel.support.StandardEvaluationContext
;
/**
* Expression evaluation where the TypeConverter plugged in is the {@link GenericConversionService}
*
* @author Andy Clement
*/
public
class
ExpressionTestsUsingCoreConversionService
extends
ExpressionTestCase
{
private
static
List
<
String
>
listOfString
=
new
ArrayList
<
String
>();
private
static
TypeDescriptor
typeDescriptorForListOfString
=
null
;
private
static
List
<
Integer
>
listOfInteger
=
new
ArrayList
<
Integer
>();
private
static
TypeDescriptor
typeDescriptorForListOfInteger
=
null
;
static
{
listOfString
.
add
(
"1"
);
listOfString
.
add
(
"2"
);
listOfString
.
add
(
"3"
);
listOfInteger
.
add
(
4
);
listOfInteger
.
add
(
5
);
listOfInteger
.
add
(
6
);
}
public
void
setUp
()
throws
Exception
{
super
.
setUp
();
typeDescriptorForListOfString
=
new
TypeDescriptor
(
ExpressionTestsUsingCoreConversionService
.
class
.
getDeclaredField
(
"listOfString"
));
typeDescriptorForListOfInteger
=
new
TypeDescriptor
(
ExpressionTestsUsingCoreConversionService
.
class
.
getDeclaredField
(
"listOfInteger"
));
}
/**
* Test the service can convert what we are about to use in the expression evaluation tests.
*/
public
void
testConversionsAvailable
()
throws
Exception
{
TypeConvertorUsingConversionService
tcs
=
new
TypeConvertorUsingConversionService
();
// ArrayList containing List<Integer> to List<String>
Class
<?>
clazz
=
typeDescriptorForListOfString
.
getElementType
();
assertEquals
(
String
.
class
,
clazz
);
ConversionExecutor
executor
=
tcs
.
getConversionExecutor
(
ArrayList
.
class
,
typeDescriptorForListOfString
);
assertNotNull
(
executor
);
List
l
=
(
List
)
executor
.
execute
(
listOfInteger
);
assertNotNull
(
l
);
// ArrayList containing List<String> to List<Integer>
clazz
=
typeDescriptorForListOfInteger
.
getElementType
();
assertEquals
(
Integer
.
class
,
clazz
);
executor
=
tcs
.
getConversionExecutor
(
ArrayList
.
class
,
typeDescriptorForListOfInteger
);
assertNotNull
(
executor
);
l
=
(
List
)
executor
.
execute
(
listOfString
);
assertNotNull
(
l
);
}
public
void
testSetParameterizedList
()
throws
Exception
{
StandardEvaluationContext
context
=
TestScenarioCreator
.
getTestEvaluationContext
();
Expression
e
=
parser
.
parseExpression
(
"listOfInteger.size()"
);
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
);
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
assertEquals
(
Integer
.
class
,
clazz
);
}
/**
* Type convertor that uses the core conversion service.
*/
private
static
class
TypeConvertorUsingConversionService
extends
DefaultConversionService
implements
TypeConverter
{
public
boolean
canConvert
(
Class
<?>
sourceType
,
Class
<?>
targetType
)
{
return
super
.
canConvert
(
sourceType
,
TypeDescriptor
.
valueOf
(
targetType
));
}
public
boolean
canConvert
(
Class
<?>
sourceType
,
TypeDescriptor
typeDescriptor
)
{
return
super
.
canConvert
(
sourceType
,
typeDescriptor
);
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
convertValue
(
Object
value
,
Class
<
T
>
targetType
)
throws
EvaluationException
{
return
(
T
)
super
.
executeConversion
(
value
,
TypeDescriptor
.
valueOf
(
targetType
));
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
convertValue
(
Object
value
,
TypeDescriptor
typeDescriptor
)
throws
EvaluationException
{
return
(
T
)
super
.
executeConversion
(
value
,
typeDescriptor
);
}
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/MapAccessTests.java
浏览文件 @
54865c0c
...
...
@@ -18,6 +18,7 @@ package org.springframework.expression.spel;
import
java.util.Map
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.Expression
;
...
...
@@ -61,7 +62,7 @@ public class MapAccessTests extends ExpressionTestCase {
}
p
rivate
static
class
MapAccessor
implements
PropertyAccessor
{
p
ublic
static
class
MapAccessor
implements
PropertyAccessor
{
public
boolean
canRead
(
EvaluationContext
context
,
Object
target
,
String
name
)
throws
AccessException
{
return
(((
Map
)
target
).
containsKey
(
name
));
...
...
@@ -75,6 +76,7 @@ public class MapAccessTests extends ExpressionTestCase {
return
true
;
}
@SuppressWarnings
(
"unchecked"
)
public
void
write
(
EvaluationContext
context
,
Object
target
,
String
name
,
Object
newValue
)
throws
AccessException
{
((
Map
)
target
).
put
(
name
,
newValue
);
...
...
@@ -83,6 +85,10 @@ public class MapAccessTests extends ExpressionTestCase {
public
Class
<?>[]
getSpecificTargetClasses
()
{
return
new
Class
[]
{
Map
.
class
};
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
TypeDescriptor
.
valueOf
(
Map
.
class
);
}
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/PropertyAccessTests.java
浏览文件 @
54865c0c
...
...
@@ -16,6 +16,7 @@
package
org.springframework.expression.spel
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
...
...
@@ -87,6 +88,10 @@ public class PropertyAccessTests extends ExpressionTestCase {
int
flibbles
=
7
;
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
null
;
}
public
Class
<?>[]
getSpecificTargetClasses
()
{
return
new
Class
[]
{
String
.
class
};
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/ScenariosForSpringSecurity.java
浏览文件 @
54865c0c
...
...
@@ -18,6 +18,7 @@ package org.springframework.expression.spel;
import
java.lang.reflect.Method
;
import
org.springframework.core.convert.TypeDescriptor
;
import
org.springframework.expression.AccessException
;
import
org.springframework.expression.EvaluationContext
;
import
org.springframework.expression.EvaluationException
;
...
...
@@ -224,6 +225,11 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
public
Class
<?>[]
getSpecificTargetClasses
()
{
return
null
;
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
null
;
}
}
...
...
@@ -252,6 +258,10 @@ public class ScenariosForSpringSecurity extends ExpressionTestCase {
public
Class
<?>[]
getSpecificTargetClasses
()
{
return
null
;
}
public
TypeDescriptor
getTypeDescriptor
(
EvaluationContext
context
,
Object
target
,
String
name
)
{
return
null
;
}
}
...
...
org.springframework.expression/src/test/java/org/springframework/expression/spel/SetValueTests.java
浏览文件 @
54865c0c
...
...
@@ -98,11 +98,14 @@ public class SetValueTests extends ExpressionTestCase {
setValueExpectError
(
"'hello'[3]"
,
'p'
);
}
// public void testSetPropertyTypeCoersion() {
// setValue("publicBoolean", "true");
// }
public
void
testSetPropertyTypeCoersion
()
{
setValue
(
"publicBoolean"
,
"true"
,
Boolean
.
TRUE
);
}
public
void
testSetPropertyTypeCoersionThroughSetter
()
{
setValue
(
"SomeProperty"
,
"true"
,
Boolean
.
TRUE
);
}
/**
* Call setValue() but expect it to fail.
*/
...
...
@@ -116,7 +119,6 @@ public class SetValueTests extends ExpressionTestCase {
SpelUtilities
.
printAbstractSyntaxTree
(
System
.
out
,
e
);
}
StandardEvaluationContext
lContext
=
TestScenarioCreator
.
getTestEvaluationContext
();
// assertTrue("Expression is not writeable but should be", e.isWritable(lContext));
e
.
setValue
(
lContext
,
value
);
fail
(
"expected an error"
);
}
catch
(
ParseException
pe
)
{
...
...
@@ -148,4 +150,30 @@ public class SetValueTests extends ExpressionTestCase {
fail
(
"Unexpected Exception: "
+
pe
.
getMessage
());
}
}
/**
* For use when coercion is happening during a setValue(). The expectedValue should be
* the coerced form of the value.
*/
protected
void
setValue
(
String
expression
,
Object
value
,
Object
expectedValue
)
{
try
{
Expression
e
=
parser
.
parseExpression
(
expression
);
if
(
e
==
null
)
{
fail
(
"Parser returned null for expression"
);
}
if
(
DEBUG
)
{
SpelUtilities
.
printAbstractSyntaxTree
(
System
.
out
,
e
);
}
StandardEvaluationContext
lContext
=
TestScenarioCreator
.
getTestEvaluationContext
();
assertTrue
(
"Expression is not writeable but should be"
,
e
.
isWritable
(
lContext
));
e
.
setValue
(
lContext
,
value
);
assertEquals
(
"Retrieved value was not equal to set value"
,
expectedValue
,
e
.
getValue
(
lContext
));
}
catch
(
EvaluationException
ee
)
{
ee
.
printStackTrace
();
fail
(
"Unexpected Exception: "
+
ee
.
getMessage
());
}
catch
(
ParseException
pe
)
{
pe
.
printStackTrace
();
fail
(
"Unexpected Exception: "
+
pe
.
getMessage
());
}
}
}
org.springframework.expression/src/test/java/org/springframework/expression/spel/testresources/Inventor.java
浏览文件 @
54865c0c
...
...
@@ -21,6 +21,8 @@ public class Inventor {
private
List
<
PlaceOfBirth
>
placesLivedList
=
new
ArrayList
<
PlaceOfBirth
>();
public
ArrayContainer
arrayContainer
;
public
boolean
publicBoolean
;
private
boolean
accessedThroughGetSet
;
public
List
<
Integer
>
listOfInteger
=
new
ArrayList
<
Integer
>();
public
Inventor
(
String
name
,
Date
birthdate
,
String
nationality
)
{
this
.
name
=
name
;
...
...
@@ -110,4 +112,12 @@ public class Inventor {
public
Inventor
(
String
...
strings
)
{
}
public
boolean
getSomeProperty
()
{
return
accessedThroughGetSet
;
}
public
void
setSomeProperty
(
boolean
b
)
{
this
.
accessedThroughGetSet
=
b
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录