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