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/ser/impl/MapEntrySerializer.java

    package com.fasterxml.jackson.databind.ser.impl;
    
    import java.io.IOException;
    import java.util.Map;
    import java.util.Map.Entry;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    
    import com.fasterxml.jackson.core.JsonGenerator;
    import com.fasterxml.jackson.core.JsonToken;
    import com.fasterxml.jackson.core.type.WritableTypeId;
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
    import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
    import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
    import com.fasterxml.jackson.databind.ser.ContainerSerializer;
    import com.fasterxml.jackson.databind.ser.ContextualSerializer;
    import com.fasterxml.jackson.databind.util.ArrayBuilders;
    import com.fasterxml.jackson.databind.util.BeanUtil;
    
    /**
     * @since 2.5
     */
    @SuppressWarnings("serial")
    @JacksonStdImpl
    public class MapEntrySerializer
        extends ContainerSerializer<Map.Entry<?,?>>
        implements ContextualSerializer
    {
        /**
         * @since 2.9
         */
        public final static Object MARKER_FOR_EMPTY = JsonInclude.Include.NON_EMPTY;
    
        /**
         * Map-valued property being serialized with this instance
         */
        protected final BeanProperty _property;
    
        /**
         * Whether static types should be used for serialization of values
         * or not (if not, dynamic runtime type is used)
         */
        protected final boolean _valueTypeIsStatic;
    
        protected final JavaType _entryType, _keyType, _valueType;
    
        /*
        /**********************************************************
        /* Serializers used
        /**********************************************************
         */
    
        /**
         * Key serializer to use, if it can be statically determined
         */
        protected JsonSerializer<Object> _keySerializer;
    
        /**
         * Value serializer to use, if it can be statically determined
         */
        protected JsonSerializer<Object> _valueSerializer;
    
        /**
         * Type identifier serializer used for values, if any.
         */
        protected final TypeSerializer _valueTypeSerializer;
    
        /**
         * If value type cannot be statically determined, mapping from
         * runtime value types to serializers are stored in this object.
         */
        protected PropertySerializerMap _dynamicValueSerializers;
    
        /*
        /**********************************************************
        /* Config settings, filtering
        /**********************************************************
         */
    
        /**
         * Value that indicates suppression mechanism to use for <b>values contained</b>;
         * either "filter" (of which <code>equals()</code> is called), or marker
         * value of {@link #MARKER_FOR_EMPTY}, or null to indicate no filtering for
         * non-null values.
         * Note that inclusion value for Map instance itself is handled by caller (POJO
         * property that refers to the Map value).
         * 
         * @since 2.5
         */
        protected final Object _suppressableValue;
    
        /**
         * Flag that indicates what to do with `null` values, distinct from
         * handling of {@link #_suppressableValue}
         *
         * @since 2.9
         */
        protected final boolean _suppressNulls;
    
        /*
        /**********************************************************
        /* Construction, initialization
        /**********************************************************
         */
    
        public MapEntrySerializer(JavaType type, JavaType keyType, JavaType valueType,
                boolean staticTyping, TypeSerializer vts,
                BeanProperty property)
        {
            super(type);
            _entryType = type;
            _keyType = keyType;
            _valueType = valueType;
            _valueTypeIsStatic = staticTyping;
            _valueTypeSerializer = vts;
            _property = property;
            _dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
            _suppressableValue = null;
            _suppressNulls = false;
        }
    
        @Deprecated // since 2.9
        protected MapEntrySerializer(MapEntrySerializer src, BeanProperty property,
                TypeSerializer vts,
                JsonSerializer<?> keySer, JsonSerializer<?> valueSer)
        {
            this(src, property, vts, keySer, valueSer,
                    src._suppressableValue, src._suppressNulls);
        }
            
        @SuppressWarnings("unchecked")
        protected MapEntrySerializer(MapEntrySerializer src, BeanProperty property,
                TypeSerializer vts,
                JsonSerializer<?> keySer, JsonSerializer<?> valueSer,
                Object suppressableValue, boolean suppressNulls)
        {
            super(Map.class, false);
            _entryType = src._entryType;
            _keyType = src._keyType;
            _valueType = src._valueType;
            _valueTypeIsStatic = src._valueTypeIsStatic;
            _valueTypeSerializer = src._valueTypeSerializer;
            _keySerializer = (JsonSerializer<Object>) keySer;
            _valueSerializer = (JsonSerializer<Object>) valueSer;
            // [databind#2181]: may not be safe to reuse, start from empty
            _dynamicValueSerializers = PropertySerializerMap.emptyForProperties();
            _property = src._property;
            _suppressableValue = suppressableValue;
            _suppressNulls = suppressNulls;
        }
    
        @Override
        public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts) {
            return new MapEntrySerializer(this, _property, vts, _keySerializer, _valueSerializer,
                    _suppressableValue, _suppressNulls);
        }
    
        /**
         * @since 2.9
         */
        public MapEntrySerializer withResolved(BeanProperty property,
                JsonSerializer<?> keySerializer, JsonSerializer<?> valueSerializer,
                Object suppressableValue, boolean suppressNulls) {
            return new MapEntrySerializer(this, property, _valueTypeSerializer,
                    keySerializer, valueSerializer, suppressableValue, suppressNulls);
        }
    
        /**
         * @since 2.9
         */
        public MapEntrySerializer withContentInclusion(Object suppressableValue,
                boolean suppressNulls) {
            if ((_suppressableValue == suppressableValue)
                    && (_suppressNulls == suppressNulls)) {
                return this;
            }
            return new MapEntrySerializer(this, _property, _valueTypeSerializer,
                    _keySerializer, _valueSerializer, suppressableValue, suppressNulls);
        }
    
        @Override
        public JsonSerializer<?> createContextual(SerializerProvider provider,
                BeanProperty property) throws JsonMappingException
        {
            JsonSerializer<?> ser = null;
            JsonSerializer<?> keySer = null;
            final AnnotationIntrospector intr = provider.getAnnotationIntrospector();
            final AnnotatedMember propertyAcc = (property == null) ? null : property.getMember();
    
            // First: if we have a property, may have property-annotation overrides
            if (propertyAcc != null && intr != null) {
                Object serDef = intr.findKeySerializer(propertyAcc);
                if (serDef != null) {
                    keySer = provider.serializerInstance(propertyAcc, serDef);
                }
                serDef = intr.findContentSerializer(propertyAcc);
                if (serDef != null) {
                    ser = provider.serializerInstance(propertyAcc, serDef);
                }
            }
            if (ser == null) {
                ser = _valueSerializer;
            }
            // [databind#124]: May have a content converter
            ser = findContextualConvertingSerializer(provider, property, ser);
            if (ser == null) {
                // 30-Sep-2012, tatu: One more thing -- if explicit content type is annotated,
                //   we can consider it a static case as well.
                // 20-Aug-2013, tatu: Need to avoid trying to access serializer for java.lang.Object tho
                if (_valueTypeIsStatic && !_valueType.isJavaLangObject()) {
                    ser = provider.findContentValueSerializer(_valueType, property);
                }
            }
            if (keySer == null) {
                keySer = _keySerializer;
            }
            if (keySer == null) {
                keySer = provider.findKeySerializer(_keyType, property);
            } else {
                keySer = provider.handleSecondaryContextualization(keySer, property);
            }
    
            Object valueToSuppress = _suppressableValue;
            boolean suppressNulls = _suppressNulls;
            if (property != null) {
                JsonInclude.Value inclV = property.findPropertyInclusion(provider.getConfig(), null);
                if (inclV != null) {
                    JsonInclude.Include incl = inclV.getContentInclusion();
                    if (incl != JsonInclude.Include.USE_DEFAULTS) {
                        switch (incl) {
                        case NON_DEFAULT:
                            valueToSuppress = BeanUtil.getDefaultValue(_valueType);
                            suppressNulls = true;
                            if (valueToSuppress != null) {
                                if (valueToSuppress.getClass().isArray()) {
                                    valueToSuppress = ArrayBuilders.getArrayComparator(valueToSuppress);
                                }
                            }
                            break;
                        case NON_ABSENT:
                            suppressNulls = true;
                            valueToSuppress = _valueType.isReferenceType() ? MARKER_FOR_EMPTY : null;
                            break;
                        case NON_EMPTY:
                            suppressNulls = true;
                            valueToSuppress = MARKER_FOR_EMPTY;
                            break;
                        case CUSTOM:
                            valueToSuppress = provider.includeFilterInstance(null, inclV.getContentFilter());
                            if (valueToSuppress == null) { // is this legal?
                                suppressNulls = true;
                            } else {
                                suppressNulls = provider.includeFilterSuppressNulls(valueToSuppress);
                            }
                            break;
                        case NON_NULL:
                            valueToSuppress = null;
                            suppressNulls = true;
                            break;
                        case ALWAYS: // default
                        default:
                            valueToSuppress = null;
                            // 30-Sep-2016, tatu: Should not need to check global flags here,
                            //   if inclusion forced to be ALWAYS
                            suppressNulls = false;
                            break;
                        }
                    }
                }
            }
            
            MapEntrySerializer mser = withResolved(property, keySer, ser,
                    valueToSuppress, suppressNulls);
            // but note: no (full) filtering or sorting (unlike Maps)
            return mser;
        }
    
        /*
        /**********************************************************
        /* Accessors
        /**********************************************************
         */
    
        @Override
        public JavaType getContentType() {
            return _valueType;
        }
    
        @Override
        public JsonSerializer<?> getContentSerializer() {
            return _valueSerializer;
        }
    
        @Override
        public boolean hasSingleElement(Map.Entry<?,?> value) {
            return true;
        }
    
        @Override
        public boolean isEmpty(SerializerProvider prov, Entry<?, ?> entry)
        {
            Object value = entry.getValue();
            if (value == null) {
                return _suppressNulls;
            }
            if (_suppressableValue == null) {
                return false;
            }
            JsonSerializer<Object> valueSer = _valueSerializer;
            if (valueSer == null) {
                // Let's not worry about generic types here, actually;
                // unlikely to make any difference, but does add significant overhead
                Class<?> cc = value.getClass();
                valueSer = _dynamicValueSerializers.serializerFor(cc);
                if (valueSer == null) {
                    try {
                        valueSer = _findAndAddDynamic(_dynamicValueSerializers, cc, prov);
                    } catch (JsonMappingException e) { // Ugh... cannot just throw as-is, so...
                        return false;
                    }
                }
            }
            if (_suppressableValue == MARKER_FOR_EMPTY) {
                return valueSer.isEmpty(prov, value);
            }
            return _suppressableValue.equals(value);
        }
    
        /*
        /**********************************************************
        /* Serialization methods
        /**********************************************************
         */
    
        @Override
        public void serialize(Map.Entry<?, ?> value, JsonGenerator gen, SerializerProvider provider)
            throws IOException
        {
            gen.writeStartObject(value);
            serializeDynamic(value, gen, provider);
            gen.writeEndObject();
        }
    
        @Override
        public void serializeWithType(Map.Entry<?, ?> value, JsonGenerator g,
                SerializerProvider provider, TypeSerializer typeSer) throws IOException
        {
            // [databind#631]: Assign current value, to be accessible by custom serializers
            g.setCurrentValue(value);
            WritableTypeId typeIdDef = typeSer.writeTypePrefix(g,
                    typeSer.typeId(value, JsonToken.START_OBJECT));
            serializeDynamic(value, g, provider);
            typeSer.writeTypeSuffix(g, typeIdDef);
        }
    
        protected void serializeDynamic(Map.Entry<?, ?> value, JsonGenerator gen,
                SerializerProvider provider)
            throws IOException
        {
            final TypeSerializer vts = _valueTypeSerializer;
            final Object keyElem = value.getKey();
    
            JsonSerializer<Object> keySerializer;
            if (keyElem == null) {
                keySerializer = provider.findNullKeySerializer(_keyType, _property);
            } else {
                keySerializer = _keySerializer;
            }
            // or by value; nulls often suppressed
            final Object valueElem = value.getValue();
            JsonSerializer<Object> valueSer;
            // And then value
            if (valueElem == null) {
                if (_suppressNulls) {
                    return;
                }
                valueSer = provider.getDefaultNullValueSerializer();
            } else {
                valueSer = _valueSerializer;
                if (valueSer == null) {
                    Class<?> cc = valueElem.getClass();
                    valueSer = _dynamicValueSerializers.serializerFor(cc);
                    if (valueSer == null) {
                        if (_valueType.hasGenericTypes()) {
                            valueSer = _findAndAddDynamic(_dynamicValueSerializers,
                                    provider.constructSpecializedType(_valueType, cc), provider);
                        } else {
                            valueSer = _findAndAddDynamic(_dynamicValueSerializers, cc, provider);
                        }
                    }
                }
                // also may need to skip non-empty values:
                if (_suppressableValue != null) {
                    if (_suppressableValue == MARKER_FOR_EMPTY) {
                        if (valueSer.isEmpty(provider, valueElem)) {
                            return;
                        }
                    } if (_suppressableValue.equals(valueElem)) {
                        return;
                    }
                }
            }
            keySerializer.serialize(keyElem, gen, provider);
            try {
                if (vts == null) {
                    valueSer.serialize(valueElem, gen, provider);
                } else {
                    valueSer.serializeWithType(valueElem, gen, provider, vts);
                }
            } catch (Exception e) {
                String keyDesc = ""+keyElem;
                wrapAndThrow(provider, e, value, keyDesc);
            }
        }
    
        /*
        /**********************************************************
        /* Internal helper methods
        /**********************************************************
         */
        
        protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
                Class<?> type, SerializerProvider provider) throws JsonMappingException
        {
            PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
            if (map != result.map) {
                _dynamicValueSerializers = result.map;
            }
            return result.serializer;
        }
    
        protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map,
                JavaType type, SerializerProvider provider) throws JsonMappingException
        {
            PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property);
            if (map != result.map) {
                _dynamicValueSerializers = result.map;
            }
            return result.serializer;
        }
    
    }

    com/fasterxml/jackson/databind/ser/impl/MapEntrySerializer.java

     

    ⇒ Jackson Annotations Source Code

    ⇐ Download and Install Jackson Binary Package

    ⇑ Downloading and Reviewing jackson-*.jar

    ⇑⇑ Jackson - Java JSON library

    2022-03-29, 32030👍, 0💬