1
1
/*
2
- * Copyright 2002-2012 the original author or authors.
2
+ * Copyright 2002-2013 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
21
21
import java .lang .reflect .TypeVariable ;
22
22
import java .util .Collection ;
23
23
import java .util .HashMap ;
24
+ import java .util .List ;
24
25
import java .util .Map ;
25
26
26
27
import org .junit .Test ;
27
28
29
+ import static org .hamcrest .Matchers .*;
28
30
import static org .junit .Assert .*;
29
31
import static org .springframework .core .GenericTypeResolver .*;
30
32
import static org .springframework .util .ReflectionUtils .*;
@@ -63,36 +65,110 @@ public void nullIfNotResolvable() {
63
65
64
66
@ Test
65
67
public void methodReturnTypes () {
66
- assertEquals (Integer .class , resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "integer" ), MyInterfaceType .class ));
67
- assertEquals (String .class , resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "string" ), MyInterfaceType .class ));
68
+ assertEquals (Integer .class ,
69
+ resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "integer" ), MyInterfaceType .class ));
70
+ assertEquals (String .class ,
71
+ resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "string" ), MyInterfaceType .class ));
68
72
assertEquals (null , resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "raw" ), MyInterfaceType .class ));
69
- assertEquals (null , resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "object" ), MyInterfaceType .class ));
73
+ assertEquals (null ,
74
+ resolveReturnTypeArgument (findMethod (MyTypeWithMethods .class , "object" ), MyInterfaceType .class ));
70
75
}
71
76
72
77
@ Test
73
78
public void testResolveType () {
74
- Method intMessageMethod = findMethod (MyTypeWithMethods .class , "readIntegerInputMessage" , MyInterfaceType .class );
75
- MethodParameter intMessageMethodParam = new MethodParameter (intMessageMethod , 0 );
76
- assertEquals (MyInterfaceType .class ,
77
- resolveType (intMessageMethodParam .getGenericParameterType (), new HashMap <TypeVariable , Type >()));
78
-
79
- Method intArrMessageMethod = findMethod (MyTypeWithMethods .class , "readIntegerArrayInputMessage" , MyInterfaceType [].class );
80
- MethodParameter intArrMessageMethodParam = new MethodParameter (intArrMessageMethod , 0 );
81
- assertEquals (MyInterfaceType [].class ,
82
- resolveType (intArrMessageMethodParam .getGenericParameterType (), new HashMap <TypeVariable , Type >()));
83
-
84
- Method genericArrMessageMethod = findMethod (MySimpleTypeWithMethods .class , "readGenericArrayInputMessage" , Object [].class );
85
- MethodParameter genericArrMessageMethodParam = new MethodParameter (genericArrMessageMethod , 0 );
86
- Map <TypeVariable , Type > varMap = getTypeVariableMap (MySimpleTypeWithMethods .class );
87
- assertEquals (Integer [].class , resolveType (genericArrMessageMethodParam .getGenericParameterType (), varMap ));
79
+ Method intMessageMethod = findMethod (MyTypeWithMethods .class , "readIntegerInputMessage" , MyInterfaceType .class );
80
+ MethodParameter intMessageMethodParam = new MethodParameter (intMessageMethod , 0 );
81
+ assertEquals (MyInterfaceType .class ,
82
+ resolveType (intMessageMethodParam .getGenericParameterType (), new HashMap <TypeVariable , Type >()));
83
+
84
+ Method intArrMessageMethod = findMethod (MyTypeWithMethods .class , "readIntegerArrayInputMessage" ,
85
+ MyInterfaceType [].class );
86
+ MethodParameter intArrMessageMethodParam = new MethodParameter (intArrMessageMethod , 0 );
87
+ assertEquals (MyInterfaceType [].class ,
88
+ resolveType (intArrMessageMethodParam .getGenericParameterType (), new HashMap <TypeVariable , Type >()));
89
+
90
+ Method genericArrMessageMethod = findMethod (MySimpleTypeWithMethods .class , "readGenericArrayInputMessage" ,
91
+ Object [].class );
92
+ MethodParameter genericArrMessageMethodParam = new MethodParameter (genericArrMessageMethod , 0 );
93
+ Map <TypeVariable , Type > varMap = getTypeVariableMap (MySimpleTypeWithMethods .class );
94
+ assertEquals (Integer [].class , resolveType (genericArrMessageMethodParam .getGenericParameterType (), varMap ));
88
95
}
89
96
90
97
@ Test
91
98
public void testBoundParameterizedType () {
92
99
assertEquals (B .class , resolveTypeArgument (TestImpl .class , ITest .class ));
93
100
}
94
101
102
+ @ Test
103
+ public void testGetTypeVariableMap () throws Exception {
104
+ Map <TypeVariable , Type > map ;
105
+
106
+ map = GenericTypeResolver .getTypeVariableMap (MySimpleInterfaceType .class );
107
+ assertThat (map .toString (), equalTo ("{T=class java.lang.String}" ));
108
+
109
+ map = GenericTypeResolver .getTypeVariableMap (MyCollectionInterfaceType .class );
110
+ assertThat (map .toString (), equalTo ("{T=java.util.Collection<java.lang.String>}" ));
111
+
112
+ map = GenericTypeResolver .getTypeVariableMap (MyCollectionSuperclassType .class );
113
+ assertThat (map .toString (), equalTo ("{T=java.util.Collection<java.lang.String>}" ));
114
+
115
+ map = GenericTypeResolver .getTypeVariableMap (MySimpleTypeWithMethods .class );
116
+ assertThat (map .toString (), equalTo ("{T=class java.lang.Integer}" ));
117
+
118
+ map = GenericTypeResolver .getTypeVariableMap (TopLevelClass .class );
119
+ assertThat (map .toString (), equalTo ("{}" ));
120
+
121
+ map = GenericTypeResolver .getTypeVariableMap (TypedTopLevelClass .class );
122
+ assertThat (map .toString (), equalTo ("{T=class java.lang.Integer}" ));
123
+
124
+ map = GenericTypeResolver .getTypeVariableMap (TypedTopLevelClass .TypedNested .class );
125
+ assertThat (map .size (), equalTo (2 ));
126
+ Type t = null ;
127
+ Type x = null ;
128
+ for (Map .Entry <TypeVariable , Type > entry : map .entrySet ()) {
129
+ if (entry .getKey ().toString ().equals ("T" )) {
130
+ t = entry .getValue ();
131
+ }
132
+ else {
133
+ x = entry .getValue ();
134
+ }
135
+ }
136
+ assertThat (t , equalTo ((Type ) Integer .class ));
137
+ assertThat (x , equalTo ((Type ) Long .class ));
138
+ }
139
+
140
+ @ Test
141
+ public void getGenericsCannotBeResolved () throws Exception {
142
+ // SPR-11030
143
+ Class <?>[] resolved = GenericTypeResolver .resolveTypeArguments (List .class , Iterable .class );
144
+ // Note: to be changed to return null in Spring 4.0
145
+ assertThat (resolved , equalTo (new Class [] {Object .class }));
146
+ }
95
147
148
+ @ Test
149
+ public void getRawMapTypeCannotBeResolved () throws Exception {
150
+ // SPR-11052
151
+ Class <?>[] resolved = GenericTypeResolver .resolveTypeArguments (Map .class , Map .class );
152
+ assertNull (resolved );
153
+ }
154
+
155
+ @ Test
156
+ public void getGenericsOnArrayFromParamCannotBeResolved () throws Exception {
157
+ // SPR-11044
158
+ MethodParameter methodParameter = MethodParameter .forMethodOrConstructor (
159
+ WithArrayBase .class .getDeclaredMethod ("array" , Object [].class ), 0 );
160
+ Class <?> resolved = GenericTypeResolver .resolveParameterType (methodParameter , WithArray .class );
161
+ assertThat (resolved , equalTo ((Class ) Object [].class ));
162
+ }
163
+
164
+ @ Test
165
+ public void getGenericsOnArrayFromReturnCannotBeResolved () throws Exception {
166
+ // SPR-11044
167
+ Class <?> resolved = GenericTypeResolver .resolveReturnType (
168
+ WithArrayBase .class .getDeclaredMethod ("array" , Object [].class ),
169
+ WithArray .class );
170
+ assertThat (resolved , equalTo ((Class ) Object [].class ));
171
+ }
96
172
97
173
public interface MyInterfaceType <T > {
98
174
}
@@ -113,26 +189,44 @@ public class MyCollectionSuperclassType extends MySuperclassType<Collection<Stri
113
189
}
114
190
115
191
public static class MyTypeWithMethods <T > {
116
- public MyInterfaceType <Integer > integer () { return null ; }
117
- public MySimpleInterfaceType string () { return null ; }
118
- public Object object () { return null ; }
192
+
193
+ public MyInterfaceType <Integer > integer () {
194
+ return null ;
195
+ }
196
+
197
+ public MySimpleInterfaceType string () {
198
+ return null ;
199
+ }
200
+
201
+ public Object object () {
202
+ return null ;
203
+ }
204
+
119
205
@ SuppressWarnings ("rawtypes" )
120
- public MyInterfaceType raw () { return null ; }
121
- public String notParameterized () { return null ; }
122
- public String notParameterizedWithArguments (Integer x , Boolean b ) { return null ; }
206
+ public MyInterfaceType raw () {
207
+ return null ;
208
+ }
209
+
210
+ public String notParameterized () {
211
+ return null ;
212
+ }
213
+
214
+ public String notParameterizedWithArguments (Integer x , Boolean b ) {
215
+ return null ;
216
+ }
123
217
124
218
/**
125
- * Simulates a factory method that wraps the supplied object in a proxy
126
- * of the same type.
219
+ * Simulates a factory method that wraps the supplied object in a proxy of the
220
+ * same type.
127
221
*/
128
222
public static <T > T createProxy (T object ) {
129
223
return null ;
130
224
}
131
225
132
226
/**
133
- * Similar to {@link #createProxy(Object)} but adds an additional argument
134
- * before the argument of type {@code T}. Note that they may potentially
135
- * be of the same time when invoked!
227
+ * Similar to {@link #createProxy(Object)} but adds an additional argument before
228
+ * the argument of type {@code T}. Note that they may potentially be of the same
229
+ * time when invoked!
136
230
*/
137
231
public static <T > T createNamedProxy (String name , T object ) {
138
232
return null ;
@@ -146,8 +240,8 @@ public static <MOCK> MOCK createMock(Class<MOCK> toMock) {
146
240
}
147
241
148
242
/**
149
- * Similar to {@link #createMock(Class)} but adds an additional method
150
- * argument before the parameterized argument.
243
+ * Similar to {@link #createMock(Class)} but adds an additional method argument
244
+ * before the parameterized argument.
151
245
*/
152
246
public static <T > T createNamedMock (String name , Class <T > toMock ) {
153
247
return null ;
@@ -162,8 +256,8 @@ public static <V extends Object, T> T createVMock(V name, Class<T> toMock) {
162
256
}
163
257
164
258
/**
165
- * Extract some value of the type supported by the interface (i.e., by
166
- * a concrete, non-generic implementation of the interface).
259
+ * Extract some value of the type supported by the interface (i.e., by a concrete,
260
+ * non-generic implementation of the interface).
167
261
*/
168
262
public static <T > T extractValueFrom (MyInterfaceType <T > myInterfaceType ) {
169
263
return null ;
@@ -201,4 +295,22 @@ class ITest<T>{}
201
295
class TestImpl <I extends A , T extends B <I >> extends ITest <T >{
202
296
}
203
297
298
+ static class TopLevelClass <T > {
299
+ class Nested <X > {
300
+ }
301
+ }
302
+
303
+ static class TypedTopLevelClass extends TopLevelClass <Integer > {
304
+ class TypedNested extends Nested <Long > {
305
+ }
306
+ }
307
+
308
+ static abstract class WithArrayBase <T > {
309
+
310
+ public abstract T [] array (T ... args );
311
+ }
312
+
313
+ static abstract class WithArray <T > extends WithArrayBase <T > {
314
+ }
315
+
204
316
}
0 commit comments