• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.cfg;
2 
3 import java.text.DateFormat;
4 import java.util.*;
5 
6 import com.fasterxml.jackson.annotation.*;
7 import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
8 import com.fasterxml.jackson.core.Base64Variant;
9 
10 import com.fasterxml.jackson.databind.*;
11 import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
12 import com.fasterxml.jackson.databind.introspect.ClassIntrospector.MixInResolver;
13 import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
14 import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
15 import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
16 import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
17 import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
18 import com.fasterxml.jackson.databind.type.TypeFactory;
19 import com.fasterxml.jackson.databind.util.RootNameLookup;
20 
21 @SuppressWarnings("serial")
22 public abstract class MapperConfigBase<CFG extends ConfigFeature,
23     T extends MapperConfigBase<CFG,T>>
24     extends MapperConfig<T>
25     implements java.io.Serializable
26 {
27     /**
28      * @since 2.9
29      */
30     protected final static ConfigOverride EMPTY_OVERRIDE = ConfigOverride.empty();
31 
32     private final static int DEFAULT_MAPPER_FEATURES = collectFeatureDefaults(MapperFeature.class);
33 
34     /**
35      * @since 2.9
36      */
37     private final static int AUTO_DETECT_MASK =
38             MapperFeature.AUTO_DETECT_FIELDS.getMask()
39             | MapperFeature.AUTO_DETECT_GETTERS.getMask()
40             | MapperFeature.AUTO_DETECT_IS_GETTERS.getMask()
41             | MapperFeature.AUTO_DETECT_SETTERS.getMask()
42             | MapperFeature.AUTO_DETECT_CREATORS.getMask()
43             ;
44 
45     /*
46     /**********************************************************
47     /* Immutable config
48     /**********************************************************
49      */
50 
51     /**
52      * Mix-in annotation mappings to use, if any: immutable,
53      * cannot be changed once defined.
54      *
55      * @since 2.6
56      */
57     protected final SimpleMixInResolver _mixIns;
58 
59     /**
60      * Registered concrete subtypes that can be used instead of (or
61      * in addition to) ones declared using annotations.
62      *<p>
63      * Note that instances are stateful and as such may need to be copied,
64      * and may NOT be demoted down to {@link BaseSettings}.
65      */
66     protected final SubtypeResolver _subtypeResolver;
67 
68     /**
69      * Explicitly defined root name to use, if any; if empty
70      * String, will disable root-name wrapping; if null, will
71      * use defaults
72      */
73     protected final PropertyName _rootName;
74 
75     /**
76      * View to use for filtering out properties to serialize
77      * or deserialize.
78      * Null if none (will also be assigned null if <code>Object.class</code>
79      * is defined), meaning that all properties are to be included.
80      */
81     protected final Class<?> _view;
82 
83     /**
84      * Contextual attributes accessible (get and set) during processing,
85      * on per-call basis.
86      *
87      * @since 2.3
88      */
89     protected final ContextAttributes _attributes;
90 
91     /**
92      * Simple cache used for finding out possible root name for root name
93      * wrapping.
94      *<p>
95      * Note that instances are stateful (for caching) and as such may need to be copied,
96      * and may NOT be demoted down to {@link BaseSettings}.
97      *
98      * @since 2.6
99      */
100     protected final RootNameLookup _rootNames;
101 
102     /**
103      * Configuration overrides to apply, keyed by type of property.
104      *
105      * @since 2.8
106      */
107     protected final ConfigOverrides _configOverrides;
108 
109     /*
110     /**********************************************************
111     /* Construction
112     /**********************************************************
113      */
114 
115     /**
116      * Constructor used when creating a new instance (compared to
117      * that of creating fluent copies)
118      *
119      * @since 2.8
120      */
MapperConfigBase(BaseSettings base, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides)121     protected MapperConfigBase(BaseSettings base,
122             SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames,
123             ConfigOverrides configOverrides)
124     {
125         super(base, DEFAULT_MAPPER_FEATURES);
126         _mixIns = mixins;
127         _subtypeResolver = str;
128         _rootNames = rootNames;
129         _rootName = null;
130         _view = null;
131         // default to "no attributes"
132         _attributes = ContextAttributes.getEmpty();
133         _configOverrides = configOverrides;
134     }
135 
136     /**
137      * Copy constructor usually called to make a copy for use by
138      * ObjectMapper that is copied.
139      *
140      * @since 2.11.2
141      */
MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides)142     protected MapperConfigBase(MapperConfigBase<CFG,T> src,
143             SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames,
144             ConfigOverrides configOverrides)
145     {
146         // 18-Apr-2018, tatu: [databind#1898] need to force copying of `ClassIntrospector`
147         //    (to clear its cache) to avoid leakage
148         super(src, src._base.copy());
149         _mixIns = mixins;
150         _subtypeResolver = str;
151         _rootNames = rootNames;
152         _rootName = src._rootName;
153         _view = src._view;
154         _attributes = src._attributes;
155         _configOverrides = configOverrides;
156     }
157 
158     /**
159      * Pass-through constructor used when no changes are needed to the
160      * base class.
161      */
MapperConfigBase(MapperConfigBase<CFG,T> src)162     protected MapperConfigBase(MapperConfigBase<CFG,T> src)
163     {
164         super(src);
165         _mixIns = src._mixIns;
166         _subtypeResolver = src._subtypeResolver;
167         _rootNames = src._rootNames;
168         _rootName = src._rootName;
169         _view = src._view;
170         _attributes = src._attributes;
171         _configOverrides = src._configOverrides;
172     }
173 
MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)174     protected MapperConfigBase(MapperConfigBase<CFG,T> src, BaseSettings base)
175     {
176         super(src, base);
177         _mixIns = src._mixIns;
178         _subtypeResolver = src._subtypeResolver;
179         _rootNames = src._rootNames;
180         _rootName = src._rootName;
181         _view = src._view;
182         _attributes = src._attributes;
183         _configOverrides = src._configOverrides;
184     }
185 
MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)186     protected MapperConfigBase(MapperConfigBase<CFG,T> src, int mapperFeatures)
187     {
188         super(src, mapperFeatures);
189         _mixIns = src._mixIns;
190         _subtypeResolver = src._subtypeResolver;
191         _rootNames = src._rootNames;
192         _rootName = src._rootName;
193         _view = src._view;
194         _attributes = src._attributes;
195         _configOverrides = src._configOverrides;
196     }
197 
MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str)198     protected MapperConfigBase(MapperConfigBase<CFG,T> src, SubtypeResolver str) {
199         super(src);
200         _mixIns = src._mixIns;
201         _subtypeResolver = str;
202         _rootNames = src._rootNames;
203         _rootName = src._rootName;
204         _view = src._view;
205         _attributes = src._attributes;
206         _configOverrides = src._configOverrides;
207     }
208 
MapperConfigBase(MapperConfigBase<CFG,T> src, PropertyName rootName)209     protected MapperConfigBase(MapperConfigBase<CFG,T> src, PropertyName rootName) {
210         super(src);
211         _mixIns = src._mixIns;
212         _subtypeResolver = src._subtypeResolver;
213         _rootNames = src._rootNames;
214         _rootName = rootName;
215         _view = src._view;
216         _attributes = src._attributes;
217         _configOverrides = src._configOverrides;
218     }
219 
MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)220     protected MapperConfigBase(MapperConfigBase<CFG,T> src, Class<?> view)
221     {
222         super(src);
223         _mixIns = src._mixIns;
224         _subtypeResolver = src._subtypeResolver;
225         _rootNames = src._rootNames;
226         _rootName = src._rootName;
227         _view = view;
228         _attributes = src._attributes;
229         _configOverrides = src._configOverrides;
230     }
231 
232     /**
233      * @since 2.1
234      */
MapperConfigBase(MapperConfigBase<CFG,T> src, SimpleMixInResolver mixins)235     protected MapperConfigBase(MapperConfigBase<CFG,T> src, SimpleMixInResolver mixins)
236     {
237         super(src);
238         _mixIns = mixins;
239         _subtypeResolver = src._subtypeResolver;
240         _rootNames = src._rootNames;
241         _rootName = src._rootName;
242         _view = src._view;
243         _attributes = src._attributes;
244         _configOverrides = src._configOverrides;
245     }
246 
247     /**
248      * @since 2.3
249      */
MapperConfigBase(MapperConfigBase<CFG,T> src, ContextAttributes attr)250     protected MapperConfigBase(MapperConfigBase<CFG,T> src, ContextAttributes attr)
251     {
252         super(src);
253         _mixIns = src._mixIns;
254         _subtypeResolver = src._subtypeResolver;
255         _rootNames = src._rootNames;
256         _rootName = src._rootName;
257         _view = src._view;
258         _attributes = attr;
259         _configOverrides = src._configOverrides;
260     }
261 
262     /*
263     /**********************************************************
264     /* Abstract fluent factory methods to be implemented by subtypes
265     /**********************************************************
266      */
267 
268     /**
269      * @since 2.9 (in this case, demoted from sub-classes)
270      */
_withBase(BaseSettings newBase)271     protected abstract T _withBase(BaseSettings newBase);
272 
273     /**
274      * @since 2.9 (in this case, demoted from sub-classes)
275      */
_withMapperFeatures(int mapperFeatures)276     protected abstract T _withMapperFeatures(int mapperFeatures);
277 
278     /*
279     /**********************************************************
280     /* Additional shared fluent factory methods; features
281     /**********************************************************
282      */
283 
284     /**
285      * Fluent factory method that will construct and return a new configuration
286      * object instance with specified features enabled.
287      */
288     @SuppressWarnings("unchecked")
289     @Override
with(MapperFeature... features)290     public final T with(MapperFeature... features)
291     {
292         int newMapperFlags = _mapperFeatures;
293         for (MapperFeature f : features) {
294             newMapperFlags |= f.getMask();
295         }
296         if (newMapperFlags == _mapperFeatures) {
297             return (T) this;
298         }
299         return _withMapperFeatures(newMapperFlags);
300     }
301 
302     /**
303      * Fluent factory method that will construct and return a new configuration
304      * object instance with specified features disabled.
305      */
306     @SuppressWarnings("unchecked")
307     @Override
without(MapperFeature... features)308     public final T without(MapperFeature... features)
309     {
310         int newMapperFlags = _mapperFeatures;
311         for (MapperFeature f : features) {
312              newMapperFlags &= ~f.getMask();
313         }
314         if (newMapperFlags == _mapperFeatures) {
315             return (T) this;
316         }
317         return _withMapperFeatures(newMapperFlags);
318     }
319 
320     @SuppressWarnings("unchecked")
321     @Override
with(MapperFeature feature, boolean state)322     public final T with(MapperFeature feature, boolean state)
323     {
324         int newMapperFlags;
325         if (state) {
326             newMapperFlags = _mapperFeatures | feature.getMask();
327         } else {
328             newMapperFlags = _mapperFeatures & ~feature.getMask();
329         }
330         if (newMapperFlags == _mapperFeatures) {
331             return (T) this;
332         }
333         return _withMapperFeatures(newMapperFlags);
334     }
335 
336     /*
337     /**********************************************************
338     /* Additional shared fluent factory methods; introspectors
339     /**********************************************************
340      */
341 
342     /**
343      * Method for constructing and returning a new instance with different
344      * {@link AnnotationIntrospector} to use (replacing old one).
345      *<p>
346      * NOTE: make sure to register new instance with <code>ObjectMapper</code>
347      * if directly calling this method.
348      */
with(AnnotationIntrospector ai)349     public final T with(AnnotationIntrospector ai) {
350         return _withBase(_base.withAnnotationIntrospector(ai));
351     }
352 
353     /**
354      * Method for constructing and returning a new instance with additional
355      * {@link AnnotationIntrospector} appended (as the lowest priority one)
356      */
withAppendedAnnotationIntrospector(AnnotationIntrospector ai)357     public final T withAppendedAnnotationIntrospector(AnnotationIntrospector ai) {
358         return _withBase(_base.withAppendedAnnotationIntrospector(ai));
359     }
360 
361     /**
362      * Method for constructing and returning a new instance with additional
363      * {@link AnnotationIntrospector} inserted (as the highest priority one)
364      */
withInsertedAnnotationIntrospector(AnnotationIntrospector ai)365     public final T withInsertedAnnotationIntrospector(AnnotationIntrospector ai) {
366         return _withBase(_base.withInsertedAnnotationIntrospector(ai));
367     }
368 
369     /**
370      * Method for constructing and returning a new instance with different
371      * {@link ClassIntrospector}
372      * to use.
373      *<p>
374      * NOTE: make sure to register new instance with <code>ObjectMapper</code>
375      * if directly calling this method.
376      */
with(ClassIntrospector ci)377     public final T with(ClassIntrospector ci) {
378         return _withBase(_base.withClassIntrospector(ci));
379     }
380 
381     /*
382     /**********************************************************
383     /* Additional shared fluent factory methods; attributes
384     /**********************************************************
385      */
386 
387     /**
388      * Method for constructing an instance that has specified
389      * contextual attributes.
390      *
391      * @since 2.3
392      */
with(ContextAttributes attrs)393     public abstract T with(ContextAttributes attrs);
394 
395     /**
396      * Method for constructing an instance that has only specified
397      * attributes, removing any attributes that exist before the call.
398      *
399      * @since 2.3
400      */
withAttributes(Map<?,?> attributes)401     public T withAttributes(Map<?,?> attributes) {
402         return with(getAttributes().withSharedAttributes(attributes));
403     }
404 
405     /**
406      * Method for constructing an instance that has specified
407      * value for attribute for given key.
408      *
409      * @since 2.3
410      */
withAttribute(Object key, Object value)411     public T withAttribute(Object key, Object value) {
412         return with(getAttributes().withSharedAttribute(key, value));
413     }
414 
415     /**
416      * Method for constructing an instance that has no
417      * value for attribute for given key.
418      *
419      * @since 2.3
420      */
withoutAttribute(Object key)421     public T withoutAttribute(Object key) {
422         return with(getAttributes().withoutSharedAttribute(key));
423     }
424 
425     /*
426     /**********************************************************
427     /* Additional shared fluent factory methods; factories
428     /**********************************************************
429      */
430 
431     /**
432      * Method for constructing and returning a new instance with different
433      * {@link TypeFactory}
434      * to use.
435      */
with(TypeFactory tf)436     public final T with(TypeFactory tf) {
437         return _withBase( _base.withTypeFactory(tf));
438     }
439 
440     /**
441      * Method for constructing and returning a new instance with different
442      * {@link TypeResolverBuilder} to use.
443      */
with(TypeResolverBuilder<?> trb)444     public final T with(TypeResolverBuilder<?> trb) {
445         return _withBase(_base.withTypeResolverBuilder(trb));
446     }
447 
448     /**
449      * Method for constructing and returning a new instance with different
450      * {@link PropertyNamingStrategy}
451      * to use.
452      *<p>
453      * NOTE: make sure to register new instance with <code>ObjectMapper</code>
454      * if directly calling this method.
455      */
with(PropertyNamingStrategy pns)456     public final T with(PropertyNamingStrategy pns) {
457         return _withBase(_base.withPropertyNamingStrategy(pns));
458     }
459 
460     /**
461      * Method for constructing and returning a new instance with different
462      * {@link HandlerInstantiator}
463      * to use.
464      *<p>
465      * NOTE: make sure to register new instance with <code>ObjectMapper</code>
466      * if directly calling this method.
467      */
with(HandlerInstantiator hi)468     public final T with(HandlerInstantiator hi) {
469         return _withBase(_base.withHandlerInstantiator(hi));
470     }
471 
472     /*
473     /**********************************************************
474     /* Additional shared fluent factory methods; other
475     /**********************************************************
476      */
477 
478     /**
479      * Method for constructing and returning a new instance with different
480      * default {@link Base64Variant} to use with base64-encoded binary values.
481      */
with(Base64Variant base64)482     public final T with(Base64Variant base64) {
483         return _withBase(_base.with(base64));
484     }
485 
486     /**
487      * Method for constructing and returning a new instance with different
488      * {@link DateFormat}
489      * to use.
490      *<p>
491      * NOTE: non-final since <code>SerializationConfig</code> needs to override this
492      */
with(DateFormat df)493     public T with(DateFormat df) {
494         return _withBase(_base.withDateFormat(df));
495     }
496 
497     /**
498      * Method for constructing and returning a new instance with different
499      * default {@link java.util.Locale} to use for formatting.
500      */
with(Locale l)501     public final T with(Locale l) {
502         return _withBase(_base.with(l));
503     }
504 
505     /**
506      * Method for constructing and returning a new instance with different
507      * default {@link java.util.TimeZone} to use for formatting of date values.
508      */
with(TimeZone tz)509     public final T with(TimeZone tz) {
510         return _withBase(_base.with(tz));
511     }
512 
513     /**
514      * Method for constructing and returning a new instance with different
515      * root name to use (none, if null).
516      *<p>
517      * Note that when a root name is set to a non-Empty String, this will automatically force use
518      * of root element wrapping with given name. If empty String passed, will
519      * disable root name wrapping; and if null used, will instead use
520      * <code>SerializationFeature</code> to determine if to use wrapping, and annotation
521      * (or default name) for actual root name to use.
522      *
523      * @param rootName to use: if null, means "use default" (clear setting);
524      *   if empty String ("") means that no root name wrapping is used;
525      *   otherwise defines root name to use.
526      *
527      * @since 2.6
528      */
withRootName(PropertyName rootName)529     public abstract T withRootName(PropertyName rootName);
530 
withRootName(String rootName)531     public T withRootName(String rootName) {
532         if (rootName == null) {
533             return withRootName((PropertyName) null);
534         }
535         return withRootName(PropertyName.construct(rootName));
536     }
537 
538     /**
539      * Method for constructing and returning a new instance with different
540      * {@link SubtypeResolver}
541      * to use.
542      *<p>
543      * NOTE: make sure to register new instance with <code>ObjectMapper</code>
544      * if directly calling this method.
545      */
with(SubtypeResolver str)546     public abstract T with(SubtypeResolver str);
547 
548     /**
549      * Method for constructing and returning a new instance with different
550      * view to use.
551      */
withView(Class<?> view)552     public abstract T withView(Class<?> view);
553 
554     /*
555     /**********************************************************
556     /* Simple accessors
557     /**********************************************************
558      */
559 
560     /**
561      * Accessor for object used for finding out all reachable subtypes
562      * for supertypes; needed when a logical type name is used instead
563      * of class name (or custom scheme).
564      */
565     @Override
getSubtypeResolver()566     public final SubtypeResolver getSubtypeResolver() {
567         return _subtypeResolver;
568     }
569 
570     /**
571      * @deprecated Since 2.6 use {@link #getFullRootName} instead.
572      */
573     @Deprecated // since 2.6
getRootName()574     public final String getRootName() {
575         return (_rootName == null) ? null : _rootName.getSimpleName();
576     }
577 
578     /**
579      * @since 2.6
580      */
getFullRootName()581     public final PropertyName getFullRootName() {
582         return _rootName;
583     }
584 
585     @Override
getActiveView()586     public final Class<?> getActiveView() {
587         return _view;
588     }
589 
590     @Override
getAttributes()591     public final ContextAttributes getAttributes() {
592         return _attributes;
593     }
594 
595     /*
596     /**********************************************************
597     /* Configuration access; default/overrides
598     /**********************************************************
599      */
600 
601     @Override
getConfigOverride(Class<?> type)602     public final ConfigOverride getConfigOverride(Class<?> type) {
603         ConfigOverride override = _configOverrides.findOverride(type);
604         return (override == null) ? EMPTY_OVERRIDE : override;
605     }
606 
607     @Override
findConfigOverride(Class<?> type)608     public final ConfigOverride findConfigOverride(Class<?> type) {
609         return _configOverrides.findOverride(type);
610     }
611 
612     @Override
getDefaultPropertyInclusion()613     public final JsonInclude.Value getDefaultPropertyInclusion() {
614         return _configOverrides.getDefaultInclusion();
615     }
616 
617     @Override
getDefaultPropertyInclusion(Class<?> baseType)618     public final JsonInclude.Value getDefaultPropertyInclusion(Class<?> baseType) {
619         JsonInclude.Value v = getConfigOverride(baseType).getInclude();
620         JsonInclude.Value def = getDefaultPropertyInclusion();
621         if (def == null) {
622             return v;
623         }
624         return def.withOverrides(v);
625     }
626 
627     @Override
getDefaultInclusion(Class<?> baseType, Class<?> propertyType)628     public final JsonInclude.Value getDefaultInclusion(Class<?> baseType,
629             Class<?> propertyType) {
630         JsonInclude.Value v = getConfigOverride(propertyType).getIncludeAsProperty();
631         JsonInclude.Value def = getDefaultPropertyInclusion(baseType);
632         if (def == null) {
633             return v;
634         }
635         return def.withOverrides(v);
636     }
637 
638     @Override
getDefaultPropertyFormat(Class<?> type)639     public final JsonFormat.Value getDefaultPropertyFormat(Class<?> type) {
640         return _configOverrides.findFormatDefaults(type);
641     }
642 
643     @Override
getDefaultPropertyIgnorals(Class<?> type)644     public final JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> type) {
645         ConfigOverride overrides = _configOverrides.findOverride(type);
646         if (overrides != null) {
647             JsonIgnoreProperties.Value v = overrides.getIgnorals();
648             if (v != null) {
649                 return v;
650             }
651         }
652         // 01-May-2015, tatu: Could return `Value.empty()` but for now `null`
653         //   seems simpler as callers can avoid processing.
654         return null;
655     }
656 
657     @Override
getDefaultPropertyIgnorals(Class<?> baseType, AnnotatedClass actualClass)658     public final JsonIgnoreProperties.Value getDefaultPropertyIgnorals(Class<?> baseType,
659             AnnotatedClass actualClass)
660     {
661         AnnotationIntrospector intr = getAnnotationIntrospector();
662         JsonIgnoreProperties.Value base = (intr == null) ? null
663                 : intr.findPropertyIgnoralByName(this, actualClass);
664         JsonIgnoreProperties.Value overrides = getDefaultPropertyIgnorals(baseType);
665         return JsonIgnoreProperties.Value.merge(base, overrides);
666     }
667 
668     @Override
getDefaultPropertyInclusions(Class<?> baseType, AnnotatedClass actualClass)669     public final JsonIncludeProperties.Value getDefaultPropertyInclusions(Class<?> baseType,
670             AnnotatedClass actualClass)
671     {
672         AnnotationIntrospector intr = getAnnotationIntrospector();
673         return (intr == null) ? null : intr.findPropertyInclusionByName(this, actualClass);
674     }
675 
676     @Override
getDefaultVisibilityChecker()677     public final VisibilityChecker<?> getDefaultVisibilityChecker()
678     {
679         VisibilityChecker<?> vchecker = _configOverrides.getDefaultVisibility();
680         // then global overrides (disabling)
681         // 05-Mar-2018, tatu: As per [databind#1947], need to see if any disabled
682         if ((_mapperFeatures & AUTO_DETECT_MASK) != AUTO_DETECT_MASK) {
683             if (!isEnabled(MapperFeature.AUTO_DETECT_FIELDS)) {
684                 vchecker = vchecker.withFieldVisibility(Visibility.NONE);
685             }
686             if (!isEnabled(MapperFeature.AUTO_DETECT_GETTERS)) {
687                 vchecker = vchecker.withGetterVisibility(Visibility.NONE);
688             }
689             if (!isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)) {
690                 vchecker = vchecker.withIsGetterVisibility(Visibility.NONE);
691             }
692             if (!isEnabled(MapperFeature.AUTO_DETECT_SETTERS)) {
693                 vchecker = vchecker.withSetterVisibility(Visibility.NONE);
694             }
695             if (!isEnabled(MapperFeature.AUTO_DETECT_CREATORS)) {
696                 vchecker = vchecker.withCreatorVisibility(Visibility.NONE);
697             }
698         }
699         return vchecker;
700     }
701 
702     @Override // since 2.9
getDefaultVisibilityChecker(Class<?> baseType, AnnotatedClass actualClass)703     public final VisibilityChecker<?> getDefaultVisibilityChecker(Class<?> baseType,
704             AnnotatedClass actualClass) {
705         VisibilityChecker<?> vc = getDefaultVisibilityChecker();
706         AnnotationIntrospector intr = getAnnotationIntrospector();
707         if (intr != null) {
708             vc = intr.findAutoDetectVisibility(actualClass, vc);
709         }
710         ConfigOverride overrides = _configOverrides.findOverride(baseType);
711         if (overrides != null) {
712             vc = vc.withOverrides(overrides.getVisibility()); // ok to pass null
713         }
714         return vc;
715     }
716 
717     @Override
getDefaultSetterInfo()718     public final JsonSetter.Value getDefaultSetterInfo() {
719         return _configOverrides.getDefaultSetterInfo();
720     }
721 
722     @Override
getDefaultMergeable()723     public Boolean getDefaultMergeable() {
724         return _configOverrides.getDefaultMergeable();
725     }
726 
727     @Override
getDefaultMergeable(Class<?> baseType)728     public Boolean getDefaultMergeable(Class<?> baseType) {
729         Boolean b;
730         ConfigOverride cfg = _configOverrides.findOverride(baseType);
731         if (cfg != null) {
732             b = cfg.getMergeable();
733             if (b != null) {
734                 return b;
735             }
736         }
737         return _configOverrides.getDefaultMergeable();
738     }
739 
740     /*
741     /**********************************************************
742     /* Other config access
743     /**********************************************************
744      */
745 
746     @Override
findRootName(JavaType rootType)747     public PropertyName findRootName(JavaType rootType) {
748         if (_rootName != null) {
749             return _rootName;
750         }
751         return _rootNames.findRootName(rootType, this);
752     }
753 
754     @Override
findRootName(Class<?> rawRootType)755     public PropertyName findRootName(Class<?> rawRootType) {
756         if (_rootName != null) {
757             return _rootName;
758         }
759         return _rootNames.findRootName(rawRootType, this);
760     }
761 
762     /*
763     /**********************************************************
764     /* ClassIntrospector.MixInResolver impl:
765     /**********************************************************
766      */
767 
768     /**
769      * Method that will check if there are "mix-in" classes (with mix-in
770      * annotations) for given class
771      */
772     @Override
findMixInClassFor(Class<?> cls)773     public final Class<?> findMixInClassFor(Class<?> cls) {
774         return _mixIns.findMixInClassFor(cls);
775     }
776 
777     // Not really relevant here (should not get called)
778     @Override
copy()779     public MixInResolver copy() {
780         throw new UnsupportedOperationException();
781     }
782 
783     /**
784      * Test-only method -- does not reflect possibly open-ended set that external
785      * mix-in resolver might provide.
786      */
mixInCount()787     public final int mixInCount() {
788         return _mixIns.localSize();
789     }
790 }
791