1 package com.fasterxml.jackson.databind.cfg; 2 3 import java.text.DateFormat; 4 import java.util.Locale; 5 import java.util.TimeZone; 6 7 import com.fasterxml.jackson.annotation.*; 8 import com.fasterxml.jackson.core.Base64Variant; 9 import com.fasterxml.jackson.core.SerializableString; 10 import com.fasterxml.jackson.core.io.SerializedString; 11 import com.fasterxml.jackson.core.type.TypeReference; 12 import com.fasterxml.jackson.databind.*; 13 import com.fasterxml.jackson.databind.introspect.Annotated; 14 import com.fasterxml.jackson.databind.introspect.AnnotatedClass; 15 import com.fasterxml.jackson.databind.introspect.ClassIntrospector; 16 import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector; 17 import com.fasterxml.jackson.databind.introspect.VisibilityChecker; 18 import com.fasterxml.jackson.databind.jsontype.DefaultBaseTypeLimitingValidator; 19 import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator; 20 import com.fasterxml.jackson.databind.jsontype.SubtypeResolver; 21 import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; 22 import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; 23 import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; 24 import com.fasterxml.jackson.databind.type.TypeFactory; 25 import com.fasterxml.jackson.databind.util.ClassUtil; 26 27 /** 28 * Interface that defines functionality accessible through both 29 * serialization and deserialization configuration objects; 30 * accessors to mode-independent configuration settings 31 * and such. 32 * In addition, shared features are defined 33 * in {@link MapperFeature}. 34 *<p> 35 * Small part of implementation is included here by aggregating 36 * {@link BaseSettings} instance that contains configuration 37 * that is shared between different types of instances. 38 */ 39 public abstract class MapperConfig<T extends MapperConfig<T>> 40 implements ClassIntrospector.MixInResolver, 41 java.io.Serializable 42 { 43 private static final long serialVersionUID = 2L; // since 2.9 44 45 /** 46 * @since 2.7 47 */ 48 protected final static JsonInclude.Value EMPTY_INCLUDE = JsonInclude.Value.empty(); 49 50 /** 51 * @since 2.7 52 */ 53 protected final static JsonFormat.Value EMPTY_FORMAT = JsonFormat.Value.empty(); 54 55 /** 56 * Set of shared mapper features enabled. 57 */ 58 protected final int _mapperFeatures; 59 60 /** 61 * Immutable container object for simple configuration settings. 62 */ 63 protected final BaseSettings _base; 64 65 /* 66 /********************************************************** 67 /* Life-cycle: constructors 68 /********************************************************** 69 */ 70 MapperConfig(BaseSettings base, int mapperFeatures)71 protected MapperConfig(BaseSettings base, int mapperFeatures) 72 { 73 _base = base; 74 _mapperFeatures = mapperFeatures; 75 } 76 MapperConfig(MapperConfig<T> src, int mapperFeatures)77 protected MapperConfig(MapperConfig<T> src, int mapperFeatures) 78 { 79 _base = src._base; 80 _mapperFeatures = mapperFeatures; 81 } 82 MapperConfig(MapperConfig<T> src, BaseSettings base)83 protected MapperConfig(MapperConfig<T> src, BaseSettings base) 84 { 85 _base = base; 86 _mapperFeatures = src._mapperFeatures; 87 } 88 MapperConfig(MapperConfig<T> src)89 protected MapperConfig(MapperConfig<T> src) 90 { 91 _base = src._base; 92 _mapperFeatures = src._mapperFeatures; 93 } 94 95 /** 96 * Method that calculates bit set (flags) of all features that 97 * are enabled by default. 98 */ collectFeatureDefaults(Class<F> enumClass)99 public static <F extends Enum<F> & ConfigFeature> int collectFeatureDefaults(Class<F> enumClass) 100 { 101 int flags = 0; 102 for (F value : enumClass.getEnumConstants()) { 103 if (value.enabledByDefault()) { 104 flags |= value.getMask(); 105 } 106 } 107 return flags; 108 } 109 110 /* 111 /********************************************************** 112 /* Life-cycle: factory methods 113 /********************************************************** 114 */ 115 116 /** 117 * Method for constructing and returning a new instance with specified 118 * mapper features enabled. 119 */ with(MapperFeature... features)120 public abstract T with(MapperFeature... features); 121 122 /** 123 * Method for constructing and returning a new instance with specified 124 * mapper features disabled. 125 */ without(MapperFeature... features)126 public abstract T without(MapperFeature... features); 127 128 /** 129 * @since 2.3 130 */ with(MapperFeature feature, boolean state)131 public abstract T with(MapperFeature feature, boolean state); 132 133 /* 134 /********************************************************** 135 /* Configuration: simple features 136 /********************************************************** 137 */ 138 139 /** 140 * Accessor for simple mapper features (which are shared for 141 * serialization, deserialization) 142 */ isEnabled(MapperFeature f)143 public final boolean isEnabled(MapperFeature f) { 144 return f.enabledIn(_mapperFeatures); 145 } 146 147 /** 148 * "Bulk" access method for checking that all features specified by 149 * mask are enabled. 150 * 151 * @since 2.3 152 */ hasMapperFeatures(int featureMask)153 public final boolean hasMapperFeatures(int featureMask) { 154 return (_mapperFeatures & featureMask) == featureMask; 155 } 156 157 /** 158 * Method for determining whether annotation processing is enabled or not 159 * (default settings are typically that it is enabled; must explicitly disable). 160 * 161 * @return True if annotation processing is enabled; false if not 162 */ isAnnotationProcessingEnabled()163 public final boolean isAnnotationProcessingEnabled() { 164 return isEnabled(MapperFeature.USE_ANNOTATIONS); 165 } 166 167 /** 168 * Accessor for determining whether it is ok to try to force override of access 169 * modifiers to be able to get or set values of non-public Methods, Fields; 170 * to invoke non-public Constructors, Methods; or to instantiate non-public 171 * Classes. By default this is enabled, but on some platforms it needs to be 172 * prevented since if this would violate security constraints and cause failures. 173 * 174 * @return True if access modifier overriding is allowed (and may be done for 175 * any Field, Method, Constructor or Class); false to prevent any attempts 176 * to override. 177 */ canOverrideAccessModifiers()178 public final boolean canOverrideAccessModifiers() { 179 return isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS); 180 } 181 182 /** 183 * Accessor for checking whether default settings for property handling 184 * indicate that properties should be alphabetically ordered or not. 185 */ shouldSortPropertiesAlphabetically()186 public final boolean shouldSortPropertiesAlphabetically() { 187 return isEnabled(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY); 188 } 189 190 /** 191 * Accessor for checking whether configuration indicates that 192 * "root wrapping" (use of an extra property/name pair at root level) 193 * is expected or not. 194 */ useRootWrapping()195 public abstract boolean useRootWrapping(); 196 197 /* 198 /********************************************************** 199 /* Configuration: factory methods 200 /********************************************************** 201 */ 202 203 /** 204 * Method for constructing a specialized textual object that can typically 205 * be serialized faster than basic {@link java.lang.String} (depending 206 * on escaping needed if any, char-to-byte encoding if needed). 207 * 208 * @param src Text to represent 209 * 210 * @return Optimized text object constructed 211 * 212 * @since 2.4 213 */ compileString(String src)214 public SerializableString compileString(String src) { 215 /* 20-Jan-2014, tatu: For now we will just construct it directly, but 216 * in future should allow overriding to support non-standard extensions 217 * to be used by extensions like Afterburner. 218 */ 219 return new SerializedString(src); 220 } 221 222 /* 223 /********************************************************** 224 /* Configuration: introspectors, mix-ins 225 /********************************************************** 226 */ 227 getClassIntrospector()228 public ClassIntrospector getClassIntrospector() { 229 return _base.getClassIntrospector(); 230 } 231 232 /** 233 * Method for getting {@link AnnotationIntrospector} configured 234 * to introspect annotation values used for configuration. 235 *<p> 236 * Non-final since it is actually overridden by sub-classes (for now?) 237 */ getAnnotationIntrospector()238 public AnnotationIntrospector getAnnotationIntrospector() { 239 if (isEnabled(MapperFeature.USE_ANNOTATIONS)) { 240 return _base.getAnnotationIntrospector(); 241 } 242 return NopAnnotationIntrospector.instance; 243 } 244 getPropertyNamingStrategy()245 public final PropertyNamingStrategy getPropertyNamingStrategy() { 246 return _base.getPropertyNamingStrategy(); 247 } 248 getHandlerInstantiator()249 public final HandlerInstantiator getHandlerInstantiator() { 250 return _base.getHandlerInstantiator(); 251 } 252 253 /* 254 /********************************************************** 255 /* Configuration: type and subtype handling 256 /********************************************************** 257 */ 258 259 /** 260 * Method called to locate a type info handler for types that do not have 261 * one explicitly declared via annotations (or other configuration). 262 * If such default handler is configured, it is returned; otherwise 263 * null is returned. 264 */ getDefaultTyper(JavaType baseType)265 public final TypeResolverBuilder<?> getDefaultTyper(JavaType baseType) { 266 return _base.getTypeResolverBuilder(); 267 } 268 getSubtypeResolver()269 public abstract SubtypeResolver getSubtypeResolver(); 270 271 /** 272 * Simple accessor for default {@link PolymorphicTypeValidator} to use for 273 * legacy Default Typing methods ({@code ObjectMapper.enableDefaultTyping()}) 274 * and annotation based enabling. 275 *<p> 276 * Since 2.11 will also check {@link MapperFeature#BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES} 277 * to possibly override default to more restrictive implementation, see 278 * {@link com.fasterxml.jackson.databind.jsontype.DefaultBaseTypeLimitingValidator}). 279 * 280 * @since 2.10 281 */ getPolymorphicTypeValidator()282 public PolymorphicTypeValidator getPolymorphicTypeValidator() { 283 PolymorphicTypeValidator ptv = _base.getPolymorphicTypeValidator(); 284 // [databind#2587]: allow stricter default settings: 285 if (ptv == LaissezFaireSubTypeValidator.instance) { 286 if (isEnabled(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)) { 287 ptv = new DefaultBaseTypeLimitingValidator(); 288 } 289 } 290 return ptv; 291 } 292 getTypeFactory()293 public final TypeFactory getTypeFactory() { 294 return _base.getTypeFactory(); 295 } 296 297 /** 298 * Helper method that will construct {@link JavaType} for given 299 * raw class. 300 * This is a simple short-cut for: 301 *<pre> 302 * getTypeFactory().constructType(cls); 303 *</pre> 304 */ constructType(Class<?> cls)305 public final JavaType constructType(Class<?> cls) { 306 return getTypeFactory().constructType(cls); 307 } 308 309 /** 310 * Helper method that will construct {@link JavaType} for given 311 * type reference 312 * This is a simple short-cut for: 313 *<pre> 314 * getTypeFactory().constructType(valueTypeRef); 315 *</pre> 316 */ constructType(TypeReference<?> valueTypeRef)317 public final JavaType constructType(TypeReference<?> valueTypeRef) { 318 return getTypeFactory().constructType(valueTypeRef.getType()); 319 } 320 constructSpecializedType(JavaType baseType, Class<?> subclass)321 public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) { 322 // note: since 2.11 specify "strict" resolution 323 return getTypeFactory().constructSpecializedType(baseType, subclass, true); 324 } 325 326 /* 327 /********************************************************** 328 /* Configuration: introspection support 329 /********************************************************** 330 */ 331 332 /** 333 * Accessor for getting bean description that only contains class 334 * annotations: useful if no getter/setter/creator information is needed. 335 */ introspectClassAnnotations(Class<?> cls)336 public BeanDescription introspectClassAnnotations(Class<?> cls) { 337 return introspectClassAnnotations(constructType(cls)); 338 } 339 340 /** 341 * Accessor for getting bean description that only contains class 342 * annotations: useful if no getter/setter/creator information is needed. 343 */ introspectClassAnnotations(JavaType type)344 public BeanDescription introspectClassAnnotations(JavaType type) { 345 return getClassIntrospector().forClassAnnotations(this, type, this); 346 } 347 348 /** 349 * Accessor for getting bean description that only contains immediate class 350 * annotations: ones from the class, and its direct mix-in, if any, but 351 * not from super types. 352 */ introspectDirectClassAnnotations(Class<?> cls)353 public BeanDescription introspectDirectClassAnnotations(Class<?> cls) { 354 return introspectDirectClassAnnotations(constructType(cls)); 355 } 356 357 /** 358 * Accessor for getting bean description that only contains immediate class 359 * annotations: ones from the class, and its direct mix-in, if any, but 360 * not from super types. 361 */ introspectDirectClassAnnotations(JavaType type)362 public final BeanDescription introspectDirectClassAnnotations(JavaType type) { 363 return getClassIntrospector().forDirectClassAnnotations(this, type, this); 364 } 365 366 /* 367 /********************************************************** 368 /* Configuration: default settings with per-type overrides 369 /********************************************************** 370 */ 371 372 /** 373 * Accessor for finding {@link ConfigOverride} to use for 374 * properties of given type, if any exist; or return `null` if not. 375 *<p> 376 * Note that only directly associated override 377 * is found; no type hierarchy traversal is performed. 378 * 379 * @since 2.8 380 * 381 * @return Override object to use for the type, if defined; null if none. 382 */ findConfigOverride(Class<?> type)383 public abstract ConfigOverride findConfigOverride(Class<?> type); 384 385 /** 386 * Accessor for finding {@link ConfigOverride} to use for 387 * properties of given type, if any exist; or if none, return an immutable 388 * "empty" instance with no overrides. 389 *<p> 390 * Note that only directly associated override 391 * is found; no type hierarchy traversal is performed. 392 * 393 * @since 2.9 394 * 395 * @return Override object to use for the type, never null (but may be empty) 396 */ getConfigOverride(Class<?> type)397 public abstract ConfigOverride getConfigOverride(Class<?> type); 398 399 /** 400 * Accessor for default property inclusion to use for serialization, 401 * used unless overridden by per-type or per-property overrides. 402 * 403 * @since 2.7 404 */ getDefaultPropertyInclusion()405 public abstract JsonInclude.Value getDefaultPropertyInclusion(); 406 407 /** 408 * Accessor for default property inclusion to use for serialization, 409 * considering possible per-type override for given base type.<br> 410 * NOTE: if no override found, defaults to value returned by 411 * {@link #getDefaultPropertyInclusion()}. 412 * 413 * @since 2.7 414 */ getDefaultPropertyInclusion(Class<?> baseType)415 public abstract JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType); 416 417 /** 418 * Accessor for default property inclusion to use for serialization, 419 * considering possible per-type override for given base type; but 420 * if none found, returning given <code>defaultIncl</code> 421 * 422 * @param defaultIncl Inclusion setting to return if no overrides found. 423 * 424 * @since 2.8.2 425 */ getDefaultPropertyInclusion(Class<?> baseType, JsonInclude.Value defaultIncl)426 public JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType, 427 JsonInclude.Value defaultIncl) 428 { 429 JsonInclude.Value v = getConfigOverride(baseType).getInclude(); 430 if (v != null) { 431 return v; 432 } 433 return defaultIncl; 434 } 435 436 /** 437 * Accessor for default property inclusion to use for serialization, 438 * considering possible per-type override for given base type and 439 * possible per-type override for given property type.<br> 440 * NOTE: if no override found, defaults to value returned by 441 * {@link #getDefaultPropertyInclusion()}. 442 * 443 * @param baseType Type of the instance containing the targeted property. 444 * @param propertyType Type of the property to look up inclusion setting for. 445 * 446 * @since 2.9 447 */ getDefaultInclusion(Class<?> baseType, Class<?> propertyType)448 public abstract JsonInclude.Value getDefaultInclusion(Class<?> baseType, 449 Class<?> propertyType); 450 451 /** 452 * Accessor for default property inclusion to use for serialization, 453 * considering possible per-type override for given base type and 454 * possible per-type override for given property type; but 455 * if none found, returning given <code>defaultIncl</code> 456 * 457 * @param baseType Type of the instance containing the targeted property. 458 * @param propertyType Type of the property to look up inclusion setting for. 459 * @param defaultIncl Inclusion setting to return if no overrides found. 460 * 461 * @since 2.9 462 */ getDefaultInclusion(Class<?> baseType, Class<?> propertyType, JsonInclude.Value defaultIncl)463 public JsonInclude.Value getDefaultInclusion(Class<?> baseType, 464 Class<?> propertyType, JsonInclude.Value defaultIncl) 465 { 466 JsonInclude.Value baseOverride = getConfigOverride(baseType).getInclude(); 467 JsonInclude.Value propOverride = getConfigOverride(propertyType).getIncludeAsProperty(); 468 469 JsonInclude.Value result = JsonInclude.Value.mergeAll(defaultIncl, baseOverride, propOverride); 470 return result; 471 } 472 473 /** 474 * Accessor for default format settings to use for serialization (and, to a degree 475 * deserialization), considering baseline settings and per-type defaults 476 * for given base type (if any). 477 * 478 * @since 2.7 479 */ getDefaultPropertyFormat(Class<?> baseType)480 public abstract JsonFormat.Value getDefaultPropertyFormat(Class<?> baseType); 481 482 /** 483 * Accessor for default property ignorals to use, if any, for given base type, 484 * based on config overrides settings (see {@link #findConfigOverride(Class)}). 485 * 486 * @since 2.8 487 */ getDefaultPropertyIgnorals(Class<?> baseType)488 public abstract JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> baseType); 489 490 /** 491 * Helper method that may be called to see if there are property ignoral 492 * definitions from annotations (via {@link AnnotatedClass}) or through 493 * "config overrides". If both exist, config overrides have precedence 494 * over class annotations. 495 * 496 * @since 2.8 497 */ getDefaultPropertyIgnorals(Class<?> baseType, AnnotatedClass actualClass)498 public abstract JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> baseType, 499 AnnotatedClass actualClass); 500 501 /** 502 * Helper method that may be called to see if there are property inclusion 503 * definitions from annotations (via {@link AnnotatedClass}). 504 * 505 * TODO: config override. 506 * 507 * @since 2.12 508 */ getDefaultPropertyInclusions(Class<?> baseType, AnnotatedClass actualClass)509 public abstract JsonIncludeProperties.Value getDefaultPropertyInclusions(Class<?> baseType, 510 AnnotatedClass actualClass); 511 512 /** 513 * Accessor for object used for determining whether specific property elements 514 * (method, constructors, fields) can be auto-detected based on 515 * their visibility (access modifiers). Can be changed to allow 516 * different minimum visibility levels for auto-detection. Note 517 * that this is the global handler; individual types (classes) 518 * can further override active checker used (using 519 * {@link JsonAutoDetect} annotation) 520 */ getDefaultVisibilityChecker()521 public abstract VisibilityChecker<?> getDefaultVisibilityChecker(); 522 523 /** 524 * Accessor for object used for determining whether specific property elements 525 * (method, constructors, fields) can be auto-detected based on 526 * their visibility (access modifiers). This is based on global defaults 527 * (as would be returned by {@link #getDefaultVisibilityChecker()}, but 528 * then modified by possible class annotation (see {@link JsonAutoDetect}) 529 * and/or per-type config override (see {@link ConfigOverride#getVisibility()}). 530 * 531 * @since 2.9 532 */ getDefaultVisibilityChecker(Class<?> baseType, AnnotatedClass actualClass)533 public abstract VisibilityChecker<?> getDefaultVisibilityChecker(Class<?> baseType, 534 AnnotatedClass actualClass); 535 536 /** 537 * Accessor for the baseline setter info used as the global baseline, 538 * not considering possible per-type overrides. 539 * 540 * @return Global base settings; never null 541 * 542 * @since 2.9 543 */ getDefaultSetterInfo()544 public abstract JsonSetter.Value getDefaultSetterInfo(); 545 546 /** 547 * Accessor for the baseline merge info used as the global baseline, 548 * not considering possible per-type overrides. 549 * 550 * @return Global base settings, if any; `null` if none. 551 * 552 * @since 2.9 553 */ getDefaultMergeable()554 public abstract Boolean getDefaultMergeable(); 555 556 /** 557 * Accessor for the baseline merge info used for given type, including global 558 * defaults if no type-specific overrides defined. 559 * 560 * @return Type-specific settings (if any); global defaults (same as 561 * {@link #getDefaultMergeable()}) otherwise, if any defined; or `null` 562 * if neither defined 563 * 564 * @since 2.9 565 */ getDefaultMergeable(Class<?> baseType)566 public abstract Boolean getDefaultMergeable(Class<?> baseType); 567 568 /* 569 /********************************************************** 570 /* Configuration: other 571 /********************************************************** 572 */ 573 574 /** 575 * Method for accessing currently configured (textual) date format 576 * that will be used for reading or writing date values (in case 577 * of writing, only if textual output is configured; not if dates 578 * are to be serialized as time stamps). 579 *<p> 580 * Note that typically {@link DateFormat} instances are <b>not thread-safe</b> 581 * (at least ones provided by JDK): 582 * this means that calling code should clone format instance before 583 * using it. 584 *<p> 585 * This method is usually only called by framework itself, since there 586 * are convenience methods available via 587 * {@link DeserializationContext} and {@link SerializerProvider} that 588 * take care of cloning and thread-safe reuse. 589 */ getDateFormat()590 public final DateFormat getDateFormat() { return _base.getDateFormat(); } 591 592 /** 593 * Method for accessing the default {@link java.util.Locale} to use 594 * for formatting, unless overridden by local annotations. 595 * Initially set to {@link Locale#getDefault()}. 596 */ getLocale()597 public final Locale getLocale() { return _base.getLocale(); } 598 599 /** 600 * Method for accessing the default {@link java.util.TimeZone} to use 601 * for formatting, unless overridden by local annotations. 602 * Initially set to {@link TimeZone#getDefault()}. 603 */ getTimeZone()604 public final TimeZone getTimeZone() { return _base.getTimeZone(); } 605 606 /** 607 * Accessor for finding currently active view, if any (null if none) 608 */ getActiveView()609 public abstract Class<?> getActiveView(); 610 611 /** 612 * Method called during deserialization if Base64 encoded content 613 * needs to be decoded. Default version just returns default Jackson 614 * uses, which is modified-mime which does not add linefeeds (because 615 * those would have to be escaped in JSON strings); but this can 616 * be configured on {@link ObjectWriter}. 617 */ getBase64Variant()618 public Base64Variant getBase64Variant() { 619 return _base.getBase64Variant(); 620 } 621 622 /** 623 * Method for accessing per-instance shared (baseline/default) 624 * attribute values; these are used as the basis for per-call 625 * attributes. 626 * 627 * @since 2.3 628 */ getAttributes()629 public abstract ContextAttributes getAttributes(); 630 631 /** 632 * @since 2.6 633 */ findRootName(JavaType rootType)634 public abstract PropertyName findRootName(JavaType rootType); 635 636 /** 637 * @since 2.6 638 */ findRootName(Class<?> rawRootType)639 public abstract PropertyName findRootName(Class<?> rawRootType); 640 641 /* 642 /********************************************************** 643 /* Methods for instantiating handlers 644 /********************************************************** 645 */ 646 647 /** 648 * Method that can be called to obtain an instance of <code>TypeIdResolver</code> of 649 * specified type. 650 */ typeResolverBuilderInstance(Annotated annotated, Class<? extends TypeResolverBuilder<?>> builderClass)651 public TypeResolverBuilder<?> typeResolverBuilderInstance(Annotated annotated, 652 Class<? extends TypeResolverBuilder<?>> builderClass) 653 { 654 HandlerInstantiator hi = getHandlerInstantiator(); 655 if (hi != null) { 656 TypeResolverBuilder<?> builder = hi.typeResolverBuilderInstance(this, annotated, builderClass); 657 if (builder != null) { 658 return builder; 659 } 660 } 661 return (TypeResolverBuilder<?>) ClassUtil.createInstance(builderClass, canOverrideAccessModifiers()); 662 } 663 664 /** 665 * Method that can be called to obtain an instance of <code>TypeIdResolver</code> of 666 * specified type. 667 */ typeIdResolverInstance(Annotated annotated, Class<? extends TypeIdResolver> resolverClass)668 public TypeIdResolver typeIdResolverInstance(Annotated annotated, 669 Class<? extends TypeIdResolver> resolverClass) 670 { 671 HandlerInstantiator hi = getHandlerInstantiator(); 672 if (hi != null) { 673 TypeIdResolver builder = hi.typeIdResolverInstance(this, annotated, resolverClass); 674 if (builder != null) { 675 return builder; 676 } 677 } 678 return (TypeIdResolver) ClassUtil.createInstance(resolverClass, canOverrideAccessModifiers()); 679 } 680 } 681