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<String,Integer>" 360 * from "Map<String,Integer>" 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<String,Integer>" 379 * from "Map<String,Integer>" 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