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