1 package com.fasterxml.jackson.databind;
2
3 import java.text.DateFormat;
4
5 import com.fasterxml.jackson.annotation.*;
6
7 import com.fasterxml.jackson.core.*;
8 import com.fasterxml.jackson.core.json.JsonWriteFeature;
9 import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
10 import com.fasterxml.jackson.core.util.Instantiatable;
11
12 import com.fasterxml.jackson.databind.cfg.*;
13 import com.fasterxml.jackson.databind.introspect.SimpleMixInResolver;
14 import com.fasterxml.jackson.databind.jsontype.SubtypeResolver;
15 import com.fasterxml.jackson.databind.ser.FilterProvider;
16 import com.fasterxml.jackson.databind.ser.SerializerFactory;
17 import com.fasterxml.jackson.databind.util.RootNameLookup;
18
19 /**
20  * Object that contains baseline configuration for serialization
21  * process. An instance is owned by {@link ObjectMapper}, which
22  * passes an immutable instance for serialization process to
23  * {@link SerializerProvider} and {@link SerializerFactory}
24  * (either directly, or through {@link ObjectWriter}.
25  *<p>
26  * Note that instances are considered immutable and as such no copies
27  * should need to be created for sharing; all copying is done with
28  * "fluent factory" methods.
29  */

30 public final class SerializationConfig
31     extends MapperConfigBase<SerializationFeature, SerializationConfig>
32     implements java.io.Serializable // since 2.1
33 {
34     // since 2.5
35     private static final long serialVersionUID = 1;
36
37     // since 2.6
38     protected final static PrettyPrinter DEFAULT_PRETTY_PRINTER = new DefaultPrettyPrinter();
39
40     // since 2.10.1
41     private final static int SER_FEATURE_DEFAULTS = collectFeatureDefaults(SerializationFeature.class);
42
43     /*
44     /**********************************************************
45     /* Configured helper objects
46     /**********************************************************
47      */

48
49     /**
50      * Object used for resolving filter ids to filter instances.
51      * Non-null if explicitly defined; null by default.
52      */

53     protected final FilterProvider _filterProvider;
54
55     /**
56      * If "default pretty-printing" is enabled, it will create the instance
57      * from this blueprint object.
58      *
59      * @since 2.6
60      */

61     protected final PrettyPrinter _defaultPrettyPrinter;
62
63     /*
64     /**********************************************************
65     /* Serialization features 
66     /**********************************************************
67      */

68
69     /**
70      * Set of {@link SerializationFeature}s enabled.
71      */

72     protected final int _serFeatures;
73
74     /*
75     /**********************************************************
76     /* Generator features: generic, format-specific
77     /**********************************************************
78      */

79     /**
80      * States of {@link com.fasterxml.jackson.core.JsonGenerator.Feature}s to enable/disable.
81      */

82     protected final int _generatorFeatures;
83
84     /**
85      * Bitflag of {@link com.fasterxml.jackson.core.JsonGenerator.Feature}s to enable/disable
86      */

87     protected final int _generatorFeaturesToChange;
88
89     /**
90      * States of {@link com.fasterxml.jackson.core.FormatFeature}s to enable/disable.
91      *
92      * @since 2.7
93      */

94     protected final int _formatWriteFeatures;
95
96     /**
97      * Bitflag of {@link com.fasterxml.jackson.core.FormatFeature}s to enable/disable
98      *
99      * @since 2.7
100      */

101     protected final int _formatWriteFeaturesToChange;
102
103     /*
104     /**********************************************************
105     /* Life-cycle, primary constructors for new instances
106     /**********************************************************
107      */

108
109     /**
110      * Constructor used by ObjectMapper to create default configuration object instance.
111      *
112      * @since 2.9
113      */

114     public SerializationConfig(BaseSettings base,
115             SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames,
116             ConfigOverrides configOverrides)
117     {
118         super(base, str, mixins, rootNames, configOverrides);
119         _serFeatures = SER_FEATURE_DEFAULTS;
120         _filterProvider = null;
121         _defaultPrettyPrinter = DEFAULT_PRETTY_PRINTER;
122         _generatorFeatures = 0;
123         _generatorFeaturesToChange = 0;
124         _formatWriteFeatures = 0;
125         _formatWriteFeaturesToChange = 0;
126     }
127
128     /**
129      * Copy-constructor used for making a copy to be used by new {@link ObjectMapper}.
130      *
131      * @since 2.11.2
132      */

133     protected SerializationConfig(SerializationConfig src,
134             SubtypeResolver str, SimpleMixInResolver mixins, RootNameLookup rootNames,
135             ConfigOverrides configOverrides)
136     {
137         super(src, str, mixins, rootNames, configOverrides);
138         _serFeatures = src._serFeatures;
139         _filterProvider = src._filterProvider;
140         _defaultPrettyPrinter = src._defaultPrettyPrinter;
141         _generatorFeatures = src._generatorFeatures;
142         _generatorFeaturesToChange = src._generatorFeaturesToChange;
143         _formatWriteFeatures = src._formatWriteFeatures;
144         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
145     }
146
147     /**
148      * @since 2.9
149      * @deprecated since 2.11.2
150      */

151     @Deprecated
152     protected SerializationConfig(SerializationConfig src,
153             SimpleMixInResolver mixins, RootNameLookup rootNames,
154             ConfigOverrides configOverrides)
155     {
156         this(src, src._subtypeResolver, mixins, rootNames, configOverrides);
157     }
158
159     /*
160     /**********************************************************
161     /* Life-cycle, secondary constructors to support
162     /* "mutant factories", with single property changes
163     /**********************************************************
164      */

165
166     private SerializationConfig(SerializationConfig src, SubtypeResolver str)
167     {
168         super(src, str);
169         _serFeatures = src._serFeatures;
170         _filterProvider = src._filterProvider;
171         _defaultPrettyPrinter = src._defaultPrettyPrinter;
172         _generatorFeatures = src._generatorFeatures;
173         _generatorFeaturesToChange = src._generatorFeaturesToChange;
174         _formatWriteFeatures = src._formatWriteFeatures;
175         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
176     }
177
178     private SerializationConfig(SerializationConfig src,
179             int mapperFeatures, int serFeatures,
180             int generatorFeatures, int generatorFeatureMask,
181             int formatFeatures, int formatFeaturesMask)
182     {
183         super(src, mapperFeatures);
184         _serFeatures = serFeatures;
185         _filterProvider = src._filterProvider;
186         _defaultPrettyPrinter = src._defaultPrettyPrinter;
187         _generatorFeatures = generatorFeatures;
188         _generatorFeaturesToChange = generatorFeatureMask;
189         _formatWriteFeatures = formatFeatures;
190         _formatWriteFeaturesToChange = formatFeaturesMask;
191     }
192     
193     private SerializationConfig(SerializationConfig src, BaseSettings base)
194     {
195         super(src, base);
196         _serFeatures = src._serFeatures;
197         _filterProvider = src._filterProvider;
198         _defaultPrettyPrinter = src._defaultPrettyPrinter;
199         _generatorFeatures = src._generatorFeatures;
200         _generatorFeaturesToChange = src._generatorFeaturesToChange;
201         _formatWriteFeatures = src._formatWriteFeatures;
202         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
203     }
204
205     private SerializationConfig(SerializationConfig src, FilterProvider filters)
206     {
207         super(src);
208         _serFeatures = src._serFeatures;
209         _filterProvider = filters;
210         _defaultPrettyPrinter = src._defaultPrettyPrinter;
211         _generatorFeatures = src._generatorFeatures;
212         _generatorFeaturesToChange = src._generatorFeaturesToChange;
213         _formatWriteFeatures = src._formatWriteFeatures;
214         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
215     }
216
217     private SerializationConfig(SerializationConfig src, Class<?> view)
218     {
219         super(src, view);
220         _serFeatures = src._serFeatures;
221         _filterProvider = src._filterProvider;
222         _defaultPrettyPrinter = src._defaultPrettyPrinter;
223         _generatorFeatures = src._generatorFeatures;
224         _generatorFeaturesToChange = src._generatorFeaturesToChange;
225         _formatWriteFeatures = src._formatWriteFeatures;
226         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
227     }
228
229     private SerializationConfig(SerializationConfig src, PropertyName rootName)
230     {
231         super(src, rootName);
232         _serFeatures = src._serFeatures;
233         _filterProvider = src._filterProvider;
234         _defaultPrettyPrinter = src._defaultPrettyPrinter;
235         _generatorFeatures = src._generatorFeatures;
236         _generatorFeaturesToChange = src._generatorFeaturesToChange;
237         _formatWriteFeatures = src._formatWriteFeatures;
238         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
239     }
240
241     /**
242      * @since 2.1
243      */

244     protected SerializationConfig(SerializationConfig src, ContextAttributes attrs)
245     {
246         super(src, attrs);
247         _serFeatures = src._serFeatures;
248         _filterProvider = src._filterProvider;
249         _defaultPrettyPrinter = src._defaultPrettyPrinter;
250         _generatorFeatures = src._generatorFeatures;
251         _generatorFeaturesToChange = src._generatorFeaturesToChange;
252         _formatWriteFeatures = src._formatWriteFeatures;
253         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
254     }
255
256     /**
257      * @since 2.1
258      */

259     protected SerializationConfig(SerializationConfig src, SimpleMixInResolver mixins)
260     {
261         super(src, mixins);
262         _serFeatures = src._serFeatures;
263         _filterProvider = src._filterProvider;
264         _defaultPrettyPrinter = src._defaultPrettyPrinter;
265         _generatorFeatures = src._generatorFeatures;
266         _generatorFeaturesToChange = src._generatorFeaturesToChange;
267         _formatWriteFeatures = src._formatWriteFeatures;
268         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
269     }
270     
271     /**
272      * @since 2.6
273      */

274     protected SerializationConfig(SerializationConfig src, PrettyPrinter defaultPP)
275     {
276         super(src);
277         _serFeatures = src._serFeatures;
278         _filterProvider = src._filterProvider;
279         _defaultPrettyPrinter = defaultPP;
280         _generatorFeatures = src._generatorFeatures;
281         _generatorFeaturesToChange = src._generatorFeaturesToChange;
282         _formatWriteFeatures = src._formatWriteFeatures;
283         _formatWriteFeaturesToChange = src._formatWriteFeaturesToChange;
284     }
285
286     /*
287     /**********************************************************
288     /* Life-cycle, factory methods from MapperConfig(Base)
289     /**********************************************************
290      */

291
292     @Override // since 2.9
293     protected final SerializationConfig _withBase(BaseSettings newBase) {
294         return (_base == newBase) ? this : new SerializationConfig(this, newBase);
295     }
296
297     @Override // since 2.9
298     protected final SerializationConfig _withMapperFeatures(int mapperFeatures) {
299         return new SerializationConfig(this, mapperFeatures, _serFeatures,
300                         _generatorFeatures, _generatorFeaturesToChange,
301                         _formatWriteFeatures, _formatWriteFeaturesToChange);
302     }
303
304     @Override
305     public SerializationConfig withRootName(PropertyName rootName) {
306         if (rootName == null) {
307             if (_rootName == null) {
308                 return this;
309             }
310         } else if (rootName.equals(_rootName)) {
311             return this;
312         }
313         return new SerializationConfig(this, rootName);
314     }
315
316     @Override
317     public SerializationConfig with(SubtypeResolver str) {
318         return (str == _subtypeResolver)? this : new SerializationConfig(this, str);
319     }
320
321     @Override
322     public SerializationConfig withView(Class<?> view) {
323         return (_view == view) ? this : new SerializationConfig(this, view);
324     }
325     
326     @Override
327     public SerializationConfig with(ContextAttributes attrs) {
328         return (attrs == _attributes) ? this : new SerializationConfig(this, attrs);
329     }
330
331     /*
332     /**********************************************************
333     /* Factory method overrides
334     /**********************************************************
335      */

336
337     /**
338      * In addition to constructing instance with specified date format,
339      * will enable or disable <code>SerializationFeature.WRITE_DATES_AS_TIMESTAMPS</code>
340      * (enable if format set as null; disable if non-null)
341      */

342     @Override
343     public SerializationConfig with(DateFormat df) {
344         SerializationConfig cfg = super.with(df);
345         // Also need to toggle this feature based on existence of date format:
346         if (df == null) {
347             return cfg.with(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
348         }
349         return cfg.without(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
350     }
351
352     /*
353     /**********************************************************
354     /* Factory methods for SerializationFeature
355     /**********************************************************
356      */

357
358     /**
359      * Fluent factory method that will construct and return a new configuration
360      * object instance with specified feature enabled.
361      */

362     public SerializationConfig with(SerializationFeature feature)
363     {
364         int newSerFeatures = _serFeatures | feature.getMask();
365         return (newSerFeatures == _serFeatures) ? this
366                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
367                         _generatorFeatures, _generatorFeaturesToChange,
368                         _formatWriteFeatures, _formatWriteFeaturesToChange);
369     }
370
371     /**
372      * Fluent factory method that will construct and return a new configuration
373      * object instance with specified features enabled.
374      */

375     public SerializationConfig with(SerializationFeature first, SerializationFeature... features)
376     {
377         int newSerFeatures = _serFeatures | first.getMask();
378         for (SerializationFeature f : features) {
379             newSerFeatures |= f.getMask();
380         }
381         return (newSerFeatures == _serFeatures) ? this
382                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
383                         _generatorFeatures, _generatorFeaturesToChange,
384                         _formatWriteFeatures, _formatWriteFeaturesToChange);
385     }
386
387     /**
388      * Fluent factory method that will construct and return a new configuration
389      * object instance with specified features enabled.
390      */

391     public SerializationConfig withFeatures(SerializationFeature... features)
392     {
393         int newSerFeatures = _serFeatures;
394         for (SerializationFeature f : features) {
395             newSerFeatures |= f.getMask();
396         }
397         return (newSerFeatures == _serFeatures) ? this
398                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
399                         _generatorFeatures, _generatorFeaturesToChange,
400                         _formatWriteFeatures, _formatWriteFeaturesToChange);
401     }
402
403     /**
404      * Fluent factory method that will construct and return a new configuration
405      * object instance with specified feature disabled.
406      */

407     public SerializationConfig without(SerializationFeature feature)
408     {
409         int newSerFeatures = _serFeatures & ~feature.getMask();
410         return (newSerFeatures == _serFeatures) ? this
411                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
412                         _generatorFeatures, _generatorFeaturesToChange,
413                         _formatWriteFeatures, _formatWriteFeaturesToChange);
414     }
415
416     /**
417      * Fluent factory method that will construct and return a new configuration
418      * object instance with specified features disabled.
419      */

420     public SerializationConfig without(SerializationFeature first, SerializationFeature... features)
421     {
422         int newSerFeatures = _serFeatures & ~first.getMask();
423         for (SerializationFeature f : features) {
424             newSerFeatures &= ~f.getMask();
425         }
426         return (newSerFeatures == _serFeatures) ? this
427                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
428                         _generatorFeatures, _generatorFeaturesToChange,
429                         _formatWriteFeatures, _formatWriteFeaturesToChange);
430     }
431
432     /**
433      * Fluent factory method that will construct and return a new configuration
434      * object instance with specified features disabled.
435      */

436     public SerializationConfig withoutFeatures(SerializationFeature... features)
437     {
438         int newSerFeatures = _serFeatures;
439         for (SerializationFeature f : features) {
440             newSerFeatures &= ~f.getMask();
441         }
442         return (newSerFeatures == _serFeatures) ? this
443                 : new SerializationConfig(this, _mapperFeatures, newSerFeatures,
444                         _generatorFeatures, _generatorFeaturesToChange,
445                         _formatWriteFeatures, _formatWriteFeaturesToChange);
446     }
447
448     /*
449     /**********************************************************
450     /* Factory methods for JsonGenerator.Feature (2.5)
451     /**********************************************************
452      */

453     /**
454      * Fluent factory method that will construct and return a new configuration
455      * object instance with specified feature enabled.
456      *
457      * @since 2.5
458      */

459     public SerializationConfig with(JsonGenerator.Feature feature)
460     {
461         int newSet = _generatorFeatures | feature.getMask();
462         int newMask = _generatorFeaturesToChange | feature.getMask();
463         return ((_generatorFeatures == newSet) && (_generatorFeaturesToChange == newMask)) ? this :
464             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
465                     newSet, newMask,
466                     _formatWriteFeatures, _formatWriteFeaturesToChange);
467     }
468
469     /**
470      * Fluent factory method that will construct and return a new configuration
471      * object instance with specified features enabled.
472      *
473      * @since 2.5
474      */

475     public SerializationConfig withFeatures(JsonGenerator.Feature... features)
476     {
477         int newSet = _generatorFeatures;
478         int newMask = _generatorFeaturesToChange;
479         for (JsonGenerator.Feature f : features) {
480             int mask = f.getMask();
481             newSet |= mask;
482             newMask |= mask;
483         }
484         return ((_generatorFeatures == newSet) && (_generatorFeaturesToChange == newMask)) ? this :
485             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
486                     newSet, newMask,
487                     _formatWriteFeatures, _formatWriteFeaturesToChange);
488     }
489
490     /**
491      * Fluent factory method that will construct and return a new configuration
492      * object instance with specified feature disabled.
493      *
494      * @since 2.5
495      */

496     public SerializationConfig without(JsonGenerator.Feature feature)
497     {
498         int newSet = _generatorFeatures & ~feature.getMask();
499         int newMask = _generatorFeaturesToChange | feature.getMask();
500         return ((_generatorFeatures == newSet) && (_generatorFeaturesToChange == newMask)) ? this :
501             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
502                     newSet, newMask,
503                     _formatWriteFeatures, _formatWriteFeaturesToChange);
504     }
505
506     /**
507      * Fluent factory method that will construct and return a new configuration
508      * object instance with specified features disabled.
509      *
510      * @since 2.5
511      */

512     public SerializationConfig withoutFeatures(JsonGenerator.Feature... features)
513     {
514         int newSet = _generatorFeatures;
515         int newMask = _generatorFeaturesToChange;
516         for (JsonGenerator.Feature f : features) {
517             int mask = f.getMask();
518             newSet &= ~mask;
519             newMask |= mask;
520         }
521         return ((_generatorFeatures == newSet) && (_generatorFeaturesToChange == newMask)) ? this :
522             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
523                     newSet, newMask,
524                     _formatWriteFeatures, _formatWriteFeaturesToChange);
525     }
526
527     /*
528     /**********************************************************
529     /* Factory methods for FormatFeature (2.7)
530     /**********************************************************
531      */

532     /**
533      * Fluent factory method that will construct and return a new configuration
534      * object instance with specified feature enabled.
535      *
536      * @since 2.7
537      */

538     public SerializationConfig with(FormatFeature feature)
539     {
540         // 27-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features:
541         if (feature instanceof JsonWriteFeature) {
542             return _withJsonWriteFeatures(feature);
543         }
544         int newSet = _formatWriteFeatures | feature.getMask();
545         int newMask = _formatWriteFeaturesToChange | feature.getMask();
546         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)) ? this :
547             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
548                     _generatorFeatures, _generatorFeaturesToChange,
549                     newSet, newMask);
550     }
551
552     /**
553      * Fluent factory method that will construct and return a new configuration
554      * object instance with specified features enabled.
555      *
556      * @since 2.7
557      */

558     public SerializationConfig withFeatures(FormatFeature... features)
559     {
560         // 27-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features:
561         if (features.length > 0 && (features[0] instanceof JsonWriteFeature)) {
562             return _withJsonWriteFeatures(features);
563         }
564         int newSet = _formatWriteFeatures;
565         int newMask = _formatWriteFeaturesToChange;
566         for (FormatFeature f : features) {
567             int mask = f.getMask();
568             newSet |= mask;
569             newMask |= mask;
570         }
571         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)) ? this :
572             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
573                     _generatorFeatures, _generatorFeaturesToChange,
574                     newSet, newMask);
575     }
576
577     /**
578      * Fluent factory method that will construct and return a new configuration
579      * object instance with specified feature disabled.
580      *
581      * @since 2.7
582      */

583     public SerializationConfig without(FormatFeature feature)
584     {
585         // 27-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features:
586         if (feature instanceof JsonWriteFeature) {
587             return _withoutJsonWriteFeatures(feature);
588         }
589         int newSet = _formatWriteFeatures & ~feature.getMask();
590         int newMask = _formatWriteFeaturesToChange | feature.getMask();
591         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)) ? this :
592             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
593                     _generatorFeatures, _generatorFeaturesToChange,
594                     newSet, newMask);
595     }
596
597     /**
598      * Fluent factory method that will construct and return a new configuration
599      * object instance with specified features disabled.
600      *
601      * @since 2.7
602      */

603     public SerializationConfig withoutFeatures(FormatFeature... features)
604     {
605         if (features.length > 0 && (features[0] instanceof JsonWriteFeature)) {
606             return _withoutJsonWriteFeatures(features);
607         }
608         int newSet = _formatWriteFeatures;
609         int newMask = _formatWriteFeaturesToChange;
610         for (FormatFeature f : features) {
611             int mask = f.getMask();
612             newSet &= ~mask;
613             newMask |= mask;
614         }
615         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)) ? this :
616             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
617                     _generatorFeatures, _generatorFeaturesToChange,
618                     newSet, newMask);
619     }
620
621     // temporary for 2.10
622     private SerializationConfig _withJsonWriteFeatures(FormatFeature... features) {
623         int parserSet = _generatorFeatures;
624         int parserMask = _generatorFeaturesToChange;
625         int newSet = _formatWriteFeatures;
626         int newMask = _formatWriteFeaturesToChange;
627         for (FormatFeature f : features) {
628             final int mask = f.getMask();
629             newSet |= mask;
630             newMask |= mask;
631
632             if (f instanceof JsonWriteFeature) {
633                 JsonGenerator.Feature oldF = ((JsonWriteFeature) f).mappedFeature();
634                 if (oldF != null) {
635                     final int pmask = oldF.getMask();
636                     parserSet |= pmask;
637                     parserMask |= pmask;
638                 }
639             }
640         }
641         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)
642                 && (_generatorFeatures == parserSet) && (_generatorFeaturesToChange == parserMask)
643                 ) ? this :
644             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
645                     parserSet, parserMask, newSet, newMask);
646     }
647
648     // temporary for 2.10
649     private SerializationConfig _withoutJsonWriteFeatures(FormatFeature... features) {
650         int parserSet = _generatorFeatures;
651         int parserMask = _generatorFeaturesToChange;
652         int newSet = _formatWriteFeatures;
653         int newMask = _formatWriteFeaturesToChange;
654         for (FormatFeature f : features) {
655             final int mask = f.getMask();
656             newSet &= ~mask;
657             newMask |= mask;
658
659             if (f instanceof JsonWriteFeature) {
660                 JsonGenerator.Feature oldF = ((JsonWriteFeature) f).mappedFeature();
661                 if (oldF != null) {
662                     final int pmask = oldF.getMask();
663                     parserSet &= ~pmask;
664                     parserMask |= pmask;
665                 }
666             }
667         }
668         return ((_formatWriteFeatures == newSet) && (_formatWriteFeaturesToChange == newMask)
669                 && (_generatorFeatures == parserSet) && (_generatorFeaturesToChange == parserMask)
670                 ) ? this :
671             new SerializationConfig(this,  _mapperFeatures, _serFeatures,
672                     parserSet, parserMask, newSet, newMask);
673     }
674
675     /*
676     /**********************************************************
677     /* Factory methods, other
678     /**********************************************************
679      */

680
681     public SerializationConfig withFilters(FilterProvider filterProvider) {
682         return (filterProvider == _filterProvider) ? this : new SerializationConfig(this, filterProvider);
683     }
684
685     /**
686      * Mutant factory method for constructing a new instance with different
687      * default inclusion criteria configuration.
688      *
689      * @since 2.7
690      *
691      * @deprecated Since 2.9; not needed any more
692      */

693     @Deprecated
694     public SerializationConfig withPropertyInclusion(JsonInclude.Value incl) {
695         _configOverrides.setDefaultInclusion(incl);
696         return this;
697     }
698
699     /**
700      * @since 2.6
701      */

702     public SerializationConfig withDefaultPrettyPrinter(PrettyPrinter pp) {
703         return (_defaultPrettyPrinter == pp) ? this:  new SerializationConfig(this, pp);
704     }
705
706     /*
707     /**********************************************************
708     /* Factories for objects configured here
709     /**********************************************************
710      */

711
712     public PrettyPrinter constructDefaultPrettyPrinter() {
713         PrettyPrinter pp = _defaultPrettyPrinter;
714         if (pp instanceof Instantiatable<?>) {
715             pp = (PrettyPrinter) ((Instantiatable<?>) pp).createInstance();
716         }
717         return pp;
718     }
719     
720     /*
721     /**********************************************************
722     /* JsonParser initialization
723     /**********************************************************
724      */

725
726     /**
727      * Method called by {@link ObjectMapper} and {@link ObjectWriter}
728      * to modify those {@link com.fasterxml.jackson.core.JsonGenerator.Feature} settings
729      * that have been configured via this config instance.
730      * 
731      * @since 2.5
732      */

733     public void initialize(JsonGenerator g)
734     {
735         if (SerializationFeature.INDENT_OUTPUT.enabledIn(_serFeatures)) {
736             // but do not override an explicitly set one
737             if (g.getPrettyPrinter() == null) {
738                 PrettyPrinter pp = constructDefaultPrettyPrinter();
739                 if (pp != null) {
740                     g.setPrettyPrinter(pp);
741                 }
742             }
743         }
744         @SuppressWarnings("deprecation")
745         boolean useBigDec = SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN.enabledIn(_serFeatures);
746
747         int mask = _generatorFeaturesToChange;
748         if ((mask != 0) || useBigDec) {
749             int newFlags = _generatorFeatures;
750             // although deprecated, needs to be supported for now
751             if (useBigDec) {
752                 int f = JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN.getMask();
753                 newFlags |= f;
754                 mask |= f;
755             }
756             g.overrideStdFeatures(newFlags, mask);
757         }
758         if (_formatWriteFeaturesToChange != 0) {
759             g.overrideFormatFeatures(_formatWriteFeatures, _formatWriteFeaturesToChange);
760         }
761     }
762
763     /*
764     /**********************************************************
765     /* Configuration: default settings with per-type overrides
766     /**********************************************************
767      */

768
769     /**
770      * @deprecated Since 2.7 use {@link #getDefaultPropertyInclusion} instead
771      */

772     @Deprecated
773     public JsonInclude.Include getSerializationInclusion()
774     {
775         JsonInclude.Include incl = getDefaultPropertyInclusion().getValueInclusion();
776         return (incl == JsonInclude.Include.USE_DEFAULTS) ? JsonInclude.Include.ALWAYS : incl;
777     }
778
779     /*
780     /**********************************************************
781     /* Configuration: other
782     /**********************************************************
783      */

784
785     @Override
786     public boolean useRootWrapping()
787     {
788         if (_rootName != null) { // empty String disables wrapping; non-empty enables
789             return !_rootName.isEmpty();
790         }
791         return isEnabled(SerializationFeature.WRAP_ROOT_VALUE);
792     }
793     
794     public final boolean isEnabled(SerializationFeature f) {
795         return (_serFeatures & f.getMask()) != 0;
796     }
797
798     /**
799      * Accessor method that first checks if we have any overrides
800      * for feature, and only if not, checks state of passed-in
801      * factory.
802      * 
803      * @since 2.5
804      */

805     public final boolean isEnabled(JsonGenerator.Feature f, JsonFactory factory) {
806         int mask = f.getMask();
807         if ((_generatorFeaturesToChange & mask) != 0) {
808             return (_generatorFeatures & f.getMask()) != 0;
809         }
810         return factory.isEnabled(f);
811     }
812     
813     /**
814      * "Bulk" access method for checking that all features specified by
815      * mask are enabled.
816      * 
817      * @since 2.3
818      */

819     public final boolean hasSerializationFeatures(int featureMask) {
820         return (_serFeatures & featureMask) == featureMask;
821     }
822
823     public final int getSerializationFeatures() {
824         return _serFeatures;
825     }
826
827     /**
828      * Method for getting provider used for locating filters given
829      * id (which is usually provided with filter annotations).
830      * Will be null if no provided was set for {@link ObjectWriter}
831      * (or if serialization directly called from {@link ObjectMapper})
832      */

833     public FilterProvider getFilterProvider() {
834         return _filterProvider;
835     }
836     
837     /**
838      * Accessor for configured blueprint "default" {@link PrettyPrinter} to
839      * use, if default pretty-printing is enabled.
840      *<p>
841      * NOTE: returns the "blueprint" instance, and does NOT construct
842      * an instance ready to use; call {@link #constructDefaultPrettyPrinter()} if
843      * actually usable instance is desired.
844      *
845      * @since 2.6
846      */

847     public PrettyPrinter getDefaultPrettyPrinter() {
848         return _defaultPrettyPrinter;
849     }
850
851     /*
852     /**********************************************************
853     /* Introspection methods
854     /**********************************************************
855      */

856
857     /**
858      * Method that will introspect full bean properties for the purpose
859      * of building a bean serializer
860      */

861     @SuppressWarnings("unchecked")
862     public <T extends BeanDescription> T introspect(JavaType type) {
863         return (T) getClassIntrospector().forSerialization(this, type, this);
864     }
865 }
866