Jackson Annotations Source Code

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

Jackson Annotations Source Code files are provided in the source packge (jackson-annotations-2.12.4-sources.jar). You can download it at Jackson Maven Website.

You can also browse Jackson Annotations Source Code below:

✍: FYIcenter.com

com/fasterxml/jackson/databind/cfg/ContextAttributes.java

package com.fasterxml.jackson.databind.cfg;

import java.util.*;

/**
 * Helper class used for storing and accessing per-call attributes.
 * Storage is two-layered: at higher precedence, we have actual per-call
 * attributes; and at lower precedence, default attributes that may be
 * defined for Object readers and writers.
 *<p>
 * Note that the way mutability is implemented differs between kinds
 * of attributes, to account for thread-safety: per-call attributes
 * are handled assuming that instances are never shared, whereas
 * changes to per-reader/per-writer attributes are made assuming
 * sharing, by creating new copies instead of modifying state.
 * This allows sharing of default values without per-call copying, but
 * requires two-level lookup on access.
 * 
 * @since 2.3
 */
public abstract class ContextAttributes
{
    public static ContextAttributes getEmpty() {
        return Impl.getEmpty();
    }
    
    /*
    /**********************************************************
    /* Per-reader/writer access
    /**********************************************************
     */

    public abstract ContextAttributes withSharedAttribute(Object key, Object value);

    public abstract ContextAttributes withSharedAttributes(Map<?,?> attributes);
    
    public abstract ContextAttributes withoutSharedAttribute(Object key);
    
    /*
    /**********************************************************
    /* Per-operation (serialize/deserialize) access
    /**********************************************************
     */

    /**
     * Accessor for value of specified attribute
     */
    public abstract Object getAttribute(Object key);

    /**
     * Mutator used during call (via context) to set value of "non-shared"
     * part of attribute set.
     */
    public abstract ContextAttributes withPerCallAttribute(Object key, Object value);

    /*
    /**********************************************************
    /* Default implementation
    /**********************************************************
     */

    public static class Impl extends ContextAttributes
        implements java.io.Serializable // just so ObjectReader/ObjectWriter can retain configs
    {
        private static final long serialVersionUID = 1L;

        protected final static Impl EMPTY = new Impl(Collections.emptyMap());

        protected final static Object NULL_SURROGATE = new Object();
        
        /**
         * Shared attributes that we cannot modify in-place.
         */
        protected final Map<?,?> _shared;

        /**
         * Per-call attributes that we can directly modify, since they are not
         * shared between threads.
         *<p>
         * NOTE: typed as Object-to-Object, unlike {@link #_shared}, because
         * we need to be able to modify contents, and wildcard type would
         * complicate that access.
         */
        protected transient Map<Object,Object> _nonShared;
        
        /*
        /**********************************************************
        /* Construction, factory methods
        /**********************************************************
         */
        
        protected Impl(Map<?,?> shared) {
            _shared = shared;
            _nonShared = null;
        }

        protected Impl(Map<?,?> shared, Map<Object,Object> nonShared) {
            _shared = shared;
            _nonShared = nonShared;
        }
        
        public static ContextAttributes getEmpty() {
            return EMPTY;
        }

        /*
        /**********************************************************
        /* Per-reader/writer mutant factories
        /**********************************************************
         */
        
        @Override
        public ContextAttributes withSharedAttribute(Object key, Object value)
        {
            Map<Object,Object> m;
            // need to cover one special case, since EMPTY uses Immutable map:
            if (this == EMPTY) {
                m = new HashMap<Object,Object>(8);
            } else {
                m = _copy(_shared);
            }
            m.put(key, value);
            return new Impl(m);
        }

        @Override
        public ContextAttributes withSharedAttributes(Map<?,?> shared) {
            return new Impl(shared);
        }

        @Override
        public ContextAttributes withoutSharedAttribute(Object key)
        {
            // first couple of trivial optimizations
            if (_shared.isEmpty()) {
                return this;
            }
            if (_shared.containsKey(key)) {
                if (_shared.size() == 1) {
                    return EMPTY;
                }
            } else { // if we didn't have it anyway, return as-is
                return this;
            }
            // otherwise make copy, modify
            Map<Object,Object> m = _copy(_shared);
            m.remove(key);
            return new Impl(m);
        }

        /*
        /**********************************************************
        /* Per-call access
        /**********************************************************
         */
        
        @Override
        public Object getAttribute(Object key)
        {
            if (_nonShared != null) {
                Object ob = _nonShared.get(key);
                if (ob != null) {
                    if (ob == NULL_SURROGATE) {
                        return null;
                    }
                    return ob;
                }
            }
            return _shared.get(key);
        }
        
        @Override
        public ContextAttributes withPerCallAttribute(Object key, Object value)
        {
            // First: null value may need masking
            if (value == null) {
                // need to mask nulls to ensure default values won't be showing
                if (_shared.containsKey(key)) {
                    value = NULL_SURROGATE;
                } else if ((_nonShared == null) || !_nonShared.containsKey(key)) {
                    // except if non-mutable shared list has no entry, we don't care
                    return this;
                } else {
                    _nonShared.remove(key);
                    return this;
                }
            }
            // a special case: create non-shared instance if need be
            if (_nonShared == null) {
                return nonSharedInstance(key, value);
            }
            _nonShared.put(key, value);
            return this;
        }

        /*
        /**********************************************************
        /* Internal methods
        /**********************************************************
         */

        /**
         * Overridable method that creates initial non-shared instance,
         * with the first explicit set value.
         */
        protected ContextAttributes nonSharedInstance(Object key, Object value)
        {
            Map<Object,Object> m = new HashMap<Object,Object>();
            if (value == null) {
                value = NULL_SURROGATE;
            }
            m.put(key, value);
            return new Impl(_shared, m);
        }
        
        private Map<Object,Object> _copy(Map<?,?> src)
        {
            return new HashMap<Object,Object>(src);
        }
    }
}

com/fasterxml/jackson/databind/cfg/ContextAttributes.java

 

⇒ Jackson Dataformat Extensions

⇐ Jackson Data Binding Source Code

⇑ Downloading and Reviewing jackson-*.jar

⇑⇑ Jackson - Java JSON library

2022-02-19, 36552👍, 0💬