1616package org .springframework .data .util ;
1717
1818import java .lang .reflect .Method ;
19- import java .lang .reflect .Type ;
20- import java .lang .reflect .TypeVariable ;
2119import java .util .Arrays ;
2220import java .util .Collection ;
23- import java .util .Collections ;
24- import java .util .HashMap ;
25- import java .util .HashSet ;
2621import java .util .List ;
2722import java .util .Map ;
2823import java .util .Set ;
2924
30- import org .springframework .core .GenericTypeResolver ;
3125import org .springframework .core .convert .TypeDescriptor ;
26+ import org .springframework .core .ResolvableType ;
27+ import org .springframework .lang .Nullable ;
3228import org .springframework .util .Assert ;
3329import org .springframework .util .ConcurrentReferenceHashMap ;
3430import org .springframework .util .ConcurrentReferenceHashMap .ReferenceType ;
3935 * @author Oliver Gierke
4036 * @author Christoph Strobl
4137 */
42- @ SuppressWarnings ({ "unchecked" , "rawtypes" })
4338public class ClassTypeInformation <S > extends TypeDiscoverer <S > {
4439
4540 public static final ClassTypeInformation <Collection > COLLECTION = new ClassTypeInformation (Collection .class );
@@ -51,95 +46,51 @@ public class ClassTypeInformation<S> extends TypeDiscoverer<S> {
5146 private static final Map <Class <?>, ClassTypeInformation <?>> cache = new ConcurrentReferenceHashMap <>(64 ,
5247 ReferenceType .WEAK );
5348
54- static {
55- Arrays .asList (COLLECTION , LIST , SET , MAP , OBJECT ).forEach (it -> cache .put (it .getType (), it ));
56- }
57-
58- private final Class <S > type ;
59- private final Lazy <TypeDescriptor > descriptor ;
60-
6149 /**
62- * Simple factory method to easily create new instances of {@link ClassTypeInformation}.
63- *
64- * @param <S>
65- * @param type must not be {@literal null}.
50+ * Warning: Does not fully resolve generic arguments.
51+ * @param method
6652 * @return
53+ * @deprecated since 3.0 Use {@link #fromReturnTypeOf(Method, Class)} instead.
6754 */
68- public static <S > ClassTypeInformation <S > from (Class <S > type ) {
69-
70- Assert .notNull (type , "Type must not be null" );
71-
72- return (ClassTypeInformation <S >) cache .computeIfAbsent (type , ClassTypeInformation ::new );
55+ @ Deprecated
56+ public static TypeInformation <?> fromReturnTypeOf (Method method ) {
57+ return new TypeDiscoverer <>(ResolvableType .forMethodReturnType (method ));
7358 }
7459
7560 /**
76- * Creates a {@link TypeInformation} from the given method's return type.
77- *
78- * @param method must not be {@literal null}.
61+ * @param method
62+ * @param actualType can be {@literal null}.
7963 * @return
8064 */
81- public static < S > TypeInformation <S > fromReturnTypeOf (Method method ) {
65+ public static TypeInformation <? > fromReturnTypeOf (Method method , @ Nullable Class <?> actualType ) {
8266
83- Assert .notNull (method , "Method must not be null" );
84- return (TypeInformation <S >) ClassTypeInformation .from (method .getDeclaringClass ())
85- .createInfo (method .getGenericReturnType ());
67+ if (actualType == null ) {
68+ return new TypeDiscoverer <>(ResolvableType .forMethodReturnType (method ));
69+ }
70+ return new TypeDiscoverer <>(ResolvableType .forMethodReturnType (method , actualType ));
8671 }
8772
88- /**
89- * Creates {@link ClassTypeInformation} for the given type.
90- *
91- * @param type
92- */
93- ClassTypeInformation (Class <S > type ) {
94-
95- super (type , getTypeVariableMap (type ));
73+ Class <?> type ;
9674
97- this .type = type ;
98- this .descriptor = Lazy .of (() -> TypeDescriptor .valueOf (type ));
99- }
100-
101- /**
102- * Little helper to allow us to create a generified map, actually just to satisfy the compiler.
103- *
104- * @param type must not be {@literal null}.
105- * @return
106- */
107- private static Map <TypeVariable <?>, Type > getTypeVariableMap (Class <?> type ) {
108- return getTypeVariableMap (type , new HashSet <>());
75+ static {
76+ Arrays .asList (COLLECTION , LIST , SET , MAP , OBJECT ).forEach (it -> cache .put (it .getType (), it ));
10977 }
11078
111- private static Map <TypeVariable <?>, Type > getTypeVariableMap (Class <?> type , Collection <Type > visited ) {
112-
113- if (visited .contains (type )) {
114- return Collections .emptyMap ();
115- } else {
116- visited .add (type );
117- }
118-
119- Map <TypeVariable , Type > source = GenericTypeResolver .getTypeVariableMap (type );
120- Map <TypeVariable <?>, Type > map = new HashMap <>(source .size ());
121-
122- for (Map .Entry <TypeVariable , Type > entry : source .entrySet ()) {
123-
124- Type value = entry .getValue ();
125- map .put (entry .getKey (), entry .getValue ());
79+ public static <S > ClassTypeInformation <S > from (Class <S > type ) {
12680
127- if ( value instanceof Class ) {
81+ Assert . notNull ( type , "Type must not be null" );
12882
129- for (Map .Entry <TypeVariable <?>, Type > nestedEntry : getTypeVariableMap ((Class <?>) value , visited ).entrySet ()) {
130- if (!map .containsKey (nestedEntry .getKey ())) {
131- map .put (nestedEntry .getKey (), nestedEntry .getValue ());
132- }
133- }
134- }
135- }
83+ return (ClassTypeInformation <S >) cache .computeIfAbsent (type , ClassTypeInformation ::new );
84+ }
13685
137- return map ;
86+ ClassTypeInformation (Class <S > type ) {
87+ super (ResolvableType .forClass (type ));
88+ this .type = type ;
13889 }
13990
14091 @ Override
14192 public Class <S > getType () {
142- return type ;
93+ return ( Class < S >) type ;
14394 }
14495
14596 @ Override
@@ -158,12 +109,12 @@ public TypeInformation<? extends S> specialize(ClassTypeInformation<?> type) {
158109 }
159110
160111 @ Override
161- public TypeDescriptor toTypeDescriptor () {
162- return descriptor . get ();
112+ public String toString () {
113+ return type . getName ();
163114 }
164115
165116 @ Override
166- public String toString ( ) {
167- return type . getName ( );
117+ public boolean equals ( Object o ) {
118+ return super . equals ( o );
168119 }
169120}
0 commit comments