1 package com.fasterxml.jackson.databind; 2 3 import java.util.*; 4 5 import com.fasterxml.jackson.core.*; 6 import com.fasterxml.jackson.core.json.JsonReadFeature; 7 import com.fasterxml.jackson.databind.cfg.*; 8 import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; 9 import com.fasterxml.jackson.databind.introspect.*; 10 import com.fasterxml.jackson.databind.jsontype.*; 11 import com.fasterxml.jackson.databind.node.JsonNodeFactory; 12 import com.fasterxml.jackson.databind.type.LogicalType; 13 import com.fasterxml.jackson.databind.util.LinkedNode; 14 import com.fasterxml.jackson.databind.util.RootNameLookup; 15 16 /** 17 * Object that contains baseline configuration for deserialization 18 * process. An instance is owned by {@link ObjectMapper}, which 19 * passes an immutable instance to be used for deserialization process. 20 *<p> 21 * Note that instances are considered immutable and as such no copies 22 * should need to be created for sharing; all copying is done with 23 * "fluent factory" methods. 24 */ 25 public final class DeserializationConfig 26 extends MapperConfigBase<DeserializationFeature, DeserializationConfig> 27 implements java.io.Serializable // since 2.1 28 { 29 // since 2.9 30 private static final long serialVersionUID = 2; 31 32 // since 2.10.1 33 private final static int DESER_FEATURE_DEFAULTS = collectFeatureDefaults(DeserializationFeature.class); 34 35 /* 36 /********************************************************** 37 /* Configured helper objects 38 /********************************************************** 39 */ 40 41 /** 42 * Linked list that contains all registered problem handlers. 43 * Implementation as front-added linked list allows for sharing 44 * of the list (tail) without copying the list. 45 */ 46 protected final LinkedNode<DeserializationProblemHandler> _problemHandlers; 47 48 /** 49 * Factory used for constructing {@link com.fasterxml.jackson.databind.JsonNode} instances. 50 */ 51 protected final JsonNodeFactory _nodeFactory; 52 53 /** 54 * @since 2.12 55 */ 56 protected final CoercionConfigs _coercionConfigs; 57 58 /* 59 /********************************************************** 60 /* Deserialization features 61 /********************************************************** 62 */ 63 64 /** 65 * Set of {@link DeserializationFeature}s enabled. 66 */ 67 protected final int _deserFeatures; 68 69 /* 70 /********************************************************** 71 /* Parser features: generic, format-specific 72 /********************************************************** 73 */ 74 75 /** 76 * States of {@link com.fasterxml.jackson.core.JsonParser.Feature}s to enable/disable. 77 */ 78 protected final int _parserFeatures; 79 80 /** 81 * Bitflag of {@link com.fasterxml.jackson.core.JsonParser.Feature}s to enable/disable 82 */ 83 protected final int _parserFeaturesToChange; 84 85 /** 86 * States of {@link com.fasterxml.jackson.core.FormatFeature}s to enable/disable. 87 * 88 * @since 2.7 89 */ 90 protected final int _formatReadFeatures; 91 92 /** 93 * Bitflag of {@link com.fasterxml.jackson.core.FormatFeature}s to enable/disable 94 * 95 * @since 2.7 96 */ 97 protected final int _formatReadFeaturesToChange; 98 99 /* 100 /********************************************************** 101 /* Life-cycle, primary constructors for new instances 102 /********************************************************** 103 */ 104 105 /** 106 * Constructor used by ObjectMapper to create default configuration object instance. 107 * 108 * @since 2.12 109 */ DeserializationConfig(BaseSettings base, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides, CoercionConfigs coercionConfigs)110 public DeserializationConfig(BaseSettings base, 111 SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, 112 ConfigOverrides configOverrides, 113 CoercionConfigs coercionConfigs) 114 { 115 super(base, str, mixins, rootNames, configOverrides); 116 _deserFeatures = DESER_FEATURE_DEFAULTS; 117 _problemHandlers = null; 118 _nodeFactory = JsonNodeFactory.instance; 119 _coercionConfigs = coercionConfigs; 120 _parserFeatures = 0; 121 _parserFeaturesToChange = 0; 122 _formatReadFeatures = 0; 123 _formatReadFeaturesToChange = 0; 124 } 125 126 /** 127 * Copy-constructor used for making a copy used by new {@link ObjectMapper}. 128 * 129 * @since 2.12 130 */ DeserializationConfig(DeserializationConfig src, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides, CoercionConfigs coercionConfigs)131 protected DeserializationConfig(DeserializationConfig src, 132 SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, 133 ConfigOverrides configOverrides, 134 CoercionConfigs coercionConfigs) 135 { 136 super(src, str, mixins, rootNames, configOverrides); 137 _deserFeatures = src._deserFeatures; 138 _problemHandlers = src._problemHandlers; 139 _nodeFactory = src._nodeFactory; 140 _coercionConfigs = coercionConfigs; 141 _parserFeatures = src._parserFeatures; 142 _parserFeaturesToChange = src._parserFeaturesToChange; 143 _formatReadFeatures = src._formatReadFeatures; 144 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 145 } 146 147 @Deprecated // since 2.12, remove from 2.13 or later DeserializationConfig(BaseSettings base, SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides)148 public DeserializationConfig(BaseSettings base, 149 SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames, 150 ConfigOverrides configOverrides) { 151 this(base, str, mixins, rootNames, configOverrides, new CoercionConfigs()); 152 } 153 154 @Deprecated // since 2.11.2, remove from 2.13 or later DeserializationConfig(DeserializationConfig src, SimpleMixInResolver mixins, RootNameLookup rootNames, ConfigOverrides configOverrides)155 protected DeserializationConfig(DeserializationConfig src, 156 SimpleMixInResolver mixins, RootNameLookup rootNames, 157 ConfigOverrides configOverrides) { 158 this(src, src._subtypeResolver, mixins, rootNames, configOverrides, new CoercionConfigs()); 159 } 160 161 /* 162 /********************************************************** 163 /* Life-cycle, secondary constructors to support 164 /* "mutant factories", with single property changes 165 /********************************************************** 166 */ 167 DeserializationConfig(DeserializationConfig src, int mapperFeatures, int deserFeatures, int parserFeatures, int parserFeatureMask, int formatFeatures, int formatFeatureMask)168 private DeserializationConfig(DeserializationConfig src, 169 int mapperFeatures, int deserFeatures, 170 int parserFeatures, int parserFeatureMask, 171 int formatFeatures, int formatFeatureMask) 172 { 173 super(src, mapperFeatures); 174 _deserFeatures = deserFeatures; 175 _problemHandlers = src._problemHandlers; 176 _nodeFactory = src._nodeFactory; 177 _coercionConfigs = src._coercionConfigs; 178 _parserFeatures = parserFeatures; 179 _parserFeaturesToChange = parserFeatureMask; 180 _formatReadFeatures = formatFeatures; 181 _formatReadFeaturesToChange = formatFeatureMask; 182 } 183 184 /** 185 * Copy constructor used to create a non-shared instance with given mix-in 186 * annotation definitions and subtype resolver. 187 */ DeserializationConfig(DeserializationConfig src, SubtypeResolver str)188 private DeserializationConfig(DeserializationConfig src, SubtypeResolver str) 189 { 190 super(src, str); 191 _deserFeatures = src._deserFeatures; 192 _problemHandlers = src._problemHandlers; 193 _nodeFactory = src._nodeFactory; 194 _coercionConfigs = src._coercionConfigs; 195 _parserFeatures = src._parserFeatures; 196 _parserFeaturesToChange = src._parserFeaturesToChange; 197 _formatReadFeatures = src._formatReadFeatures; 198 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 199 } 200 DeserializationConfig(DeserializationConfig src, BaseSettings base)201 private DeserializationConfig(DeserializationConfig src, BaseSettings base) 202 { 203 super(src, base); 204 _deserFeatures = src._deserFeatures; 205 _problemHandlers = src._problemHandlers; 206 _nodeFactory = src._nodeFactory; 207 _coercionConfigs = src._coercionConfigs; 208 _parserFeatures = src._parserFeatures; 209 _parserFeaturesToChange = src._parserFeaturesToChange; 210 _formatReadFeatures = src._formatReadFeatures; 211 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 212 } 213 DeserializationConfig(DeserializationConfig src, JsonNodeFactory f)214 private DeserializationConfig(DeserializationConfig src, JsonNodeFactory f) 215 { 216 super(src); 217 _deserFeatures = src._deserFeatures; 218 _problemHandlers = src._problemHandlers; 219 _nodeFactory = f; 220 _coercionConfigs = src._coercionConfigs; 221 _parserFeatures = src._parserFeatures; 222 _parserFeaturesToChange = src._parserFeaturesToChange; 223 _formatReadFeatures = src._formatReadFeatures; 224 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 225 } 226 DeserializationConfig(DeserializationConfig src, LinkedNode<DeserializationProblemHandler> problemHandlers)227 private DeserializationConfig(DeserializationConfig src, 228 LinkedNode<DeserializationProblemHandler> problemHandlers) 229 { 230 super(src); 231 _deserFeatures = src._deserFeatures; 232 _problemHandlers = problemHandlers; 233 _nodeFactory = src._nodeFactory; 234 _coercionConfigs = src._coercionConfigs; 235 _parserFeatures = src._parserFeatures; 236 _parserFeaturesToChange = src._parserFeaturesToChange; 237 _formatReadFeatures = src._formatReadFeatures; 238 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 239 } 240 DeserializationConfig(DeserializationConfig src, PropertyName rootName)241 private DeserializationConfig(DeserializationConfig src, PropertyName rootName) 242 { 243 super(src, rootName); 244 _deserFeatures = src._deserFeatures; 245 _problemHandlers = src._problemHandlers; 246 _nodeFactory = src._nodeFactory; 247 _coercionConfigs = src._coercionConfigs; 248 _parserFeatures = src._parserFeatures; 249 _parserFeaturesToChange = src._parserFeaturesToChange; 250 _formatReadFeatures = src._formatReadFeatures; 251 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 252 } 253 DeserializationConfig(DeserializationConfig src, Class<?> view)254 private DeserializationConfig(DeserializationConfig src, Class<?> view) 255 { 256 super(src, view); 257 _deserFeatures = src._deserFeatures; 258 _problemHandlers = src._problemHandlers; 259 _nodeFactory = src._nodeFactory; 260 _coercionConfigs = src._coercionConfigs; 261 _parserFeatures = src._parserFeatures; 262 _parserFeaturesToChange = src._parserFeaturesToChange; 263 _formatReadFeatures = src._formatReadFeatures; 264 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 265 } 266 DeserializationConfig(DeserializationConfig src, ContextAttributes attrs)267 protected DeserializationConfig(DeserializationConfig src, ContextAttributes attrs) 268 { 269 super(src, attrs); 270 _deserFeatures = src._deserFeatures; 271 _problemHandlers = src._problemHandlers; 272 _nodeFactory = src._nodeFactory; 273 _coercionConfigs = src._coercionConfigs; 274 _parserFeatures = src._parserFeatures; 275 _parserFeaturesToChange = src._parserFeaturesToChange; 276 _formatReadFeatures = src._formatReadFeatures; 277 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 278 } 279 DeserializationConfig(DeserializationConfig src, SimpleMixInResolver mixins)280 protected DeserializationConfig(DeserializationConfig src, SimpleMixInResolver mixins) 281 { 282 super(src, mixins); 283 _deserFeatures = src._deserFeatures; 284 _problemHandlers = src._problemHandlers; 285 _nodeFactory = src._nodeFactory; 286 _coercionConfigs = src._coercionConfigs; 287 _parserFeatures = src._parserFeatures; 288 _parserFeaturesToChange = src._parserFeaturesToChange; 289 _formatReadFeatures = src._formatReadFeatures; 290 _formatReadFeaturesToChange = src._formatReadFeaturesToChange; 291 } 292 293 // for unit tests only: getBaseSettings()294 protected BaseSettings getBaseSettings() { return _base; } 295 296 /* 297 /********************************************************** 298 /* Life-cycle, general factory methods from MapperConfig(Base) 299 /********************************************************** 300 */ 301 302 @Override // since 2.9 _withBase(BaseSettings newBase)303 protected final DeserializationConfig _withBase(BaseSettings newBase) { 304 return (_base == newBase) ? this : new DeserializationConfig(this, newBase); 305 } 306 307 @Override // since 2.9 _withMapperFeatures(int mapperFeatures)308 protected final DeserializationConfig _withMapperFeatures(int mapperFeatures) { 309 return new DeserializationConfig(this, mapperFeatures, _deserFeatures, 310 _parserFeatures, _parserFeaturesToChange, 311 _formatReadFeatures, _formatReadFeaturesToChange); 312 } 313 314 /* 315 /********************************************************** 316 /* Life-cycle, specific factory methods from MapperConfig 317 /********************************************************** 318 */ 319 320 @Override with(SubtypeResolver str)321 public DeserializationConfig with(SubtypeResolver str) { 322 return (_subtypeResolver == str) ? this : new DeserializationConfig(this, str); 323 } 324 325 @Override withRootName(PropertyName rootName)326 public DeserializationConfig withRootName(PropertyName rootName) { 327 if (rootName == null) { 328 if (_rootName == null) { 329 return this; 330 } 331 } else if (rootName.equals(_rootName)) { 332 return this; 333 } 334 return new DeserializationConfig(this, rootName); 335 } 336 337 @Override withView(Class<?> view)338 public DeserializationConfig withView(Class<?> view) { 339 return (_view == view) ? this : new DeserializationConfig(this, view); 340 } 341 342 @Override with(ContextAttributes attrs)343 public DeserializationConfig with(ContextAttributes attrs) { 344 return (attrs == _attributes) ? this : new DeserializationConfig(this, attrs); 345 } 346 347 /* 348 /********************************************************** 349 /* Life-cycle, DeserializationFeature-based factory methods 350 /********************************************************** 351 */ 352 353 /** 354 * Fluent factory method that will construct and return a new configuration 355 * object instance with specified features enabled. 356 */ with(DeserializationFeature feature)357 public DeserializationConfig with(DeserializationFeature feature) 358 { 359 int newDeserFeatures = (_deserFeatures | feature.getMask()); 360 return (newDeserFeatures == _deserFeatures) ? this : 361 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 362 _parserFeatures, _parserFeaturesToChange, 363 _formatReadFeatures, _formatReadFeaturesToChange); 364 } 365 366 /** 367 * Fluent factory method that will construct and return a new configuration 368 * object instance with specified features enabled. 369 */ with(DeserializationFeature first, DeserializationFeature... features)370 public DeserializationConfig with(DeserializationFeature first, 371 DeserializationFeature... features) 372 { 373 int newDeserFeatures = _deserFeatures | first.getMask(); 374 for (DeserializationFeature f : features) { 375 newDeserFeatures |= f.getMask(); 376 } 377 return (newDeserFeatures == _deserFeatures) ? this : 378 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 379 _parserFeatures, _parserFeaturesToChange, 380 _formatReadFeatures, _formatReadFeaturesToChange); 381 } 382 383 /** 384 * Fluent factory method that will construct and return a new configuration 385 * object instance with specified features enabled. 386 */ withFeatures(DeserializationFeature... features)387 public DeserializationConfig withFeatures(DeserializationFeature... features) 388 { 389 int newDeserFeatures = _deserFeatures; 390 for (DeserializationFeature f : features) { 391 newDeserFeatures |= f.getMask(); 392 } 393 return (newDeserFeatures == _deserFeatures) ? this : 394 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 395 _parserFeatures, _parserFeaturesToChange, 396 _formatReadFeatures, _formatReadFeaturesToChange); 397 } 398 399 /** 400 * Fluent factory method that will construct and return a new configuration 401 * object instance with specified feature disabled. 402 */ without(DeserializationFeature feature)403 public DeserializationConfig without(DeserializationFeature feature) 404 { 405 int newDeserFeatures = _deserFeatures & ~feature.getMask(); 406 return (newDeserFeatures == _deserFeatures) ? this : 407 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 408 _parserFeatures, _parserFeaturesToChange, 409 _formatReadFeatures, _formatReadFeaturesToChange); 410 } 411 412 /** 413 * Fluent factory method that will construct and return a new configuration 414 * object instance with specified features disabled. 415 */ without(DeserializationFeature first, DeserializationFeature... features)416 public DeserializationConfig without(DeserializationFeature first, 417 DeserializationFeature... features) 418 { 419 int newDeserFeatures = _deserFeatures & ~first.getMask(); 420 for (DeserializationFeature f : features) { 421 newDeserFeatures &= ~f.getMask(); 422 } 423 return (newDeserFeatures == _deserFeatures) ? this : 424 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 425 _parserFeatures, _parserFeaturesToChange, 426 _formatReadFeatures, _formatReadFeaturesToChange); 427 } 428 429 /** 430 * Fluent factory method that will construct and return a new configuration 431 * object instance with specified features disabled. 432 */ withoutFeatures(DeserializationFeature... features)433 public DeserializationConfig withoutFeatures(DeserializationFeature... features) 434 { 435 int newDeserFeatures = _deserFeatures; 436 for (DeserializationFeature f : features) { 437 newDeserFeatures &= ~f.getMask(); 438 } 439 return (newDeserFeatures == _deserFeatures) ? this : 440 new DeserializationConfig(this, _mapperFeatures, newDeserFeatures, 441 _parserFeatures, _parserFeaturesToChange, 442 _formatReadFeatures, _formatReadFeaturesToChange); 443 } 444 445 /* 446 /********************************************************** 447 /* Life-cycle, JsonParser.Feature-based factory methods 448 /********************************************************** 449 */ 450 451 /** 452 * Fluent factory method that will construct and return a new configuration 453 * object instance with specified features enabled. 454 * 455 * @since 2.5 456 */ with(JsonParser.Feature feature)457 public DeserializationConfig with(JsonParser.Feature feature) 458 { 459 int newSet = _parserFeatures | feature.getMask(); 460 int newMask = _parserFeaturesToChange | feature.getMask(); 461 return ((_parserFeatures == newSet) && (_parserFeaturesToChange == newMask)) ? this : 462 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 463 newSet, newMask, 464 _formatReadFeatures, _formatReadFeaturesToChange); 465 } 466 467 /** 468 * Fluent factory method that will construct and return a new configuration 469 * object instance with specified features enabled. 470 * 471 * @since 2.5 472 */ withFeatures(JsonParser.Feature... features)473 public DeserializationConfig withFeatures(JsonParser.Feature... features) 474 { 475 int newSet = _parserFeatures; 476 int newMask = _parserFeaturesToChange; 477 for (JsonParser.Feature f : features) { 478 int mask = f.getMask(); 479 newSet |= mask; 480 newMask |= mask; 481 } 482 return ((_parserFeatures == newSet) && (_parserFeaturesToChange == newMask)) ? this : 483 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 484 newSet, newMask, 485 _formatReadFeatures, _formatReadFeaturesToChange); 486 } 487 488 /** 489 * Fluent factory method that will construct and return a new configuration 490 * object instance with specified feature disabled. 491 * 492 * @since 2.5 493 */ without(JsonParser.Feature feature)494 public DeserializationConfig without(JsonParser.Feature feature) 495 { 496 int newSet = _parserFeatures & ~feature.getMask(); 497 int newMask = _parserFeaturesToChange | feature.getMask(); 498 return ((_parserFeatures == newSet) && (_parserFeaturesToChange == newMask)) ? this : 499 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 500 newSet, newMask, 501 _formatReadFeatures, _formatReadFeaturesToChange); 502 } 503 504 /** 505 * Fluent factory method that will construct and return a new configuration 506 * object instance with specified features disabled. 507 * 508 * @since 2.5 509 */ withoutFeatures(JsonParser.Feature... features)510 public DeserializationConfig withoutFeatures(JsonParser.Feature... features) 511 { 512 int newSet = _parserFeatures; 513 int newMask = _parserFeaturesToChange; 514 for (JsonParser.Feature f : features) { 515 int mask = f.getMask(); 516 newSet &= ~mask; 517 newMask |= mask; 518 } 519 return ((_parserFeatures == newSet) && (_parserFeaturesToChange == newMask)) ? this : 520 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 521 newSet, newMask, 522 _formatReadFeatures, _formatReadFeaturesToChange); 523 } 524 525 /* 526 /********************************************************** 527 /* Life-cycle, JsonParser.FormatFeature-based factory methods 528 /********************************************************** 529 */ 530 531 /** 532 * Fluent factory method that will construct and return a new configuration 533 * object instance with specified features enabled. 534 * 535 * @since 2.7 536 */ with(FormatFeature feature)537 public DeserializationConfig with(FormatFeature feature) 538 { 539 // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: 540 if (feature instanceof JsonReadFeature) { 541 return _withJsonReadFeatures(feature); 542 } 543 int newSet = _formatReadFeatures | feature.getMask(); 544 int newMask = _formatReadFeaturesToChange | feature.getMask(); 545 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : 546 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 547 _parserFeatures, _parserFeaturesToChange, 548 newSet, newMask); 549 } 550 551 /** 552 * Fluent factory method that will construct and return a new configuration 553 * object instance with specified features enabled. 554 * 555 * @since 2.7 556 */ withFeatures(FormatFeature... features)557 public DeserializationConfig withFeatures(FormatFeature... features) 558 { 559 // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: 560 if (features.length > 0 && (features[0] instanceof JsonReadFeature)) { 561 return _withJsonReadFeatures(features); 562 } 563 int newSet = _formatReadFeatures; 564 int newMask = _formatReadFeaturesToChange; 565 for (FormatFeature f : features) { 566 int mask = f.getMask(); 567 newSet |= mask; 568 newMask |= mask; 569 } 570 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : 571 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 572 _parserFeatures, _parserFeaturesToChange, 573 newSet, newMask); 574 } 575 576 /** 577 * Fluent factory method that will construct and return a new configuration 578 * object instance with specified feature disabled. 579 * 580 * @since 2.7 581 */ without(FormatFeature feature)582 public DeserializationConfig without(FormatFeature feature) 583 { 584 // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: 585 if (feature instanceof JsonReadFeature) { 586 return _withoutJsonReadFeatures(feature); 587 } 588 int newSet = _formatReadFeatures & ~feature.getMask(); 589 int newMask = _formatReadFeaturesToChange | feature.getMask(); 590 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : 591 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 592 _parserFeatures, _parserFeaturesToChange, 593 newSet, newMask); 594 } 595 596 /** 597 * Fluent factory method that will construct and return a new configuration 598 * object instance with specified features disabled. 599 * 600 * @since 2.7 601 */ withoutFeatures(FormatFeature... features)602 public DeserializationConfig withoutFeatures(FormatFeature... features) 603 { 604 // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: 605 if (features.length > 0 && (features[0] instanceof JsonReadFeature)) { 606 return _withoutJsonReadFeatures(features); 607 } 608 int newSet = _formatReadFeatures; 609 int newMask = _formatReadFeaturesToChange; 610 for (FormatFeature f : features) { 611 int mask = f.getMask(); 612 newSet &= ~mask; 613 newMask |= mask; 614 } 615 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : 616 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 617 _parserFeatures, _parserFeaturesToChange, 618 newSet, newMask); 619 } 620 621 // temporary for 2.10 _withJsonReadFeatures(FormatFeature... features)622 private DeserializationConfig _withJsonReadFeatures(FormatFeature... features) { 623 int parserSet = _parserFeatures; 624 int parserMask = _parserFeaturesToChange; 625 int newSet = _formatReadFeatures; 626 int newMask = _formatReadFeaturesToChange; 627 for (FormatFeature f : features) { 628 final int mask = f.getMask(); 629 newSet |= mask; 630 newMask |= mask; 631 632 if (f instanceof JsonReadFeature) { 633 JsonParser.Feature oldF = ((JsonReadFeature) f).mappedFeature(); 634 if (oldF != null) { 635 final int pmask = oldF.getMask(); 636 parserSet |= pmask; 637 parserMask |= pmask; 638 } 639 } 640 } 641 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask) 642 && (_parserFeatures == parserSet) && (_parserFeaturesToChange == parserMask) 643 ) ? this : 644 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 645 parserSet, parserMask, newSet, newMask); 646 } 647 648 // temporary for 2.10 _withoutJsonReadFeatures(FormatFeature... features)649 private DeserializationConfig _withoutJsonReadFeatures(FormatFeature... features) { 650 int parserSet = _parserFeatures; 651 int parserMask = _parserFeaturesToChange; 652 int newSet = _formatReadFeatures; 653 int newMask = _formatReadFeaturesToChange; 654 for (FormatFeature f : features) { 655 final int mask = f.getMask(); 656 newSet &= ~mask; 657 newMask |= mask; 658 659 if (f instanceof JsonReadFeature) { 660 JsonParser.Feature oldF = ((JsonReadFeature) f).mappedFeature(); 661 if (oldF != null) { 662 final int pmask = oldF.getMask(); 663 parserSet &= ~pmask; 664 parserMask |= pmask; 665 } 666 } 667 } 668 return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask) 669 && (_parserFeatures == parserSet) && (_parserFeaturesToChange == parserMask) 670 ) ? this : 671 new DeserializationConfig(this, _mapperFeatures, _deserFeatures, 672 parserSet, parserMask, newSet, newMask); 673 } 674 675 /* 676 /********************************************************** 677 /* Life-cycle, deserialization-specific factory methods 678 /********************************************************** 679 */ 680 681 /** 682 * Fluent factory method that will construct a new instance with 683 * specified {@link JsonNodeFactory} 684 */ with(JsonNodeFactory f)685 public DeserializationConfig with(JsonNodeFactory f) { 686 if (_nodeFactory == f) { 687 return this; 688 } 689 return new DeserializationConfig(this, f); 690 } 691 692 /** 693 * Method that can be used to add a handler that can (try to) 694 * resolve non-fatal deserialization problems. 695 */ withHandler(DeserializationProblemHandler h)696 public DeserializationConfig withHandler(DeserializationProblemHandler h) 697 { 698 // Sanity check: let's prevent adding same handler multiple times 699 if (LinkedNode.contains(_problemHandlers, h)) { 700 return this; 701 } 702 return new DeserializationConfig(this, 703 new LinkedNode<DeserializationProblemHandler>(h, _problemHandlers)); 704 } 705 706 /** 707 * Method for removing all configured problem handlers; usually done to replace 708 * existing handler(s) with different one(s) 709 */ withNoProblemHandlers()710 public DeserializationConfig withNoProblemHandlers() { 711 if (_problemHandlers == null) { 712 return this; 713 } 714 return new DeserializationConfig(this, 715 (LinkedNode<DeserializationProblemHandler>) null); 716 } 717 718 /* 719 /********************************************************** 720 /* JsonParser initialization 721 /********************************************************** 722 */ 723 724 /** 725 * Method called by {@link ObjectMapper} and {@link ObjectReader} 726 * to modify those {@link com.fasterxml.jackson.core.JsonParser.Feature} settings 727 * that have been configured via this config instance. 728 * 729 * @since 2.5 730 */ initialize(JsonParser p)731 public JsonParser initialize(JsonParser p) { 732 if (_parserFeaturesToChange != 0) { 733 p.overrideStdFeatures(_parserFeatures, _parserFeaturesToChange); 734 } 735 if (_formatReadFeaturesToChange != 0) { 736 p.overrideFormatFeatures(_formatReadFeatures, _formatReadFeaturesToChange); 737 } 738 return p; 739 } 740 741 /** 742 * @since 2.12 743 */ initialize(JsonParser p, FormatSchema schema)744 public JsonParser initialize(JsonParser p, FormatSchema schema) { 745 if (_parserFeaturesToChange != 0) { 746 p.overrideStdFeatures(_parserFeatures, _parserFeaturesToChange); 747 } 748 if (_formatReadFeaturesToChange != 0) { 749 p.overrideFormatFeatures(_formatReadFeatures, _formatReadFeaturesToChange); 750 } 751 if (schema != null) { 752 p.setSchema(schema); 753 } 754 return p; 755 } 756 757 /* 758 /********************************************************** 759 /* MapperConfig implementation/overrides: other 760 /********************************************************** 761 */ 762 763 @Override useRootWrapping()764 public boolean useRootWrapping() 765 { 766 if (_rootName != null) { // empty String disables wrapping; non-empty enables 767 return !_rootName.isEmpty(); 768 } 769 return isEnabled(DeserializationFeature.UNWRAP_ROOT_VALUE); 770 } 771 isEnabled(DeserializationFeature f)772 public final boolean isEnabled(DeserializationFeature f) { 773 return (_deserFeatures & f.getMask()) != 0; 774 } 775 isEnabled(JsonParser.Feature f, JsonFactory factory)776 public final boolean isEnabled(JsonParser.Feature f, JsonFactory factory) { 777 int mask = f.getMask(); 778 if ((_parserFeaturesToChange & mask) != 0) { 779 return (_parserFeatures & f.getMask()) != 0; 780 } 781 return factory.isEnabled(f); 782 } 783 784 /** 785 * Bulk access method for checking that all features specified by 786 * mask are enabled. 787 * 788 * @since 2.3 789 */ hasDeserializationFeatures(int featureMask)790 public final boolean hasDeserializationFeatures(int featureMask) { 791 return (_deserFeatures & featureMask) == featureMask; 792 } 793 794 /** 795 * Bulk access method for checking that at least one of features specified by 796 * mask is enabled. 797 * 798 * @since 2.6 799 */ hasSomeOfFeatures(int featureMask)800 public final boolean hasSomeOfFeatures(int featureMask) { 801 return (_deserFeatures & featureMask) != 0; 802 } 803 804 /** 805 * Bulk access method for getting the bit mask of all {@link DeserializationFeature}s 806 * that are enabled. 807 */ getDeserializationFeatures()808 public final int getDeserializationFeatures() { 809 return _deserFeatures; 810 } 811 812 /** 813 * Convenience method equivalant to: 814 *<code> 815 * isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS) 816 *</code> 817 * 818 * @since 2.9 819 */ requiresFullValue()820 public final boolean requiresFullValue() { 821 return DeserializationFeature.FAIL_ON_TRAILING_TOKENS.enabledIn(_deserFeatures); 822 } 823 824 /* 825 /********************************************************** 826 /* Other configuration 827 /********************************************************** 828 */ 829 830 /** 831 * Method for getting head of the problem handler chain. May be null, 832 * if no handlers have been added. 833 */ getProblemHandlers()834 public LinkedNode<DeserializationProblemHandler> getProblemHandlers() { 835 return _problemHandlers; 836 } 837 getNodeFactory()838 public final JsonNodeFactory getNodeFactory() { 839 return _nodeFactory; 840 } 841 842 /* 843 /********************************************************** 844 /* Introspection methods 845 /********************************************************** 846 */ 847 848 /** 849 * Method that will introspect full bean properties for the purpose 850 * of building a bean deserializer 851 * 852 * @param type Type of class to be introspected 853 */ 854 @SuppressWarnings("unchecked") introspect(JavaType type)855 public <T extends BeanDescription> T introspect(JavaType type) { 856 return (T) getClassIntrospector().forDeserialization(this, type, this); 857 } 858 859 /** 860 * Method that will introspect subset of bean properties needed to 861 * construct bean instance. 862 */ 863 @SuppressWarnings("unchecked") introspectForCreation(JavaType type)864 public <T extends BeanDescription> T introspectForCreation(JavaType type) { 865 return (T) getClassIntrospector().forCreation(this, type, this); 866 } 867 868 /** 869 * @since 2.0 870 */ 871 @SuppressWarnings("unchecked") introspectForBuilder(JavaType type)872 public <T extends BeanDescription> T introspectForBuilder(JavaType type) { 873 return (T) getClassIntrospector().forDeserializationWithBuilder(this, type, this); 874 } 875 876 /* 877 /********************************************************** 878 /* Support for polymorphic type handling 879 /********************************************************** 880 */ 881 882 /** 883 * Helper method that is needed to properly handle polymorphic referenced 884 * types, such as types referenced by {@link java.util.concurrent.atomic.AtomicReference}, 885 * or various "optional" types. 886 * 887 * @since 2.4 888 */ findTypeDeserializer(JavaType baseType)889 public TypeDeserializer findTypeDeserializer(JavaType baseType) 890 throws JsonMappingException 891 { 892 BeanDescription bean = introspectClassAnnotations(baseType.getRawClass()); 893 AnnotatedClass ac = bean.getClassInfo(); 894 TypeResolverBuilder<?> b = getAnnotationIntrospector().findTypeResolver(this, ac, baseType); 895 896 /* Ok: if there is no explicit type info handler, we may want to 897 * use a default. If so, config object knows what to use. 898 */ 899 Collection<NamedType> subtypes = null; 900 if (b == null) { 901 b = getDefaultTyper(baseType); 902 if (b == null) { 903 return null; 904 } 905 } else { 906 subtypes = getSubtypeResolver().collectAndResolveSubtypesByTypeId(this, ac); 907 } 908 return b.buildTypeDeserializer(this, baseType, subtypes); 909 } 910 911 /* 912 /********************************************************************** 913 /* CoercionConfig access 914 /********************************************************************** 915 */ 916 917 /** 918 * General-purpose accessor for finding what to do when specified coercion 919 * from shape that is now always allowed to be coerced from is requested. 920 * 921 * @param targetType Logical target type of coercion 922 * @param targetClass Physical target type of coercion 923 * @param inputShape Input shape to coerce from 924 * 925 * @return CoercionAction configured for specific coercion 926 * 927 * @since 2.12 928 */ findCoercionAction(LogicalType targetType, Class<?> targetClass, CoercionInputShape inputShape)929 public CoercionAction findCoercionAction(LogicalType targetType, 930 Class<?> targetClass, CoercionInputShape inputShape) 931 { 932 return _coercionConfigs.findCoercion(this, 933 targetType, targetClass, inputShape); 934 } 935 936 /** 937 * More specialized accessor called in case of input being a blank 938 * String (one consisting of only white space characters with length of at least one). 939 * Will basically first determine if "blank as empty" is allowed: if not, 940 * returns {@code actionIfBlankNotAllowed}, otherwise returns action for 941 * {@link CoercionInputShape#EmptyString}. 942 * 943 * @param targetType Logical target type of coercion 944 * @param targetClass Physical target type of coercion 945 * @param actionIfBlankNotAllowed Return value to use in case "blanks as empty" 946 * is not allowed 947 * 948 * @return CoercionAction configured for specified coercion from blank string 949 * 950 * @since 2.12 951 */ findCoercionFromBlankString(LogicalType targetType, Class<?> targetClass, CoercionAction actionIfBlankNotAllowed)952 public CoercionAction findCoercionFromBlankString(LogicalType targetType, 953 Class<?> targetClass, 954 CoercionAction actionIfBlankNotAllowed) 955 { 956 return _coercionConfigs.findCoercionFromBlankString(this, 957 targetType, targetClass, actionIfBlankNotAllowed); 958 } 959 } 960