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/deser/SettableBeanProperty.java

    package com.fasterxml.jackson.databind.deser;
    
    import java.io.IOException;
    import java.lang.annotation.Annotation;
    
    import com.fasterxml.jackson.core.*;
    
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.deser.impl.FailingDeserializer;
    import com.fasterxml.jackson.databind.deser.impl.NullsConstantProvider;
    import com.fasterxml.jackson.databind.introspect.*;
    import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonObjectFormatVisitor;
    import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
    import com.fasterxml.jackson.databind.util.Annotations;
    import com.fasterxml.jackson.databind.util.ClassUtil;
    import com.fasterxml.jackson.databind.util.ViewMatcher;
    
    /**
     * Base class for deserializable properties of a bean: contains
     * both type and name definitions, and reflection-based set functionality.
     * Concrete sub-classes implement details, so that field- and
     * setter-backed properties, as well as a few more esoteric variations,
     * can be handled.
     */
    @SuppressWarnings("serial")
    public abstract class SettableBeanProperty
        extends ConcreteBeanPropertyBase
        implements java.io.Serializable
    {
        /**
         * To avoid nasty NPEs, let's use a placeholder for _valueDeserializer,
         * if real deserializer is not (yet) available.
         * 
         * @since 2.2
         */
        protected static final JsonDeserializer<Object> MISSING_VALUE_DESERIALIZER = new FailingDeserializer(
                "No _valueDeserializer assigned");
    
        /**
         * Logical name of the property (often but not always derived
         * from the setter method name)
         */
        protected final PropertyName _propName;
    
        /**
         * Base type for property; may be a supertype of actual value.
         */
        protected final JavaType _type;
    
        /**
         * @since 2.2
         */
        protected final PropertyName _wrapperName;
    
        /**
         * Class that contains this property (either class that declares
         * the property or one of its subclasses), class that is
         * deserialized using deserializer that contains this property.
         */
        protected final transient Annotations _contextAnnotations;
    
        /**
         * Deserializer used for handling property value.
         *<p>
         * NOTE: has been immutable since 2.3
         */
        protected final JsonDeserializer<Object> _valueDeserializer;
    
        /**
         * If value will contain type information (to support
         * polymorphic handling), this is the type deserializer
         * used to handle type resolution.
         */
        protected final TypeDeserializer _valueTypeDeserializer;
    
        /**
         * Entity used for possible translation from `null` into non-null
         * value of type of this property.
         * Often same as <code>_valueDeserializer</code>, but not always.
         *
         * @since 2.9
         */
        protected final NullValueProvider _nullProvider;
    
        /*
        /**********************************************************
        /* Configuration that is not yet immutable; generally assigned
        /* during initialization process but cannot be passed to
        /* constructor.
        /**********************************************************
         */
    
        /**
         * If property represents a managed (forward) reference, we will need
         * the name of reference for later linking.
         *<p>
         * TODO: should try to make immutable.
         */
        protected String _managedReferenceName;
    
        /**
         * This is the information for object identity associated with the property.
         * <p>
         * TODO: should try to make immutable.
         */
        protected ObjectIdInfo _objectIdInfo;
    
        /**
         * Helper object used for checking whether this property is to
         * be included in the active view, if property is view-specific;
         * null otherwise.
         *<p>
         * TODO: should try to make immutable.
         */
        protected ViewMatcher _viewMatcher;
    
        /**
         * Index of property (within all property of a bean); assigned
         * when all properties have been collected. Order of entries
         * is arbitrary, but once indexes are assigned they are not
         * changed.
         *<p>
         * TODO: should try to make immutable if at all possible
         */
        protected int _propertyIndex = -1;
    
        /*
        /**********************************************************
        /* Life-cycle (construct & configure)
        /**********************************************************
         */
    
        protected SettableBeanProperty(BeanPropertyDefinition propDef,
                JavaType type, TypeDeserializer typeDeser, Annotations contextAnnotations)
        {
            this(propDef.getFullName(), type, propDef.getWrapperName(), typeDeser,
                    contextAnnotations, propDef.getMetadata());
        }
    
        protected SettableBeanProperty(PropertyName propName, JavaType type, PropertyName wrapper,
                TypeDeserializer typeDeser, Annotations contextAnnotations,
                PropertyMetadata metadata)
        {
            super(metadata);
            // 09-Jan-2009, tatu: Intern()ing makes sense since Jackson parsed
            //  field names are (usually) interned too, hence lookups will be faster.
            // 23-Oct-2009, tatu: should this be disabled wrt [JACKSON-180]?
            //   Probably need not, given that namespace of field/method names
            //   is not unbounded, unlike potential JSON names.
            if (propName == null) {
                _propName = PropertyName.NO_NAME;
            } else {
                _propName = propName.internSimpleName();
            }
            _type = type;
            _wrapperName = wrapper;
            _contextAnnotations = contextAnnotations;
            _viewMatcher = null;
    
            // 30-Jan-2012, tatu: Important: contextualize TypeDeserializer now...
            if (typeDeser != null) {
                typeDeser = typeDeser.forProperty(this);
            }
            _valueTypeDeserializer = typeDeser;
            _valueDeserializer = MISSING_VALUE_DESERIALIZER;
            _nullProvider = MISSING_VALUE_DESERIALIZER;
        }
    
        /**
         * Constructor only used by {@link com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty}.
         * 
         * @since 2.3
         */
        protected SettableBeanProperty(PropertyName propName, JavaType type, 
                PropertyMetadata metadata, JsonDeserializer<Object> valueDeser)
        {
            super(metadata);
            // as with above ctor, intern()ing probably fine
            if (propName == null) {
                _propName = PropertyName.NO_NAME;
            } else {
                _propName = propName.internSimpleName();
            }
            _type = type;
            _wrapperName = null;
            _contextAnnotations = null;
            _viewMatcher = null;
            _valueTypeDeserializer = null;
            _valueDeserializer = valueDeser;
            // 29-Jan-2017, tatu: Presumed to be irrelevant for ObjectId values...
            _nullProvider = valueDeser;
        }
    
        /**
         * Basic copy-constructor for sub-classes to use.
         */
        protected SettableBeanProperty(SettableBeanProperty src)
        {
            super(src);
            _propName = src._propName;
            _type = src._type;
            _wrapperName = src._wrapperName;
            _contextAnnotations = src._contextAnnotations;
            _valueDeserializer = src._valueDeserializer;
            _valueTypeDeserializer = src._valueTypeDeserializer;
            _managedReferenceName = src._managedReferenceName;
            _propertyIndex = src._propertyIndex;
            _viewMatcher = src._viewMatcher;
            _nullProvider = src._nullProvider;
        }
    
        /**
         * Copy-with-deserializer-change constructor for sub-classes to use.
         */
        @SuppressWarnings("unchecked")
        protected SettableBeanProperty(SettableBeanProperty src,
                JsonDeserializer<?> deser, NullValueProvider nuller)
        {
            super(src);
            _propName = src._propName;
            _type = src._type;
            _wrapperName = src._wrapperName;
            _contextAnnotations = src._contextAnnotations;
            _valueTypeDeserializer = src._valueTypeDeserializer;
            _managedReferenceName = src._managedReferenceName;
            _propertyIndex = src._propertyIndex;
    
            if (deser == null) {
                _valueDeserializer = MISSING_VALUE_DESERIALIZER;
            } else {
                _valueDeserializer = (JsonDeserializer<Object>) deser;
            }
            _viewMatcher = src._viewMatcher;
            // 29-Jan-2017, tatu: Bit messy, but for now has to do...
            if (nuller == MISSING_VALUE_DESERIALIZER) {
                nuller = _valueDeserializer;
            }
            _nullProvider = nuller;
        }
    
        /**
         * Copy-with-deserializer-change constructor for sub-classes to use.
         */
        protected SettableBeanProperty(SettableBeanProperty src, PropertyName newName)
        {
            super(src);
            _propName = newName;
            _type = src._type;
            _wrapperName = src._wrapperName;
            _contextAnnotations = src._contextAnnotations;
            _valueDeserializer = src._valueDeserializer;
            _valueTypeDeserializer = src._valueTypeDeserializer;
            _managedReferenceName = src._managedReferenceName;
            _propertyIndex = src._propertyIndex;
            _viewMatcher = src._viewMatcher;
            _nullProvider = src._nullProvider;
        }
    
        /**
         * Fluent factory method for constructing and returning a new instance
         * with specified value deserializer.
         * Note that this method should NOT change configuration of this instance.
         * 
         * @param deser Deserializer to assign to the new property instance
         * 
         * @return Newly constructed instance, if value deserializer differs from the
         *   one used for this instance; or 'this' if not.
         */
        public abstract SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser);
    
        /**
         * Fluent factory method for constructing and returning a new instance
         * with specified property name.
         * Note that this method should NOT change configuration of this instance.
         * 
         * @param newName Name to use for the new instance.
         * 
         * @return Newly constructed instance, if property name differs from the
         *   one used for this instance; or 'this' if not.
         */
        public abstract SettableBeanProperty withName(PropertyName newName);
    
        /**
         * @since 2.3
         */
        public SettableBeanProperty withSimpleName(String simpleName) {
            PropertyName n = (_propName == null)
                    ? new PropertyName(simpleName) : _propName.withSimpleName(simpleName);
            return (n == _propName) ? this : withName(n);
        }
    
        /**
         * @since 2.9
         */
        public abstract SettableBeanProperty withNullProvider(NullValueProvider nva);
    
        public void setManagedReferenceName(String n) {
            _managedReferenceName = n;
        }
    
        public void setObjectIdInfo(ObjectIdInfo objectIdInfo) {
            _objectIdInfo = objectIdInfo;
        }
    
        public void setViews(Class<?>[] views) {
            if (views == null) {
                _viewMatcher = null;
            } else {
                _viewMatcher = ViewMatcher.construct(views);
            }
        }
    
        /**
         * Method used to assign index for property.
         */
        public void assignIndex(int index) {
            if (_propertyIndex != -1) {
                throw new IllegalStateException("Property '"+getName()+"' already had index ("+_propertyIndex+"), trying to assign "+index);
            }
            _propertyIndex = index;
        }
    
        /**
         * Method called to ensure that the mutator has proper access rights to
         * be called, as per configuration. Overridden by implementations that
         * have mutators that require access, fields and setters.
         *
         * @since 2.8.3
         */
        public void fixAccess(DeserializationConfig config) {
            ;
        }
    
        /**
         * @since 2.9.4
         */
        public void markAsIgnorable() { }
    
        /**
         * @since 2.9.4
         */
        public boolean isIgnorable() { return false; }
    
        /*
        /**********************************************************
        /* BeanProperty impl
        /**********************************************************
         */
        
        @Override
        public final String getName() {
            return _propName.getSimpleName();
        }
    
        @Override
        public PropertyName getFullName() {
            return _propName;
        }
    
        @Override
        public JavaType getType() { return _type; }
    
        @Override
        public PropertyName getWrapperName() {
            return _wrapperName;
        }
        
        @Override
        public abstract AnnotatedMember getMember();
    
        @Override
        public abstract <A extends Annotation> A getAnnotation(Class<A> acls);
    
        @Override
        public <A extends Annotation> A getContextAnnotation(Class<A> acls) {
            return _contextAnnotations.get(acls);
        }
    
        @Override
        public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor,
                SerializerProvider provider)
            throws JsonMappingException
        {
            if (isRequired()) {
                objectVisitor.property(this); 
            } else {
                objectVisitor.optionalProperty(this);
            }
        }
    
        /*
        /**********************************************************
        /* Accessors
        /**********************************************************
         */
    
        protected Class<?> getDeclaringClass() {
            return getMember().getDeclaringClass();
        }
    
        public String getManagedReferenceName() { return _managedReferenceName; }
    
        public ObjectIdInfo getObjectIdInfo() { return _objectIdInfo; }
    
        public boolean hasValueDeserializer() {
            return (_valueDeserializer != null) && (_valueDeserializer != MISSING_VALUE_DESERIALIZER);
        }
    
        public boolean hasValueTypeDeserializer() { return (_valueTypeDeserializer != null); }
    
        public JsonDeserializer<Object> getValueDeserializer() {
            JsonDeserializer<Object> deser = _valueDeserializer;
            if (deser == MISSING_VALUE_DESERIALIZER) {
                return null;
            }
            return deser;
        }
    
        public TypeDeserializer getValueTypeDeserializer() { return _valueTypeDeserializer; }
    
        /**
         * @since 2.9
         */
        public NullValueProvider getNullValueProvider() { return _nullProvider; }
    
        public boolean visibleInView(Class<?> activeView) {
            return (_viewMatcher == null) || _viewMatcher.isVisibleForView(activeView);
        }
    
        public boolean hasViews() { return _viewMatcher != null; }
        
        /**
         * Method for accessing unique index of this property; indexes are
         * assigned once all properties of a {@link BeanDeserializer} have
         * been collected.
         * 
         * @return Index of this property
         */
        public int getPropertyIndex() { return _propertyIndex; }
    
        /**
         * Method for accessing index of the creator property: for other
         * types of properties will simply return -1.
         * 
         * @since 2.1
         */
        public int getCreatorIndex() {
            // changed from 'return -1' in 2.7.9 / 2.8.7
            throw new IllegalStateException(String.format(
                    "Internal error: no creator index for property '%s' (of type %s)",
                    this.getName(), getClass().getName()));
        }
    
        /**
         * Accessor for id of injectable value, if this bean property supports
         * value injection.
         */
        public Object getInjectableValueId() { return null; }
    
        /**
         * Accessor for checking whether this property is injectable, and if so,
         * ONLY injectable (will not bind from input).
         * Currently (2.11) can only return {@code true} for Creator-backed properties.
         *
         * @return True if (and only if) property has injector that is also defined NOT
         *    to bind from input.
         *
         * @since 2.11
         */
        public boolean isInjectionOnly() { return false; } // overridden by CreatorProperty
    
        /*
        /**********************************************************
        /* Public API
        /**********************************************************
         */
    
        /**
         * Method called to deserialize appropriate value, given parser (and
         * context), and set it using appropriate mechanism.
         * Pre-condition is that passed parser must point to the first token
         * that should be consumed to produce the value (the only value for
         * scalars, multiple for Objects and Arrays).
         */
        public abstract void deserializeAndSet(JsonParser p,
        		DeserializationContext ctxt, Object instance) throws IOException;
    
    	/**
    	 * Alternative to {@link #deserializeAndSet} that returns
    	 * either return value of setter method called (if one is),
    	 * or null to indicate that no return value is available.
    	 * Mostly used to support Builder style deserialization.
    	 *
    	 * @since 2.0
    	 */
        public abstract Object deserializeSetAndReturn(JsonParser p,
        		DeserializationContext ctxt, Object instance) throws IOException;
    
        /**
         * Method called to assign given value to this property, on
         * specified Object.
         *<p>
         * Note: this is an optional operation, not supported by all
         * implementations, creator-backed properties for example do not
         * support this method.
         */
        public abstract void set(Object instance, Object value) throws IOException;
    
        /**
         * Method called to assign given value to this property, on
         * specified Object, and return whatever delegating accessor
         * returned (if anything)
         *<p>
         * Note: this is an optional operation, not supported by all
         * implementations, creator-backed properties for example do not
         * support this method.
         */
        public abstract Object setAndReturn(Object instance, Object value) throws IOException;
        
        /**
         * This method is needed by some specialized bean deserializers,
         * and also called by some {@link #deserializeAndSet} implementations.
         *<p>
         * Pre-condition is that passed parser must point to the first token
         * that should be consumed to produce the value (the only value for
         * scalars, multiple for Objects and Arrays).
         *<p> 
         * Note that this method is final for performance reasons: to override
         * functionality you must override other methods that call this method;
         * this method should also not be called directly unless you really know
         * what you are doing (and probably not even then).
         */
        public final Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
        {
            if (p.hasToken(JsonToken.VALUE_NULL)) {
                return _nullProvider.getNullValue(ctxt);
            }
            if (_valueTypeDeserializer != null) {
                return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
            }
            // 04-May-2018, tatu: [databind#2023] Coercion from String (mostly) can give null
            Object value =  _valueDeserializer.deserialize(p, ctxt);
            if (value == null) {
                value = _nullProvider.getNullValue(ctxt);
            }
            return value;
        }
    
        /**
         * @since 2.9
         */
        public final Object deserializeWith(JsonParser p, DeserializationContext ctxt,
                Object toUpdate) throws IOException
        {
            // 20-Oct-2016, tatu: Not 100% sure what to do; probably best to simply return
            //   null value and let caller decide what to do.
            if (p.hasToken(JsonToken.VALUE_NULL)) {
                // ... except for "skip nulls" case which should just do that:
                if (NullsConstantProvider.isSkipper(_nullProvider)) {
                    return toUpdate;
                }
                return _nullProvider.getNullValue(ctxt);
            }
            // 20-Oct-2016, tatu: Also tricky -- for now, report an error
            if (_valueTypeDeserializer != null) {
                ctxt.reportBadDefinition(getType(),
                        String.format("Cannot merge polymorphic property '%s'",
                                getName()));
    //            return _valueDeserializer.deserializeWithType(p, ctxt, _valueTypeDeserializer);
            }
            // 04-May-2018, tatu: [databind#2023] Coercion from String (mostly) can give null
            Object value = _valueDeserializer.deserialize(p, ctxt, toUpdate);
            if (value == null) {
                if (NullsConstantProvider.isSkipper(_nullProvider)) {
                    return toUpdate;
                }
                value = _nullProvider.getNullValue(ctxt);
            }
            return value;
        }
    
        /*
        /**********************************************************
        /* Helper methods
        /**********************************************************
         */
    
        /**
         * Method that takes in exception of any type, and casts or wraps it
         * to an IOException or its subclass.
         */
        protected void _throwAsIOE(JsonParser p, Exception e, Object value) throws IOException
        {
            if (e instanceof IllegalArgumentException) {
                String actType = ClassUtil.classNameOf(value);
                StringBuilder msg = new StringBuilder("Problem deserializing property '")
                        .append(getName())
                        .append("' (expected type: ")
                        .append(getType())
                        .append("; actual type: ")
                        .append(actType).append(")");
                String origMsg = ClassUtil.exceptionMessage(e);
                if (origMsg != null) {
                    msg.append(", problem: ")
                        .append(origMsg);
                } else {
                    msg.append(" (no error message provided)");
                }
                throw JsonMappingException.from(p, msg.toString(), e);
            }
            _throwAsIOE(p, e);
        }
        
        /**
         * @since 2.7
         */
        protected IOException _throwAsIOE(JsonParser p, Exception e) throws IOException
        {
            ClassUtil.throwIfIOE(e);
            ClassUtil.throwIfRTE(e);
            // let's wrap the innermost problem
            Throwable th = ClassUtil.getRootCause(e);
            throw JsonMappingException.from(p, ClassUtil.exceptionMessage(th), th);
        }
    
        @Deprecated // since 2.7
        protected IOException _throwAsIOE(Exception e) throws IOException {
            return _throwAsIOE((JsonParser) null, e);
        }
    
        // 10-Oct-2015, tatu: _Should_ be deprecated, too, but its remaining
        //   callers cannot actually provide a JsonParser
        protected void _throwAsIOE(Exception e, Object value) throws IOException {
            _throwAsIOE((JsonParser) null, e, value);
        }
    
        @Override public String toString() { return "[property '"+getName()+"']"; }
    
        /*
        /**********************************************************
        /* Helper classes
        /**********************************************************
         */
    
        /**
         * Helper class that is designed to both make it easier to sub-class
         * delegating subtypes and to reduce likelihood of breakage when
         * new methods are added.
         *<p>
         * Class was specifically added to help with {@code Afterburner}
         * module, but its use is not limited to only support it.
         *
         * @since 2.9
         */
        public static abstract class Delegating
            extends SettableBeanProperty
        {
            protected final SettableBeanProperty delegate;
    
            protected Delegating(SettableBeanProperty d) {
                super(d);
                delegate = d;
            }
    
            /**
             * Method sub-classes must implement, to construct a new instance
             * with given delegate.
             */
            protected abstract SettableBeanProperty withDelegate(SettableBeanProperty d);
    
            protected SettableBeanProperty _with(SettableBeanProperty newDelegate) {
                if (newDelegate == delegate) {
                    return this;
                }
                return withDelegate(newDelegate);
            }
            
            @Override
            public SettableBeanProperty withValueDeserializer(JsonDeserializer<?> deser) {
                return _with(delegate.withValueDeserializer(deser));
            }
    
            @Override
            public SettableBeanProperty withName(PropertyName newName) {
                return _with(delegate.withName(newName));
            }
    
            @Override
            public SettableBeanProperty withNullProvider(NullValueProvider nva) {
                return _with(delegate.withNullProvider(nva));
            }
    
            @Override
            public void assignIndex(int index) {
                delegate.assignIndex(index);
            }
    
            @Override
            public void fixAccess(DeserializationConfig config) {
                delegate.fixAccess(config);
            }
    
            /*
            /**********************************************************
            /* Accessors
            /**********************************************************
             */
    
            @Override
            protected Class<?> getDeclaringClass() { return delegate.getDeclaringClass(); }
    
            @Override
            public String getManagedReferenceName() { return delegate.getManagedReferenceName(); }
    
            @Override
            public ObjectIdInfo getObjectIdInfo() { return delegate.getObjectIdInfo(); }
    
            @Override
            public boolean hasValueDeserializer() { return delegate.hasValueDeserializer(); }
    
            @Override
            public boolean hasValueTypeDeserializer() { return delegate.hasValueTypeDeserializer(); }
            
            @Override
            public JsonDeserializer<Object> getValueDeserializer() { return delegate.getValueDeserializer(); }
    
            @Override
            public TypeDeserializer getValueTypeDeserializer() { return delegate.getValueTypeDeserializer(); }
    
            @Override
            public boolean visibleInView(Class<?> activeView) { return delegate.visibleInView(activeView); }
    
            @Override
            public boolean hasViews() { return delegate.hasViews(); }
    
            @Override
            public int getPropertyIndex() { return delegate.getPropertyIndex(); }
    
            @Override
            public int getCreatorIndex() { return delegate.getCreatorIndex(); }
    
            @Override
            public Object getInjectableValueId() { return delegate.getInjectableValueId(); }
    
            @Override
            public boolean isInjectionOnly() { return delegate.isInjectionOnly(); }
    
            @Override
            public AnnotatedMember getMember() {
                return delegate.getMember();
            }
    
            @Override
            public <A extends Annotation> A getAnnotation(Class<A> acls) {
                return delegate.getAnnotation(acls);
            }
    
            /*
            /**********************************************************
            /* Extended API
            /**********************************************************
             */
    
            public SettableBeanProperty getDelegate() {
                return delegate;
            }
    
            /*
            /**********************************************************
            /* Actual mutators
            /**********************************************************
             */
    
            @Override
            public void deserializeAndSet(JsonParser p, DeserializationContext ctxt,
                    Object instance) throws IOException {
                delegate.deserializeAndSet(p, ctxt, instance);
            }
    
            @Override
            public Object deserializeSetAndReturn(JsonParser p,
                    DeserializationContext ctxt, Object instance) throws IOException
            {
                return delegate.deserializeSetAndReturn(p, ctxt, instance);
            }
    
            @Override
            public void set(Object instance, Object value) throws IOException {
                delegate.set(instance, value);
            }
    
            @Override
            public Object setAndReturn(Object instance, Object value) throws IOException {
                return delegate.setAndReturn(instance, value);
            }
        }
    }
    

    com/fasterxml/jackson/databind/deser/SettableBeanProperty.java

     

    ⇒ Jackson Annotations Source Code

    ⇐ Download and Install Jackson Binary Package

    ⇑ Downloading and Reviewing jackson-*.jar

    ⇑⇑ Jackson - Java JSON library

    2022-03-29, 32274👍, 0💬