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/MappingIterator.java

package com.fasterxml.jackson.databind;

import java.io.Closeable;
import java.io.IOException;
import java.util.*;

import com.fasterxml.jackson.core.*;

/**
 * Iterator exposed by {@link ObjectMapper} when binding sequence of
 * objects. Extension is done to allow more convenient exposing of
 * {@link IOException} (which basic {@link Iterator} does not expose)
 */
public class MappingIterator<T> implements Iterator<T>, Closeable
{
    protected final static MappingIterator<?> EMPTY_ITERATOR =
        new MappingIterator<Object>(null, null, null, null, false, null);

    /*
    /**********************************************************
    /* State constants
    /**********************************************************
     */

    /**
     * State in which iterator is closed
     */
    protected final static int STATE_CLOSED = 0;
    
    /**
     * State in which value read failed
     */
    protected final static int STATE_NEED_RESYNC = 1;
    
    /**
     * State in which no recovery is needed, but "hasNextValue()" needs
     * to be called first
     */
    protected final static int STATE_MAY_HAVE_VALUE = 2;

    /**
     * State in which "hasNextValue()" has been succesfully called
     * and deserializer can be called to fetch value
     */
    protected final static int STATE_HAS_VALUE = 3;

    /*
    /**********************************************************
    /* Configuration
    /**********************************************************
     */

    /**
     * Type to bind individual elements to.
     */
    protected final JavaType _type;

    /**
     * Context for deserialization, needed to pass through to deserializer
     */
    protected final DeserializationContext _context;

    /**
     * Deserializer for individual element values.
     */
    protected final JsonDeserializer<T> _deserializer;

    /**
     * Underlying parser used for reading content to bind. Initialized
     * as not <code>null</code> but set as <code>null</code> when
     * iterator is closed, to denote closing.
     */
    protected final JsonParser _parser;

    /**
     * Context to resynchronize to, in case an exception is encountered
     * but caller wants to try to read more elements.
     */
    protected final JsonStreamContext _seqContext;
    
    /**
     * If not null, "value to update" instead of creating a new instance
     * for each call.
     */
    protected final T _updatedValue;
    
    /**
     * Flag that indicates whether input {@link JsonParser} should be closed
     * when we are done or not; generally only called when caller did not
     * pass JsonParser.
     */
    protected final boolean _closeParser;

    /*
    /**********************************************************
    /* Parsing state
    /**********************************************************
     */
    
    /**
     * State of the iterator
     */
    protected int _state;

    /*
    /**********************************************************
    /* Construction
    /**********************************************************
     */
    
    /**
     * @param managedParser Whether we "own" the {@link JsonParser} passed or not:
     *   if true, it was created by {@link ObjectReader} and code here needs to
     *   close it; if false, it was passed by calling code and should not be
     *   closed by iterator.
     */
    @SuppressWarnings("unchecked")
    protected MappingIterator(JavaType type, JsonParser p, DeserializationContext ctxt,
            JsonDeserializer<?> deser,
            boolean managedParser, Object valueToUpdate)
    {
        _type = type;
        _parser = p;
        _context = ctxt;
        _deserializer = (JsonDeserializer<T>) deser;
        _closeParser = managedParser;
        if (valueToUpdate == null) {
            _updatedValue = null;
        } else {
            _updatedValue = (T) valueToUpdate;
        }

        /* Ok: one more thing; we may have to skip START_ARRAY, assuming
         * "wrapped" sequence; but this is ONLY done for 'managed' parsers
         * and never if JsonParser was directly passed by caller (if it
         * was, caller must have either positioned it over first token of
         * the first element, or cleared the START_ARRAY token explicitly).
         * Note, however, that we do not try to guess whether this could be
         * an unwrapped sequence of arrays/Lists: we just assume it is wrapped;
         * and if not, caller needs to hand us JsonParser instead, pointing to
         * the first token of the first element.
         */
        if (p == null) { // can this occur?
            _seqContext = null;
            _state = STATE_CLOSED;
        } else {
            JsonStreamContext sctxt = p.getParsingContext();
            if (managedParser && p.isExpectedStartArrayToken()) {
                // If pointing to START_ARRAY, context should be that ARRAY
                p.clearCurrentToken();
            } else {
                // regardless, recovery context should be whatever context we have now,
                // with sole exception of pointing to a start marker, in which case it's
                // the parent
                JsonToken t = p.currentToken();
                if ((t == JsonToken.START_OBJECT) || (t == JsonToken.START_ARRAY)) {
                    sctxt = sctxt.getParent();
                }
            }
            _seqContext = sctxt;
            _state = STATE_MAY_HAVE_VALUE;
        }
    }

    /**
     * Method for getting an "empty" iterator instance: one that never
     * has more values; may be freely shared.
     *
     * @since 2.10 Existed earlier but {@code public} since 2.10
     */
    @SuppressWarnings("unchecked")
    public static <T> MappingIterator<T> emptyIterator() {
        return (MappingIterator<T>) EMPTY_ITERATOR;
    }

    /*
    /**********************************************************
    /* Basic iterator impl
    /**********************************************************
     */

    @Override
    public boolean hasNext()
    {
        try {
            return hasNextValue();
        } catch (JsonMappingException e) {
            return (Boolean) _handleMappingException(e);
        } catch (IOException e) {
            return (Boolean) _handleIOException(e);
        }
    }
    
    @SuppressWarnings("unchecked")
    @Override
    public T next()
    {
        try {
            return nextValue();
        } catch (JsonMappingException e) {
            return (T) _handleMappingException(e);
        } catch (IOException e) {
            return (T) _handleIOException(e);
        }
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void close() throws IOException {
        if (_state != STATE_CLOSED) {
            _state = STATE_CLOSED;
            if (_parser != null) {
                _parser.close();
            }
        }
    }

    /*
    /**********************************************************
    /* Extended API, iteration
    /**********************************************************
     */

    /**
     * Equivalent of {@link #next} but one that may throw checked
     * exceptions from Jackson due to invalid input.
     */
    public boolean hasNextValue() throws IOException
    {
        switch (_state) {
        case STATE_CLOSED:
            return false;
        case STATE_NEED_RESYNC:
            _resync();
            // fall-through
        case STATE_MAY_HAVE_VALUE:
            JsonToken t = _parser.currentToken();
            if (t == null) { // un-initialized or cleared; find next
                t = _parser.nextToken();
                // If EOF, no more, or if we hit END_ARRAY (although we don't clear the token).
                if (t == null || t == JsonToken.END_ARRAY) {
                    _state = STATE_CLOSED;
                    if (_closeParser && (_parser != null)) {
                        _parser.close();
                    }
                    return false;
                }
            }
            _state = STATE_HAS_VALUE;
            return true;
        case STATE_HAS_VALUE:
            // fall through
        }
        return true;
    }

    public T nextValue() throws IOException
    {
        switch (_state) {
        case STATE_CLOSED:
            return _throwNoSuchElement();
        case STATE_NEED_RESYNC: // fall-through, will do re-sync
        case STATE_MAY_HAVE_VALUE:
            if (!hasNextValue()) {
                return _throwNoSuchElement();
            }
            break;
        case STATE_HAS_VALUE:
            break;
        }

        int nextState = STATE_NEED_RESYNC;
        try {
            T value;
            if (_updatedValue == null) {
                value = _deserializer.deserialize(_parser, _context);
            } else{
                _deserializer.deserialize(_parser, _context, _updatedValue);
                value = _updatedValue;
            }
            nextState = STATE_MAY_HAVE_VALUE;
            return value;
        } finally {
            _state = nextState;
            /* 24-Mar-2015, tatu: As per [#733], need to mark token consumed no
             *   matter what, to avoid infinite loop for certain failure cases.
             *   For 2.6 need to improve further.
             */
            _parser.clearCurrentToken();
        }
    }

    /**
     * Convenience method for reading all entries accessible via
     * this iterator; resulting container will be a {@link java.util.ArrayList}.
     * 
     * @return List of entries read
     * 
     * @since 2.2
     */
    public List<T> readAll() throws IOException {
        return readAll(new ArrayList<T>());
    }

    /**
     * Convenience method for reading all entries accessible via
     * this iterator
     * 
     * @return List of entries read (same as passed-in argument)
     * 
     * @since 2.2
     */
    public <L extends List<? super T>> L readAll(L resultList) throws IOException
    {
        while (hasNextValue()) {
            resultList.add(nextValue());
        }
        return resultList;
    }

    /**
     * Convenience method for reading all entries accessible via
     * this iterator
     * 
     * @since 2.5
     */
    public <C extends Collection<? super T>> C readAll(C results) throws IOException
    {
        while (hasNextValue()) {
            results.add(nextValue());
        }
        return results;
    }
    
    /*
    /**********************************************************
    /* Extended API, accessors
    /**********************************************************
     */

    /**
     * Accessor for getting underlying parser this iterator uses.
     * 
     * @since 2.2
     */
    public JsonParser getParser() {
        return _parser;
    }

    /**
     * Accessor for accessing {@link FormatSchema} that the underlying parser
     * (as per {@link #getParser}) is using, if any; only parser of schema-aware
     * formats use schemas.
     * 
     * @since 2.2
     */
    public FormatSchema getParserSchema() {
    	return _parser.getSchema();
    }

    /**
     * Convenience method, functionally equivalent to:
     *<code>
     *   iterator.getParser().getCurrentLocation()
     *</code>
     * 
     * @return Location of the input stream of the underlying parser
     * 
     * @since 2.2.1
     */
    public JsonLocation getCurrentLocation() {
        return _parser.getCurrentLocation();
    }

    /*
    /**********************************************************
    /* Helper methods
    /**********************************************************
     */

    protected void _resync() throws IOException
    {
        final JsonParser p = _parser;
        // First, a quick check to see if we might have been lucky and no re-sync needed
        if (p.getParsingContext() == _seqContext) {
            return;
        }

        while (true) {
            JsonToken t = p.nextToken();
            if ((t == JsonToken.END_ARRAY) || (t == JsonToken.END_OBJECT)) {
                if (p.getParsingContext() == _seqContext) {
                    p.clearCurrentToken();
                    return;
                }
            } else if ((t == JsonToken.START_ARRAY) || (t == JsonToken.START_OBJECT)) {
                p.skipChildren();
            } else if (t == null) {
                return;
            }
        }
    }

    protected <R> R _throwNoSuchElement() {
        throw new NoSuchElementException();
    }
    
    protected <R> R _handleMappingException(JsonMappingException e) {
        throw new RuntimeJsonMappingException(e.getMessage(), e);
    }

    protected <R> R _handleIOException(IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
}

com/fasterxml/jackson/databind/MappingIterator.java

 

⇒ Jackson Dataformat Extensions

⇐ Jackson Data Binding Source Code

⇑ Downloading and Reviewing jackson-*.jar

⇑⇑ Jackson - Java JSON library

2022-02-19, 36136👍, 0💬