• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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