Jackson Data Binding Source Code

Jackson is "the Java JSON library" or "the best JSON parser for Java". Or simply as "JSON for Java".

  • Jackson Data Binding module allows you to converts JSON to and from POJO (Plain Old Java Object) using property accessor or using annotations.
  • Jackson Databind Source Code files are provided in the source packge (jackson-databind-2.12.4-sources.jar). You can download it at Jackson Maven Website.

    You can also browse Jackson Databind Source Code below:

    ✍: FYIcenter.com

    com/fasterxml/jackson/databind/ObjectWriter.java

    package com.fasterxml.jackson.databind;
    
    import java.io.*;
    import java.text.*;
    import java.util.Locale;
    import java.util.Map;
    import java.util.TimeZone;
    import java.util.concurrent.atomic.AtomicReference;
    
    import com.fasterxml.jackson.core.*;
    import com.fasterxml.jackson.core.io.CharacterEscapes;
    import com.fasterxml.jackson.core.io.SegmentedStringWriter;
    import com.fasterxml.jackson.core.io.SerializedString;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.core.util.*;
    import com.fasterxml.jackson.databind.cfg.ContextAttributes;
    import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
    import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
    import com.fasterxml.jackson.databind.ser.*;
    import com.fasterxml.jackson.databind.ser.impl.TypeWrappedSerializer;
    import com.fasterxml.jackson.databind.type.TypeFactory;
    import com.fasterxml.jackson.databind.util.ClassUtil;
    
    /**
     * Builder object that can be used for per-serialization configuration of
     * serialization parameters, such as JSON View and root type to use.
     * (and thus fully thread-safe with no external synchronization);
     * new instances are constructed for different configurations.
     * Instances are initially constructed by {@link ObjectMapper} and can be
     * reused in completely thread-safe manner with no explicit synchronization
     */
    public class ObjectWriter
        implements Versioned,
            java.io.Serializable // since 2.1
    {
        private static final long serialVersionUID = 1; // since 2.5
    
        /**
         * We need to keep track of explicit disabling of pretty printing;
         * easiest to do by a token value.
         */
        protected final static PrettyPrinter NULL_PRETTY_PRINTER = new MinimalPrettyPrinter();
    
        /*
        /**********************************************************
        /* Immutable configuration from ObjectMapper
        /**********************************************************
         */
    
        /**
         * General serialization configuration settings
         */
        protected final SerializationConfig _config;
    
        protected final DefaultSerializerProvider _serializerProvider;
    
        protected final SerializerFactory _serializerFactory;
    
        /**
         * Factory used for constructing {@link JsonGenerator}s
         */
        protected final JsonFactory _generatorFactory;
    
        /*
        /**********************************************************
        /* Configuration that can be changed via mutant factories
        /**********************************************************
         */
    
        /**
         * Container for settings that need to be passed to {@link JsonGenerator}
         * constructed for serializing values.
         *
         * @since 2.5
         */
        protected final GeneratorSettings _generatorSettings;
    
        /**
         * We may pre-fetch serializer if root type
         * is known (has been explicitly declared), and if so, reuse it afterwards.
         * This allows avoiding further serializer lookups and increases
         * performance a bit on cases where readers are reused.
         *
         * @since 2.5
         */
        protected final Prefetch _prefetch;
        
        /*
        /**********************************************************
        /* Life-cycle, constructors
        /**********************************************************
         */
    
        /**
         * Constructor used by {@link ObjectMapper} for initial instantiation
         */
        protected ObjectWriter(ObjectMapper mapper, SerializationConfig config,
                JavaType rootType, PrettyPrinter pp)
        {
            _config = config;
            _serializerProvider = mapper._serializerProvider;
            _serializerFactory = mapper._serializerFactory;
            _generatorFactory = mapper._jsonFactory;
            _generatorSettings = (pp == null) ? GeneratorSettings.empty
                    : new GeneratorSettings(pp, null, null, null);
    
            if (rootType == null) {
                _prefetch = Prefetch.empty;
            } else if (rootType.hasRawClass(Object.class)) {
                // 15-Sep-2019, tatu: There is no "untyped serializer", but...
                //     as per [databind#1093] we do need `TypeSerializer`
                _prefetch = Prefetch.empty.forRootType(this, rootType);
            } else {
                _prefetch = Prefetch.empty.forRootType(this, rootType.withStaticTyping());
            }
        }
    
        /**
         * Alternative constructor for initial instantiation by {@link ObjectMapper}
         */
        protected ObjectWriter(ObjectMapper mapper, SerializationConfig config)
        {
            _config = config;
            _serializerProvider = mapper._serializerProvider;
            _serializerFactory = mapper._serializerFactory;
            _generatorFactory = mapper._jsonFactory;
    
            _generatorSettings = GeneratorSettings.empty;
            _prefetch = Prefetch.empty;
        }
    
        /**
         * Alternative constructor for initial instantiation by {@link ObjectMapper}
         */
        protected ObjectWriter(ObjectMapper mapper, SerializationConfig config,
                FormatSchema s)
        {
            _config = config;
    
            _serializerProvider = mapper._serializerProvider;
            _serializerFactory = mapper._serializerFactory;
            _generatorFactory = mapper._jsonFactory;
    
            _generatorSettings = (s == null) ? GeneratorSettings.empty
                    : new GeneratorSettings(null, s, null, null);
            _prefetch = Prefetch.empty;
        }
        
        /**
         * Copy constructor used for building variations.
         */
        protected ObjectWriter(ObjectWriter base, SerializationConfig config,
                GeneratorSettings genSettings, Prefetch prefetch)
        {
            _config = config;
    
            _serializerProvider = base._serializerProvider;
            _serializerFactory = base._serializerFactory;
            _generatorFactory = base._generatorFactory;
    
            _generatorSettings = genSettings;
            _prefetch = prefetch;
        }
    
        /**
         * Copy constructor used for building variations.
         */
        protected ObjectWriter(ObjectWriter base, SerializationConfig config)
        {
            _config = config;
    
            _serializerProvider = base._serializerProvider;
            _serializerFactory = base._serializerFactory;
            _generatorFactory = base._generatorFactory;
    
            _generatorSettings = base._generatorSettings;
            _prefetch = base._prefetch;
        }
    
        /**
         * @since 2.3
         */
        protected ObjectWriter(ObjectWriter base, JsonFactory f)
        {
            // may need to override ordering, based on data format capabilities
            _config = base._config
                .with(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, f.requiresPropertyOrdering());
    
            _serializerProvider = base._serializerProvider;
            _serializerFactory = base._serializerFactory;
            _generatorFactory = f;
    
            _generatorSettings = base._generatorSettings;
            _prefetch = base._prefetch;
        }
    
        /**
         * Method that will return version information stored in and read from jar
         * that contains this class.
         */
        @Override
        public Version version() {
            return com.fasterxml.jackson.databind.cfg.PackageVersion.VERSION;
        }
    
        /*
        /**********************************************************************
        /* Internal factory methods, for convenience
        /**********************************************************************
         */
    
        /**
         * Overridable factory method called by various "withXxx()" methods
         * 
         * @since 2.5
         */
        protected ObjectWriter _new(ObjectWriter base, JsonFactory f) {
            return new ObjectWriter(base, f);
        }
    
        /**
         * Overridable factory method called by various "withXxx()" methods
         * 
         * @since 2.5
         */
        protected ObjectWriter _new(ObjectWriter base, SerializationConfig config) {
            if (config == _config) {
                return this;
            }
            return new ObjectWriter(base, config);
        }
    
        /**
         * Overridable factory method called by various "withXxx()" methods.
         * It assumes `this` as base for settings other than those directly
         * passed in.
         * 
         * @since 2.5
         */
        protected ObjectWriter _new(GeneratorSettings genSettings, Prefetch prefetch) {
            if ((_generatorSettings == genSettings) && (_prefetch == prefetch)) {
                return this;
            }
            return new ObjectWriter(this, _config, genSettings, prefetch);
        }
    
        /**
         * Overridable factory method called by {@link #writeValues(OutputStream)}
         * method (and its various overrides), and initializes it as necessary.
         * 
         * @since 2.5
         */
        @SuppressWarnings("resource")
        protected SequenceWriter _newSequenceWriter(boolean wrapInArray,
                JsonGenerator gen, boolean managedInput)
            throws IOException
        {
            return new SequenceWriter(_serializerProvider(),
                    _configureGenerator(gen), managedInput, _prefetch)
                .init(wrapInArray);
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories for SerializationFeature
        /**********************************************************
         */
    
        /**
         * Method for constructing a new instance that is configured
         * with specified feature enabled.
         */
        public ObjectWriter with(SerializationFeature feature)  {
            return _new(this,  _config.with(feature));
        }
    
        /**
         * Method for constructing a new instance that is configured
         * with specified features enabled.
         */
        public ObjectWriter with(SerializationFeature first, SerializationFeature... other) {
            return _new(this, _config.with(first, other));
        }    
    
        /**
         * Method for constructing a new instance that is configured
         * with specified features enabled.
         */
        public ObjectWriter withFeatures(SerializationFeature... features) {
            return _new(this, _config.withFeatures(features));
        }    
        
        /**
         * Method for constructing a new instance that is configured
         * with specified feature enabled.
         */
        public ObjectWriter without(SerializationFeature feature) {
            return _new(this, _config.without(feature));
        }    
    
        /**
         * Method for constructing a new instance that is configured
         * with specified features enabled.
         */
        public ObjectWriter without(SerializationFeature first, SerializationFeature... other) {
            return _new(this, _config.without(first, other));
        }    
    
        /**
         * Method for constructing a new instance that is configured
         * with specified features enabled.
         */
        public ObjectWriter withoutFeatures(SerializationFeature... features) {
            return _new(this, _config.withoutFeatures(features));
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories for JsonGenerator.Feature (2.5)
        /**********************************************************
         */
    
        /**
         * @since 2.5
         */
        public ObjectWriter with(JsonGenerator.Feature feature)  {
            return _new(this, _config.with(feature));
        }
    
        /**
         * @since 2.5
         */
        public ObjectWriter withFeatures(JsonGenerator.Feature... features) {
            return _new(this, _config.withFeatures(features));
        }
    
        /**
         * @since 2.5
         */
        public ObjectWriter without(JsonGenerator.Feature feature) {
            return _new(this, _config.without(feature));
        }
    
        /**
         * @since 2.5
         */
        public ObjectWriter withoutFeatures(JsonGenerator.Feature... features) {
            return _new(this, _config.withoutFeatures(features));
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories for StreamWriteFeature (2.11)
        /**********************************************************
         */
    
        /**
         * @since 2.11
         */
        public ObjectWriter with(StreamWriteFeature feature)  {
            return _new(this, _config.with(feature.mappedFeature()));
        }
    
        /**
         * @since 2.11
         */
        public ObjectWriter without(StreamWriteFeature feature) {
            return _new(this, _config.without(feature.mappedFeature()));
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories for FormatFeature (2.7)
        /**********************************************************
         */
    
        /**
         * @since 2.7
         */
        public ObjectWriter with(FormatFeature feature)  {
            return _new(this, _config.with(feature));
        }
    
        /**
         * @since 2.7
         */
        public ObjectWriter withFeatures(FormatFeature... features) {
            return _new(this, _config.withFeatures(features));
        }
    
        /**
         * @since 2.7
         */
        public ObjectWriter without(FormatFeature feature) {
            return _new(this, _config.without(feature));
        }
    
        /**
         * @since 2.7
         */
        public ObjectWriter withoutFeatures(FormatFeature... features) {
            return _new(this, _config.withoutFeatures(features));
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories, type-related
        /**********************************************************
         */
    
        /**
         * Method that will construct a new instance that uses specific type
         * as the root type for serialization, instead of runtime dynamic
         * type of the root object itself.
         *<p>
         * Note that method does NOT change state of this reader, but
         * rather construct and returns a newly configured instance.
         * 
         * @since 2.5
         */
        public ObjectWriter forType(JavaType rootType) {
            return _new(_generatorSettings, _prefetch.forRootType(this, rootType));
        }
    
        /**
         * Method that will construct a new instance that uses specific type
         * as the root type for serialization, instead of runtime dynamic
         * type of the root object itself.
         * 
         * @since 2.5
         */
        public ObjectWriter forType(Class<?> rootType) {
            return forType(_config.constructType(rootType));
        }
    
        /**
         * Method that will construct a new instance that uses specific type
         * as the root type for serialization, instead of runtime dynamic
         * type of the root object itself.
         * 
         * @since 2.5
         */
        public ObjectWriter forType(TypeReference<?> rootType) {
            return forType(_config.getTypeFactory().constructType(rootType.getType()));
        }
    
        /**
         * @deprecated since 2.5 Use {@link #forType(JavaType)} instead
         */
        @Deprecated // since 2.5
        public ObjectWriter withType(JavaType rootType) {
            return forType(rootType);
        }
    
        /**
         * @deprecated since 2.5 Use {@link #forType(Class)} instead
         */
        @Deprecated // since 2.5
        public ObjectWriter withType(Class<?> rootType) {
            return forType(rootType);
        }
    
        /**
         * @deprecated since 2.5 Use {@link #forType(TypeReference)} instead
         */
        @Deprecated // since 2.5
        public ObjectWriter withType(TypeReference<?> rootType) {
            return forType(rootType);
        }
    
        /*
        /**********************************************************
        /* Life-cycle, fluent factories, other
        /**********************************************************
         */
        
        /**
         * Fluent factory method that will construct a new writer instance that will
         * use specified date format for serializing dates; or if null passed, one
         * that will serialize dates as numeric timestamps.
         *<p>
         * Note that the method does NOT change state of this reader, but
         * rather construct and returns a newly configured instance.
         */
        public ObjectWriter with(DateFormat df) {
            return _new(this, _config.with(df));
        }
    
        /**
         * Method that will construct a new instance that will use the default
         * pretty printer for serialization.
         */
        public ObjectWriter withDefaultPrettyPrinter() {
            return with(_config.getDefaultPrettyPrinter());
        }
    
        /**
         * Method that will construct a new instance that uses specified
         * provider for resolving filter instances by id.
         */
        public ObjectWriter with(FilterProvider filterProvider) {
            if (filterProvider == _config.getFilterProvider()) {
                return this;
            }
            return _new(this, _config.withFilters(filterProvider));
        }
    
        /**
         * Method that will construct a new instance that will use specified pretty
         * printer (or, if null, will not do any pretty-printing)
         */
        public ObjectWriter with(PrettyPrinter pp) {
            return _new(_generatorSettings.with(pp), _prefetch);
        }
    
        /**
         * Method for constructing a new instance with configuration that
         * specifies what root name to use for "root element wrapping".
         * See {@link SerializationConfig#withRootName(String)} for details.
         *<p>
         * Note that method does NOT change state of this reader, but
         * rather construct and returns a newly configured instance.
         * 
         * @param rootName Root name to use, if non-empty; `null` for "use defaults",
         *    and empty String ("") for "do NOT add root wrapper"
         */
        public ObjectWriter withRootName(String rootName) {
            return _new(this, _config.withRootName(rootName));
        }
    
        /**
         * @since 2.6
         */
        public ObjectWriter withRootName(PropertyName rootName) {
            return _new(this, _config.withRootName(rootName));
        }
    
        /**
         * Convenience method that is same as calling:
         *<code>
         *   withRootName("")
         *</code>
         * which will forcibly prevent use of root name wrapping when writing
         * values with this {@link ObjectWriter}.
         * 
         * @since 2.6
         */
        public ObjectWriter withoutRootName() {
            return _new(this, _config.withRootName(PropertyName.NO_NAME));
        }
        
        /**
         * Method that will construct a new instance that uses specific format schema
         * for serialization.
         *<p>
         * Note that method does NOT change state of this reader, but
         * rather construct and returns a newly configured instance.
         */
        public ObjectWriter with(FormatSchema schema) {
            _verifySchemaType(schema);
            return _new(_generatorSettings.with(schema), _prefetch);
        }
    
        /**
         * @deprecated Since 2.5 use {@link #with(FormatSchema)} instead
         */
        @Deprecated
        public ObjectWriter withSchema(FormatSchema schema) {
            return with(schema);
        }
    
        /**
         * Method that will construct a new instance that uses specified
         * serialization view for serialization (with null basically disables
         * view processing)
         *<p>
         * Note that the method does NOT change state of this reader, but
         * rather construct and returns a newly configured instance.
         */
        public ObjectWriter withView(Class<?> view) {
            return _new(this, _config.withView(view));
        }    
    
        public ObjectWriter with(Locale l) {
            return _new(this, _config.with(l));
        }
    
        public ObjectWriter with(TimeZone tz) {
            return _new(this, _config.with(tz));
        }
    
        /**
         * Method that will construct a new instance that uses specified default
         * {@link Base64Variant} for base64 encoding
         * 
         * @since 2.1
         */
        public ObjectWriter with(Base64Variant b64variant) {
            return _new(this, _config.with(b64variant));
        }
    
        /**
         * @since 2.3
         */
        public ObjectWriter with(CharacterEscapes escapes) {
            return _new(_generatorSettings.with(escapes), _prefetch);
        }
    
        /**
         * @since 2.3
         */
        public ObjectWriter with(JsonFactory f) {
            return (f == _generatorFactory) ? this : _new(this, f);
        }    
    
        /**
         * @since 2.3
         */
        public ObjectWriter with(ContextAttributes attrs) {
            return _new(this, _config.with(attrs));
        }
    
        /**
         * Mutant factory method that allows construction of a new writer instance
         * that uses specified set of default attribute values.
         *
         * @since 2.3
         */
        public ObjectWriter withAttributes(Map<?,?> attrs) {
            return _new(this, _config.withAttributes(attrs));
        }
    
        /**
         * @since 2.3
         */
        public ObjectWriter withAttribute(Object key, Object value) {
            return _new(this, _config.withAttribute(key, value));
        }
    
        /**
         * @since 2.3
         */
        public ObjectWriter withoutAttribute(Object key) {
            return _new(this, _config.withoutAttribute(key));
        }
    
        /**
         * @since 2.5
         */
        public ObjectWriter withRootValueSeparator(String sep) {
            return _new(_generatorSettings.withRootValueSeparator(sep), _prefetch);
        }
    
        /**
         * @since 2.5
         */
        public ObjectWriter withRootValueSeparator(SerializableString sep) {
            return _new(_generatorSettings.withRootValueSeparator(sep), _prefetch);
        }
    
        /*
        /**********************************************************
        /* Factory methods for creating JsonGenerators (added in 2.11)
        /**********************************************************
         */
    
        /**
         * Factory method for constructing properly initialized {@link JsonGenerator}
         * to write content using specified {@link OutputStream}.
         * Generator is not managed (or "owned") by ObjectWriter: caller is responsible
         * for properly closing it once content generation is complete.
         *
         * @since 2.11
         */
        public JsonGenerator createGenerator(OutputStream out) throws IOException {
            _assertNotNull("out", out);
            return _configureGenerator(_generatorFactory.createGenerator(out, JsonEncoding.UTF8));
        }
    
        /**
         * Factory method for constructing properly initialized {@link JsonGenerator}
         * to write content using specified {@link OutputStream} and encoding.
         * Generator is not managed (or "owned") by ObjectWriter: caller is responsible
         * for properly closing it once content generation is complete.
         *
         * @since 2.11
         */
        public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException {
            _assertNotNull("out", out);
            return _configureGenerator(_generatorFactory.createGenerator(out, enc));
        }
    
        /**
         * Factory method for constructing properly initialized {@link JsonGenerator}
         * to write content using specified {@link Writer}.
         * Generator is not managed (or "owned") by ObjectWriter: caller is responsible
         * for properly closing it once content generation is complete.
         *
         * @since 2.11
         */
        public JsonGenerator createGenerator(Writer w) throws IOException {
            _assertNotNull("w", w);
            return _configureGenerator(_generatorFactory.createGenerator(w));
        }
    
        /**
         * Factory method for constructing properly initialized {@link JsonGenerator}
         * to write content to specified {@link File}, using specified encoding.
         * Generator is not managed (or "owned") by ObjectWriter: caller is responsible
         * for properly closing it once content generation is complete.
         *
         * @since 2.11
         */
        public JsonGenerator createGenerator(File outputFile, JsonEncoding enc) throws IOException {
            _assertNotNull("outputFile", outputFile);
            return _configureGenerator(_generatorFactory.createGenerator(outputFile, enc));
        }
    
        /**
         * Factory method for constructing properly initialized {@link JsonGenerator}
         * to write content using specified {@link DataOutput}.
         * Generator is not managed (or "owned") by ObjectWriter: caller is responsible
         * for properly closing it once content generation is complete.
         *
         * @since 2.11
         */
        public JsonGenerator createGenerator(DataOutput out) throws IOException {
            _assertNotNull("out", out);
            return _configureGenerator(_generatorFactory.createGenerator(out));
        }
    
        /*
        /**********************************************************
        /* Factory methods for sequence writers (2.5)
        /**********************************************************
         */
    
        /**
         * Method for creating a {@link SequenceWriter} to write a sequence of root
         * values using configuration of this {@link ObjectWriter}.
         * Sequence is not surrounded by JSON array; some backend types may not
         * support writing of such sequences as root level.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *
         * @param out Target file to write value sequence to.
         *
         * @since 2.5
         */
        public SequenceWriter writeValues(File out) throws IOException {
            return _newSequenceWriter(false, createGenerator(out, JsonEncoding.UTF8), true);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write a sequence of root
         * values using configuration of this {@link ObjectWriter}.
         * Sequence is not surrounded by JSON array; some backend types may not
         * support writing of such sequences as root level.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure that all content gets flushed by
         * the generator. However, since a {@link JsonGenerator} is explicitly passed,
         * it will NOT be closed when {@link SequenceWriter#close()} is called.
         *
         * @param g Low-level generator caller has already constructed that will
         *   be used for actual writing of token stream.
         *
         * @since 2.5
         */
        public SequenceWriter writeValues(JsonGenerator g) throws IOException {
            _assertNotNull("g", g);
            return _newSequenceWriter(false, _configureGenerator(g), false);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write a sequence of root
         * values using configuration of this {@link ObjectWriter}.
         * Sequence is not surrounded by JSON array; some backend types may not
         * support writing of such sequences as root level.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *
         * @param out Target writer to use for writing the token stream
         *
         * @since 2.5
         */
        public SequenceWriter writeValues(Writer out) throws IOException {
            return _newSequenceWriter(false, createGenerator(out), true);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write a sequence of root
         * values using configuration of this {@link ObjectWriter}.
         * Sequence is not surrounded by JSON array; some backend types may not
         * support writing of such sequences as root level.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *
         * @param out Physical output stream to use for writing the token stream
         *
         * @since 2.5
         */
        public SequenceWriter writeValues(OutputStream out) throws IOException {
            return _newSequenceWriter(false, createGenerator(out, JsonEncoding.UTF8), true);
        }
    
        /**
         * @since 2.8
         */
        public SequenceWriter writeValues(DataOutput out) throws IOException {
            return _newSequenceWriter(false, createGenerator(out), true);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write an array of
         * root-level values, using configuration of this {@link ObjectWriter}.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *<p>
         * Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
         * be type of individual values (elements) to write and NOT matching array
         * or {@link java.util.Collection} type.
         *
         * @param out File to write token stream to
         *
         * @since 2.5
         */
        public SequenceWriter writeValuesAsArray(File out) throws IOException {
            return _newSequenceWriter(true, createGenerator(out, JsonEncoding.UTF8), true);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write an array of
         * root-level values, using configuration of this {@link ObjectWriter}.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure that all content gets flushed by
         * the generator. However, since a {@link JsonGenerator} is explicitly passed,
         * it will NOT be closed when {@link SequenceWriter#close()} is called.
         *<p>
         * Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
         * be type of individual values (elements) to write and NOT matching array
         * or {@link java.util.Collection} type.
         *
         * @param gen Underlying generator to use for writing the token stream
         *
         * @since 2.5
         */
        public SequenceWriter writeValuesAsArray(JsonGenerator gen) throws IOException {
            _assertNotNull("gen", gen);
            return _newSequenceWriter(true, gen, false);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write an array of
         * root-level values, using configuration of this {@link ObjectWriter}.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *<p>
         * Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
         * be type of individual values (elements) to write and NOT matching array
         * or {@link java.util.Collection} type.
         *
         * @param out Writer to use for writing the token stream
         *
         * @since 2.5
         */
        public SequenceWriter writeValuesAsArray(Writer out) throws IOException {
            return _newSequenceWriter(true, createGenerator(out), true);
        }
    
        /**
         * Method for creating a {@link SequenceWriter} to write an array of
         * root-level values, using configuration of this {@link ObjectWriter}.
         * Resulting writer needs to be {@link SequenceWriter#close()}d after all
         * values have been written to ensure closing of underlying generator and
         * output stream.
         *<p>
         * Note that the type to use with {@link ObjectWriter#forType(Class)} needs to
         * be type of individual values (elements) to write and NOT matching array
         * or {@link java.util.Collection} type.
         *
         * @param out Physical output stream to use for writing the token stream
         *
         * @since 2.5
         */
        public SequenceWriter writeValuesAsArray(OutputStream out) throws IOException {
            return _newSequenceWriter(true, createGenerator(out, JsonEncoding.UTF8), true);
        }
    
        /**
         * @since 2.8
         */
        public SequenceWriter writeValuesAsArray(DataOutput out) throws IOException {
            return _newSequenceWriter(true, createGenerator(out), true);
        }
    
        /*
        /**********************************************************
        /* Simple accessors
        /**********************************************************
         */
    
        public boolean isEnabled(SerializationFeature f) {
            return _config.isEnabled(f);
        }
    
        public boolean isEnabled(MapperFeature f) {
            return _config.isEnabled(f);
        }
    
        /**
         * @since 2.9
         */
        @Deprecated
        public boolean isEnabled(JsonParser.Feature f) {
            return _generatorFactory.isEnabled(f);
        }
    
        /**
         * @since 2.9
         */
        public boolean isEnabled(JsonGenerator.Feature f) {
            return _generatorFactory.isEnabled(f);
        }
    
        /**
         * @since 2.11
         */
        public boolean isEnabled(StreamWriteFeature f) {
            return _generatorFactory.isEnabled(f);
        }
    
        /**
         * @since 2.2
         */
        public SerializationConfig getConfig() {
            return _config;
        }
    
        /**
         * @since 2.2
         */
        public JsonFactory getFactory() {
            return _generatorFactory;
        }
        
        public TypeFactory getTypeFactory() {
            return _config.getTypeFactory();
        }
    
        /**
         * Diagnostics method that can be called to check whether this writer
         * has pre-fetched serializer to use: pre-fetching improves performance
         * when writer instances are reused as it avoids a per-call serializer
         * lookup.
         * 
         * @since 2.2
         */
        public boolean hasPrefetchedSerializer() {
            return _prefetch.hasSerializer();
        }
    
        /**
         * @since 2.3
         */
        public ContextAttributes getAttributes() {
            return _config.getAttributes();
        }
        
        /*
        /**********************************************************
        /* Serialization methods; ones from ObjectCodec first
        /**********************************************************
         */
    
        /**
         * Method that can be used to serialize any Java value as
         * JSON output, using provided {@link JsonGenerator}.
         *<p>
         * Note that the given {@link JsonGenerator} is not closed; caller
         * is expected to handle that as necessary.
         */
        public void writeValue(JsonGenerator g, Object value) throws IOException
        {
            _assertNotNull("g", g);
            _configureGenerator(g);
            if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE)
                    && (value instanceof Closeable)) {
    
                Closeable toClose = (Closeable) value;
                try {
                    _prefetch.serialize(g, value, _serializerProvider());
                    if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
                        g.flush();
                    }
                } catch (Exception e) {
                    ClassUtil.closeOnFailAndThrowAsIOE(null, toClose, e);
                    return;
                }
                toClose.close();
            } else {
                _prefetch.serialize(g, value, _serializerProvider());
                if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
                    g.flush();
                }
            }
        }
    
        /*
        /**********************************************************
        /* Serialization methods, others
        /**********************************************************
         */
    
        /**
         * Method that can be used to serialize any Java value as
         * JSON output, written to File provided.
         */
        public void writeValue(File resultFile, Object value)
            throws IOException, JsonGenerationException, JsonMappingException
        {
            _writeValueAndClose(createGenerator(resultFile, JsonEncoding.UTF8), value);
        }
    
        /**
         * Method that can be used to serialize any Java value as
         * JSON output, using output stream provided (using encoding
         * {@link JsonEncoding#UTF8}).
         *<p>
         * Note: method does not close the underlying stream explicitly
         * here; however, {@link JsonFactory} this mapper uses may choose
         * to close the stream depending on its settings (by default,
         * it will try to close it when {@link JsonGenerator} we construct
         * is closed).
         */
        public void writeValue(OutputStream out, Object value)
            throws IOException, JsonGenerationException, JsonMappingException
        {
            _writeValueAndClose(createGenerator(out, JsonEncoding.UTF8), value);
        }
    
        /**
         * Method that can be used to serialize any Java value as
         * JSON output, using Writer provided.
         *<p>
         * Note: method does not close the underlying stream explicitly
         * here; however, {@link JsonFactory} this mapper uses may choose
         * to close the stream depending on its settings (by default,
         * it will try to close it when {@link JsonGenerator} we construct
         * is closed).
         */
        public void writeValue(Writer w, Object value)
            throws IOException, JsonGenerationException, JsonMappingException
        {
            _writeValueAndClose(createGenerator(w), value);
        }
    
        /**
         * @since 2.8
         */
        public void writeValue(DataOutput out, Object value)
            throws IOException
        {
            _writeValueAndClose(createGenerator(out), value);
        }
    
        /**
         * Method that can be used to serialize any Java value as
         * a String. Functionally equivalent to calling
         * {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter}
         * and constructing String, but more efficient.
         *<p>
         * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it.
         */
        public String writeValueAsString(Object value)
            throws JsonProcessingException
        {        
            // alas, we have to pull the recycler directly here...
            SegmentedStringWriter sw = new SegmentedStringWriter(_generatorFactory._getBufferRecycler());
            try {
                _writeValueAndClose(createGenerator(sw), value);
            } catch (JsonProcessingException e) {
                throw e;
            } catch (IOException e) { // shouldn't really happen, but is declared as possibility so:
                throw JsonMappingException.fromUnexpectedIOE(e);
            }
            return sw.getAndClear();
        }
    
        /**
         * Method that can be used to serialize any Java value as
         * a byte array. Functionally equivalent to calling
         * {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream}
         * and getting bytes, but more efficient.
         * Encoding used will be UTF-8.
         *<p>
         * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it.
         */
        public byte[] writeValueAsBytes(Object value)
            throws JsonProcessingException
        {
            ByteArrayBuilder bb = new ByteArrayBuilder(_generatorFactory._getBufferRecycler());
            try {
                _writeValueAndClose(createGenerator(bb, JsonEncoding.UTF8), value);
            } catch (JsonProcessingException e) { // to support [JACKSON-758]
                throw e;
            } catch (IOException e) { // shouldn't really happen, but is declared as possibility so:
                throw JsonMappingException.fromUnexpectedIOE(e);
            }
            byte[] result = bb.toByteArray();
            bb.release();
            return result;
        }
    
        /*
        /**********************************************************
        /* Other public methods
        /**********************************************************
         */
    
        /**
         * Method for visiting type hierarchy for given type, using specified visitor.
         * Visitation uses <code>Serializer</code> hierarchy and related properties
         *<p>
         * This method can be used for things like
         * generating <a href="http://json-schema.org/">Json Schema</a>
         * instance for specified type.
         *
         * @param type Type to generate schema for (possibly with generic signature)
         * 
         * @since 2.2
         */
        public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor) throws JsonMappingException
        {
            _assertNotNull("type", type);
            _assertNotNull("visitor", visitor);
            _serializerProvider().acceptJsonFormatVisitor(type, visitor);
        }
    
        /**
         * Since 2.6
         */
        public void acceptJsonFormatVisitor(Class<?> type, JsonFormatVisitorWrapper visitor) throws JsonMappingException {
            _assertNotNull("type", type);
            _assertNotNull("visitor", visitor);
            acceptJsonFormatVisitor(_config.constructType(type), visitor);
        }
    
        public boolean canSerialize(Class<?> type) {
            _assertNotNull("type", type);
            return _serializerProvider().hasSerializerFor(type, null);
        }
    
        /**
         * Method for checking whether instances of given type can be serialized,
         * and optionally why (as per {@link Throwable} returned).
         * 
         * @since 2.3
         */
        public boolean canSerialize(Class<?> type, AtomicReference<Throwable> cause) {
            _assertNotNull("type", type);
            return _serializerProvider().hasSerializerFor(type, cause);
        }
    
        /*
        /**********************************************************
        /* Overridable helper methods
        /**********************************************************
         */
    
        /**
         * Overridable helper method used for constructing
         * {@link SerializerProvider} to use for serialization.
         */
        protected DefaultSerializerProvider _serializerProvider() {
            return _serializerProvider.createInstance(_config, _serializerFactory);
        }
    
        /*
        /**********************************************************
        /* Internal methods
        /**********************************************************
         */
    
        /**
         * @since 2.2
         */
        protected void _verifySchemaType(FormatSchema schema)
        {
            if (schema != null) {
                if (!_generatorFactory.canUseSchema(schema)) {
                        throw new IllegalArgumentException("Cannot use FormatSchema of type "+schema.getClass().getName()
                                +" for format "+_generatorFactory.getFormatName());
                }
            }
        }
    
        /**
         * Method called to configure the generator as necessary and then
         * call write functionality
         *
         * @since 2.11.2
         */
        protected final void _writeValueAndClose(JsonGenerator gen, Object value) throws IOException
        {
            if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
                _writeCloseable(gen, value);
                return;
            }
            try {
                _prefetch.serialize(gen, value, _serializerProvider());
            } catch (Exception e) {
                ClassUtil.closeOnFailAndThrowAsIOE(gen, e);
                return;
            }
            gen.close();
        }
    
        /**
         * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code>
         * method is to be called right after serialization has been called
         */
        private final void _writeCloseable(JsonGenerator gen, Object value)
            throws IOException
        {
            Closeable toClose = (Closeable) value;
            try {
                _prefetch.serialize(gen, value, _serializerProvider());
                Closeable tmpToClose = toClose;
                toClose = null;
                tmpToClose.close();
            } catch (Exception e) {
                ClassUtil.closeOnFailAndThrowAsIOE(gen, toClose, e);
                return;
            }
            gen.close();
        }
    
        /**
         * Helper method called to set or override settings of passed-in
         * {@link JsonGenerator}
         * 
         * @since 2.5
         */
        protected final JsonGenerator _configureGenerator(JsonGenerator gen)
        {
            // order is slightly significant: both may change PrettyPrinter
            // settings.
            _config.initialize(gen); // since 2.5
            _generatorSettings.initialize(gen);
            return gen;
        }
    
        protected final void _assertNotNull(String paramName, Object src) {
            if (src == null) {
                throw new IllegalArgumentException(String.format("argument \"%s\" is null", paramName));
            }
        }
        
        /*
        /**********************************************************
        /* Helper classes for configuration
        /**********************************************************
         */
    
        /**
         * Helper class used for containing settings specifically related
         * to (re)configuring {@link JsonGenerator} constructed for
         * writing output.
         * 
         * @since 2.5
         */
        public final static class GeneratorSettings
            implements java.io.Serializable
        {
            private static final long serialVersionUID = 1L;
    
            public final static GeneratorSettings empty = new GeneratorSettings(null, null, null, null);
    
            /**
             * To allow for dynamic enabling/disabling of pretty printing,
             * pretty printer can be optionally configured for writer
             * as well
             */
            public final PrettyPrinter prettyPrinter;
    
            /**
             * When using data format that uses a schema, schema is passed
             * to generator.
             */
            public final FormatSchema schema;
    
            /**
             * Caller may want to specify character escaping details, either as
             * defaults, or on call-by-call basis.
             */
            public final CharacterEscapes characterEscapes;
    
            /**
             * Caller may want to override so-called "root value separator",
             * String added (verbatim, with no quoting or escaping) between
             * values in root context. Default value is a single space character,
             * but this is often changed to linefeed.
             */
            public final SerializableString rootValueSeparator;
    
            public GeneratorSettings(PrettyPrinter pp, FormatSchema sch,
                    CharacterEscapes esc, SerializableString rootSep) {
                prettyPrinter = pp;
                schema = sch;
                characterEscapes = esc;
                rootValueSeparator = rootSep;
            }
    
            public GeneratorSettings with(PrettyPrinter pp) {
                // since null would mean "don't care", need to use placeholder to indicate "disable"
                if (pp == null) {
                    pp = NULL_PRETTY_PRINTER;
                }
                return (pp == prettyPrinter) ? this
                        : new GeneratorSettings(pp, schema, characterEscapes, rootValueSeparator);
            }
    
            public GeneratorSettings with(FormatSchema sch) {
                return (schema == sch) ? this
                        : new GeneratorSettings(prettyPrinter, sch, characterEscapes, rootValueSeparator);
            }
    
            public GeneratorSettings with(CharacterEscapes esc) {
                return (characterEscapes == esc) ? this
                        : new GeneratorSettings(prettyPrinter, schema, esc, rootValueSeparator);
            }
    
            public GeneratorSettings withRootValueSeparator(String sep) {
                if (sep == null) {
                    if (rootValueSeparator == null) {
                        return this;
                    }
                    return new GeneratorSettings(prettyPrinter, schema, characterEscapes, null);
                }
                if (sep.equals(_rootValueSeparatorAsString())) {
                    return this;
                }
                return new GeneratorSettings(prettyPrinter, schema, characterEscapes,
                        new SerializedString(sep));
            }
    
            public GeneratorSettings withRootValueSeparator(SerializableString sep) {
                if (sep == null) {
                    if (rootValueSeparator == null) {
                        return this;
                    }
                    return new GeneratorSettings(prettyPrinter, schema, characterEscapes, null);
                }
                if (sep.equals(rootValueSeparator)) {
                    return this;
                }
                return new GeneratorSettings(prettyPrinter, schema, characterEscapes, sep);
            }
    
            private final String _rootValueSeparatorAsString() {
                return (rootValueSeparator == null) ? null : rootValueSeparator.getValue();
            }
    
            /**
             * @since 2.6
             */
            public void initialize(JsonGenerator gen)
            {
                PrettyPrinter pp = prettyPrinter;
                if (prettyPrinter != null) {
                    if (pp == NULL_PRETTY_PRINTER) {
                        gen.setPrettyPrinter(null);
                    } else {
                        if (pp instanceof Instantiatable<?>) {
                            pp = (PrettyPrinter) ((Instantiatable<?>) pp).createInstance();
                        }
                        gen.setPrettyPrinter(pp);
                    }
                }
                if (characterEscapes != null) {
                    gen.setCharacterEscapes(characterEscapes);
                }
                if (schema != null) {
                    gen.setSchema(schema);
                }
                if (rootValueSeparator != null) {
                    gen.setRootValueSeparator(rootValueSeparator);
                }
            }
        }
    
        /**
         * As a minor optimization, we will make an effort to pre-fetch a serializer,
         * or at least relevant <code>TypeSerializer</code>, if given enough
         * information.
         * 
         * @since 2.5
         */
        public final static class Prefetch
            implements java.io.Serializable
        {
            private static final long serialVersionUID = 1L;
    
            public final static Prefetch empty = new Prefetch(null, null, null);
            
            /**
             * Specified root serialization type to use; can be same
             * as runtime type, but usually one of its super types
             * (parent class or interface it implements).
             */
            private final JavaType rootType;
    
            /**
             * We may pre-fetch serializer if {@link #rootType}
             * is known, and if so, reuse it afterwards.
             * This allows avoiding further serializer lookups and increases
             * performance a bit on cases where readers are reused.
             */
            private final JsonSerializer<Object> valueSerializer;
    
            /**
             * When dealing with polymorphic types, we cannot pre-fetch
             * serializer, but can pre-fetch {@link TypeSerializer}.
             */
            private final TypeSerializer typeSerializer;
            
            private Prefetch(JavaType rootT,
                    JsonSerializer<Object> ser, TypeSerializer typeSer)
            {
                rootType = rootT;
                valueSerializer = ser;
                typeSerializer = typeSer;
            }
    
            public Prefetch forRootType(ObjectWriter parent, JavaType newType) {
                // First: if nominal type not defined not thing much to do
                if (newType == null) {
                    if ((rootType == null) || (valueSerializer == null)) {
                        return this;
                    }
                    return new Prefetch(null, null, null);
                }
    
                // Second: if no change, nothing to do either
                if (newType.equals(rootType)) {
                    return this;
                }
    
                // But one more trick: `java.lang.Object` has no serialized, but may
                // have `TypeSerializer` to use
                if (newType.isJavaLangObject()) {
                    DefaultSerializerProvider prov = parent._serializerProvider();
                    TypeSerializer typeSer;
    
                    try {
                        typeSer = prov.findTypeSerializer(newType);
                    } catch (JsonMappingException e) {
                        // Unlike with value serializer pre-fetch, let's not allow exception
                        // for TypeSerializer be swallowed
                        throw new RuntimeJsonMappingException(e);
                    }
                    return new Prefetch(null, null, typeSer);
                }
    
                if (parent.isEnabled(SerializationFeature.EAGER_SERIALIZER_FETCH)) {
                    DefaultSerializerProvider prov = parent._serializerProvider();
                    // 17-Dec-2014, tatu: Need to be bit careful here; TypeSerializers are NOT cached,
                    //   so although it'd seem like a good idea to look for those first, and avoid
                    //   serializer for polymorphic types, it is actually more efficient to do the
                    //   reverse here.
                    try {
                        JsonSerializer<Object> ser = prov.findTypedValueSerializer(newType, true, null);
                        // Important: for polymorphic types, "unwrap"...
                        if (ser instanceof TypeWrappedSerializer) {
                            return new Prefetch(newType, null,
                                    ((TypeWrappedSerializer) ser).typeSerializer());
                        }
                        return new Prefetch(newType, ser, null);
                    } catch (JsonMappingException e) {
                        // need to swallow?
                        ;
                    }
                }
                return new Prefetch(newType, null, typeSerializer);
            }
    
            public final JsonSerializer<Object> getValueSerializer() {
                return valueSerializer;
            }
    
            public final TypeSerializer getTypeSerializer() {
                return typeSerializer;
            }
    
            public boolean hasSerializer() {
                return (valueSerializer != null) || (typeSerializer != null);
            }
    
            public void serialize(JsonGenerator gen, Object value, DefaultSerializerProvider prov)
                throws IOException
            {
                if (typeSerializer != null) {
                    prov.serializePolymorphic(gen, value, rootType, valueSerializer, typeSerializer);
                } else  if (valueSerializer != null) {
                    prov.serializeValue(gen, value, rootType, valueSerializer);
                } else if (rootType != null) {
                    prov.serializeValue(gen, value, rootType);
                } else {
                    prov.serializeValue(gen, value);
                }
            }
        }
    }
    

    com/fasterxml/jackson/databind/ObjectWriter.java

     

    ⇒ Jackson Annotations Source Code

    ⇐ Download and Install Jackson Binary Package

    ⇑ Downloading and Reviewing jackson-*.jar

    ⇑⇑ Jackson - Java JSON library

    2022-03-29, 31718👍, 0💬