001/*
002 * Copyright 2002-2019 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.core;
018
019import java.io.Serializable;
020import java.lang.reflect.Array;
021import java.lang.reflect.Constructor;
022import java.lang.reflect.Field;
023import java.lang.reflect.GenericArrayType;
024import java.lang.reflect.Method;
025import java.lang.reflect.ParameterizedType;
026import java.lang.reflect.Type;
027import java.lang.reflect.TypeVariable;
028import java.lang.reflect.WildcardType;
029import java.util.Arrays;
030import java.util.Collection;
031import java.util.IdentityHashMap;
032import java.util.Map;
033
034import org.springframework.core.SerializableTypeWrapper.FieldTypeProvider;
035import org.springframework.core.SerializableTypeWrapper.MethodParameterTypeProvider;
036import org.springframework.core.SerializableTypeWrapper.TypeProvider;
037import org.springframework.lang.UsesJava8;
038import org.springframework.util.Assert;
039import org.springframework.util.ClassUtils;
040import org.springframework.util.ConcurrentReferenceHashMap;
041import org.springframework.util.ObjectUtils;
042import org.springframework.util.StringUtils;
043
044/**
045 * Encapsulates a Java {@link java.lang.reflect.Type}, providing access to
046 * {@link #getSuperType() supertypes}, {@link #getInterfaces() interfaces}, and
047 * {@link #getGeneric(int...) generic parameters} along with the ability to ultimately
048 * {@link #resolve() resolve} to a {@link java.lang.Class}.
049 *
050 * <p>{@code ResolvableTypes} may be obtained from {@link #forField(Field) fields},
051 * {@link #forMethodParameter(Method, int) method parameters},
052 * {@link #forMethodReturnType(Method) method returns} or
053 * {@link #forClass(Class) classes}. Most methods on this class will themselves return
054 * {@link ResolvableType}s, allowing easy navigation. For example:
055 * <pre class="code">
056 * private HashMap&lt;Integer, List&lt;String&gt;&gt; myMap;
057 *
058 * public void example() {
059 *     ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
060 *     t.getSuperType(); // AbstractMap&lt;Integer, List&lt;String&gt;&gt;
061 *     t.asMap(); // Map&lt;Integer, List&lt;String&gt;&gt;
062 *     t.getGeneric(0).resolve(); // Integer
063 *     t.getGeneric(1).resolve(); // List
064 *     t.getGeneric(1); // List&lt;String&gt;
065 *     t.resolveGeneric(1, 0); // String
066 * }
067 * </pre>
068 *
069 * @author Phillip Webb
070 * @author Juergen Hoeller
071 * @author Stephane Nicoll
072 * @since 4.0
073 * @see #forField(Field)
074 * @see #forMethodParameter(Method, int)
075 * @see #forMethodReturnType(Method)
076 * @see #forConstructorParameter(Constructor, int)
077 * @see #forClass(Class)
078 * @see #forType(Type)
079 * @see #forInstance(Object)
080 * @see ResolvableTypeProvider
081 */
082@SuppressWarnings("serial")
083public class ResolvableType implements Serializable {
084
085        /**
086         * {@code ResolvableType} returned when no value is available. {@code NONE} is used
087         * in preference to {@code null} so that multiple method calls can be safely chained.
088         */
089        public static final ResolvableType NONE = new ResolvableType(null, null, null, 0);
090
091        private static final ResolvableType[] EMPTY_TYPES_ARRAY = new ResolvableType[0];
092
093        private static final ConcurrentReferenceHashMap<ResolvableType, ResolvableType> cache =
094                        new ConcurrentReferenceHashMap<ResolvableType, ResolvableType>(256);
095
096
097        /**
098         * The underlying Java type being managed (only ever {@code null} for {@link #NONE}).
099         */
100        private final Type type;
101
102        /**
103         * Optional provider for the type.
104         */
105        private final TypeProvider typeProvider;
106
107        /**
108         * The {@code VariableResolver} to use or {@code null} if no resolver is available.
109         */
110        private final VariableResolver variableResolver;
111
112        /**
113         * The component type for an array or {@code null} if the type should be deduced.
114         */
115        private final ResolvableType componentType;
116
117        /**
118         * Copy of the resolved value.
119         */
120        private final Class<?> resolved;
121
122        private final Integer hash;
123
124        private ResolvableType superType;
125
126        private ResolvableType[] interfaces;
127
128        private ResolvableType[] generics;
129
130
131        /**
132         * Private constructor used to create a new {@link ResolvableType} for cache key purposes,
133         * with no upfront resolution.
134         */
135        private ResolvableType(Type type, TypeProvider typeProvider, VariableResolver variableResolver) {
136                this.type = type;
137                this.typeProvider = typeProvider;
138                this.variableResolver = variableResolver;
139                this.componentType = null;
140                this.resolved = null;
141                this.hash = calculateHashCode();
142        }
143
144        /**
145         * Private constructor used to create a new {@link ResolvableType} for cache value purposes,
146         * with upfront resolution and a pre-calculated hash.
147         * @since 4.2
148         */
149        private ResolvableType(Type type, TypeProvider typeProvider, VariableResolver variableResolver, Integer hash) {
150                this.type = type;
151                this.typeProvider = typeProvider;
152                this.variableResolver = variableResolver;
153                this.componentType = null;
154                this.resolved = resolveClass();
155                this.hash = hash;
156        }
157
158        /**
159         * Private constructor used to create a new {@link ResolvableType} for uncached purposes,
160         * with upfront resolution but lazily calculated hash.
161         */
162        private ResolvableType(
163                        Type type, TypeProvider typeProvider, VariableResolver variableResolver, ResolvableType componentType) {
164
165                this.type = type;
166                this.typeProvider = typeProvider;
167                this.variableResolver = variableResolver;
168                this.componentType = componentType;
169                this.resolved = resolveClass();
170                this.hash = null;
171        }
172
173        /**
174         * Private constructor used to create a new {@link ResolvableType} on a {@link Class} basis.
175         * Avoids all {@code instanceof} checks in order to create a straight {@link Class} wrapper.
176         * @since 4.2
177         */
178        private ResolvableType(Class<?> clazz) {
179                this.resolved = (clazz != null ? clazz : Object.class);
180                this.type = this.resolved;
181                this.typeProvider = null;
182                this.variableResolver = null;
183                this.componentType = null;
184                this.hash = null;
185        }
186
187
188        /**
189         * Return the underling Java {@link Type} being managed. With the exception of
190         * the {@link #NONE} constant, this method will never return {@code null}.
191         */
192        public Type getType() {
193                return SerializableTypeWrapper.unwrap(this.type);
194        }
195
196        /**
197         * Return the underlying Java {@link Class} being managed, if available;
198         * otherwise {@code null}.
199         */
200        public Class<?> getRawClass() {
201                if (this.type == this.resolved) {
202                        return this.resolved;
203                }
204                Type rawType = this.type;
205                if (rawType instanceof ParameterizedType) {
206                        rawType = ((ParameterizedType) rawType).getRawType();
207                }
208                return (rawType instanceof Class ? (Class<?>) rawType : null);
209        }
210
211        /**
212         * Return the underlying source of the resolvable type. Will return a {@link Field},
213         * {@link MethodParameter} or {@link Type} depending on how the {@link ResolvableType}
214         * was constructed. With the exception of the {@link #NONE} constant, this method will
215         * never return {@code null}. This method is primarily to provide access to additional
216         * type information or meta-data that alternative JVM languages may provide.
217         */
218        public Object getSource() {
219                Object source = (this.typeProvider != null ? this.typeProvider.getSource() : null);
220                return (source != null ? source : this.type);
221        }
222
223        /**
224         * Determine whether the given object is an instance of this {@code ResolvableType}.
225         * @param obj the object to check
226         * @since 4.2
227         * @see #isAssignableFrom(Class)
228         */
229        public boolean isInstance(Object obj) {
230                return (obj != null && isAssignableFrom(obj.getClass()));
231        }
232
233        /**
234         * Determine whether this {@code ResolvableType} is assignable from the
235         * specified other type.
236         * @param other the type to be checked against (as a {@code Class})
237         * @since 4.2
238         * @see #isAssignableFrom(ResolvableType)
239         */
240        public boolean isAssignableFrom(Class<?> other) {
241                return isAssignableFrom(forClass(other), null);
242        }
243
244        /**
245         * Determine whether this {@code ResolvableType} is assignable from the
246         * specified other type.
247         * <p>Attempts to follow the same rules as the Java compiler, considering
248         * whether both the {@link #resolve() resolved} {@code Class} is
249         * {@link Class#isAssignableFrom(Class) assignable from} the given type
250         * as well as whether all {@link #getGenerics() generics} are assignable.
251         * @param other the type to be checked against (as a {@code ResolvableType})
252         * @return {@code true} if the specified other type can be assigned to this
253         * {@code ResolvableType}; {@code false} otherwise
254         */
255        public boolean isAssignableFrom(ResolvableType other) {
256                return isAssignableFrom(other, null);
257        }
258
259        private boolean isAssignableFrom(ResolvableType other, Map<Type, Type> matchedBefore) {
260                Assert.notNull(other, "ResolvableType must not be null");
261
262                // If we cannot resolve types, we are not assignable
263                if (this == NONE || other == NONE) {
264                        return false;
265                }
266
267                // Deal with array by delegating to the component type
268                if (isArray()) {
269                        return (other.isArray() && getComponentType().isAssignableFrom(other.getComponentType()));
270                }
271
272                if (matchedBefore != null && matchedBefore.get(this.type) == other.type) {
273                        return true;
274                }
275
276                // Deal with wildcard bounds
277                WildcardBounds ourBounds = WildcardBounds.get(this);
278                WildcardBounds typeBounds = WildcardBounds.get(other);
279
280                // In the form X is assignable to <? extends Number>
281                if (typeBounds != null) {
282                        return (ourBounds != null && ourBounds.isSameKind(typeBounds) &&
283                                        ourBounds.isAssignableFrom(typeBounds.getBounds()));
284                }
285
286                // In the form <? extends Number> is assignable to X...
287                if (ourBounds != null) {
288                        return ourBounds.isAssignableFrom(other);
289                }
290
291                // Main assignability check about to follow
292                boolean exactMatch = (matchedBefore != null);  // We're checking nested generic variables now...
293                boolean checkGenerics = true;
294                Class<?> ourResolved = null;
295                if (this.type instanceof TypeVariable) {
296                        TypeVariable<?> variable = (TypeVariable<?>) this.type;
297                        // Try default variable resolution
298                        if (this.variableResolver != null) {
299                                ResolvableType resolved = this.variableResolver.resolveVariable(variable);
300                                if (resolved != null) {
301                                        ourResolved = resolved.resolve();
302                                }
303                        }
304                        if (ourResolved == null) {
305                                // Try variable resolution against target type
306                                if (other.variableResolver != null) {
307                                        ResolvableType resolved = other.variableResolver.resolveVariable(variable);
308                                        if (resolved != null) {
309                                                ourResolved = resolved.resolve();
310                                                checkGenerics = false;
311                                        }
312                                }
313                        }
314                        if (ourResolved == null) {
315                                // Unresolved type variable, potentially nested -> never insist on exact match
316                                exactMatch = false;
317                        }
318                }
319                if (ourResolved == null) {
320                        ourResolved = resolve(Object.class);
321                }
322                Class<?> otherResolved = other.resolve(Object.class);
323
324                // We need an exact type match for generics
325                // List<CharSequence> is not assignable from List<String>
326                if (exactMatch ? !ourResolved.equals(otherResolved) : !ClassUtils.isAssignable(ourResolved, otherResolved)) {
327                        return false;
328                }
329
330                if (checkGenerics) {
331                        // Recursively check each generic
332                        ResolvableType[] ourGenerics = getGenerics();
333                        ResolvableType[] typeGenerics = other.as(ourResolved).getGenerics();
334                        if (ourGenerics.length != typeGenerics.length) {
335                                return false;
336                        }
337                        if (matchedBefore == null) {
338                                matchedBefore = new IdentityHashMap<Type, Type>(1);
339                        }
340                        matchedBefore.put(this.type, other.type);
341                        for (int i = 0; i < ourGenerics.length; i++) {
342                                if (!ourGenerics[i].isAssignableFrom(typeGenerics[i], matchedBefore)) {
343                                        return false;
344                                }
345                        }
346                }
347
348                return true;
349        }
350
351        /**
352         * Return {@code true} if this type resolves to a Class that represents an array.
353         * @see #getComponentType()
354         */
355        public boolean isArray() {
356                if (this == NONE) {
357                        return false;
358                }
359                return ((this.type instanceof Class && ((Class<?>) this.type).isArray()) ||
360                                this.type instanceof GenericArrayType || resolveType().isArray());
361        }
362
363        /**
364         * Return the ResolvableType representing the component type of the array or
365         * {@link #NONE} if this type does not represent an array.
366         * @see #isArray()
367         */
368        public ResolvableType getComponentType() {
369                if (this == NONE) {
370                        return NONE;
371                }
372                if (this.componentType != null) {
373                        return this.componentType;
374                }
375                if (this.type instanceof Class) {
376                        Class<?> componentType = ((Class<?>) this.type).getComponentType();
377                        return forType(componentType, this.variableResolver);
378                }
379                if (this.type instanceof GenericArrayType) {
380                        return forType(((GenericArrayType) this.type).getGenericComponentType(), this.variableResolver);
381                }
382                return resolveType().getComponentType();
383        }
384
385        /**
386         * Convenience method to return this type as a resolvable {@link Collection} type.
387         * Returns {@link #NONE} if this type does not implement or extend
388         * {@link Collection}.
389         * @see #as(Class)
390         * @see #asMap()
391         */
392        public ResolvableType asCollection() {
393                return as(Collection.class);
394        }
395
396        /**
397         * Convenience method to return this type as a resolvable {@link Map} type.
398         * Returns {@link #NONE} if this type does not implement or extend
399         * {@link Map}.
400         * @see #as(Class)
401         * @see #asCollection()
402         */
403        public ResolvableType asMap() {
404                return as(Map.class);
405        }
406
407        /**
408         * Return this type as a {@link ResolvableType} of the specified class. Searches
409         * {@link #getSuperType() supertype} and {@link #getInterfaces() interface}
410         * hierarchies to find a match, returning {@link #NONE} if this type does not
411         * implement or extend the specified class.
412         * @param type the required type (typically narrowed)
413         * @return a {@link ResolvableType} representing this object as the specified
414         * type, or {@link #NONE} if not resolvable as that type
415         * @see #asCollection()
416         * @see #asMap()
417         * @see #getSuperType()
418         * @see #getInterfaces()
419         */
420        public ResolvableType as(Class<?> type) {
421                if (this == NONE) {
422                        return NONE;
423                }
424                if (ObjectUtils.nullSafeEquals(resolve(), type)) {
425                        return this;
426                }
427                for (ResolvableType interfaceType : getInterfaces()) {
428                        ResolvableType interfaceAsType = interfaceType.as(type);
429                        if (interfaceAsType != NONE) {
430                                return interfaceAsType;
431                        }
432                }
433                return getSuperType().as(type);
434        }
435
436        /**
437         * Return a {@link ResolvableType} representing the direct supertype of this type.
438         * If no supertype is available this method returns {@link #NONE}.
439         * @see #getInterfaces()
440         */
441        public ResolvableType getSuperType() {
442                Class<?> resolved = resolve();
443                if (resolved == null || resolved.getGenericSuperclass() == null) {
444                        return NONE;
445                }
446                if (this.superType == null) {
447                        this.superType = forType(SerializableTypeWrapper.forGenericSuperclass(resolved), asVariableResolver());
448                }
449                return this.superType;
450        }
451
452        /**
453         * Return a {@link ResolvableType} array representing the direct interfaces
454         * implemented by this type. If this type does not implement any interfaces an
455         * empty array is returned.
456         * @see #getSuperType()
457         */
458        public ResolvableType[] getInterfaces() {
459                Class<?> resolved = resolve();
460                if (resolved == null || ObjectUtils.isEmpty(resolved.getGenericInterfaces())) {
461                        return EMPTY_TYPES_ARRAY;
462                }
463                if (this.interfaces == null) {
464                        this.interfaces = forTypes(SerializableTypeWrapper.forGenericInterfaces(resolved), asVariableResolver());
465                }
466                return this.interfaces;
467        }
468
469        /**
470         * Return {@code true} if this type contains generic parameters.
471         * @see #getGeneric(int...)
472         * @see #getGenerics()
473         */
474        public boolean hasGenerics() {
475                return (getGenerics().length > 0);
476        }
477
478        /**
479         * Return {@code true} if this type contains unresolvable generics only,
480         * that is, no substitute for any of its declared type variables.
481         */
482        boolean isEntirelyUnresolvable() {
483                if (this == NONE) {
484                        return false;
485                }
486                ResolvableType[] generics = getGenerics();
487                for (ResolvableType generic : generics) {
488                        if (!generic.isUnresolvableTypeVariable() && !generic.isWildcardWithoutBounds()) {
489                                return false;
490                        }
491                }
492                return true;
493        }
494
495        /**
496         * Determine whether the underlying type has any unresolvable generics:
497         * either through an unresolvable type variable on the type itself
498         * or through implementing a generic interface in a raw fashion,
499         * i.e. without substituting that interface's type variables.
500         * The result will be {@code true} only in those two scenarios.
501         */
502        public boolean hasUnresolvableGenerics() {
503                if (this == NONE) {
504                        return false;
505                }
506                ResolvableType[] generics = getGenerics();
507                for (ResolvableType generic : generics) {
508                        if (generic.isUnresolvableTypeVariable() || generic.isWildcardWithoutBounds()) {
509                                return true;
510                        }
511                }
512                Class<?> resolved = resolve();
513                if (resolved != null) {
514                        for (Type genericInterface : resolved.getGenericInterfaces()) {
515                                if (genericInterface instanceof Class) {
516                                        if (forClass((Class<?>) genericInterface).hasGenerics()) {
517                                                return true;
518                                        }
519                                }
520                        }
521                        return getSuperType().hasUnresolvableGenerics();
522                }
523                return false;
524        }
525
526        /**
527         * Determine whether the underlying type is a type variable that
528         * cannot be resolved through the associated variable resolver.
529         */
530        private boolean isUnresolvableTypeVariable() {
531                if (this.type instanceof TypeVariable) {
532                        if (this.variableResolver == null) {
533                                return true;
534                        }
535                        TypeVariable<?> variable = (TypeVariable<?>) this.type;
536                        ResolvableType resolved = this.variableResolver.resolveVariable(variable);
537                        if (resolved == null || resolved.isUnresolvableTypeVariable()) {
538                                return true;
539                        }
540                }
541                return false;
542        }
543
544        /**
545         * Determine whether the underlying type represents a wildcard
546         * without specific bounds (i.e., equal to {@code ? extends Object}).
547         */
548        private boolean isWildcardWithoutBounds() {
549                if (this.type instanceof WildcardType) {
550                        WildcardType wt = (WildcardType) this.type;
551                        if (wt.getLowerBounds().length == 0) {
552                                Type[] upperBounds = wt.getUpperBounds();
553                                if (upperBounds.length == 0 || (upperBounds.length == 1 && Object.class == upperBounds[0])) {
554                                        return true;
555                                }
556                        }
557                }
558                return false;
559        }
560
561        /**
562         * Return a {@link ResolvableType} for the specified nesting level.
563         * See {@link #getNested(int, Map)} for details.
564         * @param nestingLevel the nesting level
565         * @return the {@link ResolvableType} type, or {@code #NONE}
566         */
567        public ResolvableType getNested(int nestingLevel) {
568                return getNested(nestingLevel, null);
569        }
570
571        /**
572         * Return a {@link ResolvableType} for the specified nesting level.
573         * <p>The nesting level refers to the specific generic parameter that should be returned.
574         * A nesting level of 1 indicates this type; 2 indicates the first nested generic;
575         * 3 the second; and so on. For example, given {@code List<Set<Integer>>} level 1 refers
576         * to the {@code List}, level 2 the {@code Set}, and level 3 the {@code Integer}.
577         * <p>The {@code typeIndexesPerLevel} map can be used to reference a specific generic
578         * for the given level. For example, an index of 0 would refer to a {@code Map} key;
579         * whereas, 1 would refer to the value. If the map does not contain a value for a
580         * specific level the last generic will be used (e.g. a {@code Map} value).
581         * <p>Nesting levels may also apply to array types; for example given
582         * {@code String[]}, a nesting level of 2 refers to {@code String}.
583         * <p>If a type does not {@link #hasGenerics() contain} generics the
584         * {@link #getSuperType() supertype} hierarchy will be considered.
585         * @param nestingLevel the required nesting level, indexed from 1 for the
586         * current type, 2 for the first nested generic, 3 for the second and so on
587         * @param typeIndexesPerLevel a map containing the generic index for a given
588         * nesting level (may be {@code null})
589         * @return a {@link ResolvableType} for the nested level, or {@link #NONE}
590         */
591        public ResolvableType getNested(int nestingLevel, Map<Integer, Integer> typeIndexesPerLevel) {
592                ResolvableType result = this;
593                for (int i = 2; i <= nestingLevel; i++) {
594                        if (result.isArray()) {
595                                result = result.getComponentType();
596                        }
597                        else {
598                                // Handle derived types
599                                while (result != ResolvableType.NONE && !result.hasGenerics()) {
600                                        result = result.getSuperType();
601                                }
602                                Integer index = (typeIndexesPerLevel != null ? typeIndexesPerLevel.get(i) : null);
603                                index = (index == null ? result.getGenerics().length - 1 : index);
604                                result = result.getGeneric(index);
605                        }
606                }
607                return result;
608        }
609
610        /**
611         * Return a {@link ResolvableType} representing the generic parameter for the
612         * given indexes. Indexes are zero based; for example given the type
613         * {@code Map<Integer, List<String>>}, {@code getGeneric(0)} will access the
614         * {@code Integer}. Nested generics can be accessed by specifying multiple indexes;
615         * for example {@code getGeneric(1, 0)} will access the {@code String} from the
616         * nested {@code List}. For convenience, if no indexes are specified the first
617         * generic is returned.
618         * <p>If no generic is available at the specified indexes {@link #NONE} is returned.
619         * @param indexes the indexes that refer to the generic parameter
620         * (may be omitted to return the first generic)
621         * @return a {@link ResolvableType} for the specified generic, or {@link #NONE}
622         * @see #hasGenerics()
623         * @see #getGenerics()
624         * @see #resolveGeneric(int...)
625         * @see #resolveGenerics()
626         */
627        public ResolvableType getGeneric(int... indexes) {
628                ResolvableType[] generics = getGenerics();
629                if (indexes == null || indexes.length == 0) {
630                        return (generics.length == 0 ? NONE : generics[0]);
631                }
632                ResolvableType generic = this;
633                for (int index : indexes) {
634                        generics = generic.getGenerics();
635                        if (index < 0 || index >= generics.length) {
636                                return NONE;
637                        }
638                        generic = generics[index];
639                }
640                return generic;
641        }
642
643        /**
644         * Return an array of {@link ResolvableType}s representing the generic parameters of
645         * this type. If no generics are available an empty array is returned. If you need to
646         * access a specific generic consider using the {@link #getGeneric(int...)} method as
647         * it allows access to nested generics and protects against
648         * {@code IndexOutOfBoundsExceptions}.
649         * @return an array of {@link ResolvableType}s representing the generic parameters
650         * (never {@code null})
651         * @see #hasGenerics()
652         * @see #getGeneric(int...)
653         * @see #resolveGeneric(int...)
654         * @see #resolveGenerics()
655         */
656        public ResolvableType[] getGenerics() {
657                if (this == NONE) {
658                        return EMPTY_TYPES_ARRAY;
659                }
660                if (this.generics == null) {
661                        if (this.type instanceof Class) {
662                                Class<?> typeClass = (Class<?>) this.type;
663                                this.generics = forTypes(SerializableTypeWrapper.forTypeParameters(typeClass), this.variableResolver);
664                        }
665                        else if (this.type instanceof ParameterizedType) {
666                                Type[] actualTypeArguments = ((ParameterizedType) this.type).getActualTypeArguments();
667                                ResolvableType[] generics = new ResolvableType[actualTypeArguments.length];
668                                for (int i = 0; i < actualTypeArguments.length; i++) {
669                                        generics[i] = forType(actualTypeArguments[i], this.variableResolver);
670                                }
671                                this.generics = generics;
672                        }
673                        else {
674                                this.generics = resolveType().getGenerics();
675                        }
676                }
677                return this.generics;
678        }
679
680        /**
681         * Convenience method that will {@link #getGenerics() get} and
682         * {@link #resolve() resolve} generic parameters.
683         * @return an array of resolved generic parameters (the resulting array
684         * will never be {@code null}, but it may contain {@code null} elements})
685         * @see #getGenerics()
686         * @see #resolve()
687         */
688        public Class<?>[] resolveGenerics() {
689                return resolveGenerics(null);
690        }
691
692        /**
693         * Convenience method that will {@link #getGenerics() get} and {@link #resolve()
694         * resolve} generic parameters, using the specified {@code fallback} if any type
695         * cannot be resolved.
696         * @param fallback the fallback class to use if resolution fails
697         * @return an array of resolved generic parameters
698         * @see #getGenerics()
699         * @see #resolve()
700         */
701        public Class<?>[] resolveGenerics(Class<?> fallback) {
702                ResolvableType[] generics = getGenerics();
703                Class<?>[] resolvedGenerics = new Class<?>[generics.length];
704                for (int i = 0; i < generics.length; i++) {
705                        resolvedGenerics[i] = generics[i].resolve(fallback);
706                }
707                return resolvedGenerics;
708        }
709
710        /**
711         * Convenience method that will {@link #getGeneric(int...) get} and
712         * {@link #resolve() resolve} a specific generic parameters.
713         * @param indexes the indexes that refer to the generic parameter
714         * (may be omitted to return the first generic)
715         * @return a resolved {@link Class} or {@code null}
716         * @see #getGeneric(int...)
717         * @see #resolve()
718         */
719        public Class<?> resolveGeneric(int... indexes) {
720                return getGeneric(indexes).resolve();
721        }
722
723        /**
724         * Resolve this type to a {@link java.lang.Class}, returning {@code null}
725         * if the type cannot be resolved. This method will consider bounds of
726         * {@link TypeVariable}s and {@link WildcardType}s if direct resolution fails;
727         * however, bounds of {@code Object.class} will be ignored.
728         * @return the resolved {@link Class}, or {@code null} if not resolvable
729         * @see #resolve(Class)
730         * @see #resolveGeneric(int...)
731         * @see #resolveGenerics()
732         */
733        public Class<?> resolve() {
734                return resolve(null);
735        }
736
737        /**
738         * Resolve this type to a {@link java.lang.Class}, returning the specified
739         * {@code fallback} if the type cannot be resolved. This method will consider bounds
740         * of {@link TypeVariable}s and {@link WildcardType}s if direct resolution fails;
741         * however, bounds of {@code Object.class} will be ignored.
742         * @param fallback the fallback class to use if resolution fails
743         * @return the resolved {@link Class} or the {@code fallback}
744         * @see #resolve()
745         * @see #resolveGeneric(int...)
746         * @see #resolveGenerics()
747         */
748        public Class<?> resolve(Class<?> fallback) {
749                return (this.resolved != null ? this.resolved : fallback);
750        }
751
752        private Class<?> resolveClass() {
753                if (this.type instanceof Class || this.type == null) {
754                        return (Class<?>) this.type;
755                }
756                if (this.type instanceof GenericArrayType) {
757                        Class<?> resolvedComponent = getComponentType().resolve();
758                        return (resolvedComponent != null ? Array.newInstance(resolvedComponent, 0).getClass() : null);
759                }
760                return resolveType().resolve();
761        }
762
763        /**
764         * Resolve this type by a single level, returning the resolved value or {@link #NONE}.
765         * <p>Note: The returned {@link ResolvableType} should only be used as an intermediary
766         * as it cannot be serialized.
767         */
768        ResolvableType resolveType() {
769                if (this.type instanceof ParameterizedType) {
770                        return forType(((ParameterizedType) this.type).getRawType(), this.variableResolver);
771                }
772                if (this.type instanceof WildcardType) {
773                        Type resolved = resolveBounds(((WildcardType) this.type).getUpperBounds());
774                        if (resolved == null) {
775                                resolved = resolveBounds(((WildcardType) this.type).getLowerBounds());
776                        }
777                        return forType(resolved, this.variableResolver);
778                }
779                if (this.type instanceof TypeVariable) {
780                        TypeVariable<?> variable = (TypeVariable<?>) this.type;
781                        // Try default variable resolution
782                        if (this.variableResolver != null) {
783                                ResolvableType resolved = this.variableResolver.resolveVariable(variable);
784                                if (resolved != null) {
785                                        return resolved;
786                                }
787                        }
788                        // Fallback to bounds
789                        return forType(resolveBounds(variable.getBounds()), this.variableResolver);
790                }
791                return NONE;
792        }
793
794        private Type resolveBounds(Type[] bounds) {
795                if (ObjectUtils.isEmpty(bounds) || Object.class == bounds[0]) {
796                        return null;
797                }
798                return bounds[0];
799        }
800
801        private ResolvableType resolveVariable(TypeVariable<?> variable) {
802                if (this.type instanceof TypeVariable) {
803                        return resolveType().resolveVariable(variable);
804                }
805                if (this.type instanceof ParameterizedType) {
806                        ParameterizedType parameterizedType = (ParameterizedType) this.type;
807                        TypeVariable<?>[] variables = resolve().getTypeParameters();
808                        for (int i = 0; i < variables.length; i++) {
809                                if (ObjectUtils.nullSafeEquals(variables[i].getName(), variable.getName())) {
810                                        Type actualType = parameterizedType.getActualTypeArguments()[i];
811                                        return forType(actualType, this.variableResolver);
812                                }
813                        }
814                        if (parameterizedType.getOwnerType() != null) {
815                                return forType(parameterizedType.getOwnerType(), this.variableResolver).resolveVariable(variable);
816                        }
817                }
818                if (this.variableResolver != null) {
819                        return this.variableResolver.resolveVariable(variable);
820                }
821                return null;
822        }
823
824
825        @Override
826        public boolean equals(Object other) {
827                if (this == other) {
828                        return true;
829                }
830                if (!(other instanceof ResolvableType)) {
831                        return false;
832                }
833
834                ResolvableType otherType = (ResolvableType) other;
835                if (!ObjectUtils.nullSafeEquals(this.type, otherType.type)) {
836                        return false;
837                }
838                if (this.typeProvider != otherType.typeProvider &&
839                                (this.typeProvider == null || otherType.typeProvider == null ||
840                                !ObjectUtils.nullSafeEquals(this.typeProvider.getType(), otherType.typeProvider.getType()))) {
841                        return false;
842                }
843                if (this.variableResolver != otherType.variableResolver &&
844                                (this.variableResolver == null || otherType.variableResolver == null ||
845                                !ObjectUtils.nullSafeEquals(this.variableResolver.getSource(), otherType.variableResolver.getSource()))) {
846                        return false;
847                }
848                if (!ObjectUtils.nullSafeEquals(this.componentType, otherType.componentType)) {
849                        return false;
850                }
851                return true;
852        }
853
854        @Override
855        public int hashCode() {
856                return (this.hash != null ? this.hash : calculateHashCode());
857        }
858
859        private int calculateHashCode() {
860                int hashCode = ObjectUtils.nullSafeHashCode(this.type);
861                if (this.typeProvider != null) {
862                        hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.typeProvider.getType());
863                }
864                if (this.variableResolver != null) {
865                        hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.variableResolver.getSource());
866                }
867                if (this.componentType != null) {
868                        hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.componentType);
869                }
870                return hashCode;
871        }
872
873        /**
874         * Adapts this {@link ResolvableType} to a {@link VariableResolver}.
875         */
876        VariableResolver asVariableResolver() {
877                if (this == NONE) {
878                        return null;
879                }
880                return new DefaultVariableResolver();
881        }
882
883        /**
884         * Custom serialization support for {@link #NONE}.
885         */
886        private Object readResolve() {
887                return (this.type == null ? NONE : this);
888        }
889
890        /**
891         * Return a String representation of this type in its fully resolved form
892         * (including any generic parameters).
893         */
894        @Override
895        public String toString() {
896                if (isArray()) {
897                        return getComponentType() + "[]";
898                }
899                if (this.resolved == null) {
900                        return "?";
901                }
902                if (this.type instanceof TypeVariable) {
903                        TypeVariable<?> variable = (TypeVariable<?>) this.type;
904                        if (this.variableResolver == null || this.variableResolver.resolveVariable(variable) == null) {
905                                // Don't bother with variable boundaries for toString()...
906                                // Can cause infinite recursions in case of self-references
907                                return "?";
908                        }
909                }
910                StringBuilder result = new StringBuilder(this.resolved.getName());
911                if (hasGenerics()) {
912                        result.append('<');
913                        result.append(StringUtils.arrayToDelimitedString(getGenerics(), ", "));
914                        result.append('>');
915                }
916                return result.toString();
917        }
918
919
920        // Factory methods
921
922        /**
923         * Return a {@link ResolvableType} for the specified {@link Class},
924         * using the full generic type information for assignability checks.
925         * For example: {@code ResolvableType.forClass(MyArrayList.class)}.
926         * @param clazz the class to introspect ({@code null} is semantically
927         * equivalent to {@code Object.class} for typical use cases here)
928         * @return a {@link ResolvableType} for the specified class
929         * @see #forClass(Class, Class)
930         * @see #forClassWithGenerics(Class, Class...)
931         */
932        public static ResolvableType forClass(Class<?> clazz) {
933                return new ResolvableType(clazz);
934        }
935
936        /**
937         * Return a {@link ResolvableType} for the specified {@link Class},
938         * doing assignability checks against the raw class only (analogous to
939         * {@link Class#isAssignableFrom}, which this serves as a wrapper for.
940         * For example: {@code ResolvableType.forRawClass(List.class)}.
941         * @param clazz the class to introspect ({@code null} is semantically
942         * equivalent to {@code Object.class} for typical use cases here)
943         * @return a {@link ResolvableType} for the specified class
944         * @since 4.2
945         * @see #forClass(Class)
946         * @see #getRawClass()
947         */
948        public static ResolvableType forRawClass(Class<?> clazz) {
949                return new ResolvableType(clazz) {
950                        @Override
951                        public ResolvableType[] getGenerics() {
952                                return EMPTY_TYPES_ARRAY;
953                        }
954                        @Override
955                        public boolean isAssignableFrom(Class<?> other) {
956                                return ClassUtils.isAssignable(getRawClass(), other);
957                        }
958                        @Override
959                        public boolean isAssignableFrom(ResolvableType other) {
960                                Class<?> otherClass = other.getRawClass();
961                                return (otherClass != null && ClassUtils.isAssignable(getRawClass(), otherClass));
962                        }
963                };
964        }
965
966        /**
967         * Return a {@link ResolvableType} for the specified base type
968         * (interface or base class) with a given implementation class.
969         * For example: {@code ResolvableType.forClass(List.class, MyArrayList.class)}.
970         * @param baseType the base type (must not be {@code null})
971         * @param implementationClass the implementation class
972         * @return a {@link ResolvableType} for the specified base type backed by the
973         * given implementation class
974         * @see #forClass(Class)
975         * @see #forClassWithGenerics(Class, Class...)
976         */
977        public static ResolvableType forClass(Class<?> baseType, Class<?> implementationClass) {
978                Assert.notNull(baseType, "Base type must not be null");
979                ResolvableType asType = forType(implementationClass).as(baseType);
980                return (asType == NONE ? forType(baseType) : asType);
981        }
982
983        /**
984         * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
985         * @param clazz the class (or interface) to introspect
986         * @param generics the generics of the class
987         * @return a {@link ResolvableType} for the specific class and generics
988         * @see #forClassWithGenerics(Class, ResolvableType...)
989         */
990        public static ResolvableType forClassWithGenerics(Class<?> clazz, Class<?>... generics) {
991                Assert.notNull(clazz, "Class must not be null");
992                Assert.notNull(generics, "Generics array must not be null");
993                ResolvableType[] resolvableGenerics = new ResolvableType[generics.length];
994                for (int i = 0; i < generics.length; i++) {
995                        resolvableGenerics[i] = forClass(generics[i]);
996                }
997                return forClassWithGenerics(clazz, resolvableGenerics);
998        }
999
1000        /**
1001         * Return a {@link ResolvableType} for the specified {@link Class} with pre-declared generics.
1002         * @param clazz the class (or interface) to introspect
1003         * @param generics the generics of the class
1004         * @return a {@link ResolvableType} for the specific class and generics
1005         * @see #forClassWithGenerics(Class, Class...)
1006         */
1007        public static ResolvableType forClassWithGenerics(Class<?> clazz, ResolvableType... generics) {
1008                Assert.notNull(clazz, "Class must not be null");
1009                Assert.notNull(generics, "Generics array must not be null");
1010                TypeVariable<?>[] variables = clazz.getTypeParameters();
1011                Assert.isTrue(variables.length == generics.length, "Mismatched number of generics specified");
1012
1013                Type[] arguments = new Type[generics.length];
1014                for (int i = 0; i < generics.length; i++) {
1015                        ResolvableType generic = generics[i];
1016                        Type argument = (generic != null ? generic.getType() : null);
1017                        arguments[i] = (argument != null ? argument : variables[i]);
1018                }
1019
1020                ParameterizedType syntheticType = new SyntheticParameterizedType(clazz, arguments);
1021                return forType(syntheticType, new TypeVariablesVariableResolver(variables, generics));
1022        }
1023
1024        /**
1025         * Return a {@link ResolvableType} for the specified instance. The instance does not
1026         * convey generic information but if it implements {@link ResolvableTypeProvider} a
1027         * more precise {@link ResolvableType} can be used than the simple one based on
1028         * the {@link #forClass(Class) Class instance}.
1029         * @param instance the instance
1030         * @return a {@link ResolvableType} for the specified instance
1031         * @since 4.2
1032         * @see ResolvableTypeProvider
1033         */
1034        public static ResolvableType forInstance(Object instance) {
1035                Assert.notNull(instance, "Instance must not be null");
1036                if (instance instanceof ResolvableTypeProvider) {
1037                        ResolvableType type = ((ResolvableTypeProvider) instance).getResolvableType();
1038                        if (type != null) {
1039                                return type;
1040                        }
1041                }
1042                return ResolvableType.forClass(instance.getClass());
1043        }
1044
1045        /**
1046         * Return a {@link ResolvableType} for the specified {@link Field}.
1047         * @param field the source field
1048         * @return a {@link ResolvableType} for the specified field
1049         * @see #forField(Field, Class)
1050         */
1051        public static ResolvableType forField(Field field) {
1052                Assert.notNull(field, "Field must not be null");
1053                return forType(null, new FieldTypeProvider(field), null);
1054        }
1055
1056        /**
1057         * Return a {@link ResolvableType} for the specified {@link Field} with a given
1058         * implementation.
1059         * <p>Use this variant when the class that declares the field includes generic
1060         * parameter variables that are satisfied by the implementation class.
1061         * @param field the source field
1062         * @param implementationClass the implementation class
1063         * @return a {@link ResolvableType} for the specified field
1064         * @see #forField(Field)
1065         */
1066        public static ResolvableType forField(Field field, Class<?> implementationClass) {
1067                Assert.notNull(field, "Field must not be null");
1068                ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass());
1069                return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
1070        }
1071
1072        /**
1073         * Return a {@link ResolvableType} for the specified {@link Field} with a given
1074         * implementation.
1075         * <p>Use this variant when the class that declares the field includes generic
1076         * parameter variables that are satisfied by the implementation type.
1077         * @param field the source field
1078         * @param implementationType the implementation type
1079         * @return a {@link ResolvableType} for the specified field
1080         * @see #forField(Field)
1081         */
1082        public static ResolvableType forField(Field field, ResolvableType implementationType) {
1083                Assert.notNull(field, "Field must not be null");
1084                ResolvableType owner = (implementationType != null ? implementationType : NONE);
1085                owner = owner.as(field.getDeclaringClass());
1086                return forType(null, new FieldTypeProvider(field), owner.asVariableResolver());
1087        }
1088
1089        /**
1090         * Return a {@link ResolvableType} for the specified {@link Field} with the
1091         * given nesting level.
1092         * @param field the source field
1093         * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
1094         * generic type; etc)
1095         * @see #forField(Field)
1096         */
1097        public static ResolvableType forField(Field field, int nestingLevel) {
1098                Assert.notNull(field, "Field must not be null");
1099                return forType(null, new FieldTypeProvider(field), null).getNested(nestingLevel);
1100        }
1101
1102        /**
1103         * Return a {@link ResolvableType} for the specified {@link Field} with a given
1104         * implementation and the given nesting level.
1105         * <p>Use this variant when the class that declares the field includes generic
1106         * parameter variables that are satisfied by the implementation class.
1107         * @param field the source field
1108         * @param nestingLevel the nesting level (1 for the outer level; 2 for a nested
1109         * generic type; etc)
1110         * @param implementationClass the implementation class
1111         * @return a {@link ResolvableType} for the specified field
1112         * @see #forField(Field)
1113         */
1114        public static ResolvableType forField(Field field, int nestingLevel, Class<?> implementationClass) {
1115                Assert.notNull(field, "Field must not be null");
1116                ResolvableType owner = forType(implementationClass).as(field.getDeclaringClass());
1117                return forType(null, new FieldTypeProvider(field), owner.asVariableResolver()).getNested(nestingLevel);
1118        }
1119
1120        /**
1121         * Return a {@link ResolvableType} for the specified {@link Constructor} parameter.
1122         * @param constructor the source constructor (must not be {@code null})
1123         * @param parameterIndex the parameter index
1124         * @return a {@link ResolvableType} for the specified constructor parameter
1125         * @see #forConstructorParameter(Constructor, int, Class)
1126         */
1127        public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex) {
1128                Assert.notNull(constructor, "Constructor must not be null");
1129                return forMethodParameter(new MethodParameter(constructor, parameterIndex));
1130        }
1131
1132        /**
1133         * Return a {@link ResolvableType} for the specified {@link Constructor} parameter
1134         * with a given implementation. Use this variant when the class that declares the
1135         * constructor includes generic parameter variables that are satisfied by the
1136         * implementation class.
1137         * @param constructor the source constructor (must not be {@code null})
1138         * @param parameterIndex the parameter index
1139         * @param implementationClass the implementation class
1140         * @return a {@link ResolvableType} for the specified constructor parameter
1141         * @see #forConstructorParameter(Constructor, int)
1142         */
1143        public static ResolvableType forConstructorParameter(Constructor<?> constructor, int parameterIndex,
1144                        Class<?> implementationClass) {
1145
1146                Assert.notNull(constructor, "Constructor must not be null");
1147                MethodParameter methodParameter = new MethodParameter(constructor, parameterIndex);
1148                methodParameter.setContainingClass(implementationClass);
1149                return forMethodParameter(methodParameter);
1150        }
1151
1152        /**
1153         * Return a {@link ResolvableType} for the specified {@link Method} return type.
1154         * @param method the source for the method return type
1155         * @return a {@link ResolvableType} for the specified method return
1156         * @see #forMethodReturnType(Method, Class)
1157         */
1158        public static ResolvableType forMethodReturnType(Method method) {
1159                Assert.notNull(method, "Method must not be null");
1160                return forMethodParameter(new MethodParameter(method, -1));
1161        }
1162
1163        /**
1164         * Return a {@link ResolvableType} for the specified {@link Method} return type.
1165         * Use this variant when the class that declares the method includes generic
1166         * parameter variables that are satisfied by the implementation class.
1167         * @param method the source for the method return type
1168         * @param implementationClass the implementation class
1169         * @return a {@link ResolvableType} for the specified method return
1170         * @see #forMethodReturnType(Method)
1171         */
1172        public static ResolvableType forMethodReturnType(Method method, Class<?> implementationClass) {
1173                Assert.notNull(method, "Method must not be null");
1174                MethodParameter methodParameter = new MethodParameter(method, -1);
1175                methodParameter.setContainingClass(implementationClass);
1176                return forMethodParameter(methodParameter);
1177        }
1178
1179        /**
1180         * Return a {@link ResolvableType} for the specified {@link Method} parameter.
1181         * @param method the source method (must not be {@code null})
1182         * @param parameterIndex the parameter index
1183         * @return a {@link ResolvableType} for the specified method parameter
1184         * @see #forMethodParameter(Method, int, Class)
1185         * @see #forMethodParameter(MethodParameter)
1186         */
1187        public static ResolvableType forMethodParameter(Method method, int parameterIndex) {
1188                Assert.notNull(method, "Method must not be null");
1189                return forMethodParameter(new MethodParameter(method, parameterIndex));
1190        }
1191
1192        /**
1193         * Return a {@link ResolvableType} for the specified {@link Method} parameter with a
1194         * given implementation. Use this variant when the class that declares the method
1195         * includes generic parameter variables that are satisfied by the implementation class.
1196         * @param method the source method (must not be {@code null})
1197         * @param parameterIndex the parameter index
1198         * @param implementationClass the implementation class
1199         * @return a {@link ResolvableType} for the specified method parameter
1200         * @see #forMethodParameter(Method, int, Class)
1201         * @see #forMethodParameter(MethodParameter)
1202         */
1203        public static ResolvableType forMethodParameter(Method method, int parameterIndex, Class<?> implementationClass) {
1204                Assert.notNull(method, "Method must not be null");
1205                MethodParameter methodParameter = new MethodParameter(method, parameterIndex);
1206                methodParameter.setContainingClass(implementationClass);
1207                return forMethodParameter(methodParameter);
1208        }
1209
1210        /**
1211         * Return a {@link ResolvableType} for the specified {@link MethodParameter}.
1212         * @param methodParameter the source method parameter (must not be {@code null})
1213         * @return a {@link ResolvableType} for the specified method parameter
1214         * @see #forMethodParameter(Method, int)
1215         */
1216        public static ResolvableType forMethodParameter(MethodParameter methodParameter) {
1217                return forMethodParameter(methodParameter, (Type) null);
1218        }
1219
1220        /**
1221         * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a
1222         * given implementation type. Use this variant when the class that declares the method
1223         * includes generic parameter variables that are satisfied by the implementation type.
1224         * @param methodParameter the source method parameter (must not be {@code null})
1225         * @param implementationType the implementation type
1226         * @return a {@link ResolvableType} for the specified method parameter
1227         * @see #forMethodParameter(MethodParameter)
1228         */
1229        public static ResolvableType forMethodParameter(MethodParameter methodParameter, ResolvableType implementationType) {
1230                Assert.notNull(methodParameter, "MethodParameter must not be null");
1231                implementationType = (implementationType != null ? implementationType :
1232                                forType(methodParameter.getContainingClass()));
1233                ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass());
1234                return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).
1235                                getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel);
1236        }
1237
1238        /**
1239         * Return a {@link ResolvableType} for the specified {@link MethodParameter},
1240         * overriding the target type to resolve with a specific given type.
1241         * @param methodParameter the source method parameter (must not be {@code null})
1242         * @param targetType the type to resolve (a part of the method parameter's type)
1243         * @return a {@link ResolvableType} for the specified method parameter
1244         * @see #forMethodParameter(Method, int)
1245         */
1246        public static ResolvableType forMethodParameter(MethodParameter methodParameter, Type targetType) {
1247                Assert.notNull(methodParameter, "MethodParameter must not be null");
1248                ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass());
1249                return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).
1250                                getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel);
1251        }
1252
1253        /**
1254         * Resolve the top-level parameter type of the given {@code MethodParameter}.
1255         * @param methodParameter the method parameter to resolve
1256         * @since 4.1.9
1257         * @see MethodParameter#setParameterType
1258         */
1259        static void resolveMethodParameter(MethodParameter methodParameter) {
1260                Assert.notNull(methodParameter, "MethodParameter must not be null");
1261                ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass());
1262                methodParameter.setParameterType(
1263                                forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()).resolve());
1264        }
1265
1266        /**
1267         * Return a {@link ResolvableType} as a array of the specified {@code componentType}.
1268         * @param componentType the component type
1269         * @return a {@link ResolvableType} as an array of the specified component type
1270         */
1271        public static ResolvableType forArrayComponent(ResolvableType componentType) {
1272                Assert.notNull(componentType, "Component type must not be null");
1273                Class<?> arrayClass = Array.newInstance(componentType.resolve(), 0).getClass();
1274                return new ResolvableType(arrayClass, null, null, componentType);
1275        }
1276
1277        private static ResolvableType[] forTypes(Type[] types, VariableResolver owner) {
1278                ResolvableType[] result = new ResolvableType[types.length];
1279                for (int i = 0; i < types.length; i++) {
1280                        result[i] = forType(types[i], owner);
1281                }
1282                return result;
1283        }
1284
1285        /**
1286         * Return a {@link ResolvableType} for the specified {@link Type}.
1287         * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
1288         * @param type the source type (potentially {@code null})
1289         * @return a {@link ResolvableType} for the specified {@link Type}
1290         * @see #forType(Type, ResolvableType)
1291         */
1292        public static ResolvableType forType(Type type) {
1293                return forType(type, null, null);
1294        }
1295
1296        /**
1297         * Return a {@link ResolvableType} for the specified {@link Type} backed by the given
1298         * owner type.
1299         * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
1300         * @param type the source type or {@code null}
1301         * @param owner the owner type used to resolve variables
1302         * @return a {@link ResolvableType} for the specified {@link Type} and owner
1303         * @see #forType(Type)
1304         */
1305        public static ResolvableType forType(Type type, ResolvableType owner) {
1306                VariableResolver variableResolver = null;
1307                if (owner != null) {
1308                        variableResolver = owner.asVariableResolver();
1309                }
1310                return forType(type, variableResolver);
1311        }
1312
1313
1314        /**
1315         * Return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}.
1316         * <p>Note: The resulting {@link ResolvableType} instance may not be {@link Serializable}.
1317         * @param typeReference the reference to obtain the source type from
1318         * @return a {@link ResolvableType} for the specified {@link ParameterizedTypeReference}
1319         * @since 4.3.12
1320         * @see #forType(Type)
1321         */
1322        public static ResolvableType forType(ParameterizedTypeReference<?> typeReference) {
1323                return forType(typeReference.getType(), null, null);
1324        }
1325
1326        /**
1327         * Return a {@link ResolvableType} for the specified {@link Type} backed by a given
1328         * {@link VariableResolver}.
1329         * @param type the source type or {@code null}
1330         * @param variableResolver the variable resolver or {@code null}
1331         * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
1332         */
1333        static ResolvableType forType(Type type, VariableResolver variableResolver) {
1334                return forType(type, null, variableResolver);
1335        }
1336
1337        /**
1338         * Return a {@link ResolvableType} for the specified {@link Type} backed by a given
1339         * {@link VariableResolver}.
1340         * @param type the source type or {@code null}
1341         * @param typeProvider the type provider or {@code null}
1342         * @param variableResolver the variable resolver or {@code null}
1343         * @return a {@link ResolvableType} for the specified {@link Type} and {@link VariableResolver}
1344         */
1345        static ResolvableType forType(Type type, TypeProvider typeProvider, VariableResolver variableResolver) {
1346                if (type == null && typeProvider != null) {
1347                        type = SerializableTypeWrapper.forTypeProvider(typeProvider);
1348                }
1349                if (type == null) {
1350                        return NONE;
1351                }
1352
1353                // For simple Class references, build the wrapper right away -
1354                // no expensive resolution necessary, so not worth caching...
1355                if (type instanceof Class) {
1356                        return new ResolvableType(type, typeProvider, variableResolver, (ResolvableType) null);
1357                }
1358
1359                // Purge empty entries on access since we don't have a clean-up thread or the like.
1360                cache.purgeUnreferencedEntries();
1361
1362                // Check the cache - we may have a ResolvableType which has been resolved before...
1363                ResolvableType key = new ResolvableType(type, typeProvider, variableResolver);
1364                ResolvableType resolvableType = cache.get(key);
1365                if (resolvableType == null) {
1366                        resolvableType = new ResolvableType(type, typeProvider, variableResolver, key.hash);
1367                        cache.put(resolvableType, resolvableType);
1368                }
1369                return resolvableType;
1370        }
1371
1372        /**
1373         * Clear the internal {@code ResolvableType}/{@code SerializableTypeWrapper} cache.
1374         * @since 4.2
1375         */
1376        public static void clearCache() {
1377                cache.clear();
1378                SerializableTypeWrapper.cache.clear();
1379        }
1380
1381
1382        /**
1383         * Strategy interface used to resolve {@link TypeVariable}s.
1384         */
1385        interface VariableResolver extends Serializable {
1386
1387                /**
1388                 * Return the source of the resolver (used for hashCode and equals).
1389                 */
1390                Object getSource();
1391
1392                /**
1393                 * Resolve the specified variable.
1394                 * @param variable the variable to resolve
1395                 * @return the resolved variable, or {@code null} if not found
1396                 */
1397                ResolvableType resolveVariable(TypeVariable<?> variable);
1398        }
1399
1400
1401        @SuppressWarnings("serial")
1402        private class DefaultVariableResolver implements VariableResolver {
1403
1404                @Override
1405                public ResolvableType resolveVariable(TypeVariable<?> variable) {
1406                        return ResolvableType.this.resolveVariable(variable);
1407                }
1408
1409                @Override
1410                public Object getSource() {
1411                        return ResolvableType.this;
1412                }
1413        }
1414
1415
1416        @SuppressWarnings("serial")
1417        private static class TypeVariablesVariableResolver implements VariableResolver {
1418
1419                private final TypeVariable<?>[] variables;
1420
1421                private final ResolvableType[] generics;
1422
1423                public TypeVariablesVariableResolver(TypeVariable<?>[] variables, ResolvableType[] generics) {
1424                        this.variables = variables;
1425                        this.generics = generics;
1426                }
1427
1428                @Override
1429                public ResolvableType resolveVariable(TypeVariable<?> variable) {
1430                        for (int i = 0; i < this.variables.length; i++) {
1431                                TypeVariable<?> v1 = SerializableTypeWrapper.unwrap(this.variables[i]);
1432                                TypeVariable<?> v2 = SerializableTypeWrapper.unwrap(variable);
1433                                if (ObjectUtils.nullSafeEquals(v1, v2)) {
1434                                        return this.generics[i];
1435                                }
1436                        }
1437                        return null;
1438                }
1439
1440                @Override
1441                public Object getSource() {
1442                        return this.generics;
1443                }
1444        }
1445
1446
1447        private static final class SyntheticParameterizedType implements ParameterizedType, Serializable {
1448
1449                private final Type rawType;
1450
1451                private final Type[] typeArguments;
1452
1453                public SyntheticParameterizedType(Type rawType, Type[] typeArguments) {
1454                        this.rawType = rawType;
1455                        this.typeArguments = typeArguments;
1456                }
1457
1458                @Override  // on Java 8
1459                @UsesJava8
1460                public String getTypeName() {
1461                        StringBuilder result = new StringBuilder(this.rawType.getTypeName());
1462                        if (this.typeArguments.length > 0) {
1463                                result.append('<');
1464                                for (int i = 0; i < this.typeArguments.length; i++) {
1465                                        if (i > 0) {
1466                                                result.append(", ");
1467                                        }
1468                                        result.append(this.typeArguments[i].getTypeName());
1469                                }
1470                                result.append('>');
1471                        }
1472                        return result.toString();
1473                }
1474
1475                @Override
1476                public Type getOwnerType() {
1477                        return null;
1478                }
1479
1480                @Override
1481                public Type getRawType() {
1482                        return this.rawType;
1483                }
1484
1485                @Override
1486                public Type[] getActualTypeArguments() {
1487                        return this.typeArguments;
1488                }
1489
1490                @Override
1491                public boolean equals(Object other) {
1492                        if (this == other) {
1493                                return true;
1494                        }
1495                        if (!(other instanceof ParameterizedType)) {
1496                                return false;
1497                        }
1498                        ParameterizedType otherType = (ParameterizedType) other;
1499                        return (otherType.getOwnerType() == null && this.rawType.equals(otherType.getRawType()) &&
1500                                        Arrays.equals(this.typeArguments, otherType.getActualTypeArguments()));
1501                }
1502
1503                @Override
1504                public int hashCode() {
1505                        return (this.rawType.hashCode() * 31 + Arrays.hashCode(this.typeArguments));
1506                }
1507        }
1508
1509
1510        /**
1511         * Internal helper to handle bounds from {@link WildcardType}s.
1512         */
1513        private static class WildcardBounds {
1514
1515                private final Kind kind;
1516
1517                private final ResolvableType[] bounds;
1518
1519                /**
1520                 * Internal constructor to create a new {@link WildcardBounds} instance.
1521                 * @param kind the kind of bounds
1522                 * @param bounds the bounds
1523                 * @see #get(ResolvableType)
1524                 */
1525                public WildcardBounds(Kind kind, ResolvableType[] bounds) {
1526                        this.kind = kind;
1527                        this.bounds = bounds;
1528                }
1529
1530                /**
1531                 * Return {@code true} if this bounds is the same kind as the specified bounds.
1532                 */
1533                public boolean isSameKind(WildcardBounds bounds) {
1534                        return this.kind == bounds.kind;
1535                }
1536
1537                /**
1538                 * Return {@code true} if this bounds is assignable to all the specified types.
1539                 * @param types the types to test against
1540                 * @return {@code true} if this bounds is assignable to all types
1541                 */
1542                public boolean isAssignableFrom(ResolvableType... types) {
1543                        for (ResolvableType bound : this.bounds) {
1544                                for (ResolvableType type : types) {
1545                                        if (!isAssignable(bound, type)) {
1546                                                return false;
1547                                        }
1548                                }
1549                        }
1550                        return true;
1551                }
1552
1553                private boolean isAssignable(ResolvableType source, ResolvableType from) {
1554                        return (this.kind == Kind.UPPER ? source.isAssignableFrom(from) : from.isAssignableFrom(source));
1555                }
1556
1557                /**
1558                 * Return the underlying bounds.
1559                 */
1560                public ResolvableType[] getBounds() {
1561                        return this.bounds;
1562                }
1563
1564                /**
1565                 * Get a {@link WildcardBounds} instance for the specified type, returning
1566                 * {@code null} if the specified type cannot be resolved to a {@link WildcardType}.
1567                 * @param type the source type
1568                 * @return a {@link WildcardBounds} instance or {@code null}
1569                 */
1570                public static WildcardBounds get(ResolvableType type) {
1571                        ResolvableType resolveToWildcard = type;
1572                        while (!(resolveToWildcard.getType() instanceof WildcardType)) {
1573                                if (resolveToWildcard == NONE) {
1574                                        return null;
1575                                }
1576                                resolveToWildcard = resolveToWildcard.resolveType();
1577                        }
1578                        WildcardType wildcardType = (WildcardType) resolveToWildcard.type;
1579                        Kind boundsType = (wildcardType.getLowerBounds().length > 0 ? Kind.LOWER : Kind.UPPER);
1580                        Type[] bounds = (boundsType == Kind.UPPER ? wildcardType.getUpperBounds() : wildcardType.getLowerBounds());
1581                        ResolvableType[] resolvableBounds = new ResolvableType[bounds.length];
1582                        for (int i = 0; i < bounds.length; i++) {
1583                                resolvableBounds[i] = ResolvableType.forType(bounds[i], type.variableResolver);
1584                        }
1585                        return new WildcardBounds(boundsType, resolvableBounds);
1586                }
1587
1588                /**
1589                 * The various kinds of bounds.
1590                 */
1591                enum Kind {UPPER, LOWER}
1592        }
1593
1594}