All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.stewseo.client.json.jackson.JacksonJsonpParser Maven / Gradle / Ivy

Go to download

java client to build api objects, handle http transport, and parse/deserialize/serialize json to/from json

There is a newer version: 1.8.0
Show newest version
package io.github.stewseo.client.json.jackson;

import com.fasterxml.jackson.core.JsonToken;
import jakarta.json.JsonArray;
import jakarta.json.JsonObject;
import jakarta.json.JsonValue;
import jakarta.json.stream.JsonLocation;
import jakarta.json.stream.JsonParser;
import jakarta.json.stream.JsonParsingException;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.EnumMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.stream.Stream;
public class JacksonJsonpParser implements JsonParser {

    private final com.fasterxml.jackson.core.JsonParser parser;

    private boolean hasNextWasCalled = false;

    private static final EnumMap tokenToEvent;

    static {
        tokenToEvent = new EnumMap<>(JsonToken.class);
        tokenToEvent.put(JsonToken.END_ARRAY, Event.END_ARRAY);
        tokenToEvent.put(JsonToken.END_OBJECT, Event.END_OBJECT);
        tokenToEvent.put(JsonToken.FIELD_NAME, Event.KEY_NAME);
        tokenToEvent.put(JsonToken.START_ARRAY, Event.START_ARRAY);
        tokenToEvent.put(JsonToken.START_OBJECT, Event.START_OBJECT);
        tokenToEvent.put(JsonToken.VALUE_FALSE, Event.VALUE_FALSE);
        tokenToEvent.put(JsonToken.VALUE_NULL, Event.VALUE_NULL);
        tokenToEvent.put(JsonToken.VALUE_NUMBER_FLOAT, Event.VALUE_NUMBER);
        tokenToEvent.put(JsonToken.VALUE_NUMBER_INT, Event.VALUE_NUMBER);
        tokenToEvent.put(JsonToken.VALUE_STRING, Event.VALUE_STRING);
        tokenToEvent.put(JsonToken.VALUE_TRUE, Event.VALUE_TRUE);

        // No equivalent for
        // - VALUE_EMBEDDED_OBJECT
        // - NOT_AVAILABLE
    }

    public JacksonJsonpParser(com.fasterxml.jackson.core.JsonParser parser) {
        this.parser = parser;
    }

    /**
     * Returns the underlying Jackson parser.
     */
    public com.fasterxml.jackson.core.JsonParser jacksonParser() {
        return this.parser;
    }

    private JsonParsingException convertException(IOException ioe) {
        return new JsonParsingException("Jackson exception: " + ioe.getMessage(), ioe, getLocation());
    }

    private JsonToken fetchNextToken() {
        try {
            return parser.nextToken();
        } catch(IOException e) {
            throw convertException(e);
        }
    }

    private void ensureTokenIsCurrent() {
        if (hasNextWasCalled) {
            throw new IllegalStateException("Cannot get event data as parser as already been moved to the next event");
        }
    }

    @Override
    public boolean hasNext() {
        if (hasNextWasCalled) {
            return parser.currentToken() != null;
        } else {
            hasNextWasCalled = true;
            return fetchNextToken() != null;
        }
    }

    @Override
    public Event next() {
        JsonToken token;
        if (hasNextWasCalled) {
            token = parser.getCurrentToken();
            hasNextWasCalled = false;
        } else {
            token = fetchNextToken();
        }

        if (token == null) {
            throw new NoSuchElementException();
        }

        Event result = tokenToEvent.get(token);
        if (result == null) {
            throw new JsonParsingException("Unsupported Jackson event type '"+ token + "'", getLocation());
        }

        return result;
    }

    @Override
    public String getString() {
        ensureTokenIsCurrent();
        try {
            return parser.getValueAsString();
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public boolean isIntegralNumber() {
        ensureTokenIsCurrent();
        return parser.isExpectedNumberIntToken();
    }

    @Override
    public int getInt() {
        ensureTokenIsCurrent();
        try {
            return parser.getIntValue();
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public long getLong() {
        ensureTokenIsCurrent();
        try {
            return parser.getLongValue();
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public BigDecimal getBigDecimal() {
        ensureTokenIsCurrent();
        try {
            return parser.getDecimalValue();
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public JsonLocation getLocation() {
        return new JacksonJsonpLocation(parser.getCurrentLocation());
    }

    @Override
    public void close() {
        try {
            parser.close();
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    private JsonValueParser valueParser;

    @Override
    public JsonObject getObject() {
        ensureTokenIsCurrent();
        if (parser.currentToken() != JsonToken.START_OBJECT) {
            throw new IllegalStateException("Unexpected event '" + parser.currentToken() +
                    "' at " + parser.getTokenLocation());
        }
        if (valueParser == null) {
            valueParser = new JsonValueParser();
        }
        try {
            return valueParser.parseObject(parser);
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public JsonArray getArray() {
        ensureTokenIsCurrent();
        if (valueParser == null) {
            valueParser = new JsonValueParser();
        }
        if (parser.currentToken() != JsonToken.START_ARRAY) {
            throw new IllegalStateException("Unexpected event '" + parser.currentToken() +
                    "' at " + parser.getTokenLocation());
        }
        try {
            return valueParser.parseArray(parser);
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public JsonValue getValue() {
        ensureTokenIsCurrent();
        if (valueParser == null) {
            valueParser = new JsonValueParser();
        }
        try {
            return valueParser.parseValue(parser);
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public void skipObject() {
        ensureTokenIsCurrent();
        if (parser.currentToken() != JsonToken.START_OBJECT) {
            return;
        }

        try {
            int depth = 1;
            JsonToken token;
            do {
                token = parser.nextToken();
                switch (token) {
                    case START_OBJECT -> depth++;
                    case END_OBJECT -> depth--;
                }
            } while(!(token == JsonToken.END_OBJECT && depth == 0));
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public void skipArray() {
        ensureTokenIsCurrent();
        if (parser.currentToken() != JsonToken.START_ARRAY) {
            return;
        }

        try {
            int depth = 1;
            JsonToken token;
            do {
                token = parser.nextToken();
                switch (token) {
                    case START_ARRAY -> depth++;
                    case END_ARRAY -> depth--;
                }
            } while(!(token == JsonToken.END_ARRAY && depth == 0));
        } catch (IOException e) {
            throw convertException(e);
        }
    }

    @Override
    public Stream> getObjectStream() {
        return getObject().entrySet().stream();
    }

    @Override
    public Stream getArrayStream() {
        return getArray().stream();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy