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/jsontype/impl/TypeDeserializerBase.java

    package com.fasterxml.jackson.databind.jsontype.impl;
    
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    
    import com.fasterxml.jackson.core.*;
    
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.deser.std.NullifyingDeserializer;
    import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
    import com.fasterxml.jackson.databind.jsontype.TypeIdResolver;
    import com.fasterxml.jackson.databind.util.ClassUtil;
    
    /**
     * Base class for all standard Jackson {@link TypeDeserializer}s.
     */
    public abstract class TypeDeserializerBase
        extends TypeDeserializer
        implements java.io.Serializable
    {
        private static final long serialVersionUID = 1;
    
        protected final TypeIdResolver _idResolver;
    
        protected final JavaType _baseType;
    
        /**
         * Property that contains value for which type information
         * is included; null if value is a root value.
         * Note that this value is not assigned during construction
         * but only when {@link #forProperty} is called to create
         * a copy.
         */
        protected final BeanProperty _property;
    
        /**
         * Type to use as the default implementation, if type id is
         * missing or cannot be resolved.
         */
        protected final JavaType _defaultImpl;
    
        /**
         * Name of type property used; needed for non-property versions too,
         * in cases where type id is to be exposed as part of JSON.
         */
        protected final String _typePropertyName;
    
        protected final boolean _typeIdVisible;
    
        /**
         * For efficient operation we will lazily build mappings from type ids
         * to actual deserializers, once needed.
         */
        protected final Map<String,JsonDeserializer<Object>> _deserializers;
    
        protected JsonDeserializer<Object> _defaultImplDeserializer;
    
        /*
        /**********************************************************
        /* Life-cycle
        /**********************************************************
         */
    
        /**
         * @since 2.8
         */
        protected TypeDeserializerBase(JavaType baseType, TypeIdResolver idRes,
                String typePropertyName, boolean typeIdVisible, JavaType defaultImpl)
        {
            _baseType = baseType;
            _idResolver = idRes;
            _typePropertyName = ClassUtil.nonNullString(typePropertyName);
            _typeIdVisible = typeIdVisible;
            // defaults are fine, although shouldn't need much concurrency
            _deserializers = new ConcurrentHashMap<String, JsonDeserializer<Object>>(16, 0.75f, 2);
            _defaultImpl = defaultImpl;
            _property = null;
        }
    
        protected TypeDeserializerBase(TypeDeserializerBase src, BeanProperty property)
        {
            _baseType = src._baseType;
            _idResolver = src._idResolver;
            _typePropertyName = src._typePropertyName;
            _typeIdVisible = src._typeIdVisible;
            _deserializers = src._deserializers;
            _defaultImpl = src._defaultImpl;
            _defaultImplDeserializer = src._defaultImplDeserializer;
            _property = property;
        }
    
        @Override
        public abstract TypeDeserializer forProperty(BeanProperty prop);
    
        /*
        /**********************************************************
        /* Accessors
        /**********************************************************
         */
        
        @Override
        public abstract JsonTypeInfo.As getTypeInclusion();
    
        public String baseTypeName() { return _baseType.getRawClass().getName(); }
    
        @Override
        public final String getPropertyName() { return _typePropertyName; }
        
        @Override    
        public TypeIdResolver getTypeIdResolver() { return _idResolver; }
    
        @Override
        public Class<?> getDefaultImpl() {
            return ClassUtil.rawClass(_defaultImpl);
        }
    
        @Override
        public boolean hasDefaultImpl() {
            return (_defaultImpl != null);
        }
    
        /**
         * @since 2.9
         */
        public JavaType baseType() {
            return _baseType;
        }
    
        @Override
        public String toString()
        {
            StringBuilder sb = new StringBuilder();
            sb.append('[').append(getClass().getName());
            sb.append("; base-type:").append(_baseType);
            sb.append("; id-resolver: ").append(_idResolver);
            sb.append(']');
            return sb.toString();
        }
        
        /*
        /**********************************************************
        /* Helper methods for sub-classes
        /**********************************************************
         */
    
        protected final JsonDeserializer<Object> _findDeserializer(DeserializationContext ctxt,
                String typeId) throws IOException
        {
            JsonDeserializer<Object> deser = _deserializers.get(typeId);
            if (deser == null) {
                /* As per [databind#305], need to provide contextual info. But for
                 * backwards compatibility, let's start by only supporting this
                 * for base class, not via interface. Later on we can add this
                 * to the interface, assuming deprecation at base class helps.
                 */
                JavaType type = _idResolver.typeFromId(ctxt, typeId);
                if (type == null) {
                    // use the default impl if no type id available:
                    deser = _findDefaultImplDeserializer(ctxt);
                    if (deser == null) {
                        // 10-May-2016, tatu: We may get some help...
                        JavaType actual = _handleUnknownTypeId(ctxt, typeId);
                        if (actual == null) { // what should this be taken to mean?
                            // 17-Jan-2019, tatu: As per [databind#2221], better NOT return `null` but...
                            return NullifyingDeserializer.instance;
                        }
                        // ... would this actually work?
                        deser = ctxt.findContextualValueDeserializer(actual, _property);
                    }
                } else {
                    /* 16-Dec-2010, tatu: Since nominal type we get here has no (generic) type parameters,
                     *   we actually now need to explicitly narrow from base type (which may have parameterization)
                     *   using raw type.
                     *
                     *   One complication, though; cannot change 'type class' (simple type to container); otherwise
                     *   we may try to narrow a SimpleType (Object.class) into MapType (Map.class), losing actual
                     *   type in process (getting SimpleType of Map.class which will not work as expected)
                     */
                    if ((_baseType != null)
                            && _baseType.getClass() == type.getClass()) {
                        /* 09-Aug-2015, tatu: Not sure if the second part of the check makes sense;
                         *   but it appears to check that JavaType impl class is the same which is
                         *   important for some reason?
                         *   Disabling the check will break 2 Enum-related tests.
                         */
                        // 19-Jun-2016, tatu: As per [databind#1270] we may actually get full
                        //   generic type with custom type resolvers. If so, should try to retain them.
                        //  Whether this is sufficient to avoid problems remains to be seen, but for
                        //  now it should improve things.
                        if (!type.hasGenericTypes()) {
                            try { // [databind#2668]: Should not expose generic RTEs
                                type = ctxt.constructSpecializedType(_baseType, type.getRawClass());
                            } catch (IllegalArgumentException e) {
                                // 29-Mar-2020, tatu: I hope this is not misleading for other cases, but
                                //   for [databind#2668] seems reasonable
                                throw ctxt.invalidTypeIdException(_baseType, typeId, e.getMessage());
                            }
                        }
                    }
                    deser = ctxt.findContextualValueDeserializer(type, _property);
                }
                _deserializers.put(typeId, deser);
            }
            return deser;
        }
    
        protected final JsonDeserializer<Object> _findDefaultImplDeserializer(DeserializationContext ctxt) throws IOException
        {
            // 06-Feb-2013, tatu: As per [databind#148], consider default implementation value of
            //   {@link java.lang.Void} to mean "serialize as null"; as well as DeserializationFeature
            //   to do swift mapping to null
            if (_defaultImpl == null) {
                if (!ctxt.isEnabled(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE)) {
                    return NullifyingDeserializer.instance;
                }
                return null;
            }
            Class<?> raw = _defaultImpl.getRawClass();
            if (ClassUtil.isBogusClass(raw)) {
                return NullifyingDeserializer.instance;
            }
            
            synchronized (_defaultImpl) {
                if (_defaultImplDeserializer == null) {
                    _defaultImplDeserializer = ctxt.findContextualValueDeserializer(
                            _defaultImpl, _property);
                }
                return _defaultImplDeserializer;
            }
        }
    
        /**
         * Helper method called when {@link JsonParser} indicates that it can use
         * so-called native type ids. Assumption from there is that only native
         * type ids are to be used.
         * 
         * @since 2.3
         */
        @Deprecated
        protected Object _deserializeWithNativeTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException {
            return _deserializeWithNativeTypeId(jp, ctxt, jp.getTypeId());
        }
    
        /**
         * Helper method called when {@link JsonParser} indicates that it can use
         * so-called native type ids, and such type id has been found.
         * 
         * @since 2.4
         */
        protected Object _deserializeWithNativeTypeId(JsonParser p, DeserializationContext ctxt, Object typeId)
            throws IOException
        {
            JsonDeserializer<Object> deser;
            if (typeId == null) {
                // 04-May-2014, tatu: Should error be obligatory, or should there be another method
                //   for "try to deserialize with native type id"?
                deser = _findDefaultImplDeserializer(ctxt);
                if (deser == null) {
                    return ctxt.reportInputMismatch(baseType(),
                            "No (native) type id found when one was expected for polymorphic type handling");
                }
            } else {
                String typeIdStr = (typeId instanceof String) ? (String) typeId : String.valueOf(typeId);
                deser = _findDeserializer(ctxt, typeIdStr);
            }
            return deser.deserialize(p, ctxt);
        }
    
        /**
         * Helper method called when given type id cannot be resolved into 
         * concrete deserializer either directly (using given {@link  TypeIdResolver}),
         * or using default type.
         * Default implementation simply throws a {@link com.fasterxml.jackson.databind.JsonMappingException} to
         * indicate the problem; sub-classes may choose
         *
         * @return If it is possible to resolve type id into a {@link JsonDeserializer}
         *   should return that deserializer; otherwise throw an exception to indicate
         *   the problem.
         *
         * @since 2.8
         */
        protected JavaType _handleUnknownTypeId(DeserializationContext ctxt, String typeId)
            throws IOException
        {
            String extraDesc = _idResolver.getDescForKnownTypeIds();
            if (extraDesc == null) {
                extraDesc = "type ids are not statically known";
            } else {
                extraDesc = "known type ids = " + extraDesc;
            }
            if (_property != null) {
                extraDesc = String.format("%s (for POJO property '%s')", extraDesc,
                        _property.getName());
            }
            return ctxt.handleUnknownTypeId(_baseType, typeId, _idResolver, extraDesc);
        }
    
        /**
         * @since 2.9
         */
        protected JavaType _handleMissingTypeId(DeserializationContext ctxt, String extraDesc)
            throws IOException
        {
            return ctxt.handleMissingTypeId(_baseType, _idResolver, extraDesc);
        }
    }
    

    com/fasterxml/jackson/databind/jsontype/impl/TypeDeserializerBase.java

     

    ⇒ Jackson Annotations Source Code

    ⇐ Download and Install Jackson Binary Package

    ⇑ Downloading and Reviewing jackson-*.jar

    ⇑⇑ Jackson - Java JSON library

    2022-03-29, 32302👍, 0💬