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

org.eclipse.persistence.internal.oxm.record.json.JsonParserReader Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Iaroslav Savytskyi - 2.6 - initial implementation
package org.eclipse.persistence.internal.oxm.record.json;

import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.MediaType;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractUnmarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ExtendedContentHandler;
import org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.json.Json;
import javax.json.JsonArrayBuilder;
import javax.json.JsonException;
import javax.json.JsonObjectBuilder;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import javax.json.stream.JsonParser;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayDeque;
import java.util.Deque;

/**
 * Reader for JSR-353 stream (StAX) parser.
 * 

* Could be instantiated with {@link JsonParserReader.JsonParserReaderBuilder#build()}; */ public final class JsonParserReader extends XMLReaderAdapter { private final JsonParser parser; private final JsonStructureReader structureReader; /** * Parsing stack */ private final Deque stack = new ArrayDeque<>(); /** * Private constructor * Use {@link JsonParserReader.JsonParserReaderBuilder} to instantiate the class; */ private JsonParserReader(JsonParserReaderBuilder b) { this.parser = b.parser; if (b.resultClass == null) this.structureReader = new JsonStructureReader(b.um); else this.structureReader = new JsonStructureReader(b.um, b.resultClass); } @Override public void parse(InputSource input) throws IOException, SAXException { if (null == input) { doParsing(parser); return; } if (null != input.getCharacterStream()) { doParsing(Json.createParser(input.getCharacterStream())); return; } InputStream inputStream = null; try { if (null != (inputStream = input.getByteStream())) { doParsing(Json.createParser(inputStream)); return; } try { URL url = new URL(input.getSystemId()); inputStream = url.openStream(); } catch (MalformedURLException malformedURLException) { try { inputStream = new FileInputStream(input.getSystemId()); } catch (FileNotFoundException fileNotFoundException) { throw malformedURLException; } } doParsing(Json.createParser(inputStream)); } catch (JsonException je) { throw XMLMarshalException.unmarshalException(je); } finally { if (null != inputStream) { inputStream.close(); } } } @Override public void parse(String systemId) { try { parse(new InputSource(systemId)); } catch (IOException | SAXException e) { throw XMLMarshalException.unmarshalException(e); } } private void doParsing(JsonParser parser) throws SAXException, IOException { JsonStructureBuilder builder = null; while (parser.hasNext()) { builder = parseEvent(parser); } assert builder != null; JsonStructure jsonStructure = builder.build(); structureReader.parseRoot(jsonStructure); } private JsonStructureBuilder parseEvent(JsonParser jp) throws SAXException { JsonParser.Event e = jp.next(); JsonStructureBuilder top = stack.peek(); switch (e) { case START_ARRAY: { JsonStructureBuilder b = new ArrayBuilder(Json.createArrayBuilder()); stack.push(b); break; } case START_OBJECT: { JsonStructureBuilder b = new ObjectBuilder(Json.createObjectBuilder()); stack.push(b); break; } case KEY_NAME: { top.setKey(jp.getString()); break; } case VALUE_STRING: { top.add(jp.getString()); break; } case VALUE_NUMBER: { top.add(jp.getBigDecimal()); break; } case VALUE_TRUE: { top.add(Boolean.TRUE); break; } case VALUE_FALSE: { top.add(Boolean.FALSE); break; } case VALUE_NULL: { top.addNull(); break; } case END_ARRAY: case END_OBJECT: { // adding build element to the upper one JsonStructureBuilder b = stack.pop(); top = stack.peek(); if (top != null) top.add(b.build()); return b; } default: throw new IllegalStateException("Unhandled event: " + e); } return null; } // ******************************** Redirecting requests to JsonStructureReader ******************************* public boolean isNullRepresentedByXsiNil(AbstractNullPolicy nullPolicy) { return true; } @Override public Object convertValueBasedOnSchemaType(Field xmlField, Object value, ConversionManager conversionManager, AbstractUnmarshalRecord record) { return structureReader.convertValueBasedOnSchemaType(xmlField, value, conversionManager, record); } @Override public char getNamespaceSeparator() { return structureReader.getNamespaceSeparator(); } @Override public ErrorHandler getErrorHandler() { return structureReader.getErrorHandler(); } @Override public ExtendedContentHandler getContentHandler() { return structureReader.getContentHandler(); } @Override public void setContentHandler(ContentHandler contentHandler) { structureReader.setContentHandler(contentHandler); } @Override public boolean isInCollection() { return structureReader.isInCollection(); } @Override public MediaType getMediaType() { return Constants.APPLICATION_JSON; } @Override public boolean isNamespaceAware() { return structureReader.isNamespaceAware(); } // ************************************************************************************************************ /** * JsonStructure builder */ private static interface JsonStructureBuilder { JsonStructure build(); void add(JsonValue value); void add(String value); void add(BigDecimal value); void add(boolean value); void addNull(); void setKey(String key); } /** * Builder for JsonParserReader */ public static final class JsonParserReaderBuilder { private final JsonParser parser; private Unmarshaller um; private Class resultClass; public JsonParserReaderBuilder(JsonParser parser) { this.parser = parser; } public JsonParserReaderBuilder setUnmarshaller(Unmarshaller um) { this.um = um; return this; } public JsonParserReaderBuilder setResultClass(Class resultClass) { this.resultClass = resultClass; return this; } public JsonParserReader build() { if (parser == null) throw new NullPointerException("JsonParser can't be null"); return new JsonParserReader(this); } } private static final class ObjectBuilder implements JsonStructureBuilder { private final JsonObjectBuilder b; private String key; public ObjectBuilder(JsonObjectBuilder b) { this.b = b; } @Override public JsonStructure build() { return b.build(); } @Override public void add(JsonValue value) { b.add(key, value); } @Override public void add(String value) { b.add(key, value); } @Override public void add(BigDecimal value) { b.add(key, value); } @Override public void add(boolean value) { b.add(key, value); } @Override public void addNull() { b.addNull(key); } @Override public void setKey(String key) { this.key = key; } } private static final class ArrayBuilder implements JsonStructureBuilder { private final JsonArrayBuilder b; public ArrayBuilder(JsonArrayBuilder b) { this.b = b; } @Override public JsonStructure build() { return b.build(); } @Override public void add(JsonValue value) { b.add(value); } @Override public void add(String value) { b.add(value); } @Override public void add(BigDecimal value) { b.add(value); } @Override public void add(boolean value) { b.add(value); } @Override public void addNull() { b.addNull(); } @Override public void setKey(String key) { // noop } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy