• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.type;
2 
3 import java.util.*;
4 import java.util.concurrent.atomic.AtomicReference;
5 import java.lang.reflect.*;
6 
7 import com.fasterxml.jackson.core.type.TypeReference;
8 import com.fasterxml.jackson.databind.JavaType;
9 import com.fasterxml.jackson.databind.JsonNode;
10 import com.fasterxml.jackson.databind.util.ArrayBuilders;
11 import com.fasterxml.jackson.databind.util.ClassUtil;
12 import com.fasterxml.jackson.databind.util.LRUMap;
13 
14 /**
15  * Class used for creating concrete {@link JavaType} instances,
16  * given various inputs.
17  *<p>
18  * Instances of this class are accessible using {@link com.fasterxml.jackson.databind.ObjectMapper}
19  * as well as many objects it constructs (like
20 * {@link com.fasterxml.jackson.databind.DeserializationConfig} and
21  * {@link com.fasterxml.jackson.databind.SerializationConfig})),
22  * but usually those objects also
23  * expose convenience methods (<code>constructType</code>).
24  * So, you can do for example:
25  *<pre>
26  *   JavaType stringType = mapper.constructType(String.class);
27  *</pre>
28  * However, more advanced methods are only exposed by factory so that you
29  * may need to use:
30  *<pre>
31  *   JavaType stringCollection = mapper.getTypeFactory().constructCollectionType(List.class, String.class);
32  *</pre>
33  */
34 @SuppressWarnings({"rawtypes" })
35 public class TypeFactory // note: was final in 2.9, removed from 2.10
36     implements java.io.Serializable
37 {
38     private static final long serialVersionUID = 1L;
39 
40     private final static JavaType[] NO_TYPES = new JavaType[0];
41 
42     /**
43      * Globally shared singleton. Not accessed directly; non-core
44      * code should use per-ObjectMapper instance (via configuration objects).
45      * Core Jackson code uses {@link #defaultInstance} for accessing it.
46      */
47     protected final static TypeFactory instance = new TypeFactory();
48 
49     protected final static TypeBindings EMPTY_BINDINGS = TypeBindings.emptyBindings();
50 
51     /*
52     /**********************************************************
53     /* Constants for "well-known" classes
54     /**********************************************************
55      */
56 
57     // // // Let's assume that a small set of core primitive/basic types
58     // // // will not be modified, and can be freely shared to streamline
59     // // // parts of processing
60 
61     private final static Class<?> CLS_STRING = String.class;
62     private final static Class<?> CLS_OBJECT = Object.class;
63 
64     private final static Class<?> CLS_COMPARABLE = Comparable.class;
65     private final static Class<?> CLS_CLASS = Class.class;
66     private final static Class<?> CLS_ENUM = Enum.class;
67     private final static Class<?> CLS_JSON_NODE = JsonNode.class; // since 2.10
68 
69     private final static Class<?> CLS_BOOL = Boolean.TYPE;
70     private final static Class<?> CLS_INT = Integer.TYPE;
71     private final static Class<?> CLS_LONG = Long.TYPE;
72 
73     /*
74     /**********************************************************
75     /* Cached pre-constructed JavaType instances
76     /**********************************************************
77      */
78 
79     // note: these are primitive, hence no super types
80     protected final static SimpleType CORE_TYPE_BOOL = new SimpleType(CLS_BOOL);
81     protected final static SimpleType CORE_TYPE_INT = new SimpleType(CLS_INT);
82     protected final static SimpleType CORE_TYPE_LONG = new SimpleType(CLS_LONG);
83 
84     // and as to String... well, for now, ignore its super types
85     protected final static SimpleType CORE_TYPE_STRING = new SimpleType(CLS_STRING);
86 
87     // @since 2.7
88     protected final static SimpleType CORE_TYPE_OBJECT = new SimpleType(CLS_OBJECT);
89 
90     /**
91      * Cache {@link Comparable} because it is both parameteric (relatively costly to
92      * resolve) and mostly useless (no special handling), better handle directly
93      *
94      * @since 2.7
95      */
96     protected final static SimpleType CORE_TYPE_COMPARABLE = new SimpleType(CLS_COMPARABLE);
97 
98     /**
99      * Cache {@link Enum} because it is parametric AND self-referential (costly to
100      * resolve) and useless in itself (no special handling).
101      *
102      * @since 2.7
103      */
104     protected final static SimpleType CORE_TYPE_ENUM = new SimpleType(CLS_ENUM);
105 
106     /**
107      * Cache {@link Class} because it is nominally parametric, but has no really
108      * useful information.
109      *
110      * @since 2.7
111      */
112     protected final static SimpleType CORE_TYPE_CLASS = new SimpleType(CLS_CLASS);
113 
114     /**
115      * Cache {@link JsonNode} because it is no critical path of simple tree model
116      * reading and does not have things to override
117      *
118      * @since 2.10
119      */
120     protected final static SimpleType CORE_TYPE_JSON_NODE = new SimpleType(CLS_JSON_NODE);
121 
122     /**
123      * Since type resolution can be expensive (specifically when resolving
124      * actual generic types), we will use small cache to avoid repetitive
125      * resolution of core types
126      */
127     protected final LRUMap<Object,JavaType> _typeCache;
128 
129     /*
130     /**********************************************************
131     /* Configuration
132     /**********************************************************
133      */
134 
135     /**
136      * Registered {@link TypeModifier}s: objects that can change details
137      * of {@link JavaType} instances factory constructs.
138      */
139     protected final TypeModifier[] _modifiers;
140 
141     protected final TypeParser _parser;
142 
143     /**
144      * ClassLoader used by this factory [databind#624].
145      */
146     protected final ClassLoader _classLoader;
147 
148     /*
149     /**********************************************************
150     /* Life-cycle
151     /**********************************************************
152      */
153 
TypeFactory()154     private TypeFactory() {
155         this(null);
156     }
157 
158     /**
159      * @since 2.8
160      */
TypeFactory(LRUMap<Object,JavaType> typeCache)161     protected TypeFactory(LRUMap<Object,JavaType> typeCache) {
162         if (typeCache == null) {
163             typeCache = new LRUMap<Object,JavaType>(16, 200);
164         }
165         _typeCache = typeCache;
166         _parser = new TypeParser(this);
167         _modifiers = null;
168         _classLoader = null;
169     }
170 
TypeFactory(LRUMap<Object,JavaType> typeCache, TypeParser p, TypeModifier[] mods, ClassLoader classLoader)171     protected TypeFactory(LRUMap<Object,JavaType> typeCache, TypeParser p,
172             TypeModifier[] mods, ClassLoader classLoader)
173     {
174         if (typeCache == null) {
175             typeCache = new LRUMap<Object,JavaType>(16, 200);
176         }
177         _typeCache = typeCache;
178         // As per [databind#894] must ensure we have back-linkage from TypeFactory:
179         _parser = p.withFactory(this);
180         _modifiers = mods;
181         _classLoader = classLoader;
182     }
183 
184     /**
185      * "Mutant factory" method which will construct a new instance with specified
186      * {@link TypeModifier} added as the first modifier to call (in case there
187      * are multiple registered).
188      */
withModifier(TypeModifier mod)189     public TypeFactory withModifier(TypeModifier mod)
190     {
191         LRUMap<Object,JavaType> typeCache = _typeCache;
192         TypeModifier[] mods;
193         if (mod == null) { // mostly for unit tests
194             mods = null;
195             // 30-Jun-2016, tatu: for some reason expected semantics are to clear cache
196             //    in this case; can't recall why, but keeping the same
197             typeCache = null;
198         } else if (_modifiers == null) {
199             mods = new TypeModifier[] { mod };
200             // 29-Jul-2019, tatu: Actually I think we better clear cache in this case
201             //    as well to ensure no leakage occurs (see [databind#2395])
202             typeCache = null;
203         } else {
204             // but may keep existing cache otherwise
205             mods = ArrayBuilders.insertInListNoDup(_modifiers, mod);
206         }
207         return new TypeFactory(typeCache, _parser, mods, _classLoader);
208     }
209 
210     /**
211      * "Mutant factory" method which will construct a new instance with specified
212      * {@link ClassLoader} to use by {@link #findClass}.
213      */
withClassLoader(ClassLoader classLoader)214     public TypeFactory withClassLoader(ClassLoader classLoader) {
215         return new TypeFactory(_typeCache, _parser, _modifiers, classLoader);
216     }
217 
218     /**
219      * Mutant factory method that will construct new {@link TypeFactory} with
220      * identical settings except for different cache; most likely one with
221      * bigger maximum size.
222      *
223      * @since 2.8
224      */
withCache(LRUMap<Object,JavaType> cache)225     public TypeFactory withCache(LRUMap<Object,JavaType> cache)  {
226         return new TypeFactory(cache, _parser, _modifiers, _classLoader);
227     }
228 
229     /**
230      * Method used to access the globally shared instance, which has
231      * no custom configuration. Used by <code>ObjectMapper</code> to
232      * get the default factory when constructed.
233      */
defaultInstance()234     public static TypeFactory defaultInstance() { return instance; }
235 
236     /**
237      * Method that will clear up any cached type definitions that may
238      * be cached by this {@link TypeFactory} instance.
239      * This method should not be commonly used, that is, only use it
240      * if you know there is a problem with retention of type definitions;
241      * the most likely (and currently only known) problem is retention
242      * of {@link Class} instances via {@link JavaType} reference.
243      *
244      * @since 2.4.1
245      */
clearCache()246     public void clearCache() {
247         _typeCache.clear();
248     }
249 
getClassLoader()250     public ClassLoader getClassLoader() {
251         return _classLoader;
252     }
253 
254     /*
255     /**********************************************************
256     /* Static methods for non-instance-specific functionality
257     /**********************************************************
258      */
259 
260     /**
261      * Method for constructing a marker type that indicates missing generic
262      * type information, which is handled same as simple type for
263      * <code>java.lang.Object</code>.
264      */
unknownType()265     public static JavaType unknownType() {
266         return defaultInstance()._unknownType();
267     }
268 
269     /**
270      * Static helper method that can be called to figure out type-erased
271      * call for given JDK type. It can be called statically since type resolution
272      * process can never change actual type-erased class; thereby static
273      * default instance is used for determination.
274      */
rawClass(Type t)275     public static Class<?> rawClass(Type t) {
276         if (t instanceof Class<?>) {
277             return (Class<?>) t;
278         }
279         // Should be able to optimize bit more in future...
280         return defaultInstance().constructType(t).getRawClass();
281     }
282 
283     /*
284     /**********************************************************
285     /* Low-level helper methods
286     /**********************************************************
287      */
288 
289     /**
290      * Low-level lookup method moved from {@link com.fasterxml.jackson.databind.util.ClassUtil},
291      * to allow for overriding of lookup functionality in environments like OSGi.
292      *
293      * @since 2.6
294      */
findClass(String className)295     public Class<?> findClass(String className) throws ClassNotFoundException
296     {
297         if (className.indexOf('.') < 0) {
298             Class<?> prim = _findPrimitive(className);
299             if (prim != null) {
300                 return prim;
301             }
302         }
303         // Two-phase lookup: first using context ClassLoader; then default
304         Throwable prob = null;
305         ClassLoader loader = this.getClassLoader();
306         if (loader == null) {
307             loader = Thread.currentThread().getContextClassLoader();
308         }
309         if (loader != null) {
310             try {
311                 return classForName(className, true, loader);
312             } catch (Exception e) {
313                 prob = ClassUtil.getRootCause(e);
314             }
315         }
316         try {
317             return classForName(className);
318         } catch (Exception e) {
319             if (prob == null) {
320                 prob = ClassUtil.getRootCause(e);
321             }
322         }
323         ClassUtil.throwIfRTE(prob);
324         throw new ClassNotFoundException(prob.getMessage(), prob);
325     }
326 
classForName(String name, boolean initialize, ClassLoader loader)327     protected Class<?> classForName(String name, boolean initialize,
328             ClassLoader loader) throws ClassNotFoundException {
329         return Class.forName(name, true, loader);
330     }
331 
classForName(String name)332     protected Class<?> classForName(String name) throws ClassNotFoundException {
333         return Class.forName(name);
334     }
335 
_findPrimitive(String className)336     protected Class<?> _findPrimitive(String className)
337     {
338         if ("int".equals(className)) return Integer.TYPE;
339         if ("long".equals(className)) return Long.TYPE;
340         if ("float".equals(className)) return Float.TYPE;
341         if ("double".equals(className)) return Double.TYPE;
342         if ("boolean".equals(className)) return Boolean.TYPE;
343         if ("byte".equals(className)) return Byte.TYPE;
344         if ("char".equals(className)) return Character.TYPE;
345         if ("short".equals(className)) return Short.TYPE;
346         if ("void".equals(className)) return Void.TYPE;
347         return null;
348     }
349 
350     /*
351     /**********************************************************
352     /* Type conversion, parameterization resolution methods
353     /**********************************************************
354      */
355 
356     /**
357      * Factory method for creating a subtype of given base type, as defined
358      * by specified subclass; but retaining generic type information if any.
359      * Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
360      * from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
361      * as subclass.
362      * Short-cut for:
363      *<pre>
364      * constructSpecializedType(baseType, subclass, class);
365      *</pre>
366      * that is, will use "strict" compatibility checking, usually used for
367      * deserialization purposes (but often not for serialization).
368      */
constructSpecializedType(JavaType baseType, Class<?> subclass)369     public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass)
370         throws IllegalArgumentException
371     {
372         return constructSpecializedType(baseType, subclass, false);
373     }
374 
375     /**
376      * Factory method for creating a subtype of given base type, as defined
377      * by specified subclass; but retaining generic type information if any.
378      * Can be used, for example, to get equivalent of "HashMap&lt;String,Integer&gt;"
379      * from "Map&lt;String,Integer&gt;" by giving <code>HashMap.class</code>
380      * as subclass.
381      *
382      * @param baseType Declared base type with resolved type parameters
383      * @param subclass Runtime subtype to use for resolving
384      * @param relaxedCompatibilityCheck Whether checking for type-assignment compatibility
385      *    should be "relaxed" ({@code true}) or "strict" ({@code false}): typically
386      *    serialization uses relaxed, deserialization strict checking.
387      *
388      * @return Resolved sub-type
389      *
390      * @since 2.11
391      */
constructSpecializedType(JavaType baseType, Class<?> subclass, boolean relaxedCompatibilityCheck)392     public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass,
393             boolean relaxedCompatibilityCheck)
394         throws IllegalArgumentException
395     {
396         // simple optimization to avoid costly introspection if type-erased type does NOT differ
397         final Class<?> rawBase = baseType.getRawClass();
398         if (rawBase == subclass) {
399             return baseType;
400         }
401         JavaType newType;
402 
403         // also: if we start from untyped, not much to save
404         do { // bogus loop to be able to break
405             if (rawBase == Object.class) {
406                 newType = _fromClass(null, subclass, EMPTY_BINDINGS);
407                 break;
408             }
409             if (!rawBase.isAssignableFrom(subclass)) {
410                 throw new IllegalArgumentException(String.format("Class %s not subtype of %s",
411                         ClassUtil.nameOf(subclass), ClassUtil.getTypeDescription(baseType)
412                 ));
413             }
414             // A few special cases where we can simplify handling:
415 
416             // (1) A small set of "well-known" List/Map subtypes where can take a short-cut
417             if (baseType.isContainerType()) {
418                 if (baseType.isMapLikeType()) {
419                     if ((subclass == HashMap.class)
420                             || (subclass == LinkedHashMap.class)
421                             || (subclass == EnumMap.class)
422                             || (subclass == TreeMap.class)) {
423                         newType = _fromClass(null, subclass,
424                                 TypeBindings.create(subclass, baseType.getKeyType(), baseType.getContentType()));
425                         break;
426                     }
427                 } else if (baseType.isCollectionLikeType()) {
428                     if ((subclass == ArrayList.class)
429                             || (subclass == LinkedList.class)
430                             || (subclass == HashSet.class)
431                             || (subclass == TreeSet.class)) {
432                         newType = _fromClass(null, subclass,
433                                 TypeBindings.create(subclass, baseType.getContentType()));
434                         break;
435                     }
436                     // 29-Oct-2015, tatu: One further shortcut: there are variants of `EnumSet`,
437                     //    but they are impl details and we basically do not care...
438                     if (rawBase == EnumSet.class) {
439                         return baseType;
440                     }
441                 }
442             }
443             // (2) Original target type has no generics -- just resolve subtype
444             if (baseType.getBindings().isEmpty()) {
445                 newType = _fromClass(null, subclass, EMPTY_BINDINGS);
446                 break;
447             }
448 
449             // (3) Sub-class does not take type parameters -- just resolve subtype
450             int typeParamCount = subclass.getTypeParameters().length;
451             if (typeParamCount == 0) {
452                 newType = _fromClass(null, subclass, EMPTY_BINDINGS);
453                 break;
454             }
455             // (4) If all else fails, do the full traversal using placeholders
456             TypeBindings tb = _bindingsForSubtype(baseType, typeParamCount,
457                     subclass, relaxedCompatibilityCheck);
458             newType = _fromClass(null, subclass, tb);
459 
460         } while (false);
461 
462         // 25-Sep-2016, tatu: As per [databind#1384] also need to ensure handlers get
463         //   copied as well
464         newType = newType.withHandlersFrom(baseType);
465         return newType;
466     }
467 
_bindingsForSubtype(JavaType baseType, int typeParamCount, Class<?> subclass, boolean relaxedCompatibilityCheck)468     private TypeBindings _bindingsForSubtype(JavaType baseType, int typeParamCount,
469             Class<?> subclass, boolean relaxedCompatibilityCheck)
470     {
471         PlaceholderForType[] placeholders = new PlaceholderForType[typeParamCount];
472         for (int i = 0; i < typeParamCount; ++i) {
473             placeholders[i] = new PlaceholderForType(i);
474         }
475         TypeBindings b = TypeBindings.create(subclass, placeholders);
476         // First: pseudo-resolve to get placeholders in place:
477         JavaType tmpSub = _fromClass(null, subclass, b);
478         // Then find super-type
479         JavaType baseWithPlaceholders = tmpSub.findSuperType(baseType.getRawClass());
480         if (baseWithPlaceholders == null) { // should be found but...
481             throw new IllegalArgumentException(String.format(
482                     "Internal error: unable to locate supertype (%s) from resolved subtype %s", baseType.getRawClass().getName(),
483                     subclass.getName()));
484         }
485         // and traverse type hierarchies to both verify and to resolve placeholders
486         String error = _resolveTypePlaceholders(baseType, baseWithPlaceholders);
487         if (error != null) {
488             // 28-Mar-2020, tatu: As per [databind#2632], need to ignore the issue in
489             //   some cases. For now, just fully ignore; may need to refine in future
490             if (!relaxedCompatibilityCheck) {
491                 throw new IllegalArgumentException("Failed to specialize base type "+baseType.toCanonical()+" as "
492                         +subclass.getName()+", problem: "+error);
493             }
494         }
495 
496         final JavaType[] typeParams = new JavaType[typeParamCount];
497         for (int i = 0; i < typeParamCount; ++i) {
498             JavaType t = placeholders[i].actualType();
499             // 18-Oct-2017, tatu: Looks like sometimes we have incomplete bindings (even if not
500             //     common, it is possible if subtype is type-erased class with added type
501             //     variable -- see test(s) with "bogus" type(s)).
502             if (t == null) {
503                 t = unknownType();
504             }
505             typeParams[i] = t;
506         }
507         return TypeBindings.create(subclass, typeParams);
508     }
509 
_resolveTypePlaceholders(JavaType sourceType, JavaType actualType)510     private String _resolveTypePlaceholders(JavaType sourceType, JavaType actualType)
511         throws IllegalArgumentException
512     {
513         List<JavaType> expectedTypes = sourceType.getBindings().getTypeParameters();
514         List<JavaType> actualTypes = actualType.getBindings().getTypeParameters();
515 
516         final int actCount = actualTypes.size();
517 
518         for (int i = 0, expCount = expectedTypes.size(); i < expCount; ++i) {
519             JavaType exp = expectedTypes.get(i);
520             JavaType act = (i < actCount) ? actualTypes.get(i) : unknownType();
521 
522             if (!_verifyAndResolvePlaceholders(exp, act)) {
523                 // 14-May-2018, tatu: As per [databind#2034] it seems we better relax assignment
524                 //   rules further -- at least likely "raw" (untyped, non-generic) base should probably
525                 //   allow specialization.
526                 if (exp.hasRawClass(Object.class)) {
527                     continue;
528                 }
529                 // 19-Apr-2018, tatu: Hack for [databind#1964] -- allow type demotion
530                 //    for `java.util.Map` key type if (and only if) target type is
531                 //    `java.lang.Object`
532                 // 19-Aug-2019, tatu: Further, allow for all Map-like types, with assumption
533                 //    first argument would be key; initially just because Scala Maps have
534                 //    some issues (see [databind#2422])
535                 if (i == 0) {
536                     if (sourceType.isMapLikeType()
537                             && act.hasRawClass(Object.class)) {
538                         continue;
539                     }
540                 }
541                 // 19-Nov-2018, tatu: To solve [databind#2155], let's allow type-compatible
542                 //   assignment for interfaces at least...
543                 if (exp.isInterface()) {
544                     if (exp.isTypeOrSuperTypeOf(act.getRawClass())) {
545                         continue;
546                     }
547                 }
548                 return String.format("Type parameter #%d/%d differs; can not specialize %s with %s",
549                         (i+1), expCount, exp.toCanonical(), act.toCanonical());
550             }
551         }
552         return null;
553     }
554 
_verifyAndResolvePlaceholders(JavaType exp, JavaType act)555     private boolean _verifyAndResolvePlaceholders(JavaType exp, JavaType act)
556     {
557         // See if we have an actual type placeholder to resolve; if yes, replace
558         if (act instanceof PlaceholderForType) {
559             ((PlaceholderForType) act).actualType(exp);
560             return true;
561         }
562         // if not, try to verify compatibility. But note that we can not
563         // use simple equality as we need to resolve recursively
564         if (exp.getRawClass() != act.getRawClass()) {
565             return false;
566         }
567         // But we can check type parameters "blindly"
568         List<JavaType> expectedTypes = exp.getBindings().getTypeParameters();
569         List<JavaType> actualTypes = act.getBindings().getTypeParameters();
570         for (int i = 0, len = expectedTypes.size(); i < len; ++i) {
571             JavaType exp2 = expectedTypes.get(i);
572             JavaType act2 = actualTypes.get(i);
573             if (!_verifyAndResolvePlaceholders(exp2, act2)) {
574                 return false;
575             }
576         }
577         return true;
578     }
579 
580     /**
581      * Method similar to {@link #constructSpecializedType}, but that creates a
582      * less-specific type of given type. Usually this is as simple as simply
583      * finding super-type with type erasure of <code>superClass</code>, but
584      * there may be need for some additional work-arounds.
585      *
586      * @param superClass
587      *
588      * @since 2.7
589      */
constructGeneralizedType(JavaType baseType, Class<?> superClass)590     public JavaType constructGeneralizedType(JavaType baseType, Class<?> superClass)
591     {
592         // simple optimization to avoid costly introspection if type-erased type does NOT differ
593         final Class<?> rawBase = baseType.getRawClass();
594         if (rawBase == superClass) {
595             return baseType;
596         }
597         JavaType superType = baseType.findSuperType(superClass);
598         if (superType == null) {
599             // Most likely, caller did not verify sub/super-type relationship
600             if (!superClass.isAssignableFrom(rawBase)) {
601                 throw new IllegalArgumentException(String.format(
602                         "Class %s not a super-type of %s", superClass.getName(), baseType));
603             }
604             // 01-Nov-2015, tatu: Should never happen, but ch
605             throw new IllegalArgumentException(String.format(
606                     "Internal error: class %s not included as super-type for %s",
607                     superClass.getName(), baseType));
608         }
609         return superType;
610     }
611 
612     /**
613      * Factory method for constructing a {@link JavaType} out of its canonical
614      * representation (see {@link JavaType#toCanonical()}).
615      *
616      * @param canonical Canonical string representation of a type
617      *
618      * @throws IllegalArgumentException If canonical representation is malformed,
619      *   or class that type represents (including its generic parameters) is
620      *   not found
621      */
constructFromCanonical(String canonical)622     public JavaType constructFromCanonical(String canonical) throws IllegalArgumentException
623     {
624         return _parser.parse(canonical);
625     }
626 
627     /**
628      * Method that is to figure out actual type parameters that given
629      * class binds to generic types defined by given (generic)
630      * interface or class.
631      * This could mean, for example, trying to figure out
632      * key and value types for Map implementations.
633      *
634      * @param type Sub-type (leaf type) that implements <code>expType</code>
635      */
findTypeParameters(JavaType type, Class<?> expType)636     public JavaType[] findTypeParameters(JavaType type, Class<?> expType)
637     {
638         JavaType match = type.findSuperType(expType);
639         if (match == null) {
640             return NO_TYPES;
641         }
642         return match.getBindings().typeParameterArray();
643     }
644 
645     /**
646      * @deprecated Since 2.7 resolve raw type first, then find type parameters
647      */
648     @Deprecated // since 2.7
findTypeParameters(Class<?> clz, Class<?> expType, TypeBindings bindings)649     public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType, TypeBindings bindings) {
650         return findTypeParameters(constructType(clz, bindings), expType);
651     }
652 
653     /**
654      * @deprecated Since 2.7 resolve raw type first, then find type parameters
655      */
656     @Deprecated // since 2.7
findTypeParameters(Class<?> clz, Class<?> expType)657     public JavaType[] findTypeParameters(Class<?> clz, Class<?> expType) {
658         return findTypeParameters(constructType(clz), expType);
659     }
660 
661     /**
662      * Method that can be called to figure out more specific of two
663      * types (if they are related; that is, one implements or extends the
664      * other); or if not related, return the primary type.
665      *
666      * @param type1 Primary type to consider
667      * @param type2 Secondary type to consider
668      *
669      * @since 2.2
670      */
moreSpecificType(JavaType type1, JavaType type2)671     public JavaType moreSpecificType(JavaType type1, JavaType type2)
672     {
673         if (type1 == null) {
674             return type2;
675         }
676         if (type2 == null) {
677             return type1;
678         }
679         Class<?> raw1 = type1.getRawClass();
680         Class<?> raw2 = type2.getRawClass();
681         if (raw1 == raw2) {
682             return type1;
683         }
684         // TODO: maybe try sub-classing, to retain generic types?
685         if (raw1.isAssignableFrom(raw2)) {
686             return type2;
687         }
688         return type1;
689     }
690 
691     /*
692     /**********************************************************
693     /* Public factory methods
694     /**********************************************************
695      */
696 
constructType(Type type)697     public JavaType constructType(Type type) {
698         return _fromAny(null, type, EMPTY_BINDINGS);
699     }
700 
701     /**
702      * Method that you very likely should NOT be using -- you need to know a lot
703      * about internal details of {@link TypeBindings} and even then it will probably
704      * not do what you want.
705      * Usually you would instead want to call one of {@code constructXxxType()}
706      * methods (where {@code Xxx} would be "Array", "Collection[Like]", "Map[Like]"
707      * or "Parametric").
708      */
constructType(Type type, TypeBindings bindings)709     public JavaType constructType(Type type, TypeBindings bindings) {
710         // 15-Jun-2020, tatu: To resolve (parts of) [databind#2796], need to
711         //    call _fromClass() directly if we get `Class` argument
712         if (type instanceof Class<?>) {
713             JavaType resultType = _fromClass(null, (Class<?>) type, bindings);
714             return _applyModifiers(type, resultType);
715         }
716         return _fromAny(null, type, bindings);
717     }
718 
constructType(TypeReference<?> typeRef)719     public JavaType constructType(TypeReference<?> typeRef)
720     {
721         // 19-Oct-2015, tatu: Simpler variant like so should work
722         return _fromAny(null, typeRef.getType(), EMPTY_BINDINGS);
723 
724         // but if not, due to funky sub-classing, type variables, what follows
725         // is a more complete processing a la Java ClassMate.
726 
727         /*
728         final Class<?> refdRawType = typeRef.getClass();
729         JavaType type = _fromClass(null, refdRawType, EMPTY_BINDINGS);
730         JavaType genType = type.findSuperType(TypeReference.class);
731         if (genType == null) { // sanity check; shouldn't occur
732             throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")");
733         }
734         TypeBindings b = genType.getBindings();
735         JavaType[] params = b.typeParameterArray();
736         if (params.length == 0) {
737             throw new IllegalArgumentException("Unparameterized GenericType instance ("+refdRawType.getName()+")");
738         }
739         return params[0];
740         */
741     }
742 
743     /**
744      * @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1)
745      */
746     @Deprecated
constructType(Type type, Class<?> contextClass)747     public JavaType constructType(Type type, Class<?> contextClass) {
748         JavaType contextType = (contextClass == null) ? null : constructType(contextClass);
749         return constructType(type, contextType);
750     }
751 
752     /**
753      * @deprecated Since 2.7 (accidentally removed in 2.7.0; added back in 2.7.1)
754      */
755     @Deprecated
constructType(Type type, JavaType contextType)756     public JavaType constructType(Type type, JavaType contextType) {
757         TypeBindings bindings;
758         if (contextType == null) {
759             bindings = EMPTY_BINDINGS;
760         } else {
761             bindings = contextType.getBindings();
762             // 16-Nov-2016, tatu: Unfortunately as per [databind#1456] this can't
763             //   be made to work for some cases used to work (even if accidentally);
764             //   however, we can try a simple heuristic to increase chances of
765             //   compatibility from 2.6 code
766             if (type.getClass() != Class.class) {
767                 // Ok: so, ideally we would test super-interfaces if necessary;
768                 // but let's assume most if not all cases are for classes.
769                 while (bindings.isEmpty()) {
770                     contextType = contextType.getSuperClass();
771                     if (contextType == null) {
772                         break;
773                     }
774                     bindings = contextType.getBindings();
775                 }
776             }
777         }
778         return _fromAny(null, type, bindings);
779     }
780 
781     /*
782     /**********************************************************
783     /* Direct factory methods
784     /**********************************************************
785      */
786 
787     /**
788      * Method for constructing an {@link ArrayType}.
789      *<p>
790      * NOTE: type modifiers are NOT called on array type itself; but are called
791      * for element type (and other contained types)
792      */
constructArrayType(Class<?> elementType)793     public ArrayType constructArrayType(Class<?> elementType) {
794         return ArrayType.construct(_fromAny(null, elementType, null), null);
795     }
796 
797     /**
798      * Method for constructing an {@link ArrayType}.
799      *<p>
800      * NOTE: type modifiers are NOT called on array type itself; but are called
801      * for contained types.
802      */
constructArrayType(JavaType elementType)803     public ArrayType constructArrayType(JavaType elementType) {
804         return ArrayType.construct(elementType, null);
805     }
806 
807     /**
808      * Method for constructing a {@link CollectionType}.
809      *<p>
810      * NOTE: type modifiers are NOT called on Collection type itself; but are called
811      * for contained types.
812      */
constructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass)813     public CollectionType constructCollectionType(Class<? extends Collection> collectionClass,
814             Class<?> elementClass) {
815         return constructCollectionType(collectionClass,
816                 _fromClass(null, elementClass, EMPTY_BINDINGS));
817     }
818 
819     /**
820      * Method for constructing a {@link CollectionType}.
821      *<p>
822      * NOTE: type modifiers are NOT called on Collection type itself; but are called
823      * for contained types.
824      */
constructCollectionType(Class<? extends Collection> collectionClass, JavaType elementType)825     public CollectionType constructCollectionType(Class<? extends Collection> collectionClass,
826             JavaType elementType)
827     {
828         TypeBindings bindings = TypeBindings.createIfNeeded(collectionClass, elementType);
829         CollectionType result = (CollectionType) _fromClass(null, collectionClass, bindings);
830         // 17-May-2017, tatu: As per [databind#1415], we better verify bound values if (but only if)
831         //    type being resolved was non-generic (i.e.element type was ignored)
832         if (bindings.isEmpty() && (elementType != null)) {
833             JavaType t = result.findSuperType(Collection.class);
834             JavaType realET = t.getContentType();
835             if (!realET.equals(elementType)) {
836                 throw new IllegalArgumentException(String.format(
837                         "Non-generic Collection class %s did not resolve to something with element type %s but %s ",
838                         ClassUtil.nameOf(collectionClass), elementType, realET));
839             }
840         }
841         return result;
842     }
843 
844     /**
845      * Method for constructing a {@link CollectionLikeType}.
846      *<p>
847      * NOTE: type modifiers are NOT called on constructed type itself; but are called
848      * for contained types.
849      */
constructCollectionLikeType(Class<?> collectionClass, Class<?> elementClass)850     public CollectionLikeType constructCollectionLikeType(Class<?> collectionClass, Class<?> elementClass) {
851         return constructCollectionLikeType(collectionClass,
852                 _fromClass(null, elementClass, EMPTY_BINDINGS));
853     }
854 
855     /**
856      * Method for constructing a {@link CollectionLikeType}.
857      *<p>
858      * NOTE: type modifiers are NOT called on constructed type itself; but are called
859      * for contained types.
860      */
constructCollectionLikeType(Class<?> collectionClass, JavaType elementType)861     public CollectionLikeType constructCollectionLikeType(Class<?> collectionClass, JavaType elementType) {
862         JavaType type = _fromClass(null, collectionClass,
863                 TypeBindings.createIfNeeded(collectionClass, elementType));
864         if (type instanceof CollectionLikeType) {
865             return (CollectionLikeType) type;
866         }
867         return CollectionLikeType.upgradeFrom(type, elementType);
868     }
869 
870     /**
871      * Method for constructing a {@link MapType} instance
872      *<p>
873      * NOTE: type modifiers are NOT called on constructed type itself; but are called
874      * for contained types.
875      */
constructMapType(Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass)876     public MapType constructMapType(Class<? extends Map> mapClass,
877             Class<?> keyClass, Class<?> valueClass) {
878         JavaType kt, vt;
879         if (mapClass == Properties.class) {
880             kt = vt = CORE_TYPE_STRING;
881         } else {
882             kt = _fromClass(null, keyClass, EMPTY_BINDINGS);
883             vt = _fromClass(null, valueClass, EMPTY_BINDINGS);
884         }
885         return constructMapType(mapClass, kt, vt);
886     }
887 
888     /**
889      * Method for constructing a {@link MapType} instance
890      *<p>
891      * NOTE: type modifiers are NOT called on constructed type itself.
892      */
constructMapType(Class<? extends Map> mapClass, JavaType keyType, JavaType valueType)893     public MapType constructMapType(Class<? extends Map> mapClass, JavaType keyType, JavaType valueType) {
894         TypeBindings bindings = TypeBindings.createIfNeeded(mapClass, new JavaType[] { keyType, valueType });
895         MapType result = (MapType) _fromClass(null, mapClass, bindings);
896         // 17-May-2017, tatu: As per [databind#1415], we better verify bound values if (but only if)
897         //    type being resolved was non-generic (i.e.element type was ignored)
898         if (bindings.isEmpty()) {
899             JavaType t = result.findSuperType(Map.class);
900             JavaType realKT = t.getKeyType();
901             if (!realKT.equals(keyType)) {
902                 throw new IllegalArgumentException(String.format(
903                         "Non-generic Map class %s did not resolve to something with key type %s but %s ",
904                         ClassUtil.nameOf(mapClass), keyType, realKT));
905             }
906             JavaType realVT = t.getContentType();
907             if (!realVT.equals(valueType)) {
908                 throw new IllegalArgumentException(String.format(
909                         "Non-generic Map class %s did not resolve to something with value type %s but %s ",
910                         ClassUtil.nameOf(mapClass), valueType, realVT));
911             }
912         }
913         return result;
914     }
915 
916     /**
917      * Method for constructing a {@link MapLikeType} instance
918      *<p>
919      * NOTE: type modifiers are NOT called on constructed type itself; but are called
920      * for contained types.
921      */
constructMapLikeType(Class<?> mapClass, Class<?> keyClass, Class<?> valueClass)922     public MapLikeType constructMapLikeType(Class<?> mapClass, Class<?> keyClass, Class<?> valueClass) {
923         return constructMapLikeType(mapClass,
924                 _fromClass(null, keyClass, EMPTY_BINDINGS),
925                 _fromClass(null, valueClass, EMPTY_BINDINGS));
926     }
927 
928     /**
929      * Method for constructing a {@link MapLikeType} instance
930      *<p>
931      * NOTE: type modifiers are NOT called on constructed type itself.
932      */
constructMapLikeType(Class<?> mapClass, JavaType keyType, JavaType valueType)933     public MapLikeType constructMapLikeType(Class<?> mapClass, JavaType keyType, JavaType valueType) {
934         // 19-Oct-2015, tatu: Allow case of no-type-variables, since it seems likely to be
935         //    a valid use case here
936         JavaType type = _fromClass(null, mapClass,
937                 TypeBindings.createIfNeeded(mapClass, new JavaType[] { keyType, valueType }));
938         if (type instanceof MapLikeType) {
939             return (MapLikeType) type;
940         }
941         return MapLikeType.upgradeFrom(type, keyType, valueType);
942     }
943 
944     /**
945      * Method for constructing a type instance with specified parameterization.
946      *<p>
947      * NOTE: type modifiers are NOT called on constructed type itself.
948      */
constructSimpleType(Class<?> rawType, JavaType[] parameterTypes)949     public JavaType constructSimpleType(Class<?> rawType, JavaType[] parameterTypes) {
950         return _fromClass(null, rawType, TypeBindings.create(rawType, parameterTypes));
951     }
952 
953     /**
954      * Method for constructing a type instance with specified parameterization.
955      *
956      * @since 2.6
957      *
958      * @deprecated Since 2.7
959      */
960     @Deprecated
constructSimpleType(Class<?> rawType, Class<?> parameterTarget, JavaType[] parameterTypes)961     public JavaType constructSimpleType(Class<?> rawType, Class<?> parameterTarget,
962             JavaType[] parameterTypes)
963     {
964         return constructSimpleType(rawType, parameterTypes);
965     }
966 
967     /**
968      * Method for constructing a {@link ReferenceType} instance with given type parameter
969      * (type MUST take one and only one type parameter)
970      *<p>
971      * NOTE: type modifiers are NOT called on constructed type itself.
972      *
973      * @since 2.6
974      */
constructReferenceType(Class<?> rawType, JavaType referredType)975     public JavaType constructReferenceType(Class<?> rawType, JavaType referredType)
976     {
977         return ReferenceType.construct(rawType,
978                 TypeBindings.create(rawType, referredType), // [databind#2091]
979                 null, null, // or super-class, interfaces?
980                 referredType);
981     }
982 
983     /**
984      * Method that use by core Databind functionality, and that should NOT be called
985      * by application code outside databind package.
986      *<p>
987      * Unchecked here not only means that no checks are made as to whether given class
988      * might be non-simple type (like {@link CollectionType}) but also that most of supertype
989      * information is not gathered. This means that unless called on primitive types or
990      * {@link java.lang.String}, results are probably not what you want to use.
991      *
992      * @deprecated Since 2.8, to indicate users should never call this method.
993      */
994     @Deprecated // since 2.8
uncheckedSimpleType(Class<?> cls)995     public JavaType uncheckedSimpleType(Class<?> cls) {
996         // 18-Oct-2015, tatu: Not sure how much problem missing super-type info is here
997         return _constructSimple(cls, EMPTY_BINDINGS, null, null);
998     }
999 
1000     /**
1001      * Factory method for constructing {@link JavaType} that
1002      * represents a parameterized type. For example, to represent
1003      * type {@code List<Set<Integer>>}, you could
1004      * call
1005      *<pre>
1006      *  JavaType inner = TypeFactory.constructParametricType(Set.class, Set.class, Integer.class);
1007      *  return TypeFactory.constructParametricType(ArrayList.class, List.class, inner);
1008      *</pre>
1009      *<p>
1010      * The reason for first two arguments to be separate is that parameterization may
1011      * apply to a super-type. For example, if generic type was instead to be
1012      * constructed for {@code ArrayList<Integer>}, the usual call would be:
1013      *<pre>
1014      *  TypeFactory.constructParametricType(ArrayList.class, List.class, Integer.class);
1015      *</pre>
1016      * since parameterization is applied to {@link java.util.List}.
1017      * In most cases distinction does not matter, but there are types where it does;
1018      * one such example is parameterization of types that implement {@link java.util.Iterator}.
1019      *<p>
1020      * NOTE: type modifiers are NOT called on constructed type.
1021      *
1022      * @param parametrized Actual full type
1023      * @param parameterClasses Type parameters to apply
1024      *
1025      * @since 2.5 NOTE: was briefly deprecated for 2.6
1026      */
constructParametricType(Class<?> parametrized, Class<?>... parameterClasses)1027     public JavaType constructParametricType(Class<?> parametrized, Class<?>... parameterClasses) {
1028         int len = parameterClasses.length;
1029         JavaType[] pt = new JavaType[len];
1030         for (int i = 0; i < len; ++i) {
1031             pt[i] = _fromClass(null, parameterClasses[i], EMPTY_BINDINGS);
1032         }
1033         return constructParametricType(parametrized, pt);
1034     }
1035 
1036     /**
1037      * Factory method for constructing {@link JavaType} that
1038      * represents a parameterized type. For example, to represent
1039      * type {@code List<Set<Integer>>}, you could
1040      *<pre>
1041      *  JavaType inner = TypeFactory.constructParametricType(Set.class, Set.class, Integer.class);
1042      *  return TypeFactory.constructParametricType(ArrayList.class, List.class, inner);
1043      *</pre>
1044      *<p>
1045      * The reason for first two arguments to be separate is that parameterization may
1046      * apply to a super-type. For example, if generic type was instead to be
1047      * constructed for {@code ArrayList<Integer>}, the usual call would be:
1048      *<pre>
1049      *  TypeFactory.constructParametricType(ArrayList.class, List.class, Integer.class);
1050      *</pre>
1051      * since parameterization is applied to {@link java.util.List}.
1052      * In most cases distinction does not matter, but there are types where it does;
1053      * one such example is parameterization of types that implement {@link java.util.Iterator}.
1054      *<p>
1055      * NOTE: since 2.11.2 {@link TypeModifier}s ARE called on result (fix for [databind#2796])
1056      *
1057      * @param rawType Actual type-erased type
1058      * @param parameterTypes Type parameters to apply
1059      *
1060      * @return Fully resolved type for given base type and type parameters
1061      */
constructParametricType(Class<?> rawType, JavaType... parameterTypes)1062     public JavaType constructParametricType(Class<?> rawType, JavaType... parameterTypes)
1063     {
1064         return constructParametricType(rawType, TypeBindings.create(rawType, parameterTypes));
1065     }
1066 
1067     /**
1068      * Factory method for constructing {@link JavaType} that
1069      * represents a parameterized type. The type's parameters are
1070      * specified as an instance of {@link TypeBindings}. This
1071      * is useful if you already have the type's parameters such
1072      * as those found on {@link JavaType}. For example, you could
1073      * call
1074      * <pre>
1075      *   return TypeFactory.constructParametricType(ArrayList.class, javaType.getBindings());
1076      * </pre>
1077      * This effectively applies the parameterized types from one
1078      * {@link JavaType} to another class.
1079      *
1080      * @param rawType Actual type-erased type
1081      * @param parameterTypes Type bindings for the raw type
1082      *
1083      * @since 2.12
1084      */
constructParametricType(Class<?> rawType, TypeBindings parameterTypes)1085     public JavaType constructParametricType(Class<?> rawType, TypeBindings parameterTypes)
1086     {
1087         // 16-Jul-2020, tatu: Since we do not call `_fromAny()`, need to make
1088         //   sure `TypeModifier`s are applied:
1089         JavaType resultType =  _fromClass(null, rawType, parameterTypes);
1090         return _applyModifiers(rawType, resultType);
1091     }
1092 
1093     /**
1094      * @since 2.5 -- but will probably deprecated in 2.7 or 2.8 (not needed with 2.7)
1095      *
1096      * @deprecated since 2.9 Use {@link #constructParametricType(Class,JavaType...)} instead
1097      */
1098     @Deprecated
constructParametrizedType(Class<?> parametrized, Class<?> parametersFor, JavaType... parameterTypes)1099     public JavaType constructParametrizedType(Class<?> parametrized, Class<?> parametersFor,
1100             JavaType... parameterTypes)
1101     {
1102         return constructParametricType(parametrized, parameterTypes);
1103     }
1104 
1105     /**
1106      * @since 2.5 -- but will probably deprecated in 2.7 or 2.8 (not needed with 2.7)
1107      *
1108      * @deprecated since 2.9 Use {@link #constructParametricType(Class,Class...)} instead
1109      */
1110     @Deprecated
constructParametrizedType(Class<?> parametrized, Class<?> parametersFor, Class<?>... parameterClasses)1111     public JavaType constructParametrizedType(Class<?> parametrized, Class<?> parametersFor,
1112             Class<?>... parameterClasses)
1113     {
1114         return constructParametricType(parametrized, parameterClasses);
1115     }
1116 
1117     /*
1118     /**********************************************************
1119     /* Direct factory methods for "raw" variants, used when
1120     /* parameterization is unknown
1121     /**********************************************************
1122      */
1123 
1124     /**
1125      * Method that can be used to construct "raw" Collection type; meaning that its
1126      * parameterization is unknown.
1127      * This is similar to using <code>Object.class</code> parameterization,
1128      * and is equivalent to calling:
1129      *<pre>
1130      *  typeFactory.constructCollectionType(collectionClass, typeFactory.unknownType());
1131      *</pre>
1132      *<p>
1133      * This method should only be used if parameterization is completely unavailable.
1134      */
constructRawCollectionType(Class<? extends Collection> collectionClass)1135     public CollectionType constructRawCollectionType(Class<? extends Collection> collectionClass) {
1136         return constructCollectionType(collectionClass, unknownType());
1137     }
1138 
1139     /**
1140      * Method that can be used to construct "raw" Collection-like type; meaning that its
1141      * parameterization is unknown.
1142      * This is similar to using <code>Object.class</code> parameterization,
1143      * and is equivalent to calling:
1144      *<pre>
1145      *  typeFactory.constructCollectionLikeType(collectionClass, typeFactory.unknownType());
1146      *</pre>
1147      *<p>
1148      * This method should only be used if parameterization is completely unavailable.
1149      */
constructRawCollectionLikeType(Class<?> collectionClass)1150     public CollectionLikeType constructRawCollectionLikeType(Class<?> collectionClass) {
1151         return constructCollectionLikeType(collectionClass, unknownType());
1152     }
1153 
1154     /**
1155      * Method that can be used to construct "raw" Map type; meaning that its
1156      * parameterization is unknown.
1157      * This is similar to using <code>Object.class</code> parameterization,
1158      * and is equivalent to calling:
1159      *<pre>
1160      *  typeFactory.constructMapType(collectionClass, typeFactory.unknownType(), typeFactory.unknownType());
1161      *</pre>
1162      *<p>
1163      * This method should only be used if parameterization is completely unavailable.
1164      */
constructRawMapType(Class<? extends Map> mapClass)1165     public MapType constructRawMapType(Class<? extends Map> mapClass) {
1166         return constructMapType(mapClass, unknownType(), unknownType());
1167     }
1168 
1169     /**
1170      * Method that can be used to construct "raw" Map-like type; meaning that its
1171      * parameterization is unknown.
1172      * This is similar to using <code>Object.class</code> parameterization,
1173      * and is equivalent to calling:
1174      *<pre>
1175      *  typeFactory.constructMapLikeType(collectionClass, typeFactory.unknownType(), typeFactory.unknownType());
1176      *</pre>
1177      *<p>
1178      * This method should only be used if parameterization is completely unavailable.
1179      */
constructRawMapLikeType(Class<?> mapClass)1180     public MapLikeType constructRawMapLikeType(Class<?> mapClass) {
1181         return constructMapLikeType(mapClass, unknownType(), unknownType());
1182     }
1183 
1184     /*
1185     /**********************************************************
1186     /* Low-level factory methods
1187     /**********************************************************
1188      */
1189 
_mapType(Class<?> rawClass, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1190     private JavaType _mapType(Class<?> rawClass, TypeBindings bindings,
1191             JavaType superClass, JavaType[] superInterfaces)
1192     {
1193         JavaType kt, vt;
1194 
1195         // 28-May-2015, tatu: Properties are special, as per [databind#810]; fake "correct" parameter sig
1196         if (rawClass == Properties.class) {
1197             kt = vt = CORE_TYPE_STRING;
1198         } else {
1199             List<JavaType> typeParams = bindings.getTypeParameters();
1200             // ok to have no types ("raw")
1201             switch (typeParams.size()) {
1202             case 0: // acceptable?
1203                 kt = vt = _unknownType();
1204                 break;
1205             case 2:
1206                 kt = typeParams.get(0);
1207                 vt = typeParams.get(1);
1208                 break;
1209             default:
1210                 throw new IllegalArgumentException("Strange Map type "+rawClass.getName()+": cannot determine type parameters");
1211             }
1212         }
1213         return MapType.construct(rawClass, bindings, superClass, superInterfaces, kt, vt);
1214     }
1215 
_collectionType(Class<?> rawClass, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1216     private JavaType _collectionType(Class<?> rawClass, TypeBindings bindings,
1217             JavaType superClass, JavaType[] superInterfaces)
1218     {
1219         List<JavaType> typeParams = bindings.getTypeParameters();
1220         // ok to have no types ("raw")
1221         JavaType ct;
1222         if (typeParams.isEmpty()) {
1223             ct = _unknownType();
1224         } else if (typeParams.size() == 1) {
1225             ct = typeParams.get(0);
1226         } else {
1227             throw new IllegalArgumentException("Strange Collection type "+rawClass.getName()+": cannot determine type parameters");
1228         }
1229         return CollectionType.construct(rawClass, bindings, superClass, superInterfaces, ct);
1230     }
1231 
_referenceType(Class<?> rawClass, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1232     private JavaType _referenceType(Class<?> rawClass, TypeBindings bindings,
1233             JavaType superClass, JavaType[] superInterfaces)
1234     {
1235         List<JavaType> typeParams = bindings.getTypeParameters();
1236         // ok to have no types ("raw")
1237         JavaType ct;
1238         if (typeParams.isEmpty()) {
1239             ct = _unknownType();
1240         } else if (typeParams.size() == 1) {
1241             ct = typeParams.get(0);
1242         } else {
1243             throw new IllegalArgumentException("Strange Reference type "+rawClass.getName()+": cannot determine type parameters");
1244         }
1245         return ReferenceType.construct(rawClass, bindings, superClass, superInterfaces, ct);
1246     }
1247 
1248     /**
1249      * Factory method to call when no special {@link JavaType} is needed,
1250      * no generic parameters are passed. Default implementation may check
1251      * pre-constructed values for "well-known" types, but if none found
1252      * will simply call {@link #_newSimpleType}
1253      *
1254      * @since 2.7
1255      */
_constructSimple(Class<?> raw, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1256     protected JavaType _constructSimple(Class<?> raw, TypeBindings bindings,
1257             JavaType superClass, JavaType[] superInterfaces)
1258     {
1259         if (bindings.isEmpty()) {
1260             JavaType result = _findWellKnownSimple(raw);
1261             if (result != null) {
1262                 return result;
1263             }
1264         }
1265         return _newSimpleType(raw, bindings, superClass, superInterfaces);
1266     }
1267 
1268     /**
1269      * Factory method that is to create a new {@link SimpleType} with no
1270      * checks whatsoever. Default implementation calls the single argument
1271      * constructor of {@link SimpleType}.
1272      *
1273      * @since 2.7
1274      */
_newSimpleType(Class<?> raw, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1275     protected JavaType _newSimpleType(Class<?> raw, TypeBindings bindings,
1276             JavaType superClass, JavaType[] superInterfaces)
1277     {
1278         return new SimpleType(raw, bindings, superClass, superInterfaces);
1279     }
1280 
_unknownType()1281     protected JavaType _unknownType() {
1282         /* 15-Sep-2015, tatu: Prior to 2.7, we constructed new instance for each call.
1283          *    This may have been due to potential mutability of the instance; but that
1284          *    should not be issue any more, and creation is somewhat wasteful. So let's
1285          *    try reusing singleton/flyweight instance.
1286          */
1287         return CORE_TYPE_OBJECT;
1288     }
1289 
1290     /**
1291      * Helper method called to see if requested, non-generic-parameterized
1292      * type is one of common, "well-known" types, instances of which are
1293      * pre-constructed and do not need dynamic caching.
1294      *
1295      * @since 2.7
1296      */
_findWellKnownSimple(Class<?> clz)1297     protected JavaType _findWellKnownSimple(Class<?> clz) {
1298         if (clz.isPrimitive()) {
1299             if (clz == CLS_BOOL) return CORE_TYPE_BOOL;
1300             if (clz == CLS_INT) return CORE_TYPE_INT;
1301             if (clz == CLS_LONG) return CORE_TYPE_LONG;
1302         } else {
1303             if (clz == CLS_STRING) return CORE_TYPE_STRING;
1304             if (clz == CLS_OBJECT) return CORE_TYPE_OBJECT; // since 2.7
1305             if (clz == CLS_JSON_NODE) return CORE_TYPE_JSON_NODE; // since 2.10
1306         }
1307         return null;
1308     }
1309 
1310     /*
1311     /**********************************************************
1312     /* Actual type resolution, traversal
1313     /**********************************************************
1314      */
1315 
1316     /**
1317      * Factory method that can be used if type information is passed
1318      * as Java typing returned from <code>getGenericXxx</code> methods
1319      * (usually for a return or argument type).
1320      */
_fromAny(ClassStack context, Type srcType, TypeBindings bindings)1321     protected JavaType _fromAny(ClassStack context, Type srcType, TypeBindings bindings)
1322     {
1323         JavaType resultType;
1324 
1325         // simple class?
1326         if (srcType instanceof Class<?>) {
1327             // Important: remove possible bindings since this is type-erased thingy
1328             resultType = _fromClass(context, (Class<?>) srcType, EMPTY_BINDINGS);
1329         }
1330         // But if not, need to start resolving.
1331         else if (srcType instanceof ParameterizedType) {
1332             resultType = _fromParamType(context, (ParameterizedType) srcType, bindings);
1333         }
1334         else if (srcType instanceof JavaType) { // [databind#116]
1335             // no need to modify further if we already had JavaType
1336             return (JavaType) srcType;
1337         }
1338         else if (srcType instanceof GenericArrayType) {
1339             resultType = _fromArrayType(context, (GenericArrayType) srcType, bindings);
1340         }
1341         else if (srcType instanceof TypeVariable<?>) {
1342             resultType = _fromVariable(context, (TypeVariable<?>) srcType, bindings);
1343         }
1344         else if (srcType instanceof WildcardType) {
1345             resultType = _fromWildcard(context, (WildcardType) srcType, bindings);
1346         } else {
1347             // sanity check
1348             throw new IllegalArgumentException("Unrecognized Type: "+((srcType == null) ? "[null]" : srcType.toString()));
1349         }
1350         // 21-Feb-2016, nateB/tatu: as per [databind#1129] (applied for 2.7.2),
1351         //   we do need to let all kinds of types to be refined, esp. for Scala module.
1352         return _applyModifiers(srcType, resultType);
1353     }
1354 
_applyModifiers(Type srcType, JavaType resolvedType)1355     protected JavaType _applyModifiers(Type srcType, JavaType resolvedType)
1356     {
1357         if (_modifiers == null) {
1358             return resolvedType;
1359         }
1360         JavaType resultType = resolvedType;
1361         TypeBindings b = resultType.getBindings();
1362         if (b == null) {
1363             b = EMPTY_BINDINGS;
1364         }
1365         for (TypeModifier mod : _modifiers) {
1366             JavaType t = mod.modifyType(resultType, srcType, b, this);
1367             if (t == null) {
1368                 throw new IllegalStateException(String.format(
1369                         "TypeModifier %s (of type %s) return null for type %s",
1370                         mod, mod.getClass().getName(), resultType));
1371             }
1372             resultType = t;
1373         }
1374         return resultType;
1375     }
1376 
1377     /**
1378      * @param bindings Mapping of formal parameter declarations (for generic
1379      *   types) into actual types
1380      */
_fromClass(ClassStack context, Class<?> rawType, TypeBindings bindings)1381     protected JavaType _fromClass(ClassStack context, Class<?> rawType, TypeBindings bindings)
1382     {
1383         // Very first thing: small set of core types we know well:
1384         JavaType result = _findWellKnownSimple(rawType);
1385         if (result != null) {
1386             return result;
1387         }
1388         // Barring that, we may have recently constructed an instance
1389         final Object key;
1390         if ((bindings == null) || bindings.isEmpty()) {
1391             key = rawType;
1392         } else {
1393             key = bindings.asKey(rawType);
1394         }
1395         result = _typeCache.get(key); // ok, cache object is synced
1396         if (result != null) {
1397             return result;
1398         }
1399 
1400         // 15-Oct-2015, tatu: recursive reference?
1401         if (context == null) {
1402             context = new ClassStack(rawType);
1403         } else {
1404             ClassStack prev = context.find(rawType);
1405             if (prev != null) {
1406                 // Self-reference: needs special handling, then...
1407                 ResolvedRecursiveType selfRef = new ResolvedRecursiveType(rawType, EMPTY_BINDINGS);
1408                 prev.addSelfReference(selfRef);
1409                 return selfRef;
1410             }
1411             // no, but need to update context to allow for proper cycle resolution
1412             context = context.child(rawType);
1413         }
1414 
1415         // First: do we have an array type?
1416         if (rawType.isArray()) {
1417             result = ArrayType.construct(_fromAny(context, rawType.getComponentType(), bindings),
1418                     bindings);
1419         } else {
1420             // If not, need to proceed by first resolving parent type hierarchy
1421 
1422             JavaType superClass;
1423             JavaType[] superInterfaces;
1424 
1425             if (rawType.isInterface()) {
1426                 superClass = null;
1427                 superInterfaces = _resolveSuperInterfaces(context, rawType, bindings);
1428             } else {
1429                 // Note: even Enums can implement interfaces, so cannot drop those
1430                 superClass = _resolveSuperClass(context, rawType, bindings);
1431                 superInterfaces = _resolveSuperInterfaces(context, rawType, bindings);
1432             }
1433 
1434             // 19-Oct-2015, tatu: Bit messy, but we need to 'fix' java.util.Properties here...
1435             if (rawType == Properties.class) {
1436                 result = MapType.construct(rawType, bindings, superClass, superInterfaces,
1437                         CORE_TYPE_STRING, CORE_TYPE_STRING);
1438             }
1439             // And then check what flavor of type we got. Start by asking resolved
1440             // super-type if refinement is all that is needed?
1441             else if (superClass != null) {
1442                 result = superClass.refine(rawType, bindings, superClass, superInterfaces);
1443             }
1444             // if not, perhaps we are now resolving a well-known class or interface?
1445             if (result == null) {
1446                 result = _fromWellKnownClass(context, rawType, bindings, superClass, superInterfaces);
1447                 if (result == null) {
1448                     result = _fromWellKnownInterface(context, rawType, bindings, superClass, superInterfaces);
1449                     if (result == null) {
1450                         // but if nothing else, "simple" class for now:
1451                         result = _newSimpleType(rawType, bindings, superClass, superInterfaces);
1452                     }
1453                 }
1454             }
1455         }
1456         context.resolveSelfReferences(result);
1457         // 16-Jul-2016, tatu: [databind#1302] is solved different way, but ideally we shouldn't
1458         //     cache anything with partially resolved `ResolvedRecursiveType`... so maybe improve
1459         if (!result.hasHandlers()) {
1460             _typeCache.putIfAbsent(key, result); // cache object syncs
1461         }
1462         return result;
1463     }
1464 
_resolveSuperClass(ClassStack context, Class<?> rawType, TypeBindings parentBindings)1465     protected JavaType _resolveSuperClass(ClassStack context, Class<?> rawType, TypeBindings parentBindings)
1466     {
1467         Type parent = ClassUtil.getGenericSuperclass(rawType);
1468         if (parent == null) {
1469             return null;
1470         }
1471         return _fromAny(context, parent, parentBindings);
1472     }
1473 
_resolveSuperInterfaces(ClassStack context, Class<?> rawType, TypeBindings parentBindings)1474     protected JavaType[] _resolveSuperInterfaces(ClassStack context, Class<?> rawType, TypeBindings parentBindings)
1475     {
1476         Type[] types = ClassUtil.getGenericInterfaces(rawType);
1477         if (types == null || types.length == 0) {
1478             return NO_TYPES;
1479         }
1480         int len = types.length;
1481         JavaType[] resolved = new JavaType[len];
1482         for (int i = 0; i < len; ++i) {
1483             Type type = types[i];
1484             resolved[i] = _fromAny(context, type, parentBindings);
1485         }
1486         return resolved;
1487     }
1488 
1489     /**
1490      * Helper class used to check whether exact class for which type is being constructed
1491      * is one of well-known base interfaces or classes that indicates alternate
1492      * {@link JavaType} implementation.
1493      */
_fromWellKnownClass(ClassStack context, Class<?> rawType, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1494     protected JavaType _fromWellKnownClass(ClassStack context, Class<?> rawType, TypeBindings bindings,
1495             JavaType superClass, JavaType[] superInterfaces)
1496     {
1497         if (bindings == null) {
1498             bindings = EMPTY_BINDINGS;
1499         }
1500 
1501         // Quite simple when we resolving exact class/interface; start with that
1502         if (rawType == Map.class) {
1503             return _mapType(rawType, bindings, superClass, superInterfaces);
1504         }
1505         if (rawType == Collection.class) {
1506             return _collectionType(rawType, bindings, superClass, superInterfaces);
1507         }
1508         // and since 2.6 one referential type
1509         if (rawType == AtomicReference.class) {
1510             return _referenceType(rawType, bindings, superClass, superInterfaces);
1511         }
1512         // 01-Nov-2015, tatu: As of 2.7, couple of potential `CollectionLikeType`s (like
1513         //    `Iterable`, `Iterator`), and `MapLikeType`s (`Map.Entry`) are not automatically
1514         //    detected, related to difficulties in propagating type upwards (Iterable, for
1515         //    example, is a weak, tag-on type). They may be detectable in future.
1516         return null;
1517     }
1518 
_fromWellKnownInterface(ClassStack context, Class<?> rawType, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)1519     protected JavaType _fromWellKnownInterface(ClassStack context, Class<?> rawType, TypeBindings bindings,
1520             JavaType superClass, JavaType[] superInterfaces)
1521     {
1522         // But that's not all: may be possible current type actually implements an
1523         // interface type. So...
1524         final int intCount = superInterfaces.length;
1525 
1526         for (int i = 0; i < intCount; ++i) {
1527             JavaType result = superInterfaces[i].refine(rawType, bindings, superClass, superInterfaces);
1528             if (result != null) {
1529                 return result;
1530             }
1531         }
1532         return null;
1533     }
1534 
1535     /**
1536      * This method deals with parameterized types, that is,
1537      * first class generic classes.
1538      */
_fromParamType(ClassStack context, ParameterizedType ptype, TypeBindings parentBindings)1539     protected JavaType _fromParamType(ClassStack context, ParameterizedType ptype,
1540             TypeBindings parentBindings)
1541     {
1542         // Assumption here is we'll always get Class, not one of other Types
1543         Class<?> rawType = (Class<?>) ptype.getRawType();
1544 
1545         // 29-Oct-2015, tatu: For performance reasons, let's streamline handling of
1546         //   couple of not-so-useful parametric types
1547         if (rawType == CLS_ENUM) {
1548             return CORE_TYPE_ENUM;
1549         }
1550         if (rawType == CLS_COMPARABLE) {
1551             return CORE_TYPE_COMPARABLE;
1552         }
1553         if (rawType == CLS_CLASS) {
1554             return CORE_TYPE_CLASS;
1555         }
1556 
1557         // First: what is the actual base type? One odd thing is that 'getRawType'
1558         // returns Type, not Class<?> as one might expect. But let's assume it is
1559         // always of type Class: if not, need to add more code to resolve it to Class.
1560         Type[] args = ptype.getActualTypeArguments();
1561         int paramCount = (args == null) ? 0 : args.length;
1562         TypeBindings newBindings;
1563 
1564         if (paramCount == 0) {
1565             newBindings = EMPTY_BINDINGS;
1566         } else {
1567             JavaType[] pt = new JavaType[paramCount];
1568             for (int i = 0; i < paramCount; ++i) {
1569                 pt[i] = _fromAny(context, args[i], parentBindings);
1570             }
1571             newBindings = TypeBindings.create(rawType, pt);
1572         }
1573         return _fromClass(context, rawType, newBindings);
1574     }
1575 
_fromArrayType(ClassStack context, GenericArrayType type, TypeBindings bindings)1576     protected JavaType _fromArrayType(ClassStack context, GenericArrayType type, TypeBindings bindings)
1577     {
1578         JavaType elementType = _fromAny(context, type.getGenericComponentType(), bindings);
1579         return ArrayType.construct(elementType, bindings);
1580     }
1581 
_fromVariable(ClassStack context, TypeVariable<?> var, TypeBindings bindings)1582     protected JavaType _fromVariable(ClassStack context, TypeVariable<?> var, TypeBindings bindings)
1583     {
1584         // ideally should find it via bindings:
1585         final String name = var.getName();
1586         if (bindings == null) {
1587             throw new IllegalArgumentException("Null `bindings` passed (type variable \""+name+"\")");
1588         }
1589         JavaType type = bindings.findBoundType(name);
1590         if (type != null) {
1591             return type;
1592         }
1593         // but if not, use bounds... note that approach here is simplistic; not taking
1594         // into account possible multiple bounds, nor consider upper bounds.
1595         if (bindings.hasUnbound(name)) {
1596             return CORE_TYPE_OBJECT;
1597         }
1598         bindings = bindings.withUnboundVariable(name);
1599 
1600         final Type[] bounds;
1601 
1602         // 15-Jan-2019, tatu: As weird as this looks, apparently on some platforms (Arm CPU, mobile
1603         //    devices), unsynchronized internal access can lead to issues, see:
1604         //
1605         //  https://vmlens.com/articles/java-lang-reflect-typevariable-getbounds-is-not-thread-safe/
1606         //
1607         //    No good way to reproduce but since this should not be on critical path, let's add
1608         //    syncing as it seems potentially necessary.
1609         synchronized (var) {
1610             bounds = var.getBounds();
1611         }
1612         return _fromAny(context, bounds[0], bindings);
1613     }
1614 
_fromWildcard(ClassStack context, WildcardType type, TypeBindings bindings)1615     protected JavaType _fromWildcard(ClassStack context, WildcardType type, TypeBindings bindings)
1616     {
1617         /* Similar to challenges with TypeVariable, we may have multiple upper bounds.
1618          * But it is also possible that if upper bound defaults to Object, we might
1619          * want to consider lower bounds instead.
1620          * For now, we won't try anything more advanced; above is just for future reference.
1621          */
1622         return _fromAny(context, type.getUpperBounds()[0], bindings);
1623     }
1624 }
1625