Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
387c8a81
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,发现更多精彩内容 >>
提交
387c8a81
编写于
12月 18, 2015
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Differentiate between TypeDescriptors with same annotations but different attributes
Issue: SPR-13714
上级
06056e6a
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
399 addition
and
298 deletion
+399
-298
spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
...java/org/springframework/core/convert/TypeDescriptor.java
+1
-1
spring-core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java
...org/springframework/core/convert/TypeDescriptorTests.java
+303
-271
spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java
...k/core/convert/support/GenericConversionServiceTests.java
+95
-26
未找到文件。
spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
浏览文件 @
387c8a81
...
...
@@ -468,7 +468,7 @@ public class TypeDescriptor implements Serializable {
return
false
;
}
for
(
Annotation
ann
:
getAnnotations
())
{
if
(!
other
.
hasAnnotation
(
ann
.
annotationType
(
)))
{
if
(!
ann
.
equals
(
other
.
getAnnotation
(
ann
.
annotationType
()
)))
{
return
false
;
}
}
...
...
spring-core/src/test/java/org/springframework/core/convert/TypeDescriptorTests.java
浏览文件 @
387c8a81
...
...
@@ -52,27 +52,11 @@ import static org.junit.Assert.*;
* @author Andy Clement
* @author Phillip Webb
* @author Sam Brannen
* @author Nathan Piper
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
TypeDescriptorTests
{
public
List
<
String
>
listOfString
;
public
List
<
List
<
String
>>
listOfListOfString
=
new
ArrayList
<
List
<
String
>>();
public
List
<
List
>
listOfListOfUnknown
=
new
ArrayList
<
List
>();
public
int
[]
intArray
;
public
List
<
String
>[]
arrayOfListOfString
;
public
List
<
Integer
>
listField
=
new
ArrayList
<
Integer
>();
public
Map
<
String
,
Integer
>
mapField
=
new
HashMap
<
String
,
Integer
>();
public
Map
<
String
,
List
<
Integer
>>
nestedMapField
=
new
HashMap
<
String
,
List
<
Integer
>>();
@Test
public
void
parameterPrimitive
()
throws
Exception
{
TypeDescriptor
desc
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterPrimitive"
,
int
.
class
),
0
));
...
...
@@ -86,10 +70,6 @@ public class TypeDescriptorTests {
assertFalse
(
desc
.
isMap
());
}
public
void
testParameterPrimitive
(
int
primitive
)
{
}
@Test
public
void
parameterScalar
()
throws
Exception
{
TypeDescriptor
desc
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterScalar"
,
String
.
class
),
0
));
...
...
@@ -104,10 +84,6 @@ public class TypeDescriptorTests {
assertFalse
(
desc
.
isMap
());
}
public
void
testParameterScalar
(
String
value
)
{
}
@Test
public
void
parameterList
()
throws
Exception
{
MethodParameter
methodParameter
=
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterList"
,
List
.
class
),
0
);
...
...
@@ -129,10 +105,6 @@ public class TypeDescriptorTests {
assertFalse
(
desc
.
isMap
());
}
public
void
testParameterList
(
List
<
List
<
Map
<
Integer
,
Enum
<?>>>>
list
)
{
}
@Test
public
void
parameterListNoParamTypes
()
throws
Exception
{
MethodParameter
methodParameter
=
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterListNoParamTypes"
,
List
.
class
),
0
);
...
...
@@ -149,10 +121,6 @@ public class TypeDescriptorTests {
assertFalse
(
desc
.
isMap
());
}
public
void
testParameterListNoParamTypes
(
List
list
)
{
}
@Test
public
void
parameterArray
()
throws
Exception
{
MethodParameter
methodParameter
=
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterArray"
,
Integer
[].
class
),
0
);
...
...
@@ -170,10 +138,6 @@ public class TypeDescriptorTests {
assertFalse
(
desc
.
isMap
());
}
public
void
testParameterArray
(
Integer
[]
array
)
{
}
@Test
public
void
parameterMap
()
throws
Exception
{
MethodParameter
methodParameter
=
new
MethodParameter
(
getClass
().
getMethod
(
"testParameterMap"
,
Map
.
class
),
0
);
...
...
@@ -194,10 +158,6 @@ public class TypeDescriptorTests {
assertEquals
(
String
.
class
,
desc
.
getMapValueTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
}
public
void
testParameterMap
(
Map
<
Integer
,
List
<
String
>>
map
)
{
}
@Test
public
void
parameterAnnotated
()
throws
Exception
{
TypeDescriptor
t1
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethod"
,
String
.
class
),
0
));
...
...
@@ -208,36 +168,20 @@ public class TypeDescriptorTests {
assertEquals
(
123
,
t1
.
getAnnotation
(
ParameterAnnotation
.
class
).
value
());
}
@Target
({
ElementType
.
PARAMETER
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ParameterAnnotation
{
int
value
();
}
public
void
testAnnotatedMethod
(
@ParameterAnnotation
(
123
)
String
parameter
)
{
}
@Test
public
void
propertyComplex
()
throws
Exception
{
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getComplexProperty"
),
getClass
().
getMethod
(
"setComplexProperty"
,
Map
.
class
));
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getComplexProperty"
),
getClass
().
getMethod
(
"setComplexProperty"
,
Map
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
String
.
class
,
desc
.
getMapKeyTypeDescriptor
().
getType
());
assertEquals
(
Integer
.
class
,
desc
.
getMapValueTypeDescriptor
().
getElementTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
}
public
Map
<
String
,
List
<
List
<
Integer
>>>
getComplexProperty
()
{
return
null
;
}
public
void
setComplexProperty
(
Map
<
String
,
List
<
List
<
Integer
>>>
complexProperty
)
{
}
@Test
public
void
propertyGenericType
()
throws
Exception
{
GenericType
<
Integer
>
genericBean
=
new
IntegerType
();
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getProperty"
),
genericBean
.
getClass
().
getMethod
(
"setProperty"
,
Integer
.
class
));
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getProperty"
),
genericBean
.
getClass
().
getMethod
(
"setProperty"
,
Integer
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
Integer
.
class
,
desc
.
getType
());
}
...
...
@@ -245,7 +189,8 @@ public class TypeDescriptorTests {
@Test
public
void
propertyTypeCovariance
()
throws
Exception
{
GenericType
<
Number
>
genericBean
=
new
NumberType
();
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getProperty"
),
genericBean
.
getClass
().
getMethod
(
"setProperty"
,
Number
.
class
));
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getProperty"
),
genericBean
.
getClass
().
getMethod
(
"setProperty"
,
Number
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
Integer
.
class
,
desc
.
getType
());
}
...
...
@@ -253,69 +198,18 @@ public class TypeDescriptorTests {
@Test
public
void
propertyGenericTypeList
()
throws
Exception
{
GenericType
<
Integer
>
genericBean
=
new
IntegerType
();
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getListProperty"
),
genericBean
.
getClass
().
getMethod
(
"setListProperty"
,
List
.
class
));
Property
property
=
new
Property
(
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getListProperty"
),
genericBean
.
getClass
().
getMethod
(
"setListProperty"
,
List
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
List
.
class
,
desc
.
getType
());
assertEquals
(
Integer
.
class
,
desc
.
getElementTypeDescriptor
().
getType
());
}
public
interface
GenericType
<
T
>
{
T
getProperty
();
void
setProperty
(
T
t
);
List
<
T
>
getListProperty
();
void
setListProperty
(
List
<
T
>
t
);
}
public
class
IntegerType
implements
GenericType
<
Integer
>
{
@Override
public
Integer
getProperty
()
{
return
null
;
}
@Override
public
void
setProperty
(
Integer
t
)
{
}
@Override
public
List
<
Integer
>
getListProperty
()
{
return
null
;
}
@Override
public
void
setListProperty
(
List
<
Integer
>
t
)
{
}
}
public
class
NumberType
implements
GenericType
<
Number
>
{
@Override
public
Integer
getProperty
()
{
return
null
;
}
@Override
public
void
setProperty
(
Number
t
)
{
}
@Override
public
List
<
Number
>
getListProperty
()
{
return
null
;
}
@Override
public
void
setListProperty
(
List
<
Number
>
t
)
{
}
}
@Test
public
void
propertyGenericClassList
()
throws
Exception
{
IntegerClass
genericBean
=
new
IntegerClass
();
Property
property
=
new
Property
(
genericBean
.
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getListProperty"
),
genericBean
.
getClass
().
getMethod
(
"setListProperty"
,
List
.
class
));
Property
property
=
new
Property
(
genericBean
.
getClass
(),
genericBean
.
getClass
().
getMethod
(
"getListProperty"
),
genericBean
.
getClass
().
getMethod
(
"setListProperty"
,
List
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
List
.
class
,
desc
.
getType
());
assertEquals
(
Integer
.
class
,
desc
.
getElementTypeDescriptor
().
getType
());
...
...
@@ -323,32 +217,10 @@ public class TypeDescriptorTests {
assertTrue
(
desc
.
hasAnnotation
(
MethodAnnotation1
.
class
));
}
public
static
class
GenericClass
<
T
>
{
public
T
getProperty
()
{
return
null
;
}
public
void
setProperty
(
T
t
)
{
}
@MethodAnnotation1
public
List
<
T
>
getListProperty
()
{
return
null
;
}
public
void
setListProperty
(
List
<
T
>
t
)
{
}
}
public
static
class
IntegerClass
extends
GenericClass
<
Integer
>
{
}
@Test
public
void
property
()
throws
Exception
{
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getProperty"
),
getClass
().
getMethod
(
"setProperty"
,
Map
.
class
));
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getProperty"
),
getClass
().
getMethod
(
"setProperty"
,
Map
.
class
));
TypeDescriptor
desc
=
new
TypeDescriptor
(
property
);
assertEquals
(
Map
.
class
,
desc
.
getType
());
assertEquals
(
Integer
.
class
,
desc
.
getMapKeyTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
...
...
@@ -358,60 +230,6 @@ public class TypeDescriptorTests {
assertNotNull
(
desc
.
getAnnotation
(
MethodAnnotation3
.
class
));
}
@MethodAnnotation1
public
Map
<
List
<
Integer
>,
List
<
Long
>>
getProperty
()
{
return
property
;
}
@MethodAnnotation2
public
void
setProperty
(
Map
<
List
<
Integer
>,
List
<
Long
>>
property
)
{
this
.
property
=
property
;
}
@MethodAnnotation3
private
Map
<
List
<
Integer
>,
List
<
Long
>>
property
;
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation1
{
}
@Target
({
ElementType
.
METHOD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation2
{
}
@Target
({
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation3
{
}
@MethodAnnotation1
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ComposedMethodAnnotation1
{}
@ComposedMethodAnnotation1
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ComposedComposedMethodAnnotation1
{}
@MethodAnnotation1
public
void
methodWithLocalAnnotation
()
{}
@ComposedMethodAnnotation1
public
void
methodWithComposedAnnotation
()
{}
@ComposedComposedMethodAnnotation1
public
void
methodWithComposedComposedAnnotation
()
{}
private
void
assertAnnotationFoundOnMethod
(
Class
<?
extends
Annotation
>
annotationType
,
String
methodName
)
throws
Exception
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
methodName
),
-
1
));
assertNotNull
(
"Should have found @"
+
annotationType
.
getSimpleName
()
+
" on "
+
methodName
+
"."
,
typeDescriptor
.
getAnnotation
(
annotationType
));
}
@Test
public
void
getAnnotationOnMethodThatIsLocallyAnnotated
()
throws
Exception
{
assertAnnotationFoundOnMethod
(
MethodAnnotation1
.
class
,
"methodWithLocalAnnotation"
);
...
...
@@ -427,6 +245,12 @@ public class TypeDescriptorTests {
assertAnnotationFoundOnMethod
(
MethodAnnotation1
.
class
,
"methodWithComposedComposedAnnotation"
);
}
private
void
assertAnnotationFoundOnMethod
(
Class
<?
extends
Annotation
>
annotationType
,
String
methodName
)
throws
Exception
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
methodName
),
-
1
));
assertNotNull
(
"Should have found @"
+
annotationType
.
getSimpleName
()
+
" on "
+
methodName
+
"."
,
typeDescriptor
.
getAnnotation
(
annotationType
));
}
@Test
public
void
fieldScalar
()
throws
Exception
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
getClass
().
getField
(
"fieldScalar"
));
...
...
@@ -438,8 +262,6 @@ public class TypeDescriptorTests {
assertEquals
(
Integer
.
class
,
typeDescriptor
.
getObjectType
());
}
public
Integer
fieldScalar
;
@Test
public
void
fieldList
()
throws
Exception
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
TypeDescriptorTests
.
class
.
getDeclaredField
(
"listOfString"
));
...
...
@@ -504,8 +326,6 @@ public class TypeDescriptorTests {
assertEquals
(
Long
.
class
,
desc
.
getMapValueTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
}
public
Map
<
List
<
Integer
>,
List
<
Long
>>
fieldMap
;
@Test
public
void
fieldAnnotated
()
throws
Exception
{
TypeDescriptor
typeDescriptor
=
new
TypeDescriptor
(
getClass
().
getField
(
"fieldAnnotated"
));
...
...
@@ -513,15 +333,6 @@ public class TypeDescriptorTests {
assertNotNull
(
typeDescriptor
.
getAnnotation
(
FieldAnnotation
.
class
));
}
@FieldAnnotation
public
List
<
String
>
fieldAnnotated
;
@Target
({
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
FieldAnnotation
{
}
@Test
public
void
valueOfScalar
()
{
TypeDescriptor
typeDescriptor
=
TypeDescriptor
.
valueOf
(
Integer
.
class
);
...
...
@@ -592,7 +403,7 @@ public class TypeDescriptorTests {
assertEquals
(
String
.
class
,
t1
.
getType
());
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
nestedMethodParameterNot1NestedLevel
()
throws
Exception
{
TypeDescriptor
.
nested
(
new
MethodParameter
(
getClass
().
getMethod
(
"test4"
,
List
.
class
),
0
,
2
),
2
);
}
...
...
@@ -609,31 +420,11 @@ public class TypeDescriptorTests {
assertNull
(
t1
);
}
@Test
(
expected
=
IllegalArgumentException
.
class
)
@Test
(
expected
=
IllegalArgumentException
.
class
)
public
void
nestedMethodParameterTypeInvalidNestingLevel
()
throws
Exception
{
TypeDescriptor
.
nested
(
new
MethodParameter
(
getClass
().
getMethod
(
"test5"
,
String
.
class
),
0
,
2
),
2
);
}
public
void
test1
(
List
<
String
>
param1
)
{
}
public
void
test2
(
List
<
List
<
String
>>
param1
)
{
}
public
void
test3
(
Map
<
Integer
,
String
>
param1
)
{
}
public
void
test4
(
List
<
Map
<
Integer
,
String
>>
param1
)
{
}
public
void
test5
(
String
param1
)
{
}
@Test
public
void
nestedNotParameterized
()
throws
Exception
{
TypeDescriptor
t1
=
TypeDescriptor
.
nested
(
new
MethodParameter
(
getClass
().
getMethod
(
"test6"
,
List
.
class
),
0
),
1
);
...
...
@@ -643,18 +434,12 @@ public class TypeDescriptorTests {
assertNull
(
t2
);
}
public
void
test6
(
List
<
List
>
param1
)
{
}
@Test
public
void
nestedFieldTypeMapTwoLevels
()
throws
Exception
{
TypeDescriptor
t1
=
TypeDescriptor
.
nested
(
getClass
().
getField
(
"test4"
),
2
);
assertEquals
(
String
.
class
,
t1
.
getType
());
}
public
List
<
Map
<
Integer
,
String
>>
test4
;
@Test
public
void
nestedPropertyTypeMapTwoLevels
()
throws
Exception
{
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getTest4"
),
getClass
().
getMethod
(
"setTest4"
,
List
.
class
));
...
...
@@ -662,14 +447,6 @@ public class TypeDescriptorTests {
assertEquals
(
String
.
class
,
t1
.
getType
());
}
public
List
<
Map
<
Integer
,
String
>>
getTest4
()
{
return
null
;
}
public
void
setTest4
(
List
<
Map
<
Integer
,
String
>>
test4
)
{
}
@Test
public
void
collection
()
{
TypeDescriptor
desc
=
TypeDescriptor
.
collection
(
List
.
class
,
TypeDescriptor
.
valueOf
(
Integer
.
class
));
...
...
@@ -762,9 +539,6 @@ public class TypeDescriptorTests {
assertNotNull
(
desc
.
getAnnotation
(
FieldAnnotation
.
class
));
}
@FieldAnnotation
public
List
<
List
<
Integer
>>
listPreserveContext
;
@Test
public
void
mapKeyType
()
{
TypeDescriptor
desc
=
TypeDescriptor
.
valueOf
(
Map
.
class
);
...
...
@@ -783,9 +557,6 @@ public class TypeDescriptorTests {
assertNotNull
(
desc
.
getAnnotation
(
FieldAnnotation
.
class
));
}
@FieldAnnotation
public
Map
<
List
<
Integer
>,
List
<
Integer
>>
mapPreserveContext
;
@Test
public
void
mapValueType
()
{
TypeDescriptor
desc
=
TypeDescriptor
.
valueOf
(
Map
.
class
);
...
...
@@ -805,7 +576,7 @@ public class TypeDescriptorTests {
}
@Test
public
void
equal
s
()
throws
Exception
{
public
void
equal
ity
()
throws
Exception
{
TypeDescriptor
t1
=
TypeDescriptor
.
valueOf
(
String
.
class
);
TypeDescriptor
t2
=
TypeDescriptor
.
valueOf
(
String
.
class
);
TypeDescriptor
t3
=
TypeDescriptor
.
valueOf
(
Date
.
class
);
...
...
@@ -826,6 +597,18 @@ public class TypeDescriptorTests {
TypeDescriptor
t11
=
new
TypeDescriptor
(
getClass
().
getField
(
"mapField"
));
TypeDescriptor
t12
=
new
TypeDescriptor
(
getClass
().
getField
(
"mapField"
));
assertEquals
(
t11
,
t12
);
TypeDescriptor
t13
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethod"
,
String
.
class
),
0
));
TypeDescriptor
t14
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethod"
,
String
.
class
),
0
));
assertEquals
(
t13
,
t14
);
TypeDescriptor
t15
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethod"
,
String
.
class
),
0
));
TypeDescriptor
t16
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethodDifferentAnnotationValue"
,
String
.
class
),
0
));
assertNotEquals
(
t15
,
t16
);
TypeDescriptor
t17
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"testAnnotatedMethod"
,
String
.
class
),
0
));
TypeDescriptor
t18
=
new
TypeDescriptor
(
new
MethodParameter
(
getClass
().
getMethod
(
"test5"
,
String
.
class
),
0
));
assertNotEquals
(
t17
,
t18
);
}
@Test
...
...
@@ -844,10 +627,6 @@ public class TypeDescriptorTests {
assertTrue
(
TypeDescriptor
.
valueOf
(
List
.
class
).
isAssignableTo
(
new
TypeDescriptor
(
getClass
().
getField
(
"listField"
))));
}
public
List
notGenericList
;
public
List
<
Number
>
isAssignableElementTypes
;
@Test
public
void
isAssignableMapKeyValueTypes
()
throws
Exception
{
assertTrue
(
new
TypeDescriptor
(
getClass
().
getField
(
"mapField"
)).
isAssignableTo
(
new
TypeDescriptor
(
getClass
().
getField
(
"mapField"
))));
...
...
@@ -857,10 +636,6 @@ public class TypeDescriptorTests {
assertTrue
(
TypeDescriptor
.
valueOf
(
Map
.
class
).
isAssignableTo
(
new
TypeDescriptor
(
getClass
().
getField
(
"mapField"
))));
}
public
Map
notGenericMap
;
public
Map
<
CharSequence
,
Number
>
isAssignableMapKeyValueTypes
;
@Test
public
void
multiValueMap
()
throws
Exception
{
TypeDescriptor
td
=
new
TypeDescriptor
(
getClass
().
getField
(
"multiValueMap"
));
...
...
@@ -871,8 +646,6 @@ public class TypeDescriptorTests {
td
.
getMapValueTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
}
public
MultiValueMap
<
String
,
Integer
>
multiValueMap
=
new
LinkedMultiValueMap
<
String
,
Integer
>();
@Test
public
void
passDownGeneric
()
throws
Exception
{
TypeDescriptor
td
=
new
TypeDescriptor
(
getClass
().
getField
(
"passDownGeneric"
));
...
...
@@ -881,12 +654,6 @@ public class TypeDescriptorTests {
assertEquals
(
Integer
.
class
,
td
.
getElementTypeDescriptor
().
getElementTypeDescriptor
().
getElementTypeDescriptor
().
getType
());
}
public
PassDownGeneric
<
Integer
>
passDownGeneric
=
new
PassDownGeneric
<
Integer
>();
@SuppressWarnings
(
"serial"
)
public
static
class
PassDownGeneric
<
T
>
extends
ArrayList
<
List
<
Set
<
T
>>>
{
}
@Test
public
void
testUpCast
()
throws
Exception
{
Property
property
=
new
Property
(
getClass
(),
getClass
().
getMethod
(
"getProperty"
),
...
...
@@ -904,8 +671,9 @@ public class TypeDescriptorTests {
try
{
typeDescriptor
.
upcast
(
Collection
.
class
);
fail
(
"Did not throw"
);
}
catch
(
IllegalArgumentException
e
)
{
assertEquals
(
"interface java.util.Map is not assignable to interface java.util.Collection"
,
e
.
getMessage
());
}
catch
(
IllegalArgumentException
ex
)
{
assertEquals
(
"interface java.util.Map is not assignable to interface java.util.Collection"
,
ex
.
getMessage
());
}
}
...
...
@@ -933,13 +701,13 @@ public class TypeDescriptorTests {
@Test
public
void
createMapArray
()
throws
Exception
{
TypeDescriptor
mapType
=
TypeDescriptor
.
map
(
LinkedHashMap
.
class
,
TypeDescriptor
.
valueOf
(
String
.
class
),
TypeDescriptor
.
valueOf
(
Integer
.
class
));
TypeDescriptor
mapType
=
TypeDescriptor
.
map
(
LinkedHashMap
.
class
,
TypeDescriptor
.
valueOf
(
String
.
class
),
TypeDescriptor
.
valueOf
(
Integer
.
class
));
TypeDescriptor
arrayType
=
TypeDescriptor
.
array
(
mapType
);
assertEquals
(
arrayType
.
getType
(),
LinkedHashMap
[].
class
);
assertEquals
(
arrayType
.
getElementTypeDescriptor
(),
mapType
);
}
@Test
public
void
createStringArray
()
throws
Exception
{
TypeDescriptor
arrayType
=
TypeDescriptor
.
array
(
TypeDescriptor
.
valueOf
(
String
.
class
));
...
...
@@ -985,4 +753,268 @@ public class TypeDescriptorTests {
assertThat
(
TypeDescriptor
.
valueOf
(
Integer
.
class
).
getSource
(),
equalTo
((
Object
)
Integer
.
class
));
}
// Methods designed for test introspection
public
void
testParameterPrimitive
(
int
primitive
)
{
}
public
void
testParameterScalar
(
String
value
)
{
}
public
void
testParameterList
(
List
<
List
<
Map
<
Integer
,
Enum
<?>>>>
list
)
{
}
public
void
testParameterListNoParamTypes
(
List
list
)
{
}
public
void
testParameterArray
(
Integer
[]
array
)
{
}
public
void
testParameterMap
(
Map
<
Integer
,
List
<
String
>>
map
)
{
}
public
void
test1
(
List
<
String
>
param1
)
{
}
public
void
test2
(
List
<
List
<
String
>>
param1
)
{
}
public
void
test3
(
Map
<
Integer
,
String
>
param1
)
{
}
public
void
test4
(
List
<
Map
<
Integer
,
String
>>
param1
)
{
}
public
void
test5
(
String
param1
)
{
}
public
void
test6
(
List
<
List
>
param1
)
{
}
public
List
<
Map
<
Integer
,
String
>>
getTest4
()
{
return
null
;
}
public
void
setTest4
(
List
<
Map
<
Integer
,
String
>>
test4
)
{
}
public
Map
<
String
,
List
<
List
<
Integer
>>>
getComplexProperty
()
{
return
null
;
}
@MethodAnnotation1
public
Map
<
List
<
Integer
>,
List
<
Long
>>
getProperty
()
{
return
property
;
}
@MethodAnnotation2
public
void
setProperty
(
Map
<
List
<
Integer
>,
List
<
Long
>>
property
)
{
this
.
property
=
property
;
}
@MethodAnnotation1
public
void
methodWithLocalAnnotation
()
{
}
@ComposedMethodAnnotation1
public
void
methodWithComposedAnnotation
()
{
}
@ComposedComposedMethodAnnotation1
public
void
methodWithComposedComposedAnnotation
()
{
}
public
void
setComplexProperty
(
Map
<
String
,
List
<
List
<
Integer
>>>
complexProperty
)
{
}
public
void
testAnnotatedMethod
(
@ParameterAnnotation
(
123
)
String
parameter
)
{
}
public
void
testAnnotatedMethodDifferentAnnotationValue
(
@ParameterAnnotation
(
567
)
String
parameter
)
{
}
// Fields designed for test introspection
public
Integer
fieldScalar
;
public
List
<
String
>
listOfString
;
public
List
<
List
<
String
>>
listOfListOfString
=
new
ArrayList
<
List
<
String
>>();
public
List
<
List
>
listOfListOfUnknown
=
new
ArrayList
<
List
>();
public
int
[]
intArray
;
public
List
<
String
>[]
arrayOfListOfString
;
public
List
<
Integer
>
listField
=
new
ArrayList
<
Integer
>();
public
Map
<
String
,
Integer
>
mapField
=
new
HashMap
<
String
,
Integer
>();
public
Map
<
String
,
List
<
Integer
>>
nestedMapField
=
new
HashMap
<
String
,
List
<
Integer
>>();
public
Map
<
List
<
Integer
>,
List
<
Long
>>
fieldMap
;
public
List
<
Map
<
Integer
,
String
>>
test4
;
@FieldAnnotation
public
List
<
String
>
fieldAnnotated
;
@FieldAnnotation
public
List
<
List
<
Integer
>>
listPreserveContext
;
@FieldAnnotation
public
Map
<
List
<
Integer
>,
List
<
Integer
>>
mapPreserveContext
;
@MethodAnnotation3
private
Map
<
List
<
Integer
>,
List
<
Long
>>
property
;
public
List
notGenericList
;
public
List
<
Number
>
isAssignableElementTypes
;
public
Map
notGenericMap
;
public
Map
<
CharSequence
,
Number
>
isAssignableMapKeyValueTypes
;
public
MultiValueMap
<
String
,
Integer
>
multiValueMap
=
new
LinkedMultiValueMap
<
String
,
Integer
>();
public
PassDownGeneric
<
Integer
>
passDownGeneric
=
new
PassDownGeneric
<
Integer
>();
// Classes designed for test introspection
@SuppressWarnings
(
"serial"
)
public
static
class
PassDownGeneric
<
T
>
extends
ArrayList
<
List
<
Set
<
T
>>>
{
}
public
static
class
GenericClass
<
T
>
{
public
T
getProperty
()
{
return
null
;
}
public
void
setProperty
(
T
t
)
{
}
@MethodAnnotation1
public
List
<
T
>
getListProperty
()
{
return
null
;
}
public
void
setListProperty
(
List
<
T
>
t
)
{
}
}
public
static
class
IntegerClass
extends
GenericClass
<
Integer
>
{
}
public
interface
GenericType
<
T
>
{
T
getProperty
();
void
setProperty
(
T
t
);
List
<
T
>
getListProperty
();
void
setListProperty
(
List
<
T
>
t
);
}
public
class
IntegerType
implements
GenericType
<
Integer
>
{
@Override
public
Integer
getProperty
()
{
return
null
;
}
@Override
public
void
setProperty
(
Integer
t
)
{
}
@Override
public
List
<
Integer
>
getListProperty
()
{
return
null
;
}
@Override
public
void
setListProperty
(
List
<
Integer
>
t
)
{
}
}
public
class
NumberType
implements
GenericType
<
Number
>
{
@Override
public
Integer
getProperty
()
{
return
null
;
}
@Override
public
void
setProperty
(
Number
t
)
{
}
@Override
public
List
<
Number
>
getListProperty
()
{
return
null
;
}
@Override
public
void
setListProperty
(
List
<
Number
>
t
)
{
}
}
// Annotations used on tested elements
@Target
({
ElementType
.
PARAMETER
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ParameterAnnotation
{
int
value
();
}
@Target
({
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
FieldAnnotation
{
}
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation1
{
}
@Target
({
ElementType
.
METHOD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation2
{
}
@Target
({
ElementType
.
FIELD
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
MethodAnnotation3
{
}
@MethodAnnotation1
@Target
({
ElementType
.
METHOD
,
ElementType
.
ANNOTATION_TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ComposedMethodAnnotation1
{
}
@ComposedMethodAnnotation1
@Target
(
ElementType
.
METHOD
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ComposedComposedMethodAnnotation1
{
}
}
spring-core/src/test/java/org/springframework/core/convert/support/GenericConversionServiceTests.java
浏览文件 @
387c8a81
...
...
@@ -478,6 +478,21 @@ public class GenericConversionServiceTests {
assertTrue
(
converter
.
getNestedMatchAttempts
()
>
0
);
}
@Test
public
void
conditionalConverterCachingForDifferentAnnotationAttributes
()
throws
Exception
{
conversionService
.
addConverter
(
new
ColorConverter
());
conversionService
.
addConverter
(
new
MyConditionalColorConverter
());
assertEquals
(
Color
.
BLACK
,
conversionService
.
convert
(
"000000xxxx"
,
new
TypeDescriptor
(
getClass
().
getField
(
"activeColor"
))));
assertEquals
(
Color
.
BLACK
,
conversionService
.
convert
(
" #000000 "
,
new
TypeDescriptor
(
getClass
().
getField
(
"inactiveColor"
))));
assertEquals
(
Color
.
BLACK
,
conversionService
.
convert
(
"000000yyyy"
,
new
TypeDescriptor
(
getClass
().
getField
(
"activeColor"
))));
assertEquals
(
Color
.
BLACK
,
conversionService
.
convert
(
" #000000 "
,
new
TypeDescriptor
(
getClass
().
getField
(
"inactiveColor"
))));
}
@Test
public
void
shouldNotSupportNullConvertibleTypesFromNonConditionalGenericConverter
()
{
GenericConverter
converter
=
new
NonConditionalGenericConverter
();
...
...
@@ -629,14 +644,49 @@ public class GenericConversionServiceTests {
}
@ExampleAnnotation
(
active
=
true
)
public
String
annotatedString
;
@ExampleAnnotation
(
active
=
true
)
public
Color
activeColor
;
@ExampleAnnotation
(
active
=
false
)
public
Color
inactiveColor
;
public
List
<
Integer
>
list
;
public
Map
<
String
,
Integer
>
map
;
public
Map
<
String
,
?>
wildcardMap
;
@SuppressWarnings
(
"rawtypes"
)
public
Collection
rawCollection
;
public
Collection
<?>
genericCollection
;
public
Collection
<
String
>
stringCollection
;
public
Collection
<
Integer
>
integerCollection
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
private
static
@interface
ExampleAnnotation
{}
private
@interface
ExampleAnnotation
{
boolean
active
();
}
private
interface
MyBaseInterface
{
}
private
static
interface
MyBaseInterface
{}
private
static
interface
MyInterface
extends
MyBaseInterface
{}
private
interface
MyInterface
extends
MyBaseInterface
{
}
private
static
class
MyInterfaceImplementer
implements
MyInterface
{
}
private
static
class
MyInterfaceImplementer
implements
MyInterface
{}
private
static
class
MyBaseInterfaceToStringConverter
implements
Converter
<
MyBaseInterface
,
String
>
{
...
...
@@ -646,6 +696,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringArrayToResourceArrayConverter
implements
Converter
<
String
[],
Resource
[]>
{
@Override
...
...
@@ -654,6 +705,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringArrayToIntegerArrayConverter
implements
Converter
<
String
[],
Integer
[]>
{
@Override
...
...
@@ -662,6 +714,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringToIntegerArrayConverter
implements
Converter
<
String
,
Integer
[]>
{
@Override
...
...
@@ -671,6 +724,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
WithCopyConstructor
{
WithCopyConstructor
()
{}
...
...
@@ -679,6 +733,7 @@ public class GenericConversionServiceTests {
WithCopyConstructor
(
WithCopyConstructor
value
)
{}
}
private
static
class
MyConditionalConverter
implements
Converter
<
String
,
Color
>,
ConditionalConverter
{
private
int
matchAttempts
=
0
;
...
...
@@ -699,6 +754,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
NonConditionalGenericConverter
implements
GenericConverter
{
@Override
...
...
@@ -712,6 +768,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyConditionalGenericConverter
implements
GenericConverter
,
ConditionalConverter
{
private
final
List
<
TypeDescriptor
>
sourceTypes
=
new
ArrayList
<
TypeDescriptor
>();
...
...
@@ -737,6 +794,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyConditionalConverterFactory
implements
ConverterFactory
<
String
,
Color
>,
ConditionalConverter
{
private
MyConditionalConverter
converter
=
new
MyConditionalConverter
();
...
...
@@ -768,11 +826,13 @@ public class GenericConversionServiceTests {
String
getBaseCode
();
}
private
static
interface
MyEnumInterface
extends
MyEnumBaseInterface
{
private
interface
MyEnumInterface
extends
MyEnumBaseInterface
{
String
getCode
();
}
private
static
enum
MyEnum
implements
MyEnumInterface
{
private
enum
MyEnum
implements
MyEnumInterface
{
A
(
"1"
),
B
(
"2"
),
...
...
@@ -795,7 +855,8 @@ public class GenericConversionServiceTests {
}
}
private
static
enum
EnumWithSubclass
{
private
enum
EnumWithSubclass
{
FIRST
{
@Override
...
...
@@ -805,6 +866,7 @@ public class GenericConversionServiceTests {
}
}
@SuppressWarnings
(
"rawtypes"
)
private
static
class
MyStringToRawCollectionConverter
implements
Converter
<
String
,
Collection
>
{
...
...
@@ -814,6 +876,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringToGenericCollectionConverter
implements
Converter
<
String
,
Collection
<?>>
{
@Override
...
...
@@ -822,6 +885,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyEnumInterfaceToStringConverter
<
T
extends
MyEnumInterface
>
implements
Converter
<
T
,
String
>
{
@Override
...
...
@@ -830,14 +894,16 @@ public class GenericConversionServiceTests {
}
}
private
static
class
StringToMyEnumInterfaceConverterFactory
implements
ConverterFactory
<
String
,
MyEnumInterface
>
{
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
public
<
T
extends
MyEnumInterface
>
Converter
<
String
,
T
>
getConverter
(
Class
<
T
>
targetType
)
{
return
new
StringToMyEnumInterfaceConverter
(
targetType
);
}
private
static
class
StringToMyEnumInterfaceConverter
<
T
extends
Enum
<?>
&
MyEnumInterface
>
implements
Converter
<
String
,
T
>
{
private
final
Class
<
T
>
enumType
;
public
StringToMyEnumInterfaceConverter
(
Class
<
T
>
enumType
)
{
...
...
@@ -855,9 +921,10 @@ public class GenericConversionServiceTests {
}
}
private
static
class
StringToMyEnumBaseInterfaceConverterFactory
implements
ConverterFactory
<
String
,
MyEnumBaseInterface
>
{
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
public
<
T
extends
MyEnumBaseInterface
>
Converter
<
String
,
T
>
getConverter
(
Class
<
T
>
targetType
)
{
return
new
StringToMyEnumBaseInterfaceConverter
(
targetType
);
}
...
...
@@ -881,6 +948,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringToStringCollectionConverter
implements
Converter
<
String
,
Collection
<
String
>>
{
@Override
...
...
@@ -889,6 +957,7 @@ public class GenericConversionServiceTests {
}
}
private
static
class
MyStringToIntegerCollectionConverter
implements
Converter
<
String
,
Collection
<
Integer
>>
{
@Override
...
...
@@ -897,6 +966,7 @@ public class GenericConversionServiceTests {
}
}
@SuppressWarnings
(
"rawtypes"
)
private
static
class
UntypedConverter
implements
Converter
{
...
...
@@ -906,28 +976,27 @@ public class GenericConversionServiceTests {
}
}
private
static
class
ColorConverter
implements
Converter
<
String
,
Color
>
{
@Override
public
Color
convert
(
String
source
)
{
if
(!
source
.
startsWith
(
"#"
))
source
=
"#"
+
source
;
return
Color
.
decode
(
source
);
}
public
Color
convert
(
String
source
)
{
return
Color
.
decode
(
source
.
trim
());
}
}
@ExampleAnnotation
public
String
annotatedString
;
public
List
<
Integer
>
list
;
public
Map
<
String
,
Integer
>
map
;
public
Map
<
String
,
?>
wildcardMap
;
@SuppressWarnings
(
"rawtypes"
)
public
Collection
rawCollection
;
public
Collection
<?>
genericCollection
;
public
Collection
<
String
>
stringCollection
;
private
static
class
MyConditionalColorConverter
implements
Converter
<
String
,
Color
>,
ConditionalConverter
{
public
Collection
<
Integer
>
integerCollection
;
@Override
public
boolean
matches
(
TypeDescriptor
sourceType
,
TypeDescriptor
targetType
)
{
ExampleAnnotation
ann
=
targetType
.
getAnnotation
(
ExampleAnnotation
.
class
);
return
(
ann
!=
null
&&
ann
.
active
());
}
@Override
public
Color
convert
(
String
source
)
{
return
Color
.
decode
(
source
.
substring
(
0
,
6
));
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录