All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.map.ser.std.StdArraySerializers Maven / Gradle / Ivy

Go to download

Data Mapper package is a high-performance data binding package built on Jackson JSON processor

There is a newer version: 1.9.13
Show newest version
package org.codehaus.jackson.map.ser.std;

import java.io.IOException;
import java.lang.reflect.Type;

import org.codehaus.jackson.*;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.annotate.JacksonStdImpl;

/**
 * Dummy container class to group standard homogenous array serializer implementations
 * (primitive arrays and String array).
 */
public class StdArraySerializers
{
    protected StdArraySerializers() { }

    /*
    /**********************************************************
    /* Base classes
    /**********************************************************
     */
    
    /**
     * Base class for serializers that will output contents as JSON
     * arrays.
     */
    public abstract static class ArraySerializerBase
        extends ContainerSerializerBase
    {
         /**
         * Type serializer used for values, if any.
         */
        protected final TypeSerializer _valueTypeSerializer;

        /**
         * Array-valued property being serialized with this instance
         * 
         * @since 1.7
         */
        protected final BeanProperty _property;
        
        protected ArraySerializerBase(Class cls, TypeSerializer vts, BeanProperty property)
        {
            super(cls);
            _valueTypeSerializer = vts;
            _property = property;
        }
        
        @Override
        public final void serialize(T value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonGenerationException
        {
            jgen.writeStartArray();
            serializeContents(value, jgen, provider);
            jgen.writeEndArray();
        }
        
        @Override
        public final void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider,
                TypeSerializer typeSer)
            throws IOException, JsonGenerationException
        {
            typeSer.writeTypePrefixForArray(value, jgen);
            serializeContents(value, jgen, provider);
            typeSer.writeTypeSuffixForArray(value, jgen);
        }

        protected abstract void serializeContents(T value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonGenerationException;
    }

    /*
     ****************************************************************
    /* Concrete serializers, arrays
     ****************************************************************
     */

    /**
     * Standard serializer used for String[] values.
     */
    @JacksonStdImpl
    public final static class StringArraySerializer
        extends ArraySerializerBase
        implements ResolvableSerializer
    {
        /**
         * Value serializer to use, if it's not the standard one
         * (if it is we can optimize serialization a lot)
         * 
         * @since 1.7
         */
        protected JsonSerializer _elementSerializer;

        public StringArraySerializer(BeanProperty prop) {
            super(String[].class, null, prop);
        }

        /**
         * Strings never add type info; hence, even if type serializer is suggested,
         * we'll ignore it...
         */
        @Override
        public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) {
            return this;
        }
        
        @Override
        public void serializeContents(String[] value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonGenerationException
        {
            final int len = value.length;
            if (len == 0) {
                return;
            }
            if (_elementSerializer != null) {
                serializeContentsSlow(value, jgen, provider, _elementSerializer);
                return;
            }
            /* 08-Dec-2008, tatus: If we want this to be fully overridable
             *  (for example, to support String cleanup during writing
             *  or something), we should find serializer  by provider.
             *  But for now, that seems like an overkill: and caller can
             *  add custom serializer if that is needed as well.
             * (ditto for null values)
             */
            //JsonSerializer ser = (JsonSerializer)provider.findValueSerializer(String.class);
            for (int i = 0; i < len; ++i) {
                String str = value[i];
                if (str == null) {
                    jgen.writeNull();
                } else {
                    //ser.serialize(value[i], jgen, provider);
                    jgen.writeString(value[i]);
                }
            }
        }

        private void serializeContentsSlow(String[] value, JsonGenerator jgen, SerializerProvider provider,
                JsonSerializer ser)
            throws IOException, JsonGenerationException
        {
            for (int i = 0, len = value.length; i < len; ++i) {
                String str = value[i];
                if (str == null) {
                    provider.defaultSerializeNull(jgen);
                } else {
                    ser.serialize(value[i], jgen, provider);
                }
            }
        }

        /**
         * Need to get callback to resolve value serializer, which may
         * be overridden by custom serializer
         */
        @Override
        public void resolve(SerializerProvider provider)
            throws JsonMappingException
        {
            JsonSerializer ser = provider.findValueSerializer(String.class, _property);
            // Retain if not the standard implementation
            if (ser != null && ser.getClass().getAnnotation(JacksonStdImpl.class) == null) {
                _elementSerializer = ser;
            }
        }        
        
        @Override
        public JsonNode getSchema(SerializerProvider provider, Type typeHint)
        {
            ObjectNode o = createSchemaNode("array", true);
            o.put("items", createSchemaNode("string"));
            return o;
        }
    }

    @JacksonStdImpl
    public final static class BooleanArraySerializer
        extends ArraySerializerBase
    {
        public BooleanArraySerializer() { super(boolean[].class, null, null); }

        /**
         * Booleans never add type info; hence, even if type serializer is suggested,
         * we'll ignore it...
         */
        @Override
        public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts)
        {
            return this;
        }
        
        @Override
        public void serializeContents(boolean[] value, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonGenerationException
        {
            for (int i = 0, len = value.length; i < len; ++i) {
                jgen.writeBoolean(value[i]);
            }
        }

        @Override
        public JsonNode getSchema(SerializerProvider provider, Type typeHint)
        {
            ObjectNode o = createSchemaNode("array", true);
            o.put("items", createSchemaNode("boolean"));
            return o;
        }
    }

    /**
     * Unlike other integral number array serializers, we do not just print out byte values
     * as numbers. Instead, we assume that it would make more sense to output content
     * as base64 encoded bytes (using default base64 encoding).
     *

* NOTE: since it is NOT serialized as an array, can not use AsArraySerializer as base */ @JacksonStdImpl public final static class ByteArraySerializer extends SerializerBase { public ByteArraySerializer() { super(byte[].class); } @Override public void serialize(byte[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeBinary(value); } @Override public void serializeWithType(byte[] value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { typeSer.writeTypePrefixForScalar(value, jgen); jgen.writeBinary(value); typeSer.writeTypeSuffixForScalar(value, jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); ObjectNode itemSchema = createSchemaNode("string"); //binary values written as strings? o.put("items", itemSchema); return o; } } @JacksonStdImpl public final static class ShortArraySerializer extends ArraySerializerBase { public ShortArraySerializer() { this(null); } public ShortArraySerializer(TypeSerializer vts) { super(short[].class, vts, null); } @Override public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) { return new ShortArraySerializer(vts); } @SuppressWarnings("cast") @Override public void serializeContents(short[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeNumber((int)value[i]); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { //no "short" type defined by json ObjectNode o = createSchemaNode("array", true); o.put("items", createSchemaNode("integer")); return o; } } /** * Character arrays are different from other integral number arrays in that * they are most likely to be textual data, and should be written as * Strings, not arrays of entries. *

* NOTE: since it is NOT serialized as an array, can not use AsArraySerializer as base */ @JacksonStdImpl public final static class CharArraySerializer extends SerializerBase { public CharArraySerializer() { super(char[].class); } @Override public void serialize(char[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { // [JACKSON-289] allows serializing as 'sparse' char array too: if (provider.isEnabled(SerializationConfig.Feature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS)) { jgen.writeStartArray(); _writeArrayContents(jgen, value); jgen.writeEndArray(); } else { jgen.writeString(value, 0, value.length); } } @Override public void serializeWithType(char[] value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { // [JACKSON-289] allows serializing as 'sparse' char array too: if (provider.isEnabled(SerializationConfig.Feature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS)) { typeSer.writeTypePrefixForArray(value, jgen); _writeArrayContents(jgen, value); typeSer.writeTypeSuffixForArray(value, jgen); } else { // default is to write as simple String typeSer.writeTypePrefixForScalar(value, jgen); jgen.writeString(value, 0, value.length); typeSer.writeTypeSuffixForScalar(value, jgen); } } private final void _writeArrayContents(JsonGenerator jgen, char[] value) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeString(value, i, 1); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); ObjectNode itemSchema = createSchemaNode("string"); itemSchema.put("type", "string"); o.put("items", itemSchema); return o; } } @JacksonStdImpl public final static class IntArraySerializer extends ArraySerializerBase { public IntArraySerializer() { super(int[].class, null, null); } /** * Ints never add type info; hence, even if type serializer is suggested, * we'll ignore it... */ @Override public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) { return this; } @Override public void serializeContents(int[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeNumber(value[i]); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); o.put("items", createSchemaNode("integer")); return o; } } @JacksonStdImpl public final static class LongArraySerializer extends ArraySerializerBase { public LongArraySerializer() { this(null); } public LongArraySerializer(TypeSerializer vts) { super(long[].class, vts, null); } @Override public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) { return new LongArraySerializer(vts); } @Override public void serializeContents(long[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeNumber(value[i]); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); o.put("items", createSchemaNode("number", true)); return o; } } @JacksonStdImpl public final static class FloatArraySerializer extends ArraySerializerBase { public FloatArraySerializer() { this(null); } public FloatArraySerializer(TypeSerializer vts) { super(float[].class, vts, null); } @Override public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) { return new FloatArraySerializer(vts); } @Override public void serializeContents(float[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeNumber(value[i]); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); o.put("items", createSchemaNode("number")); return o; } } @JacksonStdImpl public final static class DoubleArraySerializer extends ArraySerializerBase { public DoubleArraySerializer() { super(double[].class, null, null); } /** * Doubles never add type info; hence, even if type serializer is suggested, * we'll ignore it... */ @Override public ContainerSerializerBase _withValueTypeSerializer(TypeSerializer vts) { return this; } @Override public void serializeContents(double[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { jgen.writeNumber(value[i]); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("array", true); o.put("items", createSchemaNode("number")); return o; } } }