[libjsonp-java] 01/02: Imported Upstream version 0.0.20150930
Andreas Tille
tille at debian.org
Thu Jan 14 22:07:51 UTC 2016
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository libjsonp-java.
commit cfd80dc43fb152f4c8a4dee54a93dc641339a1c5
Author: Andreas Tille <tille at debian.org>
Date: Thu Jan 14 22:52:17 2016 +0100
Imported Upstream version 0.0.20150930
---
api/pom.xml | 144 ++++
api/src/main/java/javax/json/Json.java | 380 +++++++++
api/src/main/java/javax/json/JsonArray.java | 295 +++++++
api/src/main/java/javax/json/JsonArrayBuilder.java | 646 +++++++++++++++
.../main/java/javax/json/JsonBuilderFactory.java | 125 +++
api/src/main/java/javax/json/JsonException.java | 79 ++
api/src/main/java/javax/json/JsonMergePatch.java | 123 +++
api/src/main/java/javax/json/JsonNumber.java | 199 +++++
api/src/main/java/javax/json/JsonObject.java | 273 ++++++
.../main/java/javax/json/JsonObjectBuilder.java | 307 +++++++
api/src/main/java/javax/json/JsonPatch.java | 333 ++++++++
api/src/main/java/javax/json/JsonPatchBuilder.java | 353 ++++++++
api/src/main/java/javax/json/JsonPointer.java | 380 +++++++++
api/src/main/java/javax/json/JsonReader.java | 157 ++++
.../main/java/javax/json/JsonReaderFactory.java | 115 +++
api/src/main/java/javax/json/JsonString.java | 87 ++
api/src/main/java/javax/json/JsonStructure.java | 61 ++
api/src/main/java/javax/json/JsonUtil.java | 95 +++
api/src/main/java/javax/json/JsonValue.java | 303 +++++++
api/src/main/java/javax/json/JsonWriter.java | 147 ++++
.../main/java/javax/json/JsonWriterFactory.java | 118 +++
api/src/main/java/javax/json/NodeReference.java | 276 +++++++
api/src/main/java/javax/json/package-info.java | 69 ++
api/src/main/java/javax/json/spi/JsonProvider.java | 384 +++++++++
api/src/main/java/javax/json/spi/package-info.java | 56 ++
.../java/javax/json/stream/JsonCollectors.java | 169 ++++
.../javax/json/stream/JsonGenerationException.java | 81 ++
.../main/java/javax/json/stream/JsonGenerator.java | 544 ++++++++++++
.../javax/json/stream/JsonGeneratorFactory.java | 113 +++
.../main/java/javax/json/stream/JsonLocation.java | 85 ++
.../main/java/javax/json/stream/JsonParser.java | 511 ++++++++++++
.../java/javax/json/stream/JsonParserFactory.java | 132 +++
.../javax/json/stream/JsonParsingException.java | 96 +++
.../main/java/javax/json/stream/package-info.java | 71 ++
api/src/main/javadoc/doc-files/speclicense.html | 217 +++++
api/src/main/javadoc/overview.html | 90 ++
bundles/licensee/pom.xml | 108 +++
bundles/licensee/src/main/assembly/archive.xml | 69 ++
bundles/pom.xml | 72 ++
bundles/ri/pom.xml | 114 +++
bundles/ri/src/main/assembly/archive.xml | 60 ++
bundles/ri/src/main/resources/LICENSE.txt | 274 +++++++
bundles/ri/src/main/resources/README.txt | 13 +
copyright-exclude | 5 +
demos/facebook/pom.xml | 95 +++
.../jsondemos/facebook/FacebookObjectSearch.java | 103 +++
.../jsondemos/facebook/FacebookStreamSearch.java | 94 +++
.../src/main/resources/facebookconfig.properties | 1 +
demos/jaxrs/pom.xml | 90 ++
.../glassfish/jsondemos/jaxrs/ArrayResource.java | 75 ++
.../glassfish/jsondemos/jaxrs/DemoApplication.java | 77 ++
.../jsondemos/jaxrs/GeneratorResource.java | 97 +++
.../glassfish/jsondemos/jaxrs/ObjectResource.java | 85 ++
.../glassfish/jsondemos/jaxrs/ParserResource.java | 122 +++
.../jsondemos/jaxrs/StructureResource.java | 84 ++
demos/jsonpointer/pom.xml | 95 +++
.../jsondemos/jsonpointer/JsonpointerDemo.java | 161 ++++
.../src/main/resources/jsonpointer.json | 12 +
demos/jsonpointer/src/main/resources/wiki.json | 21 +
demos/pom.xml | 78 ++
demos/servlet/pom.xml | 85 ++
.../glassfish/jsondemos/servlet/ArrayServlet.java | 87 ++
demos/twitter/pom.xml | 93 +++
.../jsondemos/twitter/TwitterObjectSearch.java | 180 ++++
.../jsondemos/twitter/TwitterStreamSearch.java | 110 +++
.../src/main/resources/twitterconfig.properties | 5 +
gf/customprovider/pom.xml | 63 ++
.../json/customprovider/TestGenerator.java | 195 +++++
.../json/customprovider/TestProvider.java | 136 +++
.../glassfish/json/customprovider/TestServlet.java | 74 ++
.../META-INF/services/javax.json.spi.JsonProvider | 1 +
gf/defaultprovider/pom.xml | 63 ++
.../json/defaultprovider/TestServlet.java | 70 ++
gf/pom.xml | 84 ++
impl/pom.xml | 205 +++++
.../java/org/glassfish/json/BufferPoolImpl.java | 98 +++
.../org/glassfish/json/JsonArrayBuilderImpl.java | 484 +++++++++++
.../org/glassfish/json/JsonBuilderFactoryImpl.java | 89 ++
.../glassfish/json/JsonGeneratorFactoryImpl.java | 94 +++
.../java/org/glassfish/json/JsonGeneratorImpl.java | 709 ++++++++++++++++
.../java/org/glassfish/json/JsonLocationImpl.java | 80 ++
.../main/java/org/glassfish/json/JsonMessages.java | 221 +++++
.../java/org/glassfish/json/JsonNumberImpl.java | 263 ++++++
.../org/glassfish/json/JsonObjectBuilderImpl.java | 331 ++++++++
.../org/glassfish/json/JsonParserFactoryImpl.java | 95 +++
.../java/org/glassfish/json/JsonParserImpl.java | 513 ++++++++++++
.../glassfish/json/JsonPrettyGeneratorImpl.java | 122 +++
.../java/org/glassfish/json/JsonProviderImpl.java | 249 ++++++
.../org/glassfish/json/JsonReaderFactoryImpl.java | 83 ++
.../java/org/glassfish/json/JsonReaderImpl.java | 137 ++++
.../java/org/glassfish/json/JsonStringImpl.java | 132 +++
.../org/glassfish/json/JsonStructureParser.java | 271 ++++++
.../java/org/glassfish/json/JsonTokenizer.java | 610 ++++++++++++++
.../org/glassfish/json/JsonWriterFactoryImpl.java | 86 ++
.../java/org/glassfish/json/JsonWriterImpl.java | 187 +++++
.../json/UnicodeDetectingInputStream.java | 188 +++++
.../java/org/glassfish/json/api/BufferPool.java | 66 ++
.../org/glassfish/json/messages.properties | 47 ++
jaxrs-1x/pom.xml | 106 +++
.../json/jaxrs1x/JsonStructureBodyReader.java | 100 +++
.../json/jaxrs1x/JsonStructureBodyWriter.java | 115 +++
jaxrs/pom.xml | 106 +++
.../json/jaxrs/JsonStructureBodyReader.java | 99 +++
.../json/jaxrs/JsonStructureBodyWriter.java | 119 +++
pom.xml | 337 ++++++++
tests/pom.xml | 73 ++
.../org/glassfish/json/tests/JsonArrayTest.java | 138 ++++
.../org/glassfish/json/tests/JsonBuilderTest.java | 123 +++
.../glassfish/json/tests/JsonCollectorTest.java | 185 +++++
.../json/tests/JsonGeneratorFactoryTest.java | 94 +++
.../glassfish/json/tests/JsonGeneratorTest.java | 518 ++++++++++++
.../json/tests/JsonMergePatchDiffTest.java | 136 +++
.../glassfish/json/tests/JsonMergePatchTest.java | 138 ++++
.../org/glassfish/json/tests/JsonNumberTest.java | 234 ++++++
.../org/glassfish/json/tests/JsonObjectTest.java | 149 ++++
.../json/tests/JsonParserFactoryTest.java | 80 ++
.../org/glassfish/json/tests/JsonParserTest.java | 769 +++++++++++++++++
.../json/tests/JsonParsingExceptionTest.java | 179 ++++
.../glassfish/json/tests/JsonPatchBuilderTest.java | 106 +++
.../glassfish/json/tests/JsonPatchDiffTest.java | 138 ++++
.../org/glassfish/json/tests/JsonPatchTest.java | 142 ++++
.../json/tests/JsonPointerAddOperationTest.java | 227 +++++
.../json/tests/JsonPointerRemoveOperationTest.java | 181 ++++
.../tests/JsonPointerReplaceOperationTest.java | 225 +++++
.../org/glassfish/json/tests/JsonPointerTest.java | 132 +++
.../org/glassfish/json/tests/JsonReaderTest.java | 232 ++++++
.../json/tests/JsonSamplesParsingTest.java | 89 ++
.../org/glassfish/json/tests/JsonStringTest.java | 81 ++
.../org/glassfish/json/tests/JsonWriterTest.java | 193 +++++
.../java/org/glassfish/json/tests/RFC7159Test.java | 126 +++
.../java/org/glassfish/json/tests/ToJsonTest.java | 82 ++
.../glassfish/json/tests/TwitterSearchTest.java | 99 +++
tests/src/test/resources/facebook.json | 668 +++++++++++++++
tests/src/test/resources/facebook1.json | 911 +++++++++++++++++++++
tests/src/test/resources/facebook2.json | 555 +++++++++++++
tests/src/test/resources/jsonmergepatch.json | 103 +++
tests/src/test/resources/jsonmergepatchdiff.json | 60 ++
tests/src/test/resources/jsonpatch.json | 214 +++++
tests/src/test/resources/jsonpatchdiff.json | 132 +++
tests/src/test/resources/rfc6901.json | 20 +
tests/src/test/resources/twitter.json | 2 +
tests/src/test/resources/wiki.json | 21 +
142 files changed, 24762 insertions(+)
diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 0000000..8557bef
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.1.0-SNAPSHOT</version>
+ <name>JSR 374 (JSON Processing) API</name>
+ <description>API module of JSR 374:Java API for Processing JSON</description>
+ <url>http://json-processing-spec.java.net</url>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <groups>
+ <group>
+ <title>JSON Processing Packages</title>
+ <packages>javax.json*</packages>
+ </group>
+ </groups>
+ <bottom>
+<![CDATA[Copyright © 2012-2015,
+ <a href="http://www.oracle.com">Oracle</a>
+ and/or its affiliates. All Rights Reserved.
+ Use is subject to
+ <a href="{@docRoot}/doc-files/speclicense.html" target="_top">license terms</a>.
+ <br>Comments to : users at json-processing-spec.java.net
+]]>
+ </bottom>
+ <links>
+ <link>http://docs.oracle.com/javase/8/docs/api/</link>
+ </links>
+ </configuration>
+
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.glassfish.build</groupId>
+ <artifactId>spec-version-maven-plugin</artifactId>
+ <configuration>
+ <spec>
+ <nonFinal>false</nonFinal>
+ <jarType>api</jarType>
+ <specVersion>${spec_version}</specVersion>
+ <specImplVersion>${spec_impl_version}</specImplVersion>
+ <apiPackage>${api_package}</apiPackage>
+ </spec>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>set-spec-properties</goal>
+ <goal>check-module</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ This plugin is reponsible for packaging artifacts
+ as OSGi bundles. Please refer to
+ http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
+ for more information about how to use this plugin.
+ -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>${spec.bundle.version}</Bundle-Version>
+ <Bundle-SymbolicName>${spec.bundle.symbolic-name}</Bundle-SymbolicName>
+ <Extension-Name>${spec.extension.name}</Extension-Name>
+ <Implementation-Version>${spec.implementation.version}</Implementation-Version>
+ <Specification-Version>${spec.specification.version}</Specification-Version>
+ <Export-Package>${packages.export}</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/api/src/main/java/javax/json/Json.java b/api/src/main/java/javax/json/Json.java
new file mode 100644
index 0000000..b4990ce
--- /dev/null
+++ b/api/src/main/java/javax/json/Json.java
@@ -0,0 +1,380 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import javax.json.spi.JsonProvider;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.*;
+import java.util.Map;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Factory class for creating JSON processing objects.
+ * This class provides the most commonly used methods for creating these
+ * objects and their corresponding factories. The factory classes provide
+ * all the various ways to create these objects.
+ *
+ * <p>
+ * The methods in this class locate a provider instance using the method
+ * {@link JsonProvider#provider()}. This class uses the provider instance
+ * to create JSON processing objects.
+ *
+ * <p>
+ * The following example shows how to create a JSON parser to parse
+ * an empty array:
+ * <pre>
+ * <code>
+ * StringReader reader = new StringReader("[]");
+ * JsonParser parser = Json.createParser(reader);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public final class Json {
+
+ private Json() {
+ }
+
+ /**
+ * Creates a JSON parser from a character stream.
+ *
+ * @param reader i/o reader from which JSON is to be read
+ * @return a JSON parser
+ */
+ public static JsonParser createParser(Reader reader) {
+ return JsonProvider.provider().createParser(reader);
+ }
+
+ /**
+ * Creates a JSON parser from a byte stream.
+ * The character encoding of the stream is determined as specified in
+ * <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ *
+ * @param in i/o stream from which JSON is to be read
+ * @throws JsonException if encoding cannot be determined
+ * or i/o error (IOException would be cause of JsonException)
+ * @return a JSON parser
+ */
+ public static JsonParser createParser(InputStream in) {
+ return JsonProvider.provider().createParser(in);
+ }
+
+ /**
+ * Creates a JSON generator for writing JSON to a character stream.
+ *
+ * @param writer a i/o writer to which JSON is written
+ * @return a JSON generator
+ */
+ public static JsonGenerator createGenerator(Writer writer) {
+ return JsonProvider.provider().createGenerator(writer);
+ }
+
+ /**
+ * Creates a JSON generator for writing JSON to a byte stream.
+ *
+ * @param out i/o stream to which JSON is written
+ * @return a JSON generator
+ */
+ public static JsonGenerator createGenerator(OutputStream out) {
+ return JsonProvider.provider().createGenerator(out);
+ }
+
+ /**
+ * Creates a parser factory for creating {@link JsonParser} objects.
+ *
+ * @return JSON parser factory.
+ *
+ public static JsonParserFactory createParserFactory() {
+ return JsonProvider.provider().createParserFactory();
+ }
+ */
+
+ /**
+ * Creates a parser factory for creating {@link JsonParser} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON parsers. The map may be empty or null
+ * @return JSON parser factory
+ */
+ public static JsonParserFactory createParserFactory(Map<String, ?> config) {
+ return JsonProvider.provider().createParserFactory(config);
+ }
+
+ /**
+ * Creates a generator factory for creating {@link JsonGenerator} objects.
+ *
+ * @return JSON generator factory
+ *
+ public static JsonGeneratorFactory createGeneratorFactory() {
+ return JsonProvider.provider().createGeneratorFactory();
+ }
+ */
+
+ /**
+ * Creates a generator factory for creating {@link JsonGenerator} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON generators. The map may be empty or null
+ * @return JSON generator factory
+ */
+ public static JsonGeneratorFactory createGeneratorFactory(
+ Map<String, ?> config) {
+ return JsonProvider.provider().createGeneratorFactory(config);
+ }
+
+ /**
+ * Creates a JSON writer to write a
+ * JSON {@link JsonObject object} or {@link JsonArray array}
+ * structure to the specified character stream.
+ *
+ * @param writer to which JSON object or array is written
+ * @return a JSON writer
+ */
+ public static JsonWriter createWriter(Writer writer) {
+ return JsonProvider.provider().createWriter(writer);
+ }
+
+ /**
+ * Creates a JSON writer to write a
+ * JSON {@link JsonObject object} or {@link JsonArray array}
+ * structure to the specified byte stream. Characters written to
+ * the stream are encoded into bytes using UTF-8 encoding.
+ *
+ * @param out to which JSON object or array is written
+ * @return a JSON writer
+ */
+ public static JsonWriter createWriter(OutputStream out) {
+ return JsonProvider.provider().createWriter(out);
+ }
+
+ /**
+ * Creates a JSON reader from a character stream.
+ *
+ * @param reader a reader from which JSON is to be read
+ * @return a JSON reader
+ */
+ public static JsonReader createReader(Reader reader) {
+ return JsonProvider.provider().createReader(reader);
+ }
+
+ /**
+ * Creates a JSON reader from a byte stream. The character encoding of
+ * the stream is determined as described in
+ * <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ *
+ * @param in a byte stream from which JSON is to be read
+ * @return a JSON reader
+ */
+ public static JsonReader createReader(InputStream in) {
+ return JsonProvider.provider().createReader(in);
+ }
+
+ /**
+ * Creates a reader factory for creating {@link JsonReader} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON readers. The map may be empty or null
+ * @return a JSON reader factory
+ */
+ public static JsonReaderFactory createReaderFactory(Map<String, ?> config) {
+ return JsonProvider.provider().createReaderFactory(config);
+ }
+
+ /**
+ * Creates a writer factory for creating {@link JsonWriter} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON writers. The map may be empty or null
+ * @return a JSON writer factory
+ */
+ public static JsonWriterFactory createWriterFactory(Map<String, ?> config) {
+ return JsonProvider.provider().createWriterFactory(config);
+ }
+
+ /**
+ * Creates a JSON array builder
+ *
+ * @return a JSON array builder
+ */
+ public static JsonArrayBuilder createArrayBuilder() {
+ return JsonProvider.provider().createArrayBuilder();
+ }
+
+ /**
+ * Creates a JSON array builder, initialized with the specified array
+ *
+ * @param array the initial array in the builder
+ * @return a JSON array builder
+ *
+ * @since 1.1
+ */
+ public static JsonArrayBuilder createArrayBuilder(JsonArray array) {
+ return JsonProvider.provider().createArrayBuilder(array);
+ }
+
+ /**
+ * Creates a JSON object builder
+ *
+ * @return a JSON object builder
+ */
+ public static JsonObjectBuilder createObjectBuilder() {
+ return JsonProvider.provider().createObjectBuilder();
+ }
+
+ /**
+ * Creates a JSON object builder, initialized with the specified object.
+ *
+ * @param object the initial object in the builder
+ * @return a JSON object builder
+ *
+ * @since 1.1
+ */
+ public static JsonObjectBuilder createObjectBuilder(JsonObject object) {
+ return JsonProvider.provider().createObjectBuilder(object);
+ }
+
+ /**
+ * Creates a builder factory for creating {@link JsonArrayBuilder}
+ * and {@link JsonObjectBuilder} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON builders. The map may be empty or null
+ * @return a JSON builder factory
+ */
+ public static JsonBuilderFactory createBuilderFactory(
+ Map<String, ?> config) {
+ return JsonProvider.provider().createBuilderFactory(config);
+ }
+
+ /**
+ * Creates a JsonString
+ *
+ * @param value a JSON string
+ * @return the JsonString for the string
+ *
+ * @since 1.1
+ */
+ public static JsonString createValue(String value) {
+ return JsonProvider.provider().createValue(value);
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public static JsonNumber createValue(int value) {
+ return JsonProvider.provider().createValue(value);
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public static JsonNumber createValue(long value) {
+ return JsonProvider.provider().createValue(value);
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public static JsonNumber createValue(double value) {
+ return JsonProvider.provider().createValue(value);
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public static JsonNumber createValue(BigDecimal value) {
+ return JsonProvider.provider().createValue(value);
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public static JsonNumber createValue(BigInteger value) {
+ return JsonProvider.provider().createValue(value);
+ }
+}
diff --git a/api/src/main/java/javax/json/JsonArray.java b/api/src/main/java/javax/json/JsonArray.java
new file mode 100644
index 0000000..ddbe617
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonArray.java
@@ -0,0 +1,295 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.List;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * {@code JsonArray} represents an immutable JSON array
+ * (an ordered sequence of zero or more values).
+ * It also provides an unmodifiable list view of the values in the array.
+ *
+ * <p>A {@code JsonArray} object can be created by reading JSON data from
+ * an input source or it can be built from scratch using an array builder
+ * object.
+ *
+ * <p>The following example demonstrates how to create a {@code JsonArray}
+ * object from an input source using the method {@link JsonReader#readArray()}:
+ * <pre><code>
+ * JsonReader jsonReader = Json.createReader(...);
+ * JsonArray array = jsonReader.readArray();
+ * jsonReader.close();
+ * </code></pre>
+ *
+ * <p>The following example demonstrates how to build an empty JSON array
+ * using the class {@link JsonArrayBuilder}:
+ * <pre><code>
+ * JsonArray array = Json.createArrayBuilder().build();
+ * </code></pre>
+ *
+ * <p>The example code below demonstrates how to create the following JSON array:
+ * <pre><code>
+ * [
+ * { "type": "home", "number": "212 555-1234" },
+ * { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * </code></pre>
+ * <pre><code>
+ * JsonArray value = Json.createArrayBuilder()
+ * .add(Json.createObjectBuilder()
+ * .add("type", "home")
+ * .add("number", "212 555-1234"))
+ * .add(Json.createObjectBuilder()
+ * .add("type", "fax")
+ * .add("number", "646 555-4567"))
+ * .build();
+ * </code></pre>
+ *
+ * <p>The following example demonstrates how to write a {@code JsonArray} object
+ * as JSON data:
+ * <pre><code>
+ * JsonArray arr = ...;
+ * JsonWriter writer = Json.createWriter(...)
+ * writer.writeArray(arr);
+ * writer.close();
+ * </code></pre>
+ *
+ * <p>The values in a {@code JsonArray} can be of the following types:
+ * {@link JsonObject}, {@link JsonArray},
+ * {@link JsonString}, {@link JsonNumber}, {@link JsonValue#TRUE},
+ * {@link JsonValue#FALSE}, and {@link JsonValue#NULL}.
+ * {@code JsonArray} provides various accessor methods to access the values
+ * in an array.
+ *
+ * <p>The following example shows how to obtain the home phone number
+ * "212 555-1234" from the array built in the previous example:
+ * <pre><code>
+ * JsonObject home = array.getJsonObject(0);
+ * String number = home.getString("number");
+ * </code></pre>
+ *
+ * <p>{@code JsonArray} instances are list objects that provide read-only
+ * access to the values in the JSON array. Any attempt to modify the list,
+ * whether directly or using its collection views, results in an
+ * {@code UnsupportedOperationException}.
+ */
+public interface JsonArray extends JsonStructure, List<JsonValue> {
+
+ /**
+ * Returns the object value at the specified position in this array.
+ * This is a convenience method for {@code (JsonObject)get(index)}.
+ *
+ * @param index index of the value to be returned
+ * @return the value at the specified position in this array
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to the JsonObject type
+ */
+ JsonObject getJsonObject(int index);
+
+ /**
+ * Returns the array value at the specified position in this array.
+ * This is a convenience method for {@code (JsonArray)get(index)}.
+ *
+ * @param index index of the value to be returned
+ * @return the value at the specified position in this array
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to the JsonArray type
+ */
+ JsonArray getJsonArray(int index);
+
+ /**
+ * Returns the number value at the specified position in this array.
+ * This is a convenience method for {@code (JsonNumber)get(index)}.
+ *
+ * @param index index of the value to be returned
+ * @return the value at the specified position in this array
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to the JsonNumber type
+ */
+ JsonNumber getJsonNumber(int index);
+
+ /**
+ * Returns the string value at ths specified position in this array.
+ * This is a convenience method for {@code (JsonString)get(index)}.
+ *
+ * @param index index of the value to be returned
+ * @return the value at the specified position in this array
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to the JsonString type
+ */
+ JsonString getJsonString(int index);
+
+ /**
+ * Returns a list view of the specified type for the array. This method
+ * does not verify if there is a value of wrong type in the array. Providing
+ * this typesafe view dynamically may cause a program fail with a
+ * {@code ClassCastException}, if there is a value of wrong type in this
+ * array. Unfortunately, the exception can occur at any time after this
+ * method returns.
+ *
+ * @param <T> The type of the List for the array
+ * @param clazz a JsonValue type
+ * @return a list view of the specified type
+ */
+ <T extends JsonValue> List<T> getValuesAs(Class<T> clazz);
+
+ /**
+ * Returns a list view for the array. The value and the type of the elements
+ * in the list is specified by the {@code func} argument.
+ * <p>This method can be used to obtain a list of the unwrapped types, such as
+ * <pre>{@code
+ * List<String> strings = ary1.getValuesAs(JsonString::getString);
+ * List<Integer> ints = ary2.getValuesAs(JsonNumber::intValue);
+ * } </pre>
+ * or a list of simple projections, such as
+ * <pre> {@code
+ * Lsit<Integer> stringsizes = ary1.getValueAs((JsonString v)->v.getString().length();
+ * } </pre>
+ * @param <K> The element type (must be a subtype of JsonValue) of this JsonArray.
+ * @param <T> The element type of the returned List
+ * @param func The function that maps the elements of this JsonArray to the target elements.
+ * @return A List of the specified values and type.
+ * @throws ClassCastException if the {@code JsonArray} contains a value of wrong type
+ */
+ default <T, K extends JsonValue> List<T> getValuesAs(Function<K, T> func) {
+ Stream<K> stream = (Stream<K>) stream();
+ return stream.map(func).collect(Collectors.toList());
+ }
+
+ /**
+ * A convenience method for
+ * {@code getJsonString(index).getString()}.
+ *
+ * @param index index of the {@code JsonString} value
+ * @return the String value at the specified position
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to {@code JsonString}
+ */
+ String getString(int index);
+
+ /**
+ * Returns the {@code String} value of {@code JsonString} at the specified
+ * position in this JSON array values. If {@code JsonString} is found,
+ * its {@link javax.json.JsonString#getString()} is returned. Otherwise,
+ * the specified default value is returned.
+ *
+ * @param index index of the {@code JsonString} value
+ * @param defaultValue the String to return if the {@code JsonValue} at the
+ * specified position is not a {@code JsonString}
+ * @return the String value at the specified position in this array,
+ * or the specified default value
+ */
+ String getString(int index, String defaultValue);
+
+ /**
+ * A convenience method for
+ * {@code getJsonNumber(index).intValue()}.
+ *
+ * @param index index of the {@code JsonNumber} value
+ * @return the int value at the specified position
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to {@code JsonNumber}
+ */
+ int getInt(int index);
+
+ /**
+ * Returns the int value of the {@code JsonNumber} at the specified position.
+ * If the value at that position is a {@code JsonNumber},
+ * this method returns {@link javax.json.JsonNumber#intValue()}. Otherwise
+ * this method returns the specified default value.
+ *
+ * @param index index of the {@code JsonNumber} value
+ * @param defaultValue the int value to return if the {@code JsonValue} at
+ * the specified position is not a {@code JsonNumber}
+ * @return the int value at the specified position in this array,
+ * or the specified default value
+ */
+ int getInt(int index, int defaultValue);
+
+ /**
+ * Returns the boolean value at the specified position.
+ * If the value at the specified position is {@code JsonValue.TRUE}
+ * this method returns {@code true}. If the value at the specified position
+ * is {@code JsonValue.FALSE} this method returns {@code false}.
+ *
+ * @param index index of the JSON boolean value
+ * @return the boolean value at the specified position
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * @throws ClassCastException if the value at the specified position is not
+ * assignable to {@code JsonValue.TRUE} or {@code JsonValue.FALSE}
+ */
+ boolean getBoolean(int index);
+
+ /**
+ * Returns the boolean value at the specified position.
+ * If the value at the specified position is {@code JsonValue.TRUE}
+ * this method returns {@code true}. If the value at the specified position
+ * is {@code JsonValue.FALSE} this method returns {@code false}.
+ * Otherwise this method returns the specified default value.
+ *
+ * @param index index of the JSON boolean value
+ * @param defaultValue the boolean value to return if the {@code JsonValue}
+ * at the specified position is neither TRUE nor FALSE
+ * @return the boolean value at the specified position,
+ * or the specified default value
+ */
+ boolean getBoolean(int index, boolean defaultValue);
+
+ /**
+ * Returns {@code true} if the value at the specified location in this
+ * array is {@code JsonValue.NULL}.
+ *
+ * @param index index of the JSON null value
+ * @return return true if the value at the specified location is
+ * {@code JsonValue.NUL}, otherwise false
+ * @throws IndexOutOfBoundsException if the index is out of range
+ */
+ boolean isNull(int index);
+}
diff --git a/api/src/main/java/javax/json/JsonArrayBuilder.java b/api/src/main/java/javax/json/JsonArrayBuilder.java
new file mode 100644
index 0000000..a78ec09
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonArrayBuilder.java
@@ -0,0 +1,646 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A builder for creating {@link JsonArray} models from scratch, and for
+ * modifying a existing {@code JsonArray}.
+ * <p>A {@code JsonArrayBuilder} can start with an empty or a non-empty
+ * JSON array model. This interface provides methods to add, insert, remove
+ * and replace values in the JSON array model.</p>
+ * <p>The methods in this class can be chained to perform multiple values to
+ * the array.</p>
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create the builder
+ * object. The example code below shows how to build an empty {@code JsonArray}
+ * instance.
+ * <pre>
+ * <code>
+ * JsonArray array = Json.createArrayBuilder().build();
+ * </code>
+ * </pre>
+ *
+ * <p>The class {@link JsonBuilderFactory} also contains methods to create
+ * {@code JsonArrayBuilder} instances. A factory instance can be used to create
+ * multiple builder instances with the same configuration. This the preferred
+ * way to create multiple instances.
+ *
+ * The example code below shows how to build a {@code JsonArray} object
+ * that represents the following JSON array:
+ *
+ * <pre>
+ * <code>
+ * [
+ * { "type": "home", "number": "212 555-1234" },
+ * { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * </code>
+ * </pre>
+ *
+ * <p>The following code creates the JSON array above:
+ *
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(config);
+ * JsonArray value = factory.createArrayBuilder()
+ * .add(factory.createObjectBuilder()
+ * .add("type", "home")
+ * .add("number", "212 555-1234"))
+ * .add(factory.createObjectBuilder()
+ * .add("type", "fax")
+ * .add("number", "646 555-4567"))
+ * .build();
+ * </code>
+ * </pre>
+ *
+ * <p>This class does <em>not</em> allow <tt>null</tt> to be used as a
+ * value while building the JSON array
+ *
+ * @see JsonObjectBuilder
+ */
+public interface JsonArrayBuilder {
+
+ /**
+ * Adds a value to the array.
+ *
+ * @param value the JSON value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ */
+ JsonArrayBuilder add(JsonValue value);
+
+ /**
+ * Adds a value to the array as a {@link JsonString}.
+ *
+ * @param value the string value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ */
+ JsonArrayBuilder add(String value);
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber}.
+ *
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ *
+ * @see JsonNumber
+ */
+ JsonArrayBuilder add(BigDecimal value);
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber}.
+ *
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ *
+ * @see JsonNumber
+ */
+ JsonArrayBuilder add(BigInteger value);
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber}.
+ *
+ * @param value the number value
+ * @return this array builder
+ *
+ * @see JsonNumber
+ */
+ JsonArrayBuilder add(int value);
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber}.
+ *
+ * @param value the number value
+ * @return this array builder
+ *
+ * @see JsonNumber
+ */
+ JsonArrayBuilder add(long value);
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber}.
+ *
+ * @param value the number value
+ * @return this array builder
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or
+ * infinity
+ *
+ * @see JsonNumber
+ */
+ JsonArrayBuilder add(double value);
+
+ /**
+ * Adds a {@link JsonValue#TRUE} or {@link JsonValue#FALSE} value to the
+ * array.
+ *
+ * @param value the boolean value
+ * @return this array builder
+ */
+ JsonArrayBuilder add(boolean value);
+
+ /**
+ * Adds a {@link JsonValue#NULL} value to the array.
+ *
+ * @return this array builder
+ */
+ JsonArrayBuilder addNull();
+
+ /**
+ * Adds a {@link JsonObject} from an object builder to the array.
+ *
+ * @param builder the object builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ */
+ JsonArrayBuilder add(JsonObjectBuilder builder);
+
+ /**
+ * Adds a {@link JsonArray} from an array builder to the array.
+ *
+ * @param builder the array builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ */
+ JsonArrayBuilder add(JsonArrayBuilder builder);
+
+ /**
+ * Adds all the elements of the array in the specified array builder to the array.
+ *
+ * @param builder the array builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ *
+ @since 1.1
+ */
+ default JsonArrayBuilder addAll(JsonArrayBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Inserts a value to the array at the specified position. Shifts the value
+ * currently at that position (if any) and any subsequent values to the right
+ * (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the JSON value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, JsonValue value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonString} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the string value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, BigDecimal value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, BigInteger value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, int value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a value to the array as a {@link JsonNumber} at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or
+ * infinity
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a {@link JsonValue#TRUE} or {@link JsonValue#FALSE} value to the
+ * array at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param value the boolean value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a {@link JsonValue#NULL} value to the array at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder addNull(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a {@link JsonObject} from an object builder to the array at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param builder the object builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, JsonObjectBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Adds a {@link JsonArray} from an array builder to the array at the specified position.
+ * Shifts the value currently at that position (if any) and any subsequent values
+ * to the right (adds one to their indices). Index starts with 0.
+ *
+ * @param index the position in the array
+ * @param builder the array builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index > array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder add(int index, JsonArrayBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value at the
+ * specified position.
+ *
+ * @param index the position in the array
+ * @param value the JSON value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, JsonValue value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonString} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the string value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonNumber} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, BigDecimal value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonNumber} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NullPointerException if the specified value is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, BigInteger value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonNumber} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, int value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonNumber} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonNumber} at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the number value
+ * @return this array builder
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or
+ * infinity
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @see JsonNumber
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with
+ * a {@link JsonValue#TRUE} or {@link JsonValue#FALSE} value
+ * at the specified position.
+ *
+ * @param index the position in the array
+ * @param value the boolean value
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, boolean value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with
+ * a {@link JsonValue#NULL} value at the specified position.
+ *
+ * @param index the position in the array
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder setNull(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonObject} from an object builder at the specified position.
+ *
+ * @param index the position in the array
+ * @param builder the object builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, JsonObjectBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Replaces a value in the array with the specified value as a
+ * {@link JsonArray} from an array builder at the specified position.
+ *
+ * @param index the position in the array
+ * @param builder the array builder
+ * @return this array builder
+ * @throws NullPointerException if the specified builder is null
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder set(int index, JsonArrayBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Remove the value in the array at the specified position.
+ * Shift any subsequent values to the left (subtracts one from their
+ * indices.
+ *
+ * @param index the position in the array
+ * @return this array builder
+ * @throws IndexOutOfBoundsException if the index is out of range
+ * {@code (index < 0 || index >= array size)}
+ *
+ * @since 1.1
+ */
+ default JsonArrayBuilder remove(int index) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the current array.
+ *
+ * @return the current JSON array
+ */
+ JsonArray build();
+
+}
+
diff --git a/api/src/main/java/javax/json/JsonBuilderFactory.java b/api/src/main/java/javax/json/JsonBuilderFactory.java
new file mode 100644
index 0000000..7ffe007
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonBuilderFactory.java
@@ -0,0 +1,125 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.Map;
+
+/**
+ * Factory to create {@link JsonObjectBuilder} and {@link JsonArrayBuilder}
+ * instances. If a factory instance is configured with some configuration,
+ * that would be used to configure the created builder instances.
+ *
+ * <p>
+ * {@code JsonObjectBuilder} and {@code JsonArrayBuilder} can also be created
+ * using {@link Json}'s methods. If multiple builder instances are created,
+ * then creating them using a builder factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(...);
+ * JsonArray value = factory.createArrayBuilder()
+ * .add(factory.createObjectBuilder()
+ * .add("type", "home")
+ * .add("number", "212 555-1234"))
+ * .add(factory.createObjectBuilder()
+ * .add("type", "fax")
+ * .add("number", "646 555-4567"))
+ * .build();
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public interface JsonBuilderFactory {
+
+ /**
+ * Creates a {@code JsonObjectBuilder} instance that is used to build
+ * {@link JsonObject}.
+ *
+ * @return a JSON object builder
+ */
+ JsonObjectBuilder createObjectBuilder();
+
+ /**
+ * Creates a {@code JsonObjectBuilder} instance, initialized with an object
+ *
+ * @param object the initial object in the builder
+ * @return a JSON object builder
+ * @since 1.1
+ */
+ default JsonObjectBuilder createObjectBuilder(JsonObject object) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a {@code JsonArrayBuilder} instance that is used to build
+ * {@link JsonArray}
+ *
+ * @return a JSON array builder
+ */
+ JsonArrayBuilder createArrayBuilder();
+
+ /**
+ * Creates a {@code JsonArrayBuilder} instance, initialized with an array.
+ *
+ * @param array the initial array in the builder
+ * @return a JSON array builder
+ * @since 1.1
+ */
+ default JsonArrayBuilder createArrayBuilder(JsonArray array) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns read-only map of supported provider specific configuration
+ * properties that are used to configure the created JSON builders.
+ * If there are any specified configuration properties that are not
+ * supported by the provider, they won't be part of the returned map.
+ *
+ * @return a map of supported provider specific properties that are used
+ * to configure the builders. The map be empty but not null.
+ */
+ Map<String, ?> getConfigInUse();
+
+}
diff --git a/api/src/main/java/javax/json/JsonException.java b/api/src/main/java/javax/json/JsonException.java
new file mode 100644
index 0000000..b360575
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonException.java
@@ -0,0 +1,79 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * <code>JsonException</code> indicates that some exception happened during
+ * JSON processing.
+ */
+public class JsonException extends RuntimeException {
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public JsonException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this runtime exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public JsonException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
diff --git a/api/src/main/java/javax/json/JsonMergePatch.java b/api/src/main/java/javax/json/JsonMergePatch.java
new file mode 100644
index 0000000..4f79bb0
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonMergePatch.java
@@ -0,0 +1,123 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * This class is an implementation of a JSON Merge Patch as specified in
+ * <a href="http://tools.ietf.org/html/rfc7396">RFC 7396</a>.
+ *
+ * @since 1.1
+ */
+
+public final class JsonMergePatch {
+
+ private JsonMergePatch() {
+ }
+
+ /**
+ * Applies the specified patch to the specified target.
+ * The target is not modified by the patch.
+ *
+ * @param target the {@code JsonValue} to apply the patch operations
+ * @param patch the patch
+ * @return the {@code JsonValue} as the result of applying the patch
+ * operations on the target.
+ */
+ public static JsonValue mergePatch(JsonValue target, JsonValue patch) {
+
+ if (patch.getValueType() != JsonValue.ValueType.OBJECT) {
+ return patch;
+ }
+ if (target.getValueType() != JsonValue.ValueType.OBJECT) {
+ target = JsonValue.EMPTY_JSON_OBJECT;
+ }
+ JsonObject targetJsonObject = target.asJsonObject();
+ JsonObjectBuilder builder =
+ Json.createObjectBuilder(targetJsonObject);
+ patch.asJsonObject().forEach((key, value) -> {
+ if (value == JsonValue.NULL) {
+ if (targetJsonObject.containsKey(key)) {
+ builder.remove(key);
+ }
+ } else if (targetJsonObject.containsKey(key)) {
+ builder.add(key, mergePatch(targetJsonObject.get(key), value));
+ } else {
+ builder.add(key, mergePatch(JsonValue.EMPTY_JSON_OBJECT, value));
+ }
+ });
+ return builder.build();
+ }
+
+ /**
+ * Generate a JSON Merge Patch from the source and target {@code JsonValue}.
+ * @param source the source
+ * @param target the target
+ * @return a JSON Patch which when applied to the source, yields the target
+ */
+ public static JsonValue diff(JsonValue source, JsonValue target) {
+ if (source.getValueType() != JsonValue.ValueType.OBJECT ||
+ target.getValueType() != JsonValue.ValueType.OBJECT) {
+ return target;
+ }
+ JsonObject s = (JsonObject) source;
+ JsonObject t = (JsonObject) target;
+ JsonObjectBuilder builder = Json.createObjectBuilder();
+ // First find members to be replaced or removed
+ s.forEach((key, value) -> {
+ if (t.containsKey(key)) {
+ // key present in both.
+ if (! value.equals(t.get(key))) {
+ // If the values are equal, nop, else get diff for the values
+ builder.add(key, diff(value, t.get(key)));
+ }
+ } else {
+ builder.addNull(key);
+ }
+ });
+ // Then find members to be added
+ t.forEach((key, value) -> {
+ if (! s.containsKey(key))
+ builder.add(key, value);
+ });
+ return builder.build();
+ }
+}
+
diff --git a/api/src/main/java/javax/json/JsonNumber.java b/api/src/main/java/javax/json/JsonNumber.java
new file mode 100644
index 0000000..b453351
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonNumber.java
@@ -0,0 +1,199 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * An immutable JSON number value.
+ *
+ * <p>
+ * Implementations may use a {@link BigDecimal} object to store the numeric
+ * value internally.
+ * The {@code BigDecimal} object can be constructed from the following types:
+ * <code>int</code> {@link BigDecimal#BigDecimal(int)},
+ * <code>long</code> {@link BigDecimal#BigDecimal(long)},
+ * <code>BigInteger</code> {@link BigDecimal#BigDecimal(BigInteger)},
+ * <code>double</code> {@link BigDecimal#valueOf(double)}, and
+ * <code>String</code> {@link BigDecimal#BigDecimal(String)}.
+ * Some of the method semantics in this class are defined using the
+ * {@code BigDecimal} semantics.
+ */
+public interface JsonNumber extends JsonValue {
+
+ /**
+ * Returns true if this JSON number is a integral number. This method
+ * semantics are defined using {@code bigDecimalValue().scale()}. If the
+ * scale is zero, then it is considered integral type. This integral type
+ * information can be used to invoke an appropriate accessor method to
+ * obtain a numeric value as in the following example:
+ *
+ * <pre>
+ * <code>
+ * JsonNumber num = ...
+ * if (num.isIntegral()) {
+ * num.longValue(); // or other methods to get integral value
+ * } else {
+ * num.doubleValue(); // or other methods to get decimal number value
+ * }
+ * </code>
+ * </pre>
+ *
+ * @return true if this number is a integral number, otherwise false
+ */
+ boolean isIntegral();
+
+ /**
+ * Returns this JSON number as an {@code int}. Note that this conversion
+ * can lose information about the overall magnitude and precision of the
+ * number value as well as return a result with the opposite sign.
+ *
+ * @return an {@code int} representation of the JSON number
+ * @see java.math.BigDecimal#intValue()
+ */
+ int intValue();
+
+ /**
+ * Returns this JSON number as an {@code int}.
+ *
+ * @return an {@code int} representation of the JSON number
+ * @throws ArithmeticException if the number has a nonzero fractional
+ * part or if it does not fit in an {@code int}
+ * @see java.math.BigDecimal#intValueExact()
+ */
+ int intValueExact();
+
+ /**
+ * Returns this JSON number as a {@code long}. Note that this conversion
+ * can lose information about the overall magnitude and precision of the
+ * number value as well as return a result with the opposite sign.
+ *
+ * @return a {@code long} representation of the JSON number.
+ * @see java.math.BigDecimal#longValue()
+ */
+ long longValue();
+
+ /**
+ * Returns this JSON number as a {@code long}.
+ *
+ * @return a {@code long} representation of the JSON number
+ * @throws ArithmeticException if the number has a non-zero fractional
+ * part or if it does not fit in a {@code long}
+ * @see java.math.BigDecimal#longValueExact()
+ */
+ long longValueExact();
+
+ /**
+ * Returns this JSON number as a {@link BigInteger} object. This is a
+ * a convenience method for {@code bigDecimalValue().toBigInteger()}.
+ * Note that this conversion can lose information about the overall
+ * magnitude and precision of the number value as well as return a result
+ * with the opposite sign.
+ *
+ * @return a {@code BigInteger} representation of the JSON number.
+ * @see java.math.BigDecimal#toBigInteger()
+ */
+ BigInteger bigIntegerValue();
+
+ /**
+ * Returns this JSON number as a {@link BigInteger} object. This is a
+ * convenience method for {@code bigDecimalValue().toBigIntegerExact()}.
+ *
+ * @return a {@link BigInteger} representation of the JSON number
+ * @throws ArithmeticException if the number has a nonzero fractional part
+ * @see java.math.BigDecimal#toBigIntegerExact()
+ */
+ BigInteger bigIntegerValueExact();
+
+ /**
+ * Returns this JSON number as a {@code double}. This is a
+ * a convenience method for {@code bigDecimalValue().doubleValue()}.
+ * Note that this conversion can lose information about the overall
+ * magnitude and precision of the number value as well as return a result
+ * with the opposite sign.
+ *
+ * @return a {@code double} representation of the JSON number
+ * @see java.math.BigDecimal#doubleValue()
+ */
+ double doubleValue();
+
+ /**
+ * Returns this JSON number as a {@link BigDecimal} object.
+ *
+ * @return a {@link BigDecimal} representation of the JSON number
+ */
+ BigDecimal bigDecimalValue();
+
+ /**
+ * Returns a JSON text representation of the JSON number. The
+ * representation is equivalent to {@link BigDecimal#toString()}.
+ *
+ * @return JSON text representation of the number
+ */
+ @Override
+ String toString();
+
+ /**
+ * Compares the specified object with this {@code JsonNumber} object for
+ * equality. Returns {@code true} if and only if the type of the specified
+ * object is also {@code JsonNumber} and their {@link #bigDecimalValue()}
+ * objects are <i>equal</i>
+ *
+ * @param obj the object to be compared for equality with
+ * this {@code JsonNumber}
+ * @return {@code true} if the specified object is equal to this
+ * {@code JsonNumber}
+ */
+ @Override
+ boolean equals(Object obj);
+
+ /**
+ * Returns the hash code value for this {@code JsonNumber} object. The
+ * hash code of a {@code JsonNumber} object is defined as the hash code of
+ * its {@link #bigDecimalValue()} object.
+ *
+ * @return the hash code value for this {@code JsonNumber} object
+ */
+ @Override
+ int hashCode();
+
+}
diff --git a/api/src/main/java/javax/json/JsonObject.java b/api/src/main/java/javax/json/JsonObject.java
new file mode 100644
index 0000000..5f8ebc3
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonObject.java
@@ -0,0 +1,273 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.Map;
+
+/**
+ * {@code JsonObject} class represents an immutable JSON object value
+ * (an unordered collection of zero or more name/value pairs).
+ * It also provides unmodifiable map view to the JSON object
+ * name/value mappings.
+ *
+ * <p>A JsonObject instance can be created from an input source using
+ * {@link JsonReader#readObject()}. For example:
+ * <pre><code>
+ * JsonReader jsonReader = Json.createReader(...);
+ * JsonObject object = jsonReader.readObject();
+ * jsonReader.close();
+ * </code></pre>
+ *
+ * It can also be built from scratch using a {@link JsonObjectBuilder}.
+ *
+ * <p>For example 1: An empty JSON object can be built as follows:
+ * <pre><code>
+ * JsonObject object = Json.createObjectBuilder().build();
+ * </code></pre>
+ *
+ * For example 2: The following JSON
+ * <pre><code>
+ * {
+ * "firstName": "John", "lastName": "Smith", "age": 25,
+ * "address" : {
+ * "streetAddress": "21 2nd Street",
+ * "city": "New York",
+ * "state": "NY",
+ * "postalCode": "10021"
+ * },
+ * "phoneNumber": [
+ * { "type": "home", "number": "212 555-1234" },
+ * { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * }
+ * </code></pre>
+ * can be built using :
+ * <pre><code>
+ * JsonObject value = Json.createObjectBuilder()
+ * .add("firstName", "John")
+ * .add("lastName", "Smith")
+ * .add("age", 25)
+ * .add("address", Json.createObjectBuilder()
+ * .add("streetAddress", "21 2nd Street")
+ * .add("city", "New York")
+ * .add("state", "NY")
+ * .add("postalCode", "10021"))
+ * .add("phoneNumber", Json.createArrayBuilder()
+ * .add(Json.createObjectBuilder()
+ * .add("type", "home")
+ * .add("number", "212 555-1234"))
+ * .add(Json.createObjectBuilder()
+ * .add("type", "fax")
+ * .add("number", "646 555-4567")))
+ * .build();
+ * </code></pre>
+ *
+ * {@code JsonObject} can be written to JSON as follows:
+ * <pre><code>
+ * JsonWriter writer = ...
+ * JsonObject obj = ...;
+ * writer.writeObject(obj);
+ * </code></pre>
+ *
+ * {@code JsonObject} values can be {@link JsonObject}, {@link JsonArray},
+ * {@link JsonString}, {@link JsonNumber}, {@link JsonValue#TRUE},
+ * {@link JsonValue#FALSE}, {@link JsonValue#NULL}. These values can be
+ * accessed using various accessor methods.
+ *
+ * <p>In the above example 2, "John" can be got using
+ * <pre><code>
+ * String firstName = object.getString("firstName");
+ * </code></pre>
+ *
+ * This map object provides read-only access to the JSON object data,
+ * and attempts to modify the map, whether direct or via its collection
+ * views, result in an {@code UnsupportedOperationException}.
+ *
+ * <p>The map object's iteration ordering is based on the order in which
+ * name/value pairs are added to the corresponding builder or the order
+ * in which name/value pairs appear in the corresponding stream.
+ */
+public interface JsonObject extends JsonStructure, Map<String, JsonValue> {
+
+ /**
+ * Returns the array value to which the specified name is mapped.
+ * This is a convenience method for {@code (JsonArray)get(name)} to
+ * get the value.
+ *
+ * @param name the name whose associated value is to be returned
+ * @return the array value to which the specified name is mapped, or
+ * {@code null} if this object contains no mapping for the name
+ * @throws ClassCastException if the value to which the specified name
+ * is mapped is not assignable to JsonArray type
+ */
+ JsonArray getJsonArray(String name);
+
+ /**
+ * Returns the object value to which the specified name is mapped.
+ * This is a convenience method for {@code (JsonObject)get(name)} to
+ * get the value.
+ *
+ * @param name the name whose associated value is to be returned
+ * @return the object value to which the specified name is mapped, or
+ * {@code null} if this object contains no mapping for the name
+ * @throws ClassCastException if the value to which the specified name
+ * is mapped is not assignable to JsonObject type
+ */
+ JsonObject getJsonObject(String name);
+
+ /**
+ * Returns the number value to which the specified name is mapped.
+ * This is a convenience method for {@code (JsonNumber)get(name)} to
+ * get the value.
+ *
+ * @param name the name whose associated value is to be returned
+ * @return the number value to which the specified name is mapped, or
+ * {@code null} if this object contains no mapping for the name
+ * @throws ClassCastException if the value to which the specified name
+ * is mapped is not assignable to JsonNumber type
+ */
+ JsonNumber getJsonNumber(String name);
+
+ /**
+ * Returns the string value to which the specified name is mapped.
+ * This is a convenience method for {@code (JsonString)get(name)} to
+ * get the value.
+ *
+ * @param name the name whose associated value is to be returned
+ * @return the string value to which the specified name is mapped, or
+ * {@code null} if this object contains no mapping for the name
+ * @throws ClassCastException if the value to which the specified name
+ * is mapped is not assignable to JsonString type
+ */
+ JsonString getJsonString(String name);
+
+ /**
+ * A convenience method for
+ * {@code getJsonString(name).getString()}
+ *
+ * @param name whose associated value is to be returned as String
+ * @return the String value to which the specified name is mapped
+ * @throws NullPointerException if the specified name doesn't have any
+ * mapping
+ * @throws ClassCastException if the value for specified name mapping
+ * is not assignable to JsonString
+ */
+ String getString(String name);
+
+ /**
+ * Returns the string value of the associated {@code JsonString} mapping
+ * for the specified name. If {@code JsonString} is found, then its
+ * {@link javax.json.JsonString#getString()} is returned. Otherwise,
+ * the specified default value is returned.
+ *
+ * @param name whose associated value is to be returned as String
+ * @param defaultValue a default value to be returned
+ * @return the string value of the associated mapping for the name,
+ * or the default value
+ */
+ String getString(String name, String defaultValue);
+
+ /**
+ * A convenience method for
+ * {@code getJsonNumber(name).intValue()}
+ *
+ * @param name whose associated value is to be returned as int
+ * @return the int value to which the specified name is mapped
+ * @throws NullPointerException if the specified name doesn't have any
+ * mapping
+ * @throws ClassCastException if the value for specified name mapping
+ * is not assignable to JsonNumber
+ */
+ int getInt(String name);
+
+ /**
+ * Returns the int value of the associated {@code JsonNumber} mapping
+ * for the specified name. If {@code JsonNumber} is found, then its
+ * {@link javax.json.JsonNumber#intValue()} is returned. Otherwise,
+ * the specified default value is returned.
+ *
+ * @param name whose associated value is to be returned as int
+ * @param defaultValue a default value to be returned
+ * @return the int value of the associated mapping for the name,
+ * or the default value
+ */
+ int getInt(String name, int defaultValue);
+
+ /**
+ * Returns the boolean value of the associated mapping for the specified
+ * name. If the associated mapping is JsonValue.TRUE, then returns true.
+ * If the associated mapping is JsonValue.FALSE, then returns false.
+ *
+ * @param name whose associated value is to be returned as boolean
+ * @return the boolean value to which the specified name is mapped
+ * @throws NullPointerException if the specified name doesn't have any
+ * mapping
+ * @throws ClassCastException if the value for specified name mapping
+ * is not assignable to JsonValue.TRUE or JsonValue.FALSE
+ */
+ boolean getBoolean(String name);
+
+ /**
+ * Returns the boolean value of the associated mapping for the specified
+ * name. If the associated mapping is JsonValue.TRUE, then returns true.
+ * If the associated mapping is JsonValue.FALSE, then returns false.
+ * Otherwise, the specified default value is returned.
+ *
+ * @param name whose associated value is to be returned as int
+ * @param defaultValue a default value to be returned
+ * @return the boolean value of the associated mapping for the name,
+ * or the default value
+ */
+ boolean getBoolean(String name, boolean defaultValue);
+
+ /**
+ * Returns {@code true} if the associated value for the specified name is
+ * {@code JsonValue.NULL}.
+ *
+ * @param name name whose associated value is checked
+ * @return return true if the associated value is {@code JsonValue.NUL},
+ * otherwise false
+ * @throws NullPointerException if the specified name doesn't have any
+ * mapping
+ */
+ boolean isNull(String name);
+
+}
diff --git a/api/src/main/java/javax/json/JsonObjectBuilder.java b/api/src/main/java/javax/json/JsonObjectBuilder.java
new file mode 100644
index 0000000..7e8df0c
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonObjectBuilder.java
@@ -0,0 +1,307 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A builder for creating {@link JsonObject} models from scratch. This
+ * interface initializes an empty JSON object model and provides methods to add
+ * name/value pairs to the object model and to return the resulting object.
+ * The methods in this class can be chained to add multiple name/value pairs
+ * to the object.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create the builder
+ * object. The example code below shows how to build an empty {@code JsonObject}
+ * instance.
+ * <pre>
+ * <code>
+ * JsonObject object = Json.createObjectBuilder().build();
+ * </code>
+ * </pre>
+ *
+ * <p>The class {@link JsonBuilderFactory} also contains methods to create
+ * {@code JsonObjectBuilder} instances. A factory instance can be used to create
+ * multiple builder instances with the same configuration. This the preferred
+ * way to create multiple instances.
+ *
+ * The example code below shows how to build a {@code JsonObject} model that
+ * represents the following JSON object:
+ *
+ * <pre>
+ * <code>
+ * {
+ * "firstName": "John", "lastName": "Smith", "age": 25,
+ * "address" : {
+ * "streetAddress": "21 2nd Street",
+ * "city": "New York",
+ * "state": "NY",
+ * "postalCode": "10021"
+ * },
+ * "phoneNumber": [
+ * { "type": "home", "number": "212 555-1234" },
+ * { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * }
+ * </code>
+ * </pre>
+ *
+ * <p>The code to create the object shown above is the following:
+ *
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(config);
+ * JsonObject value = factory.createObjectBuilder()
+ * .add("firstName", "John")
+ * .add("lastName", "Smith")
+ * .add("age", 25)
+ * .add("address", factory.createObjectBuilder()
+ * .add("streetAddress", "21 2nd Street")
+ * .add("city", "New York")
+ * .add("state", "NY")
+ * .add("postalCode", "10021"))
+ * .add("phoneNumber", factory.createArrayBuilder()
+ * .add(factory.createObjectBuilder()
+ * .add("type", "home")
+ * .add("number", "212 555-1234"))
+ * .add(factory.createObjectBuilder()
+ * .add("type", "fax")
+ * .add("number", "646 555-4567")))
+ * .build();
+ * </code>
+ * </pre>
+ *
+ * <p>This class does <em>not</em> allow <tt>null</tt> to be used as a name or
+ * value while building the JSON object
+ *
+ * @see JsonArrayBuilder
+ */
+public interface JsonObjectBuilder {
+
+ /**
+ * Adds a name/{@code JsonValue} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name or value is null
+ */
+ JsonObjectBuilder add(String name, JsonValue value);
+
+ /**
+ * Adds a name/{@code JsonString} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name or value is null
+ */
+ JsonObjectBuilder add(String name, String value);
+
+ /**
+ * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name or value is null
+ *
+ * @see JsonNumber
+ */
+ JsonObjectBuilder add(String name, BigInteger value);
+
+ /**
+ * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name or value is null
+ *
+ * @see JsonNumber
+ */
+ JsonObjectBuilder add(String name, BigDecimal value);
+
+ /**
+ * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name is null
+ *
+ * @see JsonNumber
+ */
+ JsonObjectBuilder add(String name, int value);
+
+ /**
+ * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name is null
+ *
+ * @see JsonNumber
+ */
+ JsonObjectBuilder add(String name, long value);
+
+ /**
+ * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+ * this object builder. If the object contains a mapping for the specified
+ * name, this method replaces the old value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or
+ * infinity
+ * @throws NullPointerException if the specified name is null
+ *
+ * @see JsonNumber
+ */
+ JsonObjectBuilder add(String name, double value);
+
+ /**
+ * Adds a name/{@code JsonValue#TRUE} or name/{@code JsonValue#FALSE} pair
+ * to the JSON object associated with this object builder. If the object
+ * contains a mapping for the specified name, this method replaces the old
+ * value with the specified value.
+ *
+ * @param name name in the name/value pair
+ * @param value value in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name is null
+ */
+ JsonObjectBuilder add(String name, boolean value);
+
+ /**
+ * Adds a name/{@code JsonValue#NULL} pair to the JSON object associated
+ * with this object builder where the value is {@code null}.
+ * If the object contains a mapping for the specified name, this method
+ * replaces the old value with {@code null}.
+ *
+ * @param name name in the name/value pair
+ * @return this object builder
+ * @throws NullPointerException if the specified name is null
+ */
+ JsonObjectBuilder addNull(String name);
+
+ /**
+ * Adds a name/{@code JsonObject} pair to the JSON object associated
+ * with this object builder. The value {@code JsonObject} is built from the
+ * specified object builder. If the object contains a mapping for the
+ * specified name, this method replaces the old value with the
+ * {@code JsonObject} from the specified object builder.
+ *
+ * @param name name in the name/value pair
+ * @param builder the value is the object associated with this builder
+ * @return this object builder
+ * @throws NullPointerException if the specified name or builder is null
+ */
+ JsonObjectBuilder add(String name, JsonObjectBuilder builder);
+
+ /**
+ * Adds a name/{@code JsonArray} pair to the JSON object associated with
+ * this object builder. The value {@code JsonArray} is built from the
+ * specified array builder. If the object contains a mapping for the
+ * specified name, this method replaces the old value with the
+ * {@code JsonArray} from the specified array builder.
+ *
+ * @param name the name in the name/value pair
+ * @param builder the value is the object array with this builder
+ * @return this object builder
+ * @throws NullPointerException if the specified name or builder is null
+ */
+ JsonObjectBuilder add(String name, JsonArrayBuilder builder);
+
+ /**
+ * Adds all name/value pairs in the JSON object associated with the specified
+ * object builder to the JSON object associated with this object builder.
+ * The newly added name/value pair will replace any existing name/value pair with
+ * the same name.
+ *
+ * @param builder the specified object builder
+ * @return this object builder
+ * @throws NullPointerException if the specified builder is null
+ * @since 1.1
+ */
+ default JsonObjectBuilder addAll(JsonObjectBuilder builder) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Remove the name/value pair from the JSON object associated with this
+ * object builder if it is present.
+ *
+ * @param name the name in the name/value pair to be removed
+ * @return this object builder
+ * @throws NullPointerException if the specified name is null
+ * @since 1.1
+ */
+ default JsonObjectBuilder remove(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the JSON object associated with this object builder.
+ * The iteration order for the {@code JsonObject} is based
+ * on the order in which name/value pairs are added to the object using
+ * this builder.
+ *
+ * @return JSON object that is being built
+ */
+ JsonObject build();
+
+}
diff --git a/api/src/main/java/javax/json/JsonPatch.java b/api/src/main/java/javax/json/JsonPatch.java
new file mode 100644
index 0000000..b74e44f
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonPatch.java
@@ -0,0 +1,333 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import javax.json.JsonValue.ValueType;
+
+/**
+ * This class is an immutable representation of a JSON Patch as specified in
+ * <a href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>.
+ * <p>A {@code JsonPatch} can be instantiated with {@link #JsonPatch(JsonArray)}
+ * by specifying the patch operations in a JSON Patch. Alternately, it
+ * can also be constructed with a {@link JsonPatchBuilder}.
+ * </p>
+ * The following illustrates both approaches.
+ * <p>1. Construct a JsonPatch with a JSON Patch.
+ * <pre>{@code
+ * JsonArray contacts = ... // The target to be patched
+ * JsonArray patch = ... ; // JSON Patch
+ * JsonPatch jsonpatch = new JsonPatch(patch);
+ * JsonArray result = jsonpatch.apply(contacts);
+ * } </pre>
+ * 2. Construct a JsonPatch with JsonPatchBuilder.
+ * <pre>{@code
+ * JsonPatchBuilder builder = new JsonPatchBuilder();
+ * JsonArray result = builder.add("/John/phones/office", "1234-567")
+ * .remove("/Amy/age")
+ * .apply(contacts);
+ * } </pre>
+ *
+ * @since 1.1
+ */
+
+public final class JsonPatch {
+
+ private final JsonArray patch;
+
+ /**
+ * Constructs a JsonPatch
+ * @param patch the JSON Patch
+ */
+ public JsonPatch(JsonArray patch) {
+ this.patch = patch;
+ }
+
+ /**
+ * Compares this {@code JsonPatch} with another object.
+ * @param obj the object to compare this {@code JsonPatch} against
+ * @return true if the given object is a {@code JsonPatch} with the same
+ * reference tokens as this one, false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null || obj.getClass() != JsonPatch.class)
+ return false;
+ return patch.equals(((JsonPatch)obj).patch);
+ }
+
+ /**
+ * Returns the hash code value for this {@code JsonPatch}.
+ *
+ * @return the hash code value for this {@code JsonPatch} object
+ */
+ @Override
+ public int hashCode() {
+ return patch.hashCode();
+ }
+
+ /**
+ * Returns the JSON Patch text
+ * @return the JSON Patch text
+ */
+ @Override
+ public String toString() {
+ return patch.toString();
+ }
+
+ /**
+ * Applies the patch operations to the specified {@code target}.
+ * The target is not modified by the patch.
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ */
+ public JsonStructure apply(JsonStructure target) {
+
+ JsonStructure result = target;
+
+ for (JsonValue operation: patch) {
+ if (operation.getValueType() != ValueType.OBJECT) {
+ throw new JsonException("A JSON patch must be an array of JSON objects.");
+ }
+ result = apply(result, (JsonObject) operation);
+ }
+ return result;
+ }
+
+ /**
+ * Applies the patch operations to the specified {@code target}.
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ */
+ public JsonObject apply(JsonObject target) {
+ return (JsonObject) apply((JsonStructure)target);
+ }
+
+ /**
+ * Applies the patch operations to the specified {@code target}.
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ */
+ public JsonArray apply(JsonArray target) {
+ return (JsonArray) apply((JsonStructure)target);
+ }
+
+ /**
+ * Generates a JSON Patch from the source and target {@code JsonStructure}.
+ * The generated JSON Patch need not be unique.
+ * @param source the source
+ * @param target the target, must be the same type as the source
+ * @return a JSON Patch which when applied to the source, yields the target
+ */
+ public static JsonArray diff(JsonStructure source, JsonStructure target) {
+ return (new DiffGenerator()).diff(source, target);
+ }
+
+ /**
+ * Applies a JSON Patch operation to the target.
+ * @param target the target to apply the operation
+ * @param operation the JSON Patch operation
+ * @return the target after the patch
+ */
+ private JsonStructure apply(JsonStructure target, JsonObject operation) {
+
+ JsonPointer pointer = getPointer(operation, "path");
+ JsonPointer from;
+ switch (operation.getString("op")) {
+ case "add":
+ return pointer.add(target, getValue(operation));
+ case "replace":
+ return pointer.replace(target, getValue(operation));
+ case "remove":
+ return pointer.remove(target);
+ case "copy":
+ from = getPointer(operation, "from");
+ return pointer.add(target, from.getValue(target));
+ case "move":
+ from = getPointer(operation, "from");
+ if (pointer.equals(from)) {
+ // nop
+ return target;
+ }
+ // Check if from is a proper prefix of path
+ if (operation.getString("path").startsWith(operation.getString("from"))){
+ throw new JsonException("The 'from' path of the patch operation "
+ + "'move' is a proper prefix of the 'path' path");
+ }
+ return pointer.add(from.remove(target), from.getValue(target));
+ case "test":
+ if (! getValue(operation).equals(pointer.getValue(target))) {
+ throw new JsonException("The JSON patch operation 'test' failed.");
+ }
+ return target;
+ default:
+ throw new JsonException("Illegal value for the op member of the JSON patch operation: " + operation.getString("op"));
+ }
+ }
+
+ private JsonPointer getPointer(JsonObject operation, String member) {
+ JsonString pointerString = operation.getJsonString(member);
+ if (pointerString == null) {
+ missingMember(operation.getString("op"), member);
+ }
+ return new JsonPointer(pointerString.getString());
+ }
+
+ private JsonValue getValue(JsonObject operation) {
+ JsonValue value = operation.get("value");
+ if (value == null) {
+ missingMember(operation.getString("op"), "value");
+ }
+ return value;
+ }
+
+ private void missingMember(String op, String member) {
+ throw new JsonException(String.format("The JSON Patch operation %s must contain a %s member", op, member));
+ }
+
+ static class DiffGenerator {
+ private JsonPatchBuilder builder;
+
+ JsonArray diff(JsonStructure source, JsonStructure target) {
+ builder = new JsonPatchBuilder();
+ diff("", source, target);
+ return builder.build();
+ }
+
+ private void diff(String path, JsonValue source, JsonValue target) {
+ if (source.equals(target)) {
+ return;
+ }
+ ValueType s = source.getValueType();
+ ValueType t = target.getValueType();
+ if (s == ValueType.OBJECT && t == ValueType.OBJECT) {
+ diffObject(path, (JsonObject) source, (JsonObject) target);
+ } else if (s == ValueType.ARRAY && t == ValueType.ARRAY) {
+ diffArray(path, (JsonArray) source, (JsonArray) target);
+ } else {
+ builder.replace(path, target);
+ }
+ }
+
+ private void diffObject(String path, JsonObject source, JsonObject target) {
+ source.forEach((key, value) -> {
+ if (target.containsKey(key)) {
+ diff(path + '/' + key, value, target.get(key));
+ } else {
+ builder.remove(path + '/' + key);
+ }
+ });
+ target.forEach((key, value) -> {
+ if (! source.containsKey(key)) {
+ builder.add(path + '/' + key, value);
+ }
+ });
+ }
+
+ /*
+ * For array element diff, find the longest common subsequence, per
+ * http://en.wikipedia.org/wiki/Longest_common_subsequence_problem .
+ * We modify the algorithm to generate a replace if possible.
+ */
+ private void diffArray(String path, JsonArray source, JsonArray target) {
+ /* The array c keeps track of length of the subsequence. To avoid
+ * computing the equality of array elements again, we
+ * left shift its value by 1, and use the low order bit to mark
+ * that two items are equal.
+ */
+ int m = source.size();
+ int n = target.size();
+ int [][] c = new int[m+1][n+1];
+ for (int i = 0; i < m+1; i++)
+ c[i][0] = 0;
+ for (int i = 0; i < n+1; i++)
+ c[0][i] = 0;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (source.get(i).equals(target.get(j))) {
+ c[i+1][j+1] = ((c[i][j]) & ~1) + 3;
+ // 3 = (1 << 1) | 1;
+ } else {
+ c[i+1][j+1] = Math.max(c[i+1][j], c[i][j+1]) & ~1;
+ }
+ }
+ }
+
+ int i = m;
+ int j = n;
+ while (i > 0 || j > 0) {
+ if (i == 0) {
+ j--;
+ builder.add(path + '/' + j, target.get(j));
+ } else if (j == 0) {
+ i--;
+ builder.remove(path + '/' + i);
+ } else if ((c[i][j] & 1) == 1) {
+ i--; j--;
+ } else {
+ int f = c[i][j-1] >> 1;
+ int g = c[i-1][j] >> 1;
+ if (f > g) {
+ j--;
+ builder.add(path + '/' + j, target.get(j));
+ } else if (f < g) {
+ i--;
+ builder.remove(path + '/' + i);
+ } else { // f == g) {
+ i--; j--;
+ diff(path + '/' + i, source.get(i), target.get(j));
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/api/src/main/java/javax/json/JsonPatchBuilder.java b/api/src/main/java/javax/json/JsonPatchBuilder.java
new file mode 100644
index 0000000..d042830
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonPatchBuilder.java
@@ -0,0 +1,353 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * A builder for constructing a JSON Patch by adding
+ * JSON Patch operations incrementally.
+ * <p>
+ * The following illustrates the approach.
+ * <pre>
+ * JsonPatchBuilder builder = new JsonPatchBuilder();
+ * JsonArray patch = builder.add("/John/phones/office", "1234-567")
+ * .remove("/Amy/age")
+ * .build();
+ * </pre>
+ * The result is equivalent to the following JSON Patch.
+ * <pre>
+ * [
+ * {"op" = "add", "path" = "/John/phones/office", "value" = "1234-567"},
+ * {"op" = "remove", "path" = "/Amy/age"}
+ * ] </pre>
+ *
+ * @since 1.1
+ */
+
+public final class JsonPatchBuilder {
+
+ private JsonArrayBuilder builder;
+
+ /**
+ * Creates a JsonPatchBuilder, starting with the specified
+ * JSON Patch
+ * @param patch the JSON Patch
+ */
+ public JsonPatchBuilder(JsonArray patch) {
+ builder = Json.createArrayBuilder(patch);
+ }
+
+ /**
+ * Creates JsonPatchBuilder with empty JSON Patch
+ */
+ public JsonPatchBuilder() {
+ builder = Json.createArrayBuilder();
+ }
+
+ /**
+ * A convenience method for {@code new JsonPatch(build()).apply(target) }
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ */
+ public JsonStructure apply(JsonStructure target) {
+ return new JsonPatch(build()).apply(target);
+ }
+
+ /**
+ * A convenience method for {@code build().apply(target) }
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ * @see #apply(JsonStructure)
+ */
+ public JsonObject apply(JsonObject target) {
+ return new JsonPatch(build()).apply(target);
+ }
+
+ /**
+ * A convenience method for {@code build().apply(target) }
+ *
+ * @param target the target to apply the patch operations
+ * @return the transformed target after the patch
+ * @throws JsonException if the supplied JSON Patch is malformed or if
+ * it contains references to non-existing members
+ * @see #apply(JsonStructure)
+ */
+ public JsonArray apply(JsonArray target) {
+ return new JsonPatch(build()).apply(target);
+ }
+
+ /**
+ * Adds an "add" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder add(String path, JsonValue value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds an "add" JSON Patch operation
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder add(String path, String value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds an "add" JSON Patch operation
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder add(String path, int value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds an "add" JSON Patch operation
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder add(String path, boolean value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "remove" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder remove(String path) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "remove")
+ .add("path", path)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "replace" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder replace(String path, JsonValue value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "replace" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder replace(String path, String value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "replace" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder replace(String path, int value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "replace" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder replace(String path, boolean value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "move" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param from the "from" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder move(String path, String from) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "move")
+ .add("path", path)
+ .add("from", from)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "copy" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param from the "from" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder copy(String path, String from) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "copy")
+ .add("path", path)
+ .add("from", from)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "test" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder test(String path, JsonValue value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "test")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "test" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder test(String path, String value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "test")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "test" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder test(String path, int value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "test")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Adds a "test" JSON Patch operation.
+ * @param path the "path" member of the operation
+ * @param value the "value" member of the operation
+ * @return this JsonPatch
+ */
+ public JsonPatchBuilder test(String path, boolean value) {
+ builder.add(Json.createObjectBuilder()
+ .add("op", "test")
+ .add("path", path)
+ .add("value", value)
+ );
+ return this;
+ }
+
+ /**
+ * Returns the patch operations in a JsonArray
+ * @return the patch operations in a JsonArray
+ */
+ public JsonArray build() {
+ return builder.build();
+ }
+}
+
diff --git a/api/src/main/java/javax/json/JsonPointer.java b/api/src/main/java/javax/json/JsonPointer.java
new file mode 100644
index 0000000..07e1418
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonPointer.java
@@ -0,0 +1,380 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.Serializable;
+import java.util.function.BiFunction;
+
+/**
+ * <p>This class is an immutable representation of a JSON Pointer as specified in
+ * <a href="http://tools.ietf.org/html/rfc6901">RFC 6901</a>.
+ * </p>
+ * <p> A JSON Pointer, when applied to a target {@link JsonValue},
+ * defines a reference location in the target.</p>
+ * <p> An empty JSON Pointer string defines a reference to the target itself.</p>
+ * <p> If the JSON Pointer string is non-empty, it must be a sequence
+ * of '/' prefixed tokens, and the target must either be a {@link JsonArray}
+ * or {@link JsonObject}. If the target is a {@code JsonArray}, the pointer
+ * defines a reference to an array element, and the last token specifies the index.
+ * If the target is a {@link JsonObject}, the pointer defines a reference to a
+ * name/value pair, and the last token specifies the name.
+ * </p>
+ * <p> The method {@link JsonPointer#getValue getValue()} returns the referenced value.
+ * The methods {@link JsonPointer#add add()}, {@link JsonPointer#replace replace()},
+ * and {@link JsonPointer#remove remove()} executes the operations specified in
+ * <a href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>. </p>
+ *
+ * @since 1.1
+ */
+
+public final class JsonPointer implements Serializable {
+
+ private static final long serialVersionUID = -8123110179640843141L;
+ private final String[] tokens;
+ private final String jsonPointer;
+
+ /**
+ * Constructs and initializes a JsonPointer.
+ * @param jsonPointer the JSON Pointer string
+ * @throws NullPointerException if {@code jsonPointer} is {@code null}
+ * @throws JsonException if {@code jsonPointer} is not a valid JSON Pointer
+ */
+ public JsonPointer(String jsonPointer) {
+ this.jsonPointer = jsonPointer;
+ tokens = jsonPointer.split("/", -1); // keep the trailing blanks
+ if (! "".equals(tokens[0])) {
+ throw new JsonException("A non-empty JSON pointer must begin with a '/'");
+ }
+ for (int i = 1; i < tokens.length; i++) {
+ String token = tokens[i];
+ StringBuilder reftoken = new StringBuilder();
+ for (int j = 0; j < token.length(); j++) {
+ char ch = token.charAt(j);
+ if (ch == '~' && j < token.length() - 1) {
+ char ch1 = token.charAt(j+1);
+ if (ch1 == '0') {
+ ch = '~'; j++;
+ } else if (ch1 == '1') {
+ ch = '/'; j++;
+ }
+ }
+ reftoken.append(ch);
+ }
+ tokens[i] = reftoken.toString();
+ }
+ }
+
+ /**
+ * Compares this {@code JsonPointer} with another object.
+ * @param obj the object to compare this {@code JsonPointer} against
+ * @return true if the given object is a {@code JsonPointer} with the same
+ * reference tokens as this one, false otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null || obj.getClass() != JsonPointer.class)
+ return false;
+ return jsonPointer.equals(((JsonPointer)obj).jsonPointer);
+ }
+
+ /**
+ * Returns the hash code value for this {@code JsonPointer} object.
+ * The hash code of this object is defined by the hash codes of it's reference tokens.
+ *
+ * @return the hash code value for this {@code JsonPointer} object
+ */
+ @Override
+ public int hashCode() {
+ return jsonPointer.hashCode();
+ }
+
+ /**
+ * Returns the value at the referenced location in the specified {@code target}
+ *
+ * @param target the target referenced by this {@code JsonPointer}
+ * @return the referenced value in the target.
+ * @throws NullPointerException if {@code target} is null
+ * @throws JsonException if the referenced value does not exist
+ */
+ public JsonValue getValue(JsonStructure target) {
+ NodeReference[] refs = getReferences(target);
+ return refs[0].get();
+ }
+
+ /**
+ * Adds or replaces a value at the referenced location in the specified
+ * {@code target} with the specified {@code value}.
+ * <ol>
+ * <li>If the reference is the target (empty JSON Pointer string),
+ * the specified {@code value}, which must be the same type as
+ * specified {@code target}, is returned.</li>
+ * <li>If the reference is an array element, the specified {@code value} is inserted
+ * into the array, at the referenced index. The value currently at that location, and
+ * any subsequent values, are shifted to the right (adds one to the indices).
+ * Index starts with 0. If the reference is specified with a "-", or if the
+ * index is equal to the size of the array, the value is appended to the array.</li>
+ * <li>If the reference is a name/value pair of a {@code JsonObject}, and the
+ * referenced value exists, the value is replaced by the specified {@code value}.
+ * If the value does not exist, a new name/value pair is added to the object.</li>
+ * </ol>
+ *
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be added
+ * @return the transformed {@code target} after the value is added.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the reference is an array element and
+ * the index is out of range ({@code index < 0 || index > array size}),
+ * or if the pointer contains references to non-existing objects or arrays.
+ */
+ public JsonStructure add(JsonStructure target, JsonValue value) {
+ return execute(NodeReference::add, target, value);
+ }
+
+ /**
+ * Replaces the value at the referenced location in the specified
+ * {@code target} with the specified {@code value}.
+ *
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be stored at the referenced location
+ * @return the transformed {@code target} after the value is replaced.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ */
+ public JsonStructure replace(JsonStructure target, JsonValue value) {
+ return execute(NodeReference::replace, target, value);
+ }
+
+ /**
+ * Removes the value at the reference location in the specified {@code target}
+ *
+ * @param target the target referenced by this {@code JsonPointer}
+ * @return the transformed {@code target} after the value is removed.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ */
+ public JsonStructure remove(JsonStructure target) {
+ return execute((r,v)->r.remove(), target, null);
+ }
+
+ /**
+ * Adds or replaces a value at the referenced location in the specified
+ * {@code target} with the specified {@code value}.
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be added
+ * @return the transformed {@code target} after the value is added.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the reference is an array element and
+ * the index is out of range ({@code index < 0 || index > array size}),
+ * or if the pointer contains references to non-existing objects or arrays.
+ * @see #add(JsonStructure, JsonValue)
+ */
+ public JsonObject add(JsonObject target, JsonValue value) {
+ return (JsonObject) add((JsonStructure) target, value);
+ }
+
+ /**
+ * Adds or replaces a value at the referenced location in the specified
+ * {@code target} with the specified {@code value}.
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be added
+ * @return the transformed {@code target} after the value is added.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the reference is an array element and
+ * the index is out of range ({@code index < 0 || index > array size}),
+ * or if the pointer contains references to non-existing objects or arrays.
+ * @see #add(JsonStructure, JsonValue)
+ */
+ public JsonArray add(JsonArray target, JsonValue value) {
+ return (JsonArray) add((JsonStructure) target, value);
+ }
+
+ /**
+ * Replaces the value at the referenced location in the specified
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be stored at the referenced location
+ * @return the transformed {@code target} after the value is replaced.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ * {@code target} with the specified {@code value}.
+ * @see #replace(JsonStructure, JsonValue)
+ */
+ public JsonObject replace(JsonObject target, JsonValue value) {
+ return (JsonObject) replace((JsonStructure) target, value);
+ }
+
+ /**
+ * Replaces the value at the referenced location in the specified
+ * @param target the target referenced by this {@code JsonPointer}
+ * @param value the value to be stored at the referenced location
+ * @return the transformed {@code target} after the value is replaced.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ * {@code target} with the specified {@code value}.
+ * @see #replace(JsonStructure, JsonValue)
+ */
+ public JsonArray replace(JsonArray target, JsonValue value) {
+ return (JsonArray) replace((JsonStructure) target, value);
+ }
+
+ /**
+ * Removes the value at the reference location in the specified {@code target}
+ * @param target the target referenced by this {@code JsonPointer}
+ * @return the transformed {@code target} after the value is removed.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ * @see #remove(JsonStructure)
+ */
+ public JsonObject remove(JsonObject target) {
+ return (JsonObject) remove((JsonStructure) target);
+ }
+
+ /**
+ * Removes the value at the reference location in the specified {@code target}
+ * @param target the target referenced by this {@code JsonPointer}
+ * @return the transformed {@code target} after the value is removed.
+ * @throws NullPointerException if {@code target} is {@code null}
+ * @throws JsonException if the referenced value does not exist,
+ * or if the reference is the target.
+ * @see #remove(JsonStructure)
+ */
+ public JsonArray remove(JsonArray target) {
+ return (JsonArray) remove((JsonStructure) target);
+ }
+
+ /**
+ * Executes the operation
+ * @param op a {code BiFunction} used to specify the operation to execute on
+ * the leaf node of the Json Pointer
+ * @param target the target JsonStructure for this JsonPointer
+ * @param value the JsonValue for add and replace, can be null for getvalue and remove
+ */
+ private JsonStructure execute(BiFunction<NodeReference, JsonValue, JsonStructure> op,
+ JsonStructure target, JsonValue value) {
+
+ NodeReference[] refs = getReferences(target);
+ JsonStructure result = op.apply(refs[0], value);
+ for (int i = 1; i < refs.length; i++) {
+ result = refs[i].replace(result);
+ }
+ return result;
+ }
+
+ /**
+ * Computes the {@code NodeReference}s for each node on the path of
+ * the JSON Pointer, in reverse order, starting from the leaf node
+ */
+ private NodeReference[] getReferences(JsonStructure target) {
+ NodeReference[] references;
+ // First check if this is a reference to a JSON value tree
+ if (tokens.length == 1) {
+ references = new NodeReference[1];
+ references[0] = NodeReference.of(target);
+ return references;
+ }
+
+ references = new NodeReference[tokens.length-1];
+ JsonValue value = target;
+ int s = tokens.length;
+ for (int i = 1; i < s; i++) {
+ // Start with index 1, skipping the "" token
+ switch (value.getValueType()) {
+ case OBJECT:
+ JsonObject object = (JsonObject) value;
+ references[s-i-1] = NodeReference.of(object, tokens[i]);
+ if (i < s-1) {
+ value = object.get(tokens[i]);
+ if (value == null) {
+ // Except for the last name, the mapping must exist
+ throw new JsonException("The JSON object " + object + " contains no mapping "
+ + " for the name " + tokens[i]);
+ }
+ }
+ break;
+ case ARRAY:
+ int index = getIndex(tokens[i]);
+ JsonArray array = (JsonArray) value;
+ references[s-i-1] = NodeReference.of(array, index);
+ if (i < s-1 && index != -1) {
+ // The last array index in the path can have index value of -1
+ // ("-" in the JSON pointer)
+ value = array.get(index);
+ }
+ break;
+ default:
+ throw new JsonException("The reference value in a Json pointer must be a Json object or a Json array");
+ }
+ }
+ return references;
+ }
+
+ /**
+ * Computes the array index
+ * @param token the input string token
+ * @return the array index. -1 if the token is "-"
+ * @throws JsonException if the string token is not in correct format
+ */
+ static private int getIndex(String token) {
+ if (token == null || token.length() == 0) {
+ throw new JsonException("Array index format error");
+ }
+ if (token.equals("-")) {
+ return -1;
+ }
+ if (token.equals("0")) {
+ return 0;
+ }
+ if (token.charAt(0) == '+' || token.charAt(0) == '-') {
+ throw new JsonException("Array index format error");
+ }
+ try {
+ return Integer.parseInt(token);
+ } catch (NumberFormatException ex) {
+ throw new JsonException("Illegal integer format ", ex);
+ }
+ }
+}
diff --git a/api/src/main/java/javax/json/JsonReader.java b/api/src/main/java/javax/json/JsonReader.java
new file mode 100644
index 0000000..5370e64
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonReader.java
@@ -0,0 +1,157 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.Closeable;
+
+/**
+ * Reads a JSON {@link JsonObject object} or an {@link JsonArray array}
+ * structure from an input source.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create readers from
+ * input sources ({@link java.io.InputStream} and {@link java.io.Reader}).
+ *
+ * <p>
+ * The following example demonstrates how to read an empty JSON array from
+ * a string:
+ * <pre>
+ * <code>
+ * JsonReader jsonReader = Json.createReader(new StringReader("[]"));
+ * JsonArray array = jsonReader.readArray();
+ * jsonReader.close();
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonReaderFactory} also contains methods to create
+ * {@code JsonReader} instances. A factory instance can be used to create
+ * multiple reader instances with the same configuration. This the preferred
+ * way to create multiple instances. A sample usage is shown in the following
+ * example:
+ * <pre>
+ * <code>
+ * JsonReaderFactory factory = Json.createReaderFactory(config);
+ * JsonReader reader1 = factory.createReader(...);
+ * JsonReader reader2 = factory.createReader(...);
+ * </code>
+ * </pre>
+ */
+public interface JsonReader extends /*Auto*/Closeable {
+
+ /**
+ * Returns a JSON array or object that is represented in
+ * the input source. This method needs to be called
+ * only once for a reader instance.
+ *
+ * @return a JSON object or array
+ * @throws JsonException if a JSON object or array cannot
+ * be created due to i/o error (IOException would be
+ * cause of JsonException)
+ * @throws javax.json.stream.JsonParsingException if a JSON object or array
+ * cannot be created due to incorrect representation
+ * @throws IllegalStateException if read, readObject, readArray,
+ * readValue or close method is already called
+ */
+ JsonStructure read();
+
+ /**
+ * Returns a JSON object that is represented in
+ * the input source. This method needs to be called
+ * only once for a reader instance.
+ *
+ * @return a JSON object
+ * @throws JsonException if a JSON object cannot
+ * be created due to i/o error (IOException would be
+ * cause of JsonException)
+ * @throws javax.json.stream.JsonParsingException if a JSON object cannot
+ * be created due to incorrect representation
+ * @throws IllegalStateException if read, readObject, readArray,
+ * readValue or close method is already called
+ */
+ JsonObject readObject();
+
+ /**
+ * Returns a JSON array that is represented in
+ * the input source. This method needs to be called
+ * only once for a reader instance.
+ *
+ * @return a JSON array
+ * @throws JsonException if a JSON array cannot
+ * be created due to i/o error (IOException would be
+ * cause of JsonException)
+ * @throws javax.json.stream.JsonParsingException if a JSON array cannot
+ * be created due to incorrect representation
+ * @throws IllegalStateException if read, readObject, readArray,
+ * readValue or close method is already called
+ */
+ JsonArray readArray();
+
+ /**
+ * Returns a JSON value that is represented in
+ * the input source. This method needs to be called
+ * only once for a reader instance.
+ *
+ * @return a JSON value
+ * @throws JsonException if a JSON value
+ * be created due to i/o error (IOException would be
+ * cause of JsonException)
+ * @throws javax.json.stream.JsonParsingException if a JSON value
+ * cannot be created due to incorrect representation
+ * @throws IllegalStateException if read, readObject, readArray,
+ * readValue or close method is already called
+ *
+ * @since 1.1
+ */
+ default JsonValue readValue() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Closes this reader and frees any resources associated with the
+ * reader. This method closes the underlying input source.
+ *
+ * @throws JsonException if an i/o error occurs (IOException would be
+ * cause of JsonException)
+ */
+ @Override
+ void close();
+
+}
diff --git a/api/src/main/java/javax/json/JsonReaderFactory.java b/api/src/main/java/javax/json/JsonReaderFactory.java
new file mode 100644
index 0000000..5ec216e
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonReaderFactory.java
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link javax.json.JsonReader} instances. If a factory
+ * instance is configured with some configuration, that would be
+ * used to configure the created reader instances.
+ *
+ * <p>
+ * {@link javax.json.JsonReader} can also be created using {@link Json}'s
+ * {@code createReader} methods. If multiple reader instances are created,
+ * then creating them using a reader factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonReaderFactory factory = Json.createReaderFactory(...);
+ * JsonReader reader1 = factory.createReader(...);
+ * JsonReader reader2 = factory.createReader(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public interface JsonReaderFactory {
+
+ /**
+ * Creates a JSON reader from a character stream. The reader is configured
+ * with the factory configuration.
+ *
+ * @param reader a reader from which JSON is to be read
+ * @return a JSON reader
+ */
+ JsonReader createReader(Reader reader);
+
+ /**
+ * Creates a JSON reader from a byte stream. The character encoding of
+ * the stream is determined as described in
+ * <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ * The reader is configured with the factory configuration.
+ *
+ * @param in a byte stream from which JSON is to be read
+ * @return a JSON reader
+ */
+ JsonReader createReader(InputStream in);
+
+ /**
+ * Creates a JSON reader from a byte stream. The bytes of the stream
+ * are decoded to characters using the specified charset. The reader is
+ * configured with the factory configuration.
+ *
+ * @param in a byte stream from which JSON is to be read
+ * @param charset a charset
+ * @return a JSON reader
+ */
+ JsonReader createReader(InputStream in, Charset charset);
+
+ /**
+ * Returns read-only map of supported provider specific configuration
+ * properties that are used to configure the created JSON readers.
+ * If there are any specified configuration properties that are not
+ * supported by the provider, they won't be part of the returned map.
+ *
+ * @return a map of supported provider specific properties that are used
+ * to configure the readers. The map be empty but not null.
+ */
+ Map<String, ?> getConfigInUse();
+
+}
diff --git a/api/src/main/java/javax/json/JsonString.java b/api/src/main/java/javax/json/JsonString.java
new file mode 100644
index 0000000..2dcb24d
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonString.java
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * An immutable JSON string value.
+ */
+public interface JsonString extends JsonValue {
+
+ /**
+ * Returns the JSON string value.
+ *
+ * @return a JSON string value
+ */
+ String getString();
+
+
+ /**
+ * Returns the char sequence for the JSON String value
+ *
+ * @return a char sequence for the JSON String value
+ */
+ CharSequence getChars();
+
+ /**
+ * Compares the specified object with this {@code JsonString} for equality.
+ * Returns {@code true} if and only if the specified object is also a
+ * {@code JsonString}, and their {@link #getString()} objects are
+ * <i>equal</i>.
+ *
+ * @param obj the object to be compared for equality with this
+ * {@code JsonString}
+ * @return {@code true} if the specified object is equal to this
+ * {@code JsonString}
+ */
+ @Override
+ boolean equals(Object obj);
+
+ /**
+ * Returns the hash code value for this {@code JsonString} object.
+ * The hash code of a {@code JsonString} object is defined to be its
+ * {@link #getString()} object's hash code.
+ *
+ * @return the hash code value for this {@code JsonString} object
+ */
+ @Override
+ int hashCode();
+
+}
diff --git a/api/src/main/java/javax/json/JsonStructure.java b/api/src/main/java/javax/json/JsonStructure.java
new file mode 100644
index 0000000..97c15dd
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonStructure.java
@@ -0,0 +1,61 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * Super type for the two structured types in JSON ({@link JsonObject object}s
+ * and {@link JsonArray array}s).
+ */
+public interface JsonStructure extends JsonValue {
+
+ /**
+ * Get the value referenced by the provided JSON Pointer in the JsonStructure
+ * @param jsonPointer the JSON Pointer
+ * @return the {@code JsonValue} at the referenced location
+ * @throws JsonException if the JSON Pointer is malformed, or if it references
+ * a non-existing member or value.
+ *
+ * @since 1.1
+ */
+ default public JsonValue getValue(String jsonPointer) {
+ return new JsonPointer(jsonPointer).getValue(this);
+ }
+}
diff --git a/api/src/main/java/javax/json/JsonUtil.java b/api/src/main/java/javax/json/JsonUtil.java
new file mode 100644
index 0000000..7e71b15
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonUtil.java
@@ -0,0 +1,95 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package javax.json;
+
+import javax.json.stream.JsonParsingException;
+import java.io.StringReader;
+
+/**
+ * A utility class
+ *
+ * @since 1.1
+ */
+public final class JsonUtil {
+
+ private JsonUtil() {
+ }
+
+ /**
+ * Reads the input JSON text and returns a JsonValue.
+ * <p>For convenience, single quotes as well as double quotes
+ * are allowed to delimit JSON strings. If single quotes are
+ * used, any quotes, single or double, in the JSON string must be
+ * escaped (prepend with a '\').
+ *
+ * @param jsonString the input JSON data
+ * @return the object model for {@code jsonString}
+ * @throws JsonParsingException if the input is not legal JSON text
+ */
+ public static JsonValue toJson(String jsonString) {
+ StringBuilder builder = new StringBuilder();
+ boolean single_context = false;
+ for (int i = 0; i < jsonString.length(); i++) {
+ char ch = jsonString.charAt(i);
+ if (ch == '\\') {
+ i = i + 1;
+ if (i < jsonString.length()) {
+ ch = jsonString.charAt(i);
+ if (!(single_context && ch == '\'')) {
+ // unescape ' inside single quotes
+ builder.append('\\');
+ }
+ }
+ } else if (ch == '\'') {
+ // Turn ' into ", for proper JSON string
+ ch = '"';
+ single_context = ! single_context;
+ }
+ builder.append(ch);
+ }
+
+ JsonReader reader = Json.createReader(
+ new StringReader(builder.toString()));
+ JsonValue value = reader.readValue();
+ reader.close();
+ return value;
+ }
+}
+
diff --git a/api/src/main/java/javax/json/JsonValue.java b/api/src/main/java/javax/json/JsonValue.java
new file mode 100644
index 0000000..cbcd8f4
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonValue.java
@@ -0,0 +1,303 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * <code>JsonValue</code> represents an immutable JSON value.
+ *
+ *
+ * <p>A JSON value is one of the following:
+ * an object ({@link JsonObject}), an array ({@link JsonArray}),
+ * a number ({@link JsonNumber}), a string ({@link JsonString}),
+ * {@code true} ({@link JsonValue#TRUE JsonValue.TRUE}), {@code false}
+ * ({@link JsonValue#FALSE JsonValue.FALSE}),
+ * or {@code null} ({@link JsonValue#NULL JsonValue.NULL}).
+ */
+public interface JsonValue {
+
+ /**
+ * The empty JSON object.
+ *
+ * @since 1.1
+ */
+ static final JsonObject EMPTY_JSON_OBJECT = Json.createObjectBuilder().build();
+
+ /**
+ * The empty JSON array.
+ *
+ * @since 1.1
+ */
+ static final JsonArray EMPTY_JSON_ARRAY = Json.createArrayBuilder().build();
+
+ /**
+ * Indicates the type of a {@link JsonValue} object.
+ */
+ enum ValueType {
+ /**
+ * JSON array.
+ */
+ ARRAY,
+
+ /**
+ * JSON object.
+ */
+ OBJECT,
+
+ /**
+ * JSON string.
+ */
+ STRING,
+
+ /**
+ * JSON number.
+ */
+ NUMBER,
+
+ /**
+ * JSON true.
+ */
+ TRUE,
+
+ /**
+ * JSON false.
+ */
+ FALSE,
+
+ /**
+ * JSON null.
+ */
+ NULL
+ }
+
+ /**
+ * JSON null value.
+ */
+ static final JsonValue NULL = new JsonValue() {
+ @Override
+ public ValueType getValueType() {
+ return ValueType.NULL;
+ }
+
+ /**
+ * Compares the specified object with this {@link JsonValue#NULL}
+ * object for equality. Returns {@code true} if and only if the
+ * specified object is also a {@code JsonValue}, and their
+ * {@link #getValueType()} objects are <i>equal</i>.
+ *
+ * @param obj the object to be compared for equality with this
+ * {@code JsonValue}
+ * @return {@code true} if the specified object is equal to this
+ * {@code JsonValue}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj){
+ return true;
+ }
+ if (obj instanceof JsonValue) {
+ return getValueType().equals(((JsonValue)obj).getValueType());
+ }
+ return false;
+ }
+
+ /**
+ * Returns the hash code value for this {@link JsonValue#NULL} object.
+ * The hash code of the {@link JsonValue#NULL} object is defined to be
+ * its {@link #getValueType()} object's hash code.
+ *
+ * @return the hash code value for this JsonString object
+ */
+ @Override
+ public int hashCode() {
+ return ValueType.NULL.hashCode();
+ }
+
+ /**
+ * Returns a "null" string.
+ *
+ * @return "null"
+ */
+ @Override
+ public String toString() {
+ return "null";
+ }
+ };
+
+ /**
+ * JSON true value.
+ */
+ static final JsonValue TRUE = new JsonValue() {
+ @Override
+ public ValueType getValueType() {
+ return ValueType.TRUE;
+ }
+
+ /**
+ * Compares the specified object with this {@link JsonValue#TRUE}
+ * object for equality. Returns {@code true} if and only if the
+ * specified object is also a JsonValue, and their
+ * {@link #getValueType()} objects are <i>equal</i>.
+ *
+ * @param obj the object to be compared for equality with this JsonValue.
+ * @return {@code true} if the specified object is equal to this JsonValue.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj){
+ return true;
+ }
+ if (obj instanceof JsonValue) {
+ return getValueType().equals(((JsonValue)obj).getValueType());
+ }
+ return false;
+ }
+
+ /**
+ * Returns the hash code value for this {@link JsonValue#TRUE} object.
+ * The hash code of the {@link JsonValue#TRUE} object is defined to be
+ * its {@link #getValueType()} object's hash code.
+ *
+ * @return the hash code value for this JsonString object
+ */
+ @Override
+ public int hashCode() {
+ return ValueType.TRUE.hashCode();
+ }
+
+ /**
+ * Returns "true" string
+ *
+ * @return "true"
+ */
+ @Override
+ public String toString() {
+ return "true";
+ }
+ };
+
+ /**
+ * JSON false value
+ */
+ static final JsonValue FALSE = new JsonValue() {
+ @Override
+ public ValueType getValueType() {
+ return ValueType.FALSE;
+ }
+
+ /**
+ * Compares the specified object with this {@link JsonValue#FALSE}
+ * object for equality. Returns {@code true} if and only if the
+ * specified object is also a JsonValue, and their
+ * {@link #getValueType()} objects are <i>equal</i>.
+ *
+ * @param obj the object to be compared for equality with this JsonValue
+ * @return {@code true} if the specified object is equal to this JsonValue
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj){
+ return true;
+ }
+ if (obj instanceof JsonValue) {
+ return getValueType().equals(((JsonValue)obj).getValueType());
+ }
+ return false;
+ }
+
+ /**
+ * Returns the hash code value for this {@link JsonValue#FALSE} object.
+ * The hash code of the {@link JsonValue#FALSE} object is defined to be
+ * its {@link #getValueType()} object's hash code.
+ *
+ * @return the hash code value for this JsonString object
+ */
+ @Override
+ public int hashCode() {
+ return ValueType.FALSE.hashCode();
+ }
+
+ /**
+ * Returns "false" string
+ *
+ * @return "false"
+ */
+ @Override
+ public String toString() {
+ return "false";
+ }
+ };
+
+ /**
+ * Returns the value type of this JSON value.
+ *
+ * @return JSON value type
+ */
+ ValueType getValueType();
+
+ /**
+ * Return the JsonValue as a JsonObject
+ *
+ * @return the JsonValue as a JsonObject
+ * @throws ClassCastException if the JsonValue is not a JsonObject
+ */
+ default JsonObject asJsonObject() {
+ return JsonObject.class.cast(this);
+ }
+
+ /**
+ * Return the JsonValue as a JsonArray
+ *
+ * @return the JsonValue as a JsonArray
+ * @throws ClassCastException if the JsonValue is not a JsonArray
+ */
+ default JsonArray asJsonArray() {
+ return JsonArray.class.cast(this);
+ }
+
+ /**
+ * Returns JSON text for this JSON value.
+ *
+ * @return JSON text
+ */
+ @Override
+ String toString();
+
+}
diff --git a/api/src/main/java/javax/json/JsonWriter.java b/api/src/main/java/javax/json/JsonWriter.java
new file mode 100644
index 0000000..8ddb200
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonWriter.java
@@ -0,0 +1,147 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.Closeable;
+
+/**
+ * Writes a JSON {@link JsonObject object} or {@link JsonArray array} structure
+ * to an output source.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create writers from
+ * output sources ({@link java.io.OutputStream} and {@link java.io.Writer}).
+ *
+ * <p>
+ * The following example demonstrates how write an empty JSON object:
+ * <pre>
+ * <code>
+ * JsonWriter jsonWriter = Json.createWriter(...);
+ * jsonWriter.writeObject(Json.createObjectBuilder().build());
+ * jsonWriter.close();
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonWriterFactory} also contains methods to create
+ * {@code JsonWriter} instances. A factory instance can be used to create
+ * multiple writer instances with the same configuration. This the preferred
+ * way to create multiple instances. A sample usage is shown in the following
+ * example:
+ * <pre>
+ * <code>
+ * JsonWriterFactory factory = Json.createWriterFactory(config);
+ * JsonWriter writer1 = factory.createWriter(...);
+ * JsonWriter writer2 = factory.createWriter(...);
+ * </code>
+ * </pre>
+ */
+public interface JsonWriter extends /*Auto*/Closeable {
+
+ /**
+ * Writes the specified JSON {@link JsonArray array} to the output
+ * source. This method needs to be called only once for a writer instance.
+ *
+ * @param array JSON array that is to be written to the output source
+ * @throws JsonException if the specified JSON object cannot be
+ * written due to i/o error (IOException would be cause of
+ * JsonException)
+ * @throws IllegalStateException if writeArray, writeObject, write or close
+ * method is already called
+ */
+ void writeArray(JsonArray array);
+
+ /**
+ * Writes the specified JSON {@link JsonObject object} to the output
+ * source. This method needs to be called only once for a writer instance.
+ *
+ * @param object JSON object that is to be written to the output source
+ * @throws JsonException if the specified JSON object cannot be
+ * written due to i/o error (IOException would be cause of JsonException)
+ * @throws IllegalStateException if writeArray, writeObject, write or close
+ * method is already called
+ */
+ void writeObject(JsonObject object);
+
+ /**
+ * Writes the specified JSON {@link JsonObject object} or
+ * {@link JsonArray array} to the output source. This method needs
+ * to be called only once for a writer instance.
+ *
+ * @param value JSON array or object that is to be written to the output
+ * source
+ * @throws JsonException if the specified JSON object cannot be
+ * written due to i/o error (IOException would be cause of
+ * JsonException)
+ * @throws IllegalStateException if writeArray, writeObject, write
+ * or close method is already called
+ */
+ void write(JsonStructure value);
+
+ /**
+ * Closes this JSON writer and frees any resources associated with the
+ * writer. This method closes the underlying output source.
+ *
+ * @throws JsonException if an i/o error occurs (IOException would be
+ * cause of JsonException)
+ */
+
+ /**
+ * Writes the specified {@link JsonValue} to the output source.
+ * method needs to be called only once for a write instance.
+ *
+ * @param value a {@code JsonValue} to be written to the output
+ * source
+ * @throws JsonException if the specified JSON object cannot be
+ * written due to i/o error (IOException would be cause of
+ * JsonException)
+ * @throws IllegalStateException if writeArray, writeObject, write
+ * or close method is already called
+ *
+ * @since 1.1
+ */
+ default void write(JsonValue value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ void close();
+
+}
diff --git a/api/src/main/java/javax/json/JsonWriterFactory.java b/api/src/main/java/javax/json/JsonWriterFactory.java
new file mode 100644
index 0000000..c4c36e7
--- /dev/null
+++ b/api/src/main/java/javax/json/JsonWriterFactory.java
@@ -0,0 +1,118 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link javax.json.JsonWriter} instances. If a factory
+ * instance is configured with some configuration, that would be
+ * used to configure the created writer instances.
+ *
+ * <p>
+ * {@link javax.json.JsonWriter} can also be created using {@link Json}'s
+ * {@code createWriter} methods. If multiple writer instances are created,
+ * then creating them using a writer factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonWriterFactory factory = Json.createWriterFactory(...);
+ * JsonWriter writer1 = factory.createWriter(...);
+ * JsonWriter writer2 = factory.createWriter(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public interface JsonWriterFactory {
+
+ /**
+ * Creates a JSON writer to write a JSON {@link JsonObject object} or
+ * {@link JsonArray array} structure to the specified character stream.
+ * The writer is configured with the factory configuration.
+ *
+ * @param writer to which JSON object or array is written
+ * @return a JSON writer
+ */
+ JsonWriter createWriter(Writer writer);
+
+ /**
+ * Creates a JSON writer to write a JSON {@link JsonObject object} or
+ * {@link JsonArray array} structure to the specified byte stream.
+ * Characters written to the stream are encoded into bytes using UTF-8
+ * encoding. The writer is configured with the factory configuration.
+ *
+ * @param out to which JSON object or array is written
+ * @return a JSON writer
+ */
+ JsonWriter createWriter(OutputStream out);
+
+ /**
+ * Creates a JSON writer to write a JSON {@link JsonObject object} or
+ * {@link JsonArray array} structure to the specified byte stream.
+ * Characters written to the stream are encoded into bytes using the
+ * specified charset. The writer is configured with the factory
+ * configuration.
+ *
+ * @param out to which JSON object or array is written
+ * @param charset a charset
+ * @return a JSON writer
+ */
+ JsonWriter createWriter(OutputStream out, Charset charset);
+
+ /**
+ * Returns read-only map of supported provider specific configuration
+ * properties that are used to configure the created JSON writer objects.
+ * If there are any specified configuration properties that are not
+ * supported by the provider, they won't be part of the returned map.
+ *
+ * @return a map of supported provider specific properties that are used
+ * to configure the created writers. The map may be empty but not null.
+ */
+ Map<String, ?> getConfigInUse();
+
+}
diff --git a/api/src/main/java/javax/json/NodeReference.java b/api/src/main/java/javax/json/NodeReference.java
new file mode 100644
index 0000000..b1246d0
--- /dev/null
+++ b/api/src/main/java/javax/json/NodeReference.java
@@ -0,0 +1,276 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+package javax.json;
+
+/**
+ * This class is a helper class for JsonPointer implementation,
+ * and is not part of the API.
+ *
+ * This class encapsulates a reference to a JSON node.
+ * There are three types of references.
+ * <ol><li>a reference to the root of a JSON tree.</li>
+ * <li>a reference to a name/value (possibly non-existing) pair of a JSON object, identified by a name.</li>
+ * <li>a reference to a member value of a JSON array, identified by an index.</li>
+ * </ol>
+ * Static factory methods are provided for creating these references.
+ *
+ * <p>A referenced value can be retrieved or replaced.
+ * The value of a JSON object or JSON array can be
+ * removed. A new value can be added to a JSON object or
+ * inserted into a JSON array</p>
+ *
+ * <p>Since a {@code JsonObject} or {@code JsonArray} is immutable, these operations
+ * must not modify the referenced JSON object or array. The methods {@link #add},
+ * {@link #replace}, and {@link #remove} returns a new
+ * JSON object or array after the execution of the operation.</p>
+ */
+abstract class NodeReference {
+
+ /**
+ * Get the value at the referenced location.
+ *
+ * @return the JSON value referenced
+ * @throws JsonException if the referenced value does not exist
+ */
+ abstract public JsonValue get();
+
+ /**
+ * Add or replace a value at the referenced location.
+ * If the reference is the root of a JSON tree, the added value must be
+ * a JSON object or array, which becomes the referenced JSON value.
+ * If the reference is an index of a JSON array, the value is inserted
+ * into the array at the index. If the index is -1, the value is
+ * appended to the array.
+ * If the reference is a name of a JSON object, the name/value pair is added
+ * to the object, replacing any pair with the same name.
+ *
+ * @param value the value to be added
+ * @return the JsonStructure after the operation
+ * @throws JsonException if the index to the array is not -1 or is out of range
+ */
+ abstract public JsonStructure add(JsonValue value);
+
+ /**
+ * Remove the name/value pair from the JSON object, or the value in a JSON array, as specified by the reference
+ *
+ * @return the JsonStructure after the operation
+ * @throws JsonException if the name/value pair of the referenced JSON object
+ * does not exist, or if the index of the referenced JSON array is
+ * out of range, or if the reference is a root reference
+ */
+ abstract public JsonStructure remove();
+
+ /**
+ * Replace the referenced value with the specified value.
+ *
+ * @param value the JSON value to be stored at the referenced location
+ * @return the JsonStructure after the operation
+ * @throws JsonException if the name/value pair of the referenced JSON object
+ * does not exist, or if the index of the referenced JSON array is
+ * out of range, or if the reference is a root reference
+ */
+ abstract public JsonStructure replace(JsonValue value);
+
+ /**
+ * Returns a {@code NodeReference} for a {@code JsonStructure}.
+ *
+ * @param structure the {@code JsonStructure} referenced
+ * @return the {@code NodeReference}
+ */
+ public static NodeReference of(JsonStructure structure) {
+ return new RootReference(structure);
+ }
+
+ /**
+ * Returns a {@code NodeReference} for a name/value pair in a
+ * JSON object.
+ *
+ * @param object the referenced JSON object
+ * @param name the name of the name/pair
+ * @return the {@code NodeReference}
+ */
+ public static NodeReference of(JsonObject object, String name) {
+ return new ObjectReference(object, name);
+ }
+
+ /**
+ * Returns a {@code NodeReference} for a member value in a
+ * JSON array.
+ *
+ * @param array the referenced JSON array
+ * @param index the index of the member value in the JSON array
+ * @return the {@code NodeReference}
+ */
+ public static NodeReference of(JsonArray array, int index) {
+ return new ArrayReference(array, index);
+ }
+
+ static class RootReference extends NodeReference {
+
+ private JsonStructure root;
+
+ RootReference(JsonStructure root) {
+ this.root = root;
+ }
+
+ @Override
+ public JsonValue get() {
+ return root;
+ }
+
+ @Override
+ public JsonStructure add(JsonValue value) {
+ switch (value.getValueType() ) {
+ case OBJECT:
+ case ARRAY:
+ this.root = (JsonStructure) value;
+ break;
+ default:
+ throw new JsonException("The root value only allows adding a JSON object or array");
+ }
+ return root;
+ }
+
+ @Override
+ public JsonStructure remove() {
+ throw new JsonException("The JSON value at the root cannot be removed;");
+ }
+
+ @Override
+ public JsonStructure replace(JsonValue value) {
+ return add(value);
+ }
+ }
+
+ static class ObjectReference extends NodeReference {
+
+ private final JsonObject object;
+ private final String key;
+
+ ObjectReference(JsonObject object, String key) {
+ this.object = object;
+ this.key = key;
+ }
+
+ @Override
+ public JsonValue get() {
+ if (! object.containsKey(key)) {
+ throw new JsonException("Cannot get a non-existing name/value pair in the object");
+ }
+ return object.get(key);
+ }
+
+ @Override
+ public JsonObject add(JsonValue value) {
+ return Json.createObjectBuilder(object).add(key, value).build();
+ }
+
+ @Override
+ public JsonObject remove() {
+ if (! object.containsKey(key)) {
+ throw new JsonException("Cannot remove a non-existing name/value pair in the object");
+ }
+ return Json.createObjectBuilder(object).remove(key).build();
+ }
+
+ @Override
+ public JsonObject replace(JsonValue value) {
+ if (! object.containsKey(key)) {
+ throw new JsonException("Cannot replace a non-existing name/value pair in the object");
+ }
+ return add(value);
+ }
+ }
+
+ static class ArrayReference extends NodeReference {
+
+ private final JsonArray array;
+ private final int index; // -1 means "-" in JSON Pointer
+
+ ArrayReference(JsonArray array, int index) {
+ this.array = array;
+ this.index = index;
+ }
+
+ @Override
+ public JsonValue get() {
+ if (index == -1 || index >= array.size()) {
+ throw new JsonException("Cannot get an array item with an out of range index: " + index);
+ }
+ return array.get(index);
+ }
+
+ @Override
+ public JsonArray add(JsonValue value) {
+ //TODO should we check for arrayoutofbounds?
+ // The spec seems to say index = array.size() is allowed. This is handled as append
+ JsonArrayBuilder builder = Json.createArrayBuilder(this.array);
+ if (index == -1 || index == array.size()) {
+ builder.add(value);
+ } else {
+ if(index < array.size()) {
+ builder.add(index, value);
+ } else {
+ throw new JsonException("Cannot add an array item with an out of range index: " + index);
+ }
+ }
+ return builder.build();
+ }
+
+ @Override
+ public JsonArray remove() {
+ if (index == -1 || index >= array.size()) {
+ throw new JsonException("Cannot remove an array item with an out of range index: " + index);
+ }
+ JsonArrayBuilder builder = Json.createArrayBuilder(this.array);
+ return builder.remove(index).build();
+ }
+
+ @Override
+ public JsonArray replace(JsonValue value) {
+ if (index == -1 || index >= array.size()) {
+ throw new JsonException("Cannot replace an array item with an out of range index: " + index);
+ }
+ JsonArrayBuilder builder = Json.createArrayBuilder(this.array);
+ return builder.set(index, value).build();
+ }
+ }
+}
+
diff --git a/api/src/main/java/javax/json/package-info.java b/api/src/main/java/javax/json/package-info.java
new file mode 100644
index 0000000..2a63786
--- /dev/null
+++ b/api/src/main/java/javax/json/package-info.java
@@ -0,0 +1,69 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Provides an object model API to process <a href="http://json.org/">JSON</a>.
+ *
+ * <p>The object model API is a high-level API that provides immutable object
+ * models for JSON object and array structures. These JSON structures are
+ * represented as object models using the Java types {@link javax.json.JsonObject}
+ * and {@link javax.json.JsonArray}. The interface {@code javax.json.JsonObject} provides
+ * a {@link java.util.Map} view to access the unordered collection of zero or
+ * more name/value pairs from the model. Similarly, the interface
+ * {@code JsonArray} provides a {@link java.util.List} view to access the
+ * ordered sequence of zero or more values from the model.
+ *
+ * <p>The object model API uses builder patterns to create and modify
+ * these object models. The classes {@link javax.json.JsonObjectBuilder} and
+ * {@link javax.json.JsonArrayBuilder} provide methods to create and modify models
+ * of type {@code JsonObject} and {@code JsonArray} respectively.
+ *
+ * <p>These object models can also be created from an input source using
+ * the class {@link javax.json.JsonReader}. Similarly, these object models
+ * can be written to an output source using the class {@link javax.json.JsonWriter}.
+ * <p>
+ * This package includes several classes that implement other JSON related
+ * standards: <a href="http://tools.ietf.org/html/rfc6901">JSON Pointer</a>,
+ * <a Href="http://tools.ietf.org/html/rfc6902">JSON Patch</a>, and
+ * <a Href="http://tools.ietf.org/html/rfc7396">JSON Merge Patch</a>.
+ * They can be used to retrieve, transform or manipulate values in an
+ * object model.
+ */
+package javax.json;
diff --git a/api/src/main/java/javax/json/spi/JsonProvider.java b/api/src/main/java/javax/json/spi/JsonProvider.java
new file mode 100644
index 0000000..f578958
--- /dev/null
+++ b/api/src/main/java/javax/json/spi/JsonProvider.java
@@ -0,0 +1,384 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.spi;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Service provider for JSON processing objects.
+ *
+ * <p>All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @see ServiceLoader
+ */
+public abstract class JsonProvider {
+
+ /**
+ * A constant representing the name of the default
+ * {@code JsonProvider} implementation class.
+ */
+ private static final String DEFAULT_PROVIDER
+ = "org.glassfish.json.JsonProviderImpl";
+ private static final ThreadLocal<ServiceLoader<JsonProvider>> threadLoader =
+ new ThreadLocal<ServiceLoader<JsonProvider>>() {
+ @Override
+ protected ServiceLoader<JsonProvider> initialValue() {
+ return ServiceLoader.load(JsonProvider.class);
+ }
+ };
+
+ //Lazy initialization holder class idiom
+ private static class JsonProviderHolder {
+ static final JsonProvider defaultJsonProvider = initDefault();
+
+ static JsonProvider initDefault() {
+ try {
+ Class<?> clazz = Class.forName(DEFAULT_PROVIDER);
+ return (JsonProvider)clazz.newInstance();
+ } catch (ClassNotFoundException x) {
+ throw new JsonException(
+ "Provider " + DEFAULT_PROVIDER + " not found", x);
+ } catch (Exception x) {
+ throw new JsonException(
+ "Provider " + DEFAULT_PROVIDER + " could not be instantiated: " + x,
+ x);
+ }
+ }
+ }
+
+ protected JsonProvider() {
+ }
+
+ /**
+ *
+ * Creates a JSON provider object. The provider is loaded using the
+ * {@link ServiceLoader#load(Class)} method. If there are no available
+ * service providers, this method returns the default service provider.
+ *
+ * @see ServiceLoader
+ * @return a JSON provider
+ */
+ public static JsonProvider provider() {
+ Iterator<JsonProvider> it = threadLoader.get().iterator();
+ if (it.hasNext()) {
+ return it.next();
+ }
+
+ return JsonProviderHolder.defaultJsonProvider;
+ }
+
+ /**
+ * Creates a JSON parser from a character stream.
+ *
+ * @param reader i/o reader from which JSON is to be read
+ * @return a JSON parser
+ */
+ public abstract JsonParser createParser(Reader reader);
+
+ /**
+ * Creates a JSON parser from the specified byte stream.
+ * The character encoding of the stream is determined
+ * as defined in <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159
+ * </a>.
+ *
+ * @param in i/o stream from which JSON is to be read
+ * @throws JsonException if encoding cannot be determined
+ * or i/o error (IOException would be cause of JsonException)
+ * @return a JSON parser
+ */
+ public abstract JsonParser createParser(InputStream in);
+
+ /**
+ * Creates a parser factory for creating {@link JsonParser} instances.
+ *
+ * @return a JSON parser factory
+ *
+ public abstract JsonParserFactory createParserFactory();
+ */
+
+ /**
+ * Creates a parser factory for creating {@link JsonParser} instances.
+ * The factory is configured with the specified map of
+ * provider specific configuration properties. Provider implementations
+ * should ignore any unsupported configuration properties specified in
+ * the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON parsers. The map may be empty or null
+ * @return a JSON parser factory
+ */
+ public abstract JsonParserFactory createParserFactory(Map<String, ?> config);
+
+ /**
+ * Creates a JSON generator for writing JSON text to a character stream.
+ *
+ * @param writer a i/o writer to which JSON is written
+ * @return a JSON generator
+ */
+ public abstract JsonGenerator createGenerator(Writer writer);
+
+ /**
+ * Creates a JSON generator for writing JSON text to a byte stream.
+ *
+ * @param out i/o stream to which JSON is written
+ * @return a JSON generator
+ */
+ public abstract JsonGenerator createGenerator(OutputStream out);
+
+ /**
+ * Creates a generator factory for creating {@link JsonGenerator} instances.
+ *
+ * @return a JSON generator factory
+ *
+ public abstract JsonGeneratorFactory createGeneratorFactory();
+ */
+
+ /**
+ * Creates a generator factory for creating {@link JsonGenerator} instances.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should
+ * ignore any unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON generators. The map may be empty or null
+ * @return a JSON generator factory
+ */
+ public abstract JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config);
+
+ /**
+ * Creates a JSON reader from a character stream.
+ *
+ * @param reader a reader from which JSON is to be read
+ * @return a JSON reader
+ */
+ public abstract JsonReader createReader(Reader reader);
+
+ /**
+ * Creates a JSON reader from a byte stream. The character encoding of
+ * the stream is determined as described in
+ * <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ *
+ * @param in a byte stream from which JSON is to be read
+ * @return a JSON reader
+ */
+ public abstract JsonReader createReader(InputStream in);
+
+ /**
+ * Creates a JSON writer to write a
+ * JSON {@link JsonObject object} or {@link JsonArray array}
+ * structure to the specified character stream.
+ *
+ * @param writer to which JSON object or array is written
+ * @return a JSON writer
+ */
+ public abstract JsonWriter createWriter(Writer writer);
+
+ /**
+ * Creates a JSON writer to write a
+ * JSON {@link JsonObject object} or {@link JsonArray array}
+ * structure to the specified byte stream. Characters written to
+ * the stream are encoded into bytes using UTF-8 encoding.
+ *
+ * @param out to which JSON object or array is written
+ * @return a JSON writer
+ */
+ public abstract JsonWriter createWriter(OutputStream out);
+
+ /**
+ * Creates a writer factory for creating {@link JsonWriter} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON writers. The map may be empty or null
+ * @return a JSON writer factory
+ */
+ public abstract JsonWriterFactory createWriterFactory(Map<String,?> config);
+
+ /**
+ * Creates a reader factory for creating {@link JsonReader} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON readers. The map may be empty or null
+ * @return a JSON reader factory
+ */
+ public abstract JsonReaderFactory createReaderFactory(Map<String,?> config);
+
+ /**
+ * Creates a JSON object builder
+ *
+ * @return a JSON object builder
+ */
+ public abstract JsonObjectBuilder createObjectBuilder();
+
+ /**
+ * Creates a JSON object builder, initialized with the specified object.
+ *
+ * @param object the initial JSON object in the builder
+ * @return a JSON object builder
+ * @since 1.1
+ */
+ public JsonObjectBuilder createObjectBuilder(JsonObject object) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JSON array builder
+ *
+ * @return a JSON array builder
+ */
+ public abstract JsonArrayBuilder createArrayBuilder();
+
+ /**
+ * Creates a JSON array builder, initialized with the specified array
+ *
+ * @param array the initial JSON array in the builder
+ * @return a JSON array builder
+ * @since 1.1
+ */
+ public JsonArrayBuilder createArrayBuilder(JsonArray array) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a builder factory for creating {@link JsonArrayBuilder}
+ * and {@link JsonObjectBuilder} objects.
+ * The factory is configured with the specified map of provider specific
+ * configuration properties. Provider implementations should ignore any
+ * unsupported configuration properties specified in the map.
+ *
+ * @param config a map of provider specific properties to configure the
+ * JSON builders. The map may be empty or null
+ * @return a JSON builder factory
+ */
+ public abstract JsonBuilderFactory createBuilderFactory(Map<String,?> config);
+
+
+ /**
+ * Creates a JsonString
+ *
+ * @param value a JSON string
+ * @return the JsonString for the string
+ *
+ * @since 1.1
+ */
+ public JsonString createValue(String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public JsonNumber createValue(int value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public JsonNumber createValue(long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public JsonNumber createValue(double value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public JsonNumber createValue(BigDecimal value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a JsonNumber
+ *
+ * @param value a JSON number
+ * @return the JsonNumber for the number
+ *
+ * @since 1.1
+ */
+ public JsonNumber createValue(BigInteger value) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/api/src/main/java/javax/json/spi/package-info.java b/api/src/main/java/javax/json/spi/package-info.java
new file mode 100644
index 0000000..5755fd6
--- /dev/null
+++ b/api/src/main/java/javax/json/spi/package-info.java
@@ -0,0 +1,56 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Service Provider Interface (SPI) to plug in implementations for
+ * JSON processing objects.
+ *
+ * <p> {@link javax.json.spi.JsonProvider JsonProvider} is an abstract class
+ * that provides a service for creating JSON processing instances.
+ * A <i>service provider</i> for {@code JsonProvider} provides an
+ * specific implementation by subclassing and implementing the methods in
+ * {@code JsonProvider}. This enables using custom, efficient JSON processing
+ * implementations (for e.g. parser and generator) other than the default ones.
+ *
+ * <p>The API locates and loads providers using {@link java.util.ServiceLoader}.
+ *
+ * @since JSON Processing 1.0
+ */
+package javax.json.spi;
diff --git a/api/src/main/java/javax/json/stream/JsonCollectors.java b/api/src/main/java/javax/json/stream/JsonCollectors.java
new file mode 100644
index 0000000..b6db550
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonCollectors.java
@@ -0,0 +1,169 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.stream.Collector;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.BiConsumer;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+import javax.json.JsonException;
+
+/**
+ * This class contains some implementations of {@code java.util.stream.Collector} for accumulating
+ * {@link JsonValue}s into {@link JsonArray} and {@link JsonObject}.
+ *
+ * @since 1.1
+ */
+
+public final class JsonCollectors {
+
+ private JsonCollectors() {
+ }
+
+ /**
+ * Constructs a {@code java.util.stream.Collector} that accumulates the input {@code JsonValue}
+ * elements into a {@code JsonArray}.
+ *
+ * @return the constructed Collector
+ */
+ public static Collector<JsonValue, JsonArrayBuilder, JsonArray> toJsonArray() {
+ return Collector.of(
+ Json::createArrayBuilder,
+ JsonArrayBuilder::add,
+ JsonArrayBuilder::addAll,
+ JsonArrayBuilder::build);
+ }
+
+ /**
+ * Constructs a {@code java.util.stream.Collector} that accumulates the input {@code JsonValue}
+ * elements into a {@code JsonObject}. The name/value pairs of the {@code JsonObject} are computed
+ * by applying the provided mapping functions.
+ *
+ * @param keyMapper a mapping function to produce names.
+ * @param valueMapper a mapping function to produce values
+ * @return the constructed Collector
+ */
+ public static Collector<JsonValue, JsonObjectBuilder, JsonObject>
+ toJsonObject(Function<JsonValue, String> keyMapper,
+ Function<JsonValue, JsonValue> valueMapper) {
+ return Collector.of(
+ Json::createObjectBuilder,
+ (b, v) -> b.add(keyMapper.apply(v), valueMapper.apply(v)),
+ JsonObjectBuilder::addAll,
+ JsonObjectBuilder::build,
+ Collector.Characteristics.UNORDERED);
+ }
+
+ /**
+ * Constructs a {@code java.util.stream.Collector} that implements a "group by" operation on the
+ * input {@code JsonValue} elements. A classifier function maps the input {@code JsonValue}s to keys, and
+ * the {@code JsonValue}s are partitioned into groups according to the value of the key.
+ * A reduction operation is performed on the {@code JsonValue}s in each group, using the
+ * downstream {@code Collector}. For each group, the key and the results of the reduction operation
+ * become the name/value pairs of the resultant {@code JsonObject}.
+ *
+ * @param classifier a function mapping the input {@code JsonValue}s to a String, producing keys
+ * @param downstream a {@code Collector} that implements a reduction operation on the
+ * {@code JsonValue}s in each group.
+ * @return the constructed {@code Collector}
+ */
+ public static Collector<JsonValue, Map<String, JsonArrayBuilder>, JsonObject>
+ groupingBy(Function<JsonValue, String> classifier,
+ Collector<JsonValue, JsonArrayBuilder, JsonArray> downstream) {
+
+ BiConsumer<Map<String, JsonArrayBuilder>, JsonValue> accumulator =
+ (map, value) -> {
+ String key = classifier.apply(value);
+ if (key == null) {
+ throw new JsonException("element cannot be mapped to a null key");
+ }
+ // Build a map of key to JsonArrayBuilder
+ JsonArrayBuilder arrayBuilder =
+ map.computeIfAbsent(key, v->downstream.supplier().get());
+ // Add elements from downstream Collector to the arrayBuilder.
+ downstream.accumulator().accept(arrayBuilder, value);
+ };
+ Function<Map<String, JsonArrayBuilder>, JsonObject> finisher =
+ map -> {
+ // transform the map of name: JsonArrayBuilder to
+ // name: JsonArray
+ // using the downstream collector for reducing the JsonArray
+ JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+ map.forEach((k, v) -> {
+ JsonArray array = downstream.finisher().apply(v);
+ objectBuilder.add(k, array);
+ });
+ return objectBuilder.build();
+ };
+ BinaryOperator<Map<String, JsonArrayBuilder>> combiner =
+ (map1, map2) -> {
+ map1.putAll(map2);
+ return map1;
+ };
+ return Collector.of(HashMap::new, accumulator, combiner, finisher,
+ Collector.Characteristics.UNORDERED);
+ }
+
+ /**
+ * Constructs a {@code java.util.stream.Collector} that implements a "group by" operation on the
+ * input {@code JsonValue} elements. A classifier function maps the input {@code JsonValue}s to keys, and
+ * the {@code JsonValue}s are partitioned into groups according to the value of the key.
+ * The {@code JsonValue}s in each group are added to a {@code JsonArray}. The key and the
+ * {@code JsonArray} in each group becomes the name/value pair of the resultant {@code JsonObject}.
+ *
+ * @param classifier a function mapping the input {@code JsonValue}s to a String, producing keys
+ * @return the constructed {@code Collector}
+ */
+ public static Collector<JsonValue, Map<String, JsonArrayBuilder>, JsonObject>
+ groupingBy(Function<JsonValue, String> classifier) {
+ return groupingBy(classifier, toJsonArray());
+ }
+}
+
diff --git a/api/src/main/java/javax/json/stream/JsonGenerationException.java b/api/src/main/java/javax/json/stream/JsonGenerationException.java
new file mode 100644
index 0000000..7be05e0
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonGenerationException.java
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonException;
+
+/**
+ * {@code JsonGenerationException} indicates an incorrect JSON is
+ * being generated.
+ */
+public class JsonGenerationException extends JsonException {
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public JsonGenerationException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this runtime exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ */
+ public JsonGenerationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
+
diff --git a/api/src/main/java/javax/json/stream/JsonGenerator.java b/api/src/main/java/javax/json/stream/JsonGenerator.java
new file mode 100644
index 0000000..7d552a4
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonGenerator.java
@@ -0,0 +1,544 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonValue;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Writes JSON data to an output source in a streaming way. The class
+ * {@link javax.json.Json} contains methods to create generators for character
+ * or output streams ({@link java.io.Writer} and {@link java.io.OutputStream}).
+ *
+ * <p>
+ * The following example shows how to create a JSON generator:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = Json.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonGeneratorFactory} also contains methods to create
+ * {@code JsonGenerator} instances. {@link JsonGeneratorFactory} should be used
+ * when creating multiple generator instances, as in the following example:
+ * <pre>
+ * <code>
+ * JsonGeneratorFactory factory = Json.createGeneratorFactory();
+ * JsonGenerator generator1 = factory.createGenerator(...);
+ * JsonGenerator generator2 = factory.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * JSON objects can be created using {@code JsonGenerator} by calling the
+ * {@link #writeStartObject()} method and then adding name/value pairs with the
+ * {@code write} method.
+ * <p>
+ * The following example shows how to generate an empty JSON object:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = ...;
+ * generator.writeStartObject().writeEnd().close();
+ * </code>
+ * </pre>
+ *
+ * JSON arrays can be created using {@code JsonGenerator} by calling the
+ * {@link #writeStartArray()} method and then adding values with the
+ * {@code write} method.
+ *
+ * <p>
+ * The following example shows how to generate an empty JSON array:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = ...;
+ * generator.writeStartArray().writeEnd().close();
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * Other JSON values (that are not JSON objects or arrays) can be created
+ * by calling the appropiate {@code write} methods.
+ * <p>
+ * The following example shows how to generate a JSON string:
+ * <pre><code>
+ * JsonGenerator generator = ...;
+ * generator.write("message").close();
+ * </code></pre>
+ *
+ * {@code JsonGenerator} methods can be chained as in the following example:
+ * <pre>
+ * <code>
+ * generator
+ * .writeStartObject()
+ * .write("firstName", "John")
+ * .write("lastName", "Smith")
+ * .write("age", 25)
+ * .writeStartObject("address")
+ * .write("streetAddress", "21 2nd Street")
+ * .write("city", "New York")
+ * .write("state", "NY")
+ * .write("postalCode", "10021")
+ * .writeEnd()
+ * .writeStartArray("phoneNumber")
+ * .writeStartObject()
+ * .write("type", "home")
+ * .write("number", "212 555-1234")
+ * .writeEnd()
+ * .writeStartObject()
+ * .write("type", "fax")
+ * .write("number", "646 555-4567")
+ * .writeEnd()
+ * .writeEnd()
+ * .writeEnd();
+ * generator.close();
+ * </code>
+ * </pre>
+ *
+ * The example code above generates the following JSON (or equivalent):
+ * <pre>
+ * <code>
+ * {
+ * "firstName": "John", "lastName": "Smith", "age": 25,
+ * "address" : {
+ * "streetAddress": "21 2nd Street",
+ * "city": "New York",
+ * "state": "NY",
+ * "postalCode": "10021"
+ * },
+ * "phoneNumber": [
+ * {"type": "home", "number": "212 555-1234"},
+ * {"type": "fax", "number": "646 555-4567"}
+ * ]
+ * }
+ * </code>
+ * </pre>
+ *
+ * The generated JSON text must strictly conform to the grammar defined in
+ * <a href="http://www.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ *
+ * @see javax.json.Json
+ * @see JsonGeneratorFactory
+ */
+public interface JsonGenerator extends Flushable, /*Auto*/Closeable {
+ /**
+ * Configuration property to generate JSON prettily. All providers
+ * must support this property. The value of the property could be
+ * be anything.
+ */
+ String PRETTY_PRINTING = "javax.json.stream.JsonGenerator.prettyPrinting" ;
+
+ /**
+ * Writes the JSON start object character. It starts a new child object
+ * context within which JSON name/value pairs can be written to the object.
+ * This method is valid only in an array context or in no context (when a
+ * context is not yet started). This method can only be called once in
+ * no context.
+ *
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is called within an
+ * object context or if it is called more than once in no context.
+ */
+ JsonGenerator writeStartObject();
+
+ /**
+ * Writes the JSON name/start object character pair in the current
+ * object context. It starts a new child object context within which JSON
+ * name/value pairs can be written to the object.
+ *
+ * @param name a name within the JSON name/object pair to be written
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context
+ */
+ JsonGenerator writeStartObject(String name);
+
+ /**
+ * Writes the JSON start array character. It starts a new child array
+ * context within which JSON values can be written to the array. This
+ * method is valid only in an array context or in no context (when a
+ * context is not yet started). This method can only be called once in
+ * no context.
+ *
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is called within an
+ * object context or if called more than once in no context
+ */
+ JsonGenerator writeStartArray();
+
+ /**
+ * Writes the JSON name/start array character pair with in the current
+ * object context. It starts a new child array context within which JSON
+ * values can be written to the array.
+ *
+ * @param name a name within the JSON name/array pair to be written
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within
+ * an object context
+ */
+ JsonGenerator writeStartArray(String name);
+
+ /**
+ * Writes a JSON name/value pair in the current object context.
+ *
+ * @param name a name in the JSON name/value pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/value pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context
+ */
+ JsonGenerator write(String name, JsonValue value);
+
+ /**
+ * Writes a JSON name/string value pair in the current object context.
+ * The specified value is written as JSON string value.
+ *
+ * @param name a name in the JSON name/string pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/string pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context
+ */
+ JsonGenerator write(String name, String value);
+
+ /**
+ * Writes a JSON name/number value pair in the current object context.
+ * The specified value is written as a JSON number value. The string
+ * {@code new BigDecimal(value).toString()}
+ * is used as the text value for writing.
+ *
+ * @param name a name in the JSON name/number pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/number pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context.
+ */
+ JsonGenerator write(String name, BigInteger value);
+
+ /**
+ * Writes a JSON name/number value pair in the current object context.
+ * The specified value is written as a JSON number value. The specified
+ * value's {@code toString()} is used as the text value for writing.
+ *
+ * @param name a name in the JSON name/number pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/number pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context.
+ */
+ JsonGenerator write(String name, BigDecimal value);
+
+ /**
+ * Writes a JSON name/number value pair in the current object context.
+ * The specified value is written as a JSON number value. The string
+ * {@code new BigDecimal(value).toString()} is used as the text value
+ * for writing.
+ *
+ * @param name a name in the JSON name/number pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/number pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context.
+ */
+ JsonGenerator write(String name, int value);
+
+ /**
+ * Writes a JSON name/number value pair in the current object context.
+ * The specified value is written as a JSON number value. The string
+ * {@code new BigDecimal(value).toString()} is used as the text
+ * value for writing.
+ *
+ * @param name a name in the JSON name/number pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/number pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context.
+ */
+ JsonGenerator write(String name, long value);
+
+ /**
+ * Writes a JSON name/number value pair in the current object context.
+ * The specified value is written as a JSON number value. The string
+ * {@code BigDecimal.valueOf(double).toString()}
+ * is used as the text value for writing.
+ *
+ * @param name a name in the JSON name/number pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/number pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or infinity.
+ * @throws JsonGenerationException if this method is not called within an
+ * object context
+ */
+ JsonGenerator write(String name, double value);
+
+ /**
+ * Writes a JSON name/boolean value pair in the current object context.
+ * If value is true, it writes the JSON {@code true} value, otherwise
+ * it writes the JSON {@code false} value.
+ *
+ * @param name a name in the JSON name/boolean pair to be written in
+ * current JSON object
+ * @param value a value in the JSON name/boolean pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context.
+ */
+ JsonGenerator write(String name, boolean value);
+
+
+ /**
+ * Writes a JSON name/null value pair in an current object context.
+ *
+ * @param name a name in the JSON name/null pair to be written in
+ * current JSON object
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * object context
+ */
+ JsonGenerator writeNull(String name);
+
+ /**
+ * Writes the end of the current context. If the current context is
+ * an array context, this method writes the end-of-array character (']').
+ * If the current context is an object context, this method writes the
+ * end-of-object character ('}'). After writing the end of the current
+ * context, the parent context becomes the new current context.
+ *
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is called in no context.
+ */
+ JsonGenerator writeEnd();
+
+ /**
+ * Writes the specified value as a JSON value within
+ * the current array or root context.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator write(JsonValue value);
+
+ /**
+ * Writes the specified value as a JSON string value within
+ * the current array or context.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator write(String value);
+
+ /**
+ * Writes the specified value as a JSON number value within
+ * the current array or root context. The specified value's {@code toString()}
+ * is used as the the text value for writing.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ *
+ * @see javax.json.JsonNumber
+ */
+ JsonGenerator write(BigDecimal value);
+
+ /**
+ * Writes the specified value as a JSON number value within
+ * the current array or root context. The string {@code new BigDecimal(value).toString()}
+ * is used as the text value for writing.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator.
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ *
+ * @see javax.json.JsonNumber
+ */
+ JsonGenerator write(BigInteger value);
+
+ /**
+ * Writes the specified value as a JSON number value within
+ * the current array or root context. The string {@code new BigDecimal(value).toString()}
+ * is used as the text value for writing.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator write(int value);
+
+ /**
+ * Writes the specified value as a JSON number value within
+ * the current array or root context. The string {@code new BigDecimal(value).toString()}
+ * is used as the text value for writing.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator write(long value);
+
+ /**
+ * Writes the specified value as a JSON number value within the current
+ * array or root context. The string {@code BigDecimal.valueOf(value).toString()}
+ * is used as the text value for writing.
+ *
+ * @param value a value to be written in current JSON array
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ * @throws NumberFormatException if the value is Not-a-Number(NaN) or infinity.
+ */
+ JsonGenerator write(double value);
+
+ /**
+ * Writes a JSON true or false value within the current array or root context.
+ * If value is true, this method writes the JSON {@code true} value,
+ * otherwise it writes the JSON {@code false} value.
+ *
+ * @param value a {@code boolean} value
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator write(boolean value);
+
+ /**
+ * Writes a JSON null value within the current array or root context.
+ *
+ * @return this generator
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if this method is not called within an
+ * array or root context.
+ */
+ JsonGenerator writeNull();
+
+ /**
+ * Closes this generator and frees any resources associated with it.
+ * This method closes the underlying output source.
+ *
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonGenerationException if an incomplete JSON is generated
+ */
+ @Override
+ void close();
+
+ /**
+ * Flushes the underlying output source. If the generator has saved
+ * any characters in a buffer, writes them immediately to the underlying
+ * output source before flushing it.
+ *
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ */
+ @Override
+ void flush();
+
+}
diff --git a/api/src/main/java/javax/json/stream/JsonGeneratorFactory.java b/api/src/main/java/javax/json/stream/JsonGeneratorFactory.java
new file mode 100644
index 0000000..697c9a7
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonGeneratorFactory.java
@@ -0,0 +1,113 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link JsonGenerator} instances. If a factory
+ * instance is configured with some configuration, the configuration applies
+ * to all generator instances created using that factory instance.
+ *
+ * <p>
+ * The class {@link javax.json.Json Json} also provides methods to create
+ * {@link JsonGenerator} instances, but using {@code JsonGeneratorFactory} is
+ * preferred when creating multiple generator instances as shown in the
+ * following example:
+ *
+ * <pre>
+ * <code>
+ * JsonGeneratorFactory factory = Json.createGeneratorFactory();
+ * JsonGenerator generator1 = factory.createGenerator(...);
+ * JsonGenerator generator2 = factory.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public interface JsonGeneratorFactory {
+
+ /**
+ * Creates a JSON generator to write JSON text to a character stream.
+ * The generator is configured with the factory configuration.
+ *
+ * @param writer i/o writer to which JSON is written
+ * @return the created JSON generator
+ */
+ JsonGenerator createGenerator(Writer writer);
+
+ /**
+ * Creates a JSON generator to write JSON text to a byte stream. Characters
+ * written to the stream are encoded into bytes using UTF-8 encoding.
+ * The generator is configured with the factory's configuration.
+ *
+ * @param out i/o stream to which JSON is written
+ * @return the created JSON generator
+ */
+ JsonGenerator createGenerator(OutputStream out);
+
+ /**
+ * Creates a JSON generator to write JSON text to a byte stream. Characters
+ * written to the stream are encoded into bytes using the specified charset.
+ * The generator is configured with the factory's configuration.
+ *
+ * @param out i/o stream to which JSON is written
+ * @param charset a charset
+ * @return the created JSON generator
+ */
+ JsonGenerator createGenerator(OutputStream out, Charset charset);
+
+ /**
+ * Returns a read-only map of supported provider specific configuration
+ * properties that are used to configure the JSON generators.
+ * If there are any specified configuration properties that are not
+ * supported by the provider, they won't be part of the returned map.
+ *
+ * @return a map of supported provider specific properties that are used
+ * to configure the created generators. The map may be empty but not null
+ */
+ Map<String, ?> getConfigInUse();
+
+}
diff --git a/api/src/main/java/javax/json/stream/JsonLocation.java b/api/src/main/java/javax/json/stream/JsonLocation.java
new file mode 100644
index 0000000..0c9ad95
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonLocation.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+/**
+ * Provides the location information of a JSON event in an input source. The
+ * {@code JsonLocation} information can be used to identify incorrect JSON
+ * or can be used by higher frameworks to know about the processing location.
+ *
+ * <p>All the information provided by a {@code JsonLocation} is optional. For
+ * example, a provider may only report line numbers. Also, there may not be any
+ * location information for an input source. For example, if a
+ * {@code JsonParser} is created using
+ * {@link javax.json.JsonArray JsonArray} input source, all the methods in
+ * this class return -1.
+ * @see JsonParser
+ * @see JsonParsingException
+ */
+public interface JsonLocation {
+
+ /**
+ * Return the line number (starts with 1 for the first line) for the current JSON event in the input source.
+ *
+ * @return the line number (starts with 1 for the first line) or -1 if none is available
+ */
+ long getLineNumber();
+
+ /**
+ * Return the column number (starts with 1 for the first column) for the current JSON event in the input source.
+ *
+ * @return the column number (starts with 1 for the first column) or -1 if none is available
+ */
+ long getColumnNumber();
+
+ /**
+ * Return the stream offset into the input source this location
+ * is pointing to. If the input source is a file or a byte stream then
+ * this is the byte offset into that stream, but if the input source is
+ * a character media then the offset is the character offset.
+ * Returns -1 if there is no offset available.
+ *
+ * @return the offset of input source stream, or -1 if there is
+ * no offset available
+ */
+ long getStreamOffset();
+
+}
diff --git a/api/src/main/java/javax/json/stream/JsonParser.java b/api/src/main/java/javax/json/stream/JsonParser.java
new file mode 100644
index 0000000..90eb5f0
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonParser.java
@@ -0,0 +1,511 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+
+import java.io.Closeable;
+import java.math.BigDecimal;
+import java.util.stream.Stream;
+import java.util.Map;
+
+import javax.json.JsonValue;
+import javax.json.JsonObject;
+import javax.json.JsonArray;
+
+/**
+ * Provides forward, read-only access to JSON data in a streaming way. This
+ * is the most efficient way for reading JSON data.
+ * This is the only way to parse and process JSON data that are too big to be loaded in memory.
+ * <p>The class
+ * {@link javax.json.Json} contains methods to create parsers from input
+ * sources ({@link java.io.InputStream} and {@link java.io.Reader}).
+ *
+ * <p>
+ * The following example demonstrates how to create a parser from a string
+ * that contains an empty JSON array:
+ * <pre>
+ * <code>
+ * JsonParser parser = Json.createParser(new StringReader("[]"));
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonParserFactory} also contains methods to create
+ * {@code JsonParser} instances. {@link JsonParserFactory} is preferred
+ * when creating multiple parser instances. A sample usage is shown
+ * in the following example:
+ * <pre>
+ * <code>
+ * JsonParserFactory factory = Json.createParserFactory();
+ * JsonParser parser1 = factory.createParser(...);
+ * JsonParser parser2 = factory.createParser(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * {@code JsonParser} parses JSON using the pull parsing programming model.
+ * In this model the client code controls the thread and calls the method
+ * {@code next()} to advance the parser to the next state after
+ * processing each element. The parser can generate the following events:
+ * {@code START_OBJECT}, {@code END_OBJECT}, {@code START_ARRAY},
+ * {@code END_ARRAY}, {@code KEY_NAME}, {@code VALUE_STRING},
+ * {@code VALUE_NUMBER}, {@code VALUE_TRUE}, {@code VALUE_FALSE},
+ * and {@code VALUE_NULL}.
+ *
+ * <p>
+ * <b>For example</b>, for an empty JSON object ({ }), the parser generates the event
+ * {@code START_OBJECT} with the first call to the method {@code next()} and the
+ * event {@code END_OBJECT} with the second call to the method {@code next()}.
+ * The following code demonstrates how to access these events:
+ *
+ * <pre>
+ * <code>
+ * Event event = parser.next(); // START_OBJECT
+ * event = parser.next(); // END_OBJECT
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * <b>For example</b>, for the following JSON:
+ * <pre>
+ * {
+ * "firstName": "John", "lastName": "Smith", "age": 25,
+ * "phoneNumber": [
+ * { "type": "home", "number": "212 555-1234" },
+ * { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * }
+ * </pre>
+ *
+ * <p>calls to the method {@code next()} result in parse events at the specified
+ * locations below (marked in bold):
+ *
+ * <pre>
+ * {<B>START_OBJECT</B>
+ * "firstName"<B>KEY_NAME</B>: "John"<B>VALUE_STRING</B>, "lastName"<B>KEY_NAME</B>: "Smith"<B>VALUE_STRING</B>, "age"<B>KEY_NAME</B>: 25<B>VALUE_NUMBER</B>,
+ * "phoneNumber"<B>KEY_NAME</B> : [<B>START_ARRAY</B>
+ * {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "home"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "212 555-1234"<B>VALUE_STRING</B> }<B>END_OBJECT</B>,
+ * {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "fax"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "646 555-4567"<B>VALUE_STRING</B> }<B>END_OBJECT</B>
+ * ]<B>END_ARRAY</B>
+ * }<B>END_OBJECT</B>
+ * </pre>
+ *
+ * The methods {@link #next()} and {@link #hasNext()} enable iteration over
+ * parser events to process JSON data. {@code JsonParser} provides get methods
+ * to obtain the value at the current state of the parser. For example, the
+ * following code shows how to obtain the value "John" from the JSON above:
+ *
+ * <pre>
+ * <code>
+ * Event event = parser.next(); // START_OBJECT
+ * event = parser.next(); // KEY_NAME
+ * event = parser.next(); // VALUE_STRING
+ * parser.getString(); // "John"
+ * </code>
+ * </pre>
+ *
+ * Starting in version 1.1, it is possible to build a partial JSON object
+ * model from the stream, at the current parser position.
+ * The methods {@link #getArray} and {@link #getObject} can be used to read in
+ * a {@code JsonArray} or {@code JsonObject}. For example, the following code
+ * shows how to obtain the phoneNumber in a JsonArray, from the JSON above:
+ *
+ * <pre><code>
+ * while (parser.hasNext() {
+ * Event event = parser.next();
+ * if (event == JsonParser.Event.KEY_NAME ) {
+ * String key = getString();
+ * event = parser.next();
+ * if (key.equals("phoneNumber") {
+ * JsonArray phones = parser.getArray();
+ * }
+ * }
+ * }
+ * </code></pre>
+ *
+ * The methods {@link #getArrayStream} and {@link #getObjectStream} can be used
+ * to get a stream of the elements of a {@code JsonArray} or {@code JsonObject}.
+ * For example, the following code shows another way to obtain John's phoneNumber
+ * in a {@code JsonArray} :
+ *
+ * <pre>{@code
+ * Event event = parser.next(); // START_OBJECT
+ * JsonArray phones = (JsonArray)
+ * parser.getObjectStream().filter(e->e.getKey().equals("phoneNumber"))
+ * .map(e->e.getValue())
+ * .findFirst()
+ * .get();
+ * }</pre>
+ *
+ * The methods {@link #skipArray} and {@link #skipObject} can be used to
+ * skip tokens and position the parser to {@code END_ARRAY} or
+ * {@code END_OBJECT}.
+ * <p>
+ * {@code JsonParser} can be used to parse sequence of JSON values that are not
+ * enclosed in a JSON array, e.g. { } { }. The following code demonstrates how
+ * to parse such sequence.
+ * <pre><code>
+ * JsonParser parser = Json.createParser(...);
+ * while (parser.hasNext) {
+ * parser.next(); // advance parser state
+ * JsonValue value = parser.getValue();
+ * }
+ * </code></pre>
+ *
+ * @see javax.json.Json
+ * @see JsonParserFactory
+ */
+public interface JsonParser extends /*Auto*/Closeable {
+
+ /**
+ * An event from {@code JsonParser}.
+ */
+ enum Event {
+ /**
+ * Start of a JSON array. The position of the parser is after '['.
+ */
+ START_ARRAY,
+ /**
+ * Start of a JSON object. The position of the parser is after '{'.
+ */
+ START_OBJECT,
+ /**
+ * Name in a name/value pair of a JSON object. The position of the parser
+ * is after the key name. The method {@link #getString} returns the key
+ * name.
+ */
+ KEY_NAME,
+ /**
+ * String value in a JSON array or object. The position of the parser is
+ * after the string value. The method {@link #getString}
+ * returns the string value.
+ */
+ VALUE_STRING,
+ /**
+ * Number value in a JSON array or object. The position of the parser is
+ * after the number value. {@code JsonParser} provides the following
+ * methods to access the number value: {@link #getInt},
+ * {@link #getLong}, and {@link #getBigDecimal}.
+ */
+ VALUE_NUMBER,
+ /**
+ * {@code true} value in a JSON array or object. The position of the
+ * parser is after the {@code true} value.
+ */
+ VALUE_TRUE,
+ /**
+ * {@code false} value in a JSON array or object. The position of the
+ * parser is after the {@code false} value.
+ */
+ VALUE_FALSE,
+ /**
+ * {@code null} value in a JSON array or object. The position of the
+ * parser is after the {@code null} value.
+ */
+ VALUE_NULL,
+ /**
+ * End of a JSON object. The position of the parser is after '}'.
+ */
+ END_OBJECT,
+ /**
+ * End of a JSON array. The position of the parser is after ']'.
+ */
+ END_ARRAY
+ }
+
+ /**
+ * Returns {@code true} if there are more parsing states. This method returns
+ * {@code false} if the parser reaches the end of the JSON text.
+ *
+ * @return {@code true} if there are more parsing states.
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonParsingException if the parser encounters invalid JSON
+ * when advancing to next state.
+ */
+ boolean hasNext();
+
+ /**
+ * Returns the event for the next parsing state.
+ *
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ * @throws JsonParsingException if the parser encounters invalid JSON
+ * when advancing to next state.
+ * @throws java.util.NoSuchElementException if there are no more parsing
+ * @return the event for the next parsing state
+ * states.
+ */
+ Event next();
+
+ /**
+ * Returns a {@code String} for the name in a name/value pair,
+ * for a string value or a number value. This method should only be called
+ * when the parser state is {@link Event#KEY_NAME}, {@link Event#VALUE_STRING},
+ * or {@link Event#VALUE_NUMBER}.
+ *
+ * @return a name when the parser state is {@link Event#KEY_NAME}
+ * a string value when the parser state is {@link Event#VALUE_STRING}
+ * a number value when the parser state is {@link Event#VALUE_NUMBER}
+ * @throws IllegalStateException when the parser state is not
+ * {@code KEY_NAME}, {@code VALUE_STRING}, or {@code VALUE_NUMBER}
+ */
+ String getString();
+
+ /**
+ * Returns true if the JSON number at the current parser state is a
+ * integral number. A {@link BigDecimal} may be used to store the value
+ * internally and this method semantics are defined using its
+ * {@code scale()}. If the scale is zero, then it is considered integral
+ * type. This integral type information can be used to invoke an
+ * appropriate accessor method to obtain a numeric value as in the
+ * following example:
+ *
+ * <pre>
+ * <code>
+ * JsonParser parser = ...
+ * if (parser.isIntegralNumber()) {
+ * parser.getInt(); // or other methods to get integral value
+ * } else {
+ * parser.getBigDecimal();
+ * }
+ * </code>
+ * </pre>
+ *
+ * @return true if this number is a integral number, otherwise false
+ * @throws IllegalStateException when the parser state is not
+ * {@code VALUE_NUMBER}
+ */
+ boolean isIntegralNumber();
+
+ /**
+ * Returns a JSON number as an integer. The returned value is equal
+ * to {@code new BigDecimal(getString()).intValue()}. Note that
+ * this conversion can lose information about the overall magnitude
+ * and precision of the number value as well as return a result with
+ * the opposite sign. This method should only be called when the parser
+ * state is {@link Event#VALUE_NUMBER}.
+ *
+ * @return an integer for a JSON number
+ * @throws IllegalStateException when the parser state is not
+ * {@code VALUE_NUMBER}
+ * @see java.math.BigDecimal#intValue()
+ */
+ int getInt();
+
+ /**
+ * Returns a JSON number as a long. The returned value is equal
+ * to {@code new BigDecimal(getString()).longValue()}. Note that this
+ * conversion can lose information about the overall magnitude and
+ * precision of the number value as well as return a result with
+ * the opposite sign. This method is only called when the parser state is
+ * {@link Event#VALUE_NUMBER}.
+ *
+ * @return a long for a JSON number
+ * @throws IllegalStateException when the parser state is not
+ * {@code VALUE_NUMBER}
+ * @see java.math.BigDecimal#longValue()
+ */
+ long getLong();
+
+ /**
+ * Returns a JSON number as a {@code BigDecimal}. The {@code BigDecimal}
+ * is created using {@code new BigDecimal(getString())}. This
+ * method should only called when the parser state is
+ * {@link Event#VALUE_NUMBER}.
+ *
+ * @return a {@code BigDecimal} for a JSON number
+ * @throws IllegalStateException when the parser state is not
+ * {@code VALUE_NUMBER}
+ */
+ BigDecimal getBigDecimal();
+
+ /**
+ * Return the location that corresponds to the parser's current state in
+ * the JSON input source. The location information is only valid in the
+ * current parser state (or until the parser is advanced to a next state).
+ *
+ * @return a non-null location corresponding to the current parser state
+ * in JSON input source
+ */
+ JsonLocation getLocation();
+
+ /**
+ * Returns a {@code JsonObject} and advances the parser to the
+ * corresponding {@code END_OBJECT}.
+ *
+ * @return the {@code JsonObject} at the current parser position
+ *
+ * @throws IllegalStateException when the parser state is not
+ * {@code START_OBJECT}
+ *
+ * @since 1.1
+ */
+ default public JsonObject getObject() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a {@code JsonValue} at the current parser position.
+ * If the parser state is {@code START_ARRAY}, the behavior is
+ * the same as {@link #getArray}. If the parser state is
+ * {@code START_OBJECT}, the behavior is the same as
+ * {@link #getObject}. For all other cases, if applicable, the JSON value is
+ * read and returned.
+ *
+ * @return the {@code JsonValue} at the current parser position.
+ * @throws IllegalStateException when the parser state is
+ * {@code END_ARRAY} or {@code END_ARRAY}
+ *
+ * @since 1.1
+ */
+ default public JsonValue getValue() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a {@code JsonArray} and advance the parser to the
+ * the corresponding {@code END_ARRAY}.
+ *
+ * @return the {@code JsonArray} at the current parser position
+ *
+ * @throws IllegalStateException when the parser state is not
+ * {@code START_ARRAY}
+ *
+ * @since 1.1
+ */
+ default public JsonArray getArray() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a stream of the {@code JsonArray} elements.
+ * The parser state must be {@code START_ARRAY}.
+ * The elements are read lazily, on an as-needed basis, as
+ * required by the stream operations.
+ * If the stream operations do not consume
+ * all of the array elements, {@link skipArray} can be used to
+ * skip the unprocessed array elements.
+ *
+ * @return a stream of elements of the {@code JsonArray}
+ *
+ * @throws IllegalStateException when the parser state is not
+ * {@code START_ARRAY}
+ *
+ * @since 1.1
+ */
+ default public Stream<JsonValue> getArrayStream() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a stream of the {@code JsonObject}'s
+ * name/value pairs. The parser state must be {@code START_OBJECT}.
+ * The name/value pairs are read lazily, on an as-needed basis, as
+ * required by the stream operations.
+ * If the stream operations do not consume
+ * all of the object's name/value pairs, {@link skipObject} can be
+ * used to skip the unprocessed elements.
+ *
+ * @return a stream of name/value pairs of the {@code JsonObject}
+ *
+ * @throws IllegalStateException when the parser state is not
+ * {@code START_OBJECT}
+ *
+ * @since 1.1
+ */
+ default public Stream<Map.Entry<String,JsonValue>> getObjectStream() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns a stream of {@code JsonValue} from a sequence of
+ * JSON values. The values are read lazily, on an as-needed basis,
+ * as needed by the stream operations.
+ *
+ * @return a Stream of {@code JsonValue}
+ *
+ * @throws IllegalStateException if the parser is in an array or object.
+ *
+ * @since 1.1
+ */
+ default public Stream<JsonValue> getValueStream() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Advance the parser to {@code END_ARRAY}.
+ * If the parser is in array context, i.e. it has previously
+ * encountered a {@code START_ARRAY} without encountering the
+ * corresponding {@code END_ARRAY}, the parser is advanced to
+ * the corresponding {@code END_ARRAY}.
+ * If the parser is not in any array context, nothing happens.
+ *
+ * @since 1.1
+ */
+ default public void skipArray() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Advance the parser to {@code END_OBJECT}.
+ * If the parser is in object context, i.e. it has previously
+ * encountered a {@code START_OBJECT} without encountering the
+ * corresponding {@code END_OBJECT}, the parser is advanced to
+ * the corresponding {@code END_OBJECT}.
+ * If the parser is not in any object context, nothing happens.
+ *
+ * @since 1.1
+ */
+ default public void skipObject() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Closes this parser and frees any resources associated with the
+ * parser. This method closes the underlying input source.
+ *
+ * @throws javax.json.JsonException if an i/o error occurs (IOException
+ * would be cause of JsonException)
+ */
+ @Override
+ void close();
+}
diff --git a/api/src/main/java/javax/json/stream/JsonParserFactory.java b/api/src/main/java/javax/json/stream/JsonParserFactory.java
new file mode 100644
index 0000000..fc8a438
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonParserFactory.java
@@ -0,0 +1,132 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory for creating {@link JsonParser} instances. If a factory
+ * instance is configured with a configuration, the configuration applies
+ * to all parser instances created using that factory instance.
+ *
+ * <p>
+ * The class {@link javax.json.Json Json} also provides methods to create
+ * {@link JsonParser} instances, but using {@code JsonParserFactory} is
+ * preferred when creating multiple parser instances as shown in the following
+ * example:
+ *
+ * <pre>
+ * <code>
+ * JsonParserFactory factory = Json.createParserFactory();
+ * JsonParser parser1 = factory.createParser(...);
+ * JsonParser parser2 = factory.createParser(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ */
+public interface JsonParserFactory {
+
+ /**
+ * Creates a JSON parser from a character stream.
+ *
+ * @param reader a i/o reader from which JSON is to be read
+ * @return the created JSON parser
+ */
+ JsonParser createParser(Reader reader);
+
+ /**
+ * Creates a JSON parser from the specified byte stream.
+ * The character encoding of the stream is determined
+ * as specified in <a href="http://tools.ietf.org/rfc/rfc7159.txt">RFC 7159</a>.
+ *
+ * @param in i/o stream from which JSON is to be read
+ * @return the created JSON parser
+ * @throws javax.json.JsonException if encoding cannot be determined
+ * or i/o error (IOException would be cause of JsonException)
+ */
+ JsonParser createParser(InputStream in);
+
+ /**
+ * Creates a JSON parser from the specified byte stream.
+ * The bytes of the stream are decoded to characters using the
+ * specified charset.
+ *
+ * @param in i/o stream from which JSON is to be read
+ * @param charset a charset
+ * @return the created JSON parser
+ */
+ JsonParser createParser(InputStream in, Charset charset);
+
+ /**
+ * Creates a JSON parser from the specified JSON object.
+ *
+ * @param obj a JSON object
+ * @return the created JSON parser
+ */
+ JsonParser createParser(JsonObject obj);
+
+ /**
+ * Creates a JSON parser from the specified JSON array.
+ *
+ * @param array a JSON array
+ * @return the created JSON parser
+ */
+ JsonParser createParser(JsonArray array);
+
+ /**
+ * Returns a read-only map of supported provider specific configuration
+ * properties that are used to configure the JSON parsers.
+ * If there are any specified configuration properties that are not
+ * supported by the provider, they won't be part of the returned map.
+ *
+ * @return a map of supported provider specific properties that are used
+ * to configure the created parsers. The map may be empty but not null
+ */
+ Map<String, ?> getConfigInUse();
+
+}
diff --git a/api/src/main/java/javax/json/stream/JsonParsingException.java b/api/src/main/java/javax/json/stream/JsonParsingException.java
new file mode 100644
index 0000000..450747f
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/JsonParsingException.java
@@ -0,0 +1,96 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonException;
+
+/**
+ * {@code JsonParsingException} is used when an incorrect JSON is
+ * being parsed.
+ */
+public class JsonParsingException extends JsonException {
+
+ private final JsonLocation location;
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ * @param location the location of the incorrect JSON
+ */
+ public JsonParsingException(String message, JsonLocation location) {
+ super(message);
+ this.location = location;
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message and
+ * cause. <p>Note that the detail message associated with
+ * {@code cause} is <i>not</i> automatically incorporated in
+ * this runtime exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval
+ * by the {@link #getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the
+ * {@link #getCause()} method). (A <tt>null</tt> value is
+ * permitted, and indicates that the cause is nonexistent or
+ * unknown.)
+ * @param location the location of the incorrect JSON
+ */
+ public JsonParsingException(String message, Throwable cause, JsonLocation location) {
+ super(message, cause);
+ this.location = location;
+ }
+
+ /**
+ * Return the location of the incorrect JSON.
+ *
+ * @return the non-null location of the incorrect JSON
+ */
+ public JsonLocation getLocation() {
+ return location;
+ }
+
+}
+
diff --git a/api/src/main/java/javax/json/stream/package-info.java b/api/src/main/java/javax/json/stream/package-info.java
new file mode 100644
index 0000000..1f00daa
--- /dev/null
+++ b/api/src/main/java/javax/json/stream/package-info.java
@@ -0,0 +1,71 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Provides a streaming API to parse and generate
+ * <a href="http://json.org/">JSON</a>.
+ *
+ * <p>
+ * The streaming API consists of the interfaces
+ * {@link javax.json.stream.JsonParser} and
+ * {@link javax.json.stream.JsonGenerator}. The interface {@code JsonParser}
+ * contains methods to parse JSON in a streaming way. The interface
+ * {@code JsonGenerator} contains methods to write JSON to an output source
+ * in a streaming way.
+ *
+ * <p>
+ * {@code JsonParser} provides forward, read-only access to JSON data using the
+ * pull parsing programming model. In this model the application code controls
+ * the thread and calls methods in the parser interface to move the parser
+ * forward or to obtain JSON data from the current state of the parser.
+ *
+ * <p>
+ * {@code JsonGenerator} provides methods to write JSON to an output source.
+ * The generator writes name/value pairs in JSON objects and values in JSON
+ * arrays.
+ *
+ * <p>
+ * The streaming API is a low-level API designed to process large amounts of
+ * JSON data efficiently. Other JSON frameworks (such as JSON binding) can be
+ * implemented using this API.
+ *
+ * @since JSON Processing 1.0
+ */
+package javax.json.stream;
diff --git a/api/src/main/javadoc/doc-files/speclicense.html b/api/src/main/javadoc/doc-files/speclicense.html
new file mode 100644
index 0000000..3d55d92
--- /dev/null
+++ b/api/src/main/javadoc/doc-files/speclicense.html
@@ -0,0 +1,217 @@
+<html>
+<head>
+<title>Specification License</title>
+</head>
+<body>
+Specification: JSR-353 Java API for JSON Processing ("Specification")
+<br/>
+Version: 1.0
+<br/>
+Status: Final Release
+<br/>
+Specification Lead: Oracle America, Inc. ("Specification Lead")
+<br/>
+Release: Apr 15th, 2013
+<br/>
+
+<br/>
+Copyright © <Year> Oracle America, Inc.
+<br/>
+All rights reserved.
+<br/>
+<p>
+LIMITED LICENSE GRANTS
+<br/>
+1. License for Evaluation Purposes. Specification Lead hereby grants
+you a fully-paid, non-exclusive, non-transferable, worldwide, limited
+license (without the right to sublicense), under Specification Lead's
+applicable intellectual property rights to view, download, use and
+reproduce the Specification only for the purpose of internal
+evaluation. This includes (i) developing applications intended to run
+on an implementation of the Specification, provided that such
+applications do not themselves implement any portion(s) of the
+Specification, and (ii) discussing the Specification with any third
+party; and (iii) excerpting brief portions of the Specification in oral
+or written communications which discuss the Specification provided that
+such excerpts do not in the aggregate constitute a significant portion
+of the Specification.
+</p>
+<p>
+2. License for the Distribution of Compliant Implementations.
+Specification Lead also grants you a perpetual, non-exclusive,
+non-transferable, worldwide, fully paid-up, royalty free, limited
+license (without the right to sublicense) under any applicable
+copyrights or, subject to the provisions of subsection 4 below, patent
+rights it may have covering the Specification to create and/or
+distribute an Independent Implementation of the Specification that: (a)
+fully implements the Specification including all its required
+interfaces and functionality; (b) does not modify, subset, superset or
+otherwise extend the Licensor Name Space, or include any public or
+protected packages, classes, Java interfaces, fields or methods within
+the Licensor Name Space other than those required/authorized by the
+Specification or Specifications being implemented; and (c) passes the
+Technology Compatibility Kit (including satisfying the requirements of
+the applicable TCK Users Guide) for such Specification ("Compliant
+Implementation"). In addition, the foregoing license is expressly
+conditioned on your not acting outside its scope. No license is
+granted hereunder for any other purpose (including, for example,
+modifying the Specification, other than to the extent of your fair use
+rights, or distributing the Specification to third parties). Also, no
+right, title, or interest in or to any trademarks, service marks, or
+trade names of Specification Lead or Specification Lead's licensors is
+granted hereunder. Java, and Java-related logos, marks and names are
+trademarks or registered trademarks of Oracle America, Inc. in the U.S.
+and other countries.
+</p>
+<p>
+3. Pass-through Conditions. You need not include limitations (a)-(c)
+from the previous paragraph or any other particular "pass through"
+requirements in any license You grant concerning the use of your
+Independent Implementation or products derived from it. However,
+except with respect to Independent Implementations (and products
+derived from them) that satisfy limitations (a)-(c) from the previous
+paragraph, You may neither: (a) grant or otherwise pass through to
+your licensees any licenses under Specification Lead's applicable
+intellectual property rights; nor (b) authorize your licensees to make
+any claims concerning their implementation's compliance with the
+Specification in question.
+</p>
+<p>
+4. Reciprocity Concerning Patent Licenses.
+<br/>
+a. With respect to any patent claims covered by the license granted
+under subparagraph 2 above that would be infringed by all technically
+feasible implementations of the Specification, such license is
+conditioned upon your offering on fair, reasonable and
+non-discriminatory terms, to any party seeking it from You, a
+perpetual, non-exclusive, non-transferable, worldwide license under
+Your patent rights which are or would be infringed by all technically
+feasible implementations of the Specification to develop, distribute
+and use a Compliant Implementation.
+<br/>
+b. With respect to any patent claims owned by Specification Lead and
+covered by the license granted under subparagraph 2, whether or not
+their infringement can be avoided in a technically feasible manner when
+implementing the Specification, such license shall terminate with
+respect to such claims if You initiate a claim against Specification
+Lead that it has, in the course of performing its responsibilities as
+the Specification Lead, induced any other entity to infringe Your
+patent rights.
+<br/>
+c. Also with respect to any patent claims owned by Specification Lead
+and covered by the license granted under subparagraph 2 above, where
+the infringement of such claims can be avoided in a technically
+feasible manner when implementing the Specification such license, with
+respect to such claims, shall terminate if You initiate a claim against
+Specification Lead that its making, having made, using, offering to
+sell, selling or importing a Compliant Implementation infringes Your
+patent rights.
+</p>
+<p>
+5. Definitions. For the purposes of this Agreement: "Independent
+Implementation" shall mean an implementation of the Specification that
+neither derives from any of Specification Lead's source code or binary
+code materials nor, except with an appropriate and separate license
+from Specification Lead, includes any of Specification Lead's source
+code or binary code materials; "Licensor Name Space" shall mean the
+public class or interface declarations whose names begin with "java",
+"javax", "com.<Specification Lead>" or their equivalents in any
+subsequent naming convention adopted by Oracle through the Java
+Community Process, or any recognized successors or replacements
+thereof; and "Technology Compatibility Kit" or "TCK" shall mean the
+test suite and accompanying TCK User's Guide provided by Specification
+Lead which corresponds to the Specification and that was available
+either (i) from Specification Lead's 120 days before the first release
+of Your Independent Implementation that allows its use for commercial
+purposes, or (ii) more recently than 120 days from such release but
+against which You elect to test Your implementation of the
+Specification.
+</p>
+<p>
+This Agreement will terminate immediately without notice from
+Specification Lead if you breach the Agreement or act outside the scope
+of the licenses granted above.
+</p>
+<p>
+DISCLAIMER OF WARRANTIES
+<br/>
+THE SPECIFICATION IS PROVIDED "AS IS". SPECIFICATION LEAD MAKES NO
+REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
+NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE, NON-INFRINGEMENT (INCLUDING AS A CONSEQUENCE OF ANY PRACTICE
+OR IMPLEMENTATION OF THE SPECIFICATION), OR THAT THE CONTENTS OF THE
+SPECIFICATION ARE SUITABLE FOR ANY PURPOSE. This document does not
+represent any commitment to release or implement any portion of the
+Specification in any product. In addition, the Specification could
+include technical inaccuracies or typographical errors.
+</p>
+<p>
+LIMITATION OF LIABILITY
+<br/>
+TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SPECIFICATION
+LEAD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES, INCLUDING WITHOUT
+LIMITATION, LOST REVENUE, PROFITS OR DATA, OR FOR SPECIAL, INDIRECT,
+CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
+REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED IN ANY
+WAY TO YOUR HAVING, IMPELEMENTING OR OTHERWISE USING USING THE
+SPECIFICATION, EVEN IF SPECIFICATION LEAD AND/OR ITS LICENSORS HAVE
+BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. You will indemnify,
+hold harmless, and defend Specification Lead and its licensors from any
+claims arising or resulting from: (i) your use of the Specification;
+(ii) the use or distribution of your Java application, applet and/or
+implementation; and/or (iii) any claims that later versions or releases
+of any Specification furnished to you are incompatible with the
+Specification provided to you under this license.
+</p>
+<p>
+RESTRICTED RIGHTS LEGEND
+<br/>
+U.S. Government: If this Specification is being acquired by or on
+behalf of the U.S. Government or by a U.S. Government prime contractor
+or subcontractor (at any tier), then the Government's rights in the
+Software and accompanying documentation shall be only as set forth in
+this license; this is in accordance with 48 C.F.R. 227.7201 through
+227.7202-4 (for Department of Defense (DoD) acquisitions) and with 48
+C.F.R. 2.101 and 12.212 (for non-DoD acquisitions).
+</p>
+<p>
+REPORT
+<br/>
+If you provide Specification Lead with any comments or suggestions
+concerning the Specification ("Feedback"), you hereby: (i) agree that
+such Feedback is provided on a non-proprietary and non-confidential
+basis, and (ii) grant Specification Lead a perpetual, non-exclusive,
+worldwide, fully paid-up, irrevocable license, with the right to
+sublicense through multiple levels of sublicensees, to incorporate,
+disclose, and use without limitation the Feedback for any purpose.
+</p>
+<p>
+GENERAL TERMS
+<br/>
+Any action related to this Agreement will be governed by California law
+and controlling U.S. federal law. The U.N. Convention for the
+International Sale of Goods and the choice of law rules of any
+jurisdiction will not apply.
+</p>
+<p>
+The Specification is subject to U.S. export control laws and may be
+subject to export or import regulations in other countries. Licensee
+agrees to comply strictly with all such laws and regulations and
+acknowledges that it has the responsibility to obtain such licenses to
+export, re-export or import as may be required after delivery to
+Licensee.
+</p>
+<p>
+This Agreement is the parties' entire agreement relating to its subject
+matter. It supersedes all prior or contemporaneous oral or written
+communications, proposals, conditions, representations and warranties
+and prevails over any conflicting or additional terms of any quote,
+order, acknowledgment, or other communication between the parties
+relating to its subject matter during the term of this Agreement. No
+modification to this Agreement will be binding, unless in writing and
+signed by an authorized representative of each party.
+</p>
+<br/>
+Rev. April, 2006
+</body>
+</html>
diff --git a/api/src/main/javadoc/overview.html b/api/src/main/javadoc/overview.html
new file mode 100644
index 0000000..77ff8d1
--- /dev/null
+++ b/api/src/main/javadoc/overview.html
@@ -0,0 +1,90 @@
+<html>
+<body>
+The Java API for JSON Processing provides portable APIs to parse,
+generate, transform, and query <a href="http://json.org/">JSON</a> using the
+streaming API or the object model API.
+
+<p>The Streaming API provides a way to parsing and generation of JSON in a
+streaming fashion. It hands over parsing and generation control to the
+programmer. The streaming API provides an event-based parser and allows an
+application developer to ask for the next event rather than handling the event
+in a callback. This gives a developer more procedural control over
+the processing of the JSON. Application code can process or discard
+the parser event, and ask for the next event(pull the event). The
+streaming model is adequate for local processing where random access of other
+parts of the data is not required. Similarly, the streaming API provides
+a way to generate well-formed JSON to a stream by writing one event at a time.
+
+<p>The object model API creates a random access tree-like structure that
+represents the JSON data in memory. The tree can then be navigated and
+queried. This programming model is the most flexible and enables processing
+that requires random access to the complete contents of the tree. However,
+it is often not as efficient as the streaming model and requires more memory.
+The object model generates JSON output by navigating the entire tree at once.
+
+<h2>The Streaming API</h2>
+<p>The streaming API is similar to the StAX API for XML and consists of the
+interfaces {@link javax.json.stream.JsonParser} and
+{@link javax.json.stream.JsonGenerator}. {@code JsonParser}
+contains methods to parse JSON data using the streaming model.
+{@code JsonGenerator} contains methods to write JSON data to an ouptut source.
+
+<p>{@code JsonParser} provides forward, read-only access to
+JSON data using the pull parsing programming model. In this model the
+application code controls the thread and calls methods in the parser interface
+to move the parser forward or to obtain JSON data from the current state of
+the parser. Refer to
+<a href="javax/json/stream/JsonParser.html#JsonParserExample2">this example</a>
+for more details.
+
+<p>{@code JsonGenerator} provides methods to write JSON to a stream. The
+generator writes name/value pairs in JSON objects and values in JSON arrays.
+Refer to
+<a href="javax/json/stream/JsonGenerator.html#JsonGeneratorExample3">this
+example</a> for more details.
+
+<p>The streaming API is a low-level API designed to process large amounts of
+JSON data efficiently. Other JSON frameworks (such as JSON binding) can be
+implemented using this API.</p>
+
+<h2>The Object Model API</h2>
+<p>The object model API is similar to the DOM API for XML. It is a high-level
+API that provides immutable object models for JSON object and array structures.
+These JSON structures are represented as object models using the Java types
+{@link javax.json.JsonObject} and {@link javax.json.JsonArray}.
+{@code JsonObject} provides a {@link java.util.Map} view to access the unordered
+collection of zero or more name/value pairs from the model. Similarly,
+{@code JsonArray} provides a {@link java.util.List} view to access the ordered
+sequence of zero or more values from the model.
+
+<p>The object model API uses builder patterns to create these object models.
+Application code can use the interface {@link javax.json.JsonObjectBuilder}
+to create models that represent JSON objects. The resulting model is of type
+{@code JsonObject}. Refer to
+<a href="javax/json/JsonObjectBuilder.html#JsonObjectBuilderExample1">this example</a>
+for more details. Application code can use the interface
+{@link javax.json.JsonArrayBuilder} to create models that represent JSON arrays.
+The resulting model is of type {@code JsonArray}. Refer to
+<a href="javax/json/JsonArrayBuilder.html#JsonArrayBuilderExample1">this example</a>
+for more details.
+
+<p>These object models can also be created from an input source (such as
+{@link java.io.InputStream} or {@link java.io.Reader}) using the interface
+{@link javax.json.JsonReader}.
+<a href="javax/json/JsonReader.html#JsonReaderExample1">This example</a> shows
+how to read and create an empty {@code JsonArray} model using the interface
+{@code JsonReader}. Similarly, these object models can be written to an output
+source (such as {@link java.io.OutputStream} or {@link java.io.Writer}) using
+the class {@link javax.json.JsonWriter}.
+<a href="javax/json/JsonWriter.html#JsonWriterExample1">This example</a> shows
+how to write an empty {@code JsonObject} model using the interface
+{@code JsonWriter}.
+
+<h2>JSON Pointer, JSON Patch, and JSON Merge Patch</h2>
+The Java API for JSON Processing supports the latest standard on
+<a href="http://tools.ietf.org/html/rfc6901">JSON Pointer</a>,
+<a Href="http://tools.ietf.org/html/rfc6902">JSON Patch</a>, and
+<a Href="http://tools.ietf.org/html/rfc7396">JSON Merge Patch</a>.
+
+</body>
+</html>
diff --git a/bundles/licensee/pom.xml b/bundles/licensee/pom.xml
new file mode 100755
index 0000000..e36e61a
--- /dev/null
+++ b/bundles/licensee/pom.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json-bundles</artifactId>
+ <version>1.1</version>
+ </parent>
+
+ <artifactId>json-licensee-bundle</artifactId>
+ <name>Licensee source bundle</name>
+ <packaging>pom</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>wagon-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>get-license</id>
+ <phase>package</phase>
+ <goals>
+ <goal>download-single</goal>
+ </goals>
+ <configuration>
+ <url>${license.url}</url>
+ <fromFile>TLDA_SCSL_Licensees_License_Notice.txt</fromFile>
+ <toDir>${assembly.directory}</toDir>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <finalName>javax.json-ri-${impl_version}-src-licensee</finalName>
+ <descriptors>
+ <descriptor>src/main/assembly/archive.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>attached</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <properties>
+ <assembly.directory>${project.build.directory}/assembly</assembly.directory>
+ <license.url>http://hudson-sca.us.oracle.com/job/tlda-license/lastSuccessfulBuild/artifact</license.url>
+ </properties>
+
+</project>
diff --git a/bundles/licensee/src/main/assembly/archive.xml b/bundles/licensee/src/main/assembly/archive.xml
new file mode 100755
index 0000000..0de7767
--- /dev/null
+++ b/bundles/licensee/src/main/assembly/archive.xml
@@ -0,0 +1,69 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<assembly>
+ <id>dist</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>../..</directory>
+ <includes>
+ <include>api/**</include>
+ <include>impl/**</include>
+ </includes>
+ <excludes>
+ <exclude>api/target/**</exclude>
+ <exclude>impl/target/**</exclude>
+ <exclude>**/*.iml</exclude>
+ </excludes>
+ <outputDirectory/>
+ </fileSet>
+ <fileSet>
+ <directory>target/assembly</directory>
+ <includes>
+ <include>*.txt</include>
+ </includes>
+ <outputDirectory/>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/bundles/pom.xml b/bundles/pom.xml
new file mode 100644
index 0000000..37fc976
--- /dev/null
+++ b/bundles/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.glassfish</groupId>
+ <artifactId>json-bundles</artifactId>
+ <packaging>pom</packaging>
+ <name>JSR 374 (JSON Processing) bundles</name>
+ <description>JSON Processing bundles</description>
+ <url>http://json-processing-spec.java.net</url>
+
+ <modules>
+ <module>ri</module>
+ </modules>
+ <profiles>
+ <profile>
+ <id>licensee</id>
+ <modules>
+ <module>licensee</module>
+ </modules>
+ </profile>
+ </profiles>
+</project>
diff --git a/bundles/ri/pom.xml b/bundles/ri/pom.xml
new file mode 100755
index 0000000..7bef0d6
--- /dev/null
+++ b/bundles/ri/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json-bundles</artifactId>
+ <version>1.1</version>
+ </parent>
+
+ <artifactId>json-ri-bundle</artifactId>
+ <name>RI bundle</name>
+ <packaging>pom</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>copy</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <stripVersion>false</stripVersion>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <type>jar</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${assembly.directory}</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <finalName>javax.json-ri-${impl_version}</finalName>
+ <descriptors>
+ <descriptor>src/main/assembly/archive.xml</descriptor>
+ </descriptors>
+ <appendAssemblyId>false</appendAssemblyId>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id> <!-- this is used for inheritance merges -->
+ <phase>package</phase> <!-- append to the packaging phase. -->
+ <goals>
+ <goal>attached</goal> <!-- goals == mojos -->
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <properties>
+ <assembly.directory>${project.build.directory}/assembly</assembly.directory>
+ </properties>
+
+</project>
diff --git a/bundles/ri/src/main/assembly/archive.xml b/bundles/ri/src/main/assembly/archive.xml
new file mode 100755
index 0000000..676c934
--- /dev/null
+++ b/bundles/ri/src/main/assembly/archive.xml
@@ -0,0 +1,60 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ http://glassfish.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+<assembly>
+ <id>dist</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <fileSets>
+ <fileSet>
+ <directory>src/main/resources</directory>
+ <outputDirectory></outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>target/assembly</directory>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ <outputDirectory>lib</outputDirectory>
+ </fileSet>
+ </fileSets>
+</assembly>
diff --git a/bundles/ri/src/main/resources/LICENSE.txt b/bundles/ri/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..833a843
--- /dev/null
+++ b/bundles/ri/src/main/resources/LICENSE.txt
@@ -0,0 +1,274 @@
+COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)Version 1.1
+
+1. Definitions.
+
+ 1.1. "Contributor" means each individual or entity that creates or contributes to the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original Software, prior Modifications used by a Contributor (if any), and the Modifications made by that particular Contributor.
+
+ 1.3. "Covered Software" means (a) the Original Software, or (b) Modifications, or (c) the combination of files containing Original Software with files containing Modifications, in each case including portions thereof.
+
+ 1.4. "Executable" means the Covered Software in any form other than Source Code.
+
+ 1.5. "Initial Developer" means the individual or entity that first makes Original Software available under this License.
+
+ 1.6. "Larger Work" means a work which combines Covered Software or portions thereof with code not governed by the terms of this License.
+
+ 1.7. "License" means this document.
+
+ 1.8. "Licensable" means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means the Source Code and Executable form of any of the following:
+
+ A. Any file that results from an addition to, deletion from or modification of the contents of a file containing Original Software or previous Modifications;
+
+ B. Any new file that contains any part of the Original Software or previous Modification; or
+
+ C. Any new file that is contributed or otherwise made available under the terms of this License.
+
+ 1.10. "Original Software" means the Source Code and Executable form of computer software code that is originally released under this License.
+
+ 1.11. "Patent Claims" means any patent claim(s), now owned or hereafter acquired, including without limitation, method, process, and apparatus claims, in any patent Licensable by grantor.
+
+ 1.12. "Source Code" means (a) the common form of computer software code in which modifications are made and (b) associated documentation included in or with such code.
+
+ 1.13. "You" (or "Your") means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of more than fifty percent (50%) of the o [...]
+
+2. License Grants.
+
+ 2.1. The Initial Developer Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, the Initial Developer hereby grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Initial Developer, to use, reproduce, modify, display, perform, sublicense and distribute the Original Software (or portions thereof), with or without Modifications, and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using or selling of Original Software, to make, have made, use, practice, sell, and offer for sale, and/or otherwise dispose of the Original Software (or portions thereof).
+
+ (c) The licenses granted in Sections 2.1(a) and (b) are effective on the date Initial Developer first distributes or otherwise makes the Original Software available to a third party under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is granted: (1) for code that You delete from the Original Software, or (2) for infringements caused by: (i) the modification of the Original Software, or (ii) the combination of the Original Software with other software or devices.
+
+ 2.2. Contributor Grant.
+
+ Conditioned upon Your compliance with Section 3.1 below and subject to third party intellectual property claims, each Contributor hereby grants You a world-wide, royalty-free, non-exclusive license:
+
+ (a) under intellectual property rights (other than patent or trademark) Licensable by Contributor to use, reproduce, modify, display, perform, sublicense and distribute the Modifications created by such Contributor (or portions thereof), either on an unmodified basis, with other Modifications, as Covered Software and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or selling of Modifications made by that Contributor either alone and/or in combination with its Contributor Version (or portions of such combination), to make, use, sell, offer for sale, have made, and/or otherwise dispose of: (1) Modifications made by that Contributor (or portions thereof); and (2) the combination of Modifications made by that Contributor with its Contributor Version (or portions of such combination).
+
+ (c) The licenses granted in Sections 2.2(a) and 2.2(b) are effective on the date Contributor first distributes or otherwise makes the Modifications available to a third party.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is granted: (1) for any code that Contributor has deleted from the Contributor Version; (2) for infringements caused by: (i) third party modifications of Contributor Version, or (ii) the combination of Modifications made by that Contributor with other software (except as part of the Contributor Version) or other devices; or (3) under Patent Claims infringed by Covered Software in the absence of Modifications made by that Co [...]
+
+3. Distribution Obligations.
+
+ 3.1. Availability of Source Code.
+
+ Any Covered Software that You distribute or otherwise make available in Executable form must also be made available in Source Code form and that Source Code form must be distributed only under the terms of this License. You must include a copy of this License with every copy of the Source Code form of the Covered Software You distribute or otherwise make available. You must inform recipients of any such Covered Software in Executable form as to how they can obtain such Covered Softw [...]
+
+ 3.2. Modifications.
+
+ The Modifications that You create or to which You contribute are governed by the terms of this License. You represent that You believe Your Modifications are Your original creation(s) and/or You have sufficient rights to grant the rights conveyed by this License.
+
+ 3.3. Required Notices.
+
+ You must include a notice in each of Your Modifications that identifies You as the Contributor of the Modification. You may not remove or alter any copyright, patent or trademark notices contained within the Covered Software, or any notices of licensing or any descriptive text giving attribution to any Contributor or the Initial Developer.
+
+ 3.4. Application of Additional Terms.
+
+ You may not offer or impose any terms on any Covered Software in Source Code form that alters or restricts the applicable version of this License or the recipients' rights hereunder. You may choose to offer, and to charge a fee for, warranty, support, indemnity or liability obligations to one or more recipients of Covered Software. However, you may do so only on Your own behalf, and not on behalf of the Initial Developer or any Contributor. You must make it absolutely clear that any [...]
+
+ 3.5. Distribution of Executable Versions.
+
+ You may distribute the Executable form of the Covered Software under the terms of this License or under the terms of a license of Your choice, which may contain terms different from this License, provided that You are in compliance with the terms of this License and that the license for the Executable form does not attempt to limit or alter the recipient's rights in the Source Code form from the rights set forth in this License. If You distribute the Covered Software in Executable f [...]
+
+ 3.6. Larger Works.
+
+ You may create a Larger Work by combining Covered Software with other code not governed by the terms of this License and distribute the Larger Work as a single product. In such a case, You must make sure the requirements of this License are fulfilled for the Covered Software.
+
+4. Versions of the License.
+
+ 4.1. New Versions.
+
+ Oracle is the initial license steward and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. Except as provided in Section 4.3, no one other than the license steward has the right to modify this License.
+
+ 4.2. Effect of New Versions.
+
+ You may always continue to use, distribute or otherwise make the Covered Software available under the terms of the version of the License under which You originally received the Covered Software. If the Initial Developer includes a notice in the Original Software prohibiting it from being distributed or otherwise made available under any subsequent version of the License, You must distribute and make the Covered Software available under the terms of the version of the License under [...]
+
+ 4.3. Modified Versions.
+
+ When You are an Initial Developer and You want to create a new license for Your Original Software, You may create and use a modified version of this License if You: (a) rename the license and remove any references to the name of the license steward (except to note that the license differs from this License); and (b) otherwise make it clear that the license contains terms which differ from this License.
+
+5. DISCLAIMER OF WARRANTY.
+
+ COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUM [...]
+
+6. TERMINATION.
+
+ 6.1. This License and the rights granted hereunder will terminate automatically if You fail to comply with terms herein and fail to cure such breach within 30 days of becoming aware of the breach. Provisions which, by their nature, must remain in effect beyond the termination of this License shall survive.
+
+ 6.2. If You assert a patent infringement claim (excluding declaratory judgment actions) against Initial Developer or a Contributor (the Initial Developer or Contributor against whom You assert such claim is referred to as "Participant") alleging that the Participant Software (meaning the Contributor Version where the Participant is a Contributor or the Original Software where the Participant is the Initial Developer) directly or indirectly infringes any patent, then any and all righ [...]
+
+ 6.3. If You assert a patent infringement claim against Participant alleging that the Participant Software directly or indirectly infringes any patent where such claim is resolved (such as by license or settlement) prior to the initiation of patent infringement litigation, then the reasonable value of the licenses granted by such Participant under Sections 2.1 or 2.2 shall be taken into account in determining the amount or value of any payment or license.
+
+ 6.4. In the event of termination under Sections 6.1 or 6.2 above, all end user licenses that have been validly granted by You or any distributor hereunder prior to termination (excluding licenses granted to You by any distributor) shall survive termination.
+
+7. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMM [...]
+
+8. U.S. GOVERNMENT END USERS.
+
+ The Covered Software is a "commercial item," as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer software" (as that term is defined at 48 C.F.R. ? 252.227-7014(a)(1)) and "commercial computer software documentation" as such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Software with only those rights set for [...]
+
+9. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. This License shall be governed by the law of the jurisdiction specified in a notice contained within the Original Software (except to the extent applicable law, if any, provides otherwise), excluding such jurisdiction's conflict-of-law provisions. Any litiga [...]
+
+10. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is responsible for claims and damages arising, directly or indirectly, out of its utilization of rights under this License and You agree to work with Initial Developer and Contributors to distribute such responsibility on an equitable basis. Nothing herein is intended or shall be deemed to constitute any admission of liability.
+
+----------
+NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
+The code released under the CDDL shall be governed by the laws of the State of California (excluding conflict-of-law provisions). Any litigation relating to this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California.
+
+
+
+
+The GNU General Public License (GPL) Version 2, June 1991
+
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library Genera [...]
+
+When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. ( [...]
+
+Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.
+
+1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself i [...]
+
+These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose p [...]
+
+Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major co [...]
+
+If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works ba [...]
+
+6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not dist [...]
+
+If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/dono [...]
+
+This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. [...]
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO [...]
+
+END OF TERMS AND CONDITIONS
+
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+ One line to give the program's name and a brief idea of what it does.
+
+ Copyright (C)
+
+ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ signature of Ty Coon, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.
+
+
+"CLASSPATH" EXCEPTION TO THE GPL VERSION 2
+
+Certain source files distributed by Oracle are subject to the following clarification and special exception to the GPL Version 2, but only where Oracle has expressly included in the particular source file's header the words "Oracle designates this particular file as subject to the "Classpath" exception as provided by Oracle in the License file that accompanied this code."
+
+Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License Version 2 cover the whole combination.
+
+As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on th [...]
diff --git a/bundles/ri/src/main/resources/README.txt b/bundles/ri/src/main/resources/README.txt
new file mode 100644
index 0000000..c62b7d6
--- /dev/null
+++ b/bundles/ri/src/main/resources/README.txt
@@ -0,0 +1,13 @@
+* javax.json-1.0.jar contains both "JSR 353 : Java API for JSON Processing" API and its default provider implementation. Keep it in classpath for both compiling and running your application.
+
+* If you are running with maven, you can use the following maven coordinates:
+
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <version>1.0</version>
+ </dependency>
+
+* GlassFix 4.x already bundles latest JSON Processing implementation and JAX-RS integration module. If you deploy an application with GlassFish 4.x, your application (war/ear) doesn't have to bundle the ri jar.
+
+* Samples can be run from http://glassfish-samples.java.net
diff --git a/copyright-exclude b/copyright-exclude
new file mode 100644
index 0000000..f9016d9
--- /dev/null
+++ b/copyright-exclude
@@ -0,0 +1,5 @@
+.json
+/copyright-exclude
+/META-INF/services
+overview.html
+speclicense.html
diff --git a/demos/facebook/pom.xml b/demos/facebook/pom.xml
new file mode 100644
index 0000000..8b3946c
--- /dev/null
+++ b/demos/facebook/pom.xml
@@ -0,0 +1,95 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>jar</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>jsondemos-facebook</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+<!-- mvn exec:java
+-->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>org.glassfish.jsondemos.facebook.FacebookObjectSearch</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookObjectSearch.java b/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookObjectSearch.java
new file mode 100644
index 0000000..2d62173
--- /dev/null
+++ b/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookObjectSearch.java
@@ -0,0 +1,103 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.facebook;
+
+import javax.json.*;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * Parses JSON from facebook graph API using object model API.
+ * JSON would like :
+ *
+ * {
+ * data: [
+ * { "from" : { "name" : "xxx", ... }, "message: "yyy", ... },
+ * { "from" : { "name" : "ppp", ... }, "message: "qqq", ... },
+ * ...
+ * ],
+ * ...
+ * }
+ *
+ * This codes writes the facebook posts to output as follows:
+ * xxx: yyy
+ * --------
+ * ppp: qqq
+ * --------
+ *
+ * @author Jitendra Kotamraju
+ */
+public class FacebookObjectSearch {
+
+ public static void main(String... args) throws Exception {
+ try (InputStream is = getSearchStream();
+ JsonReader rdr = Json.createReader(is)) {
+
+ JsonObject obj = rdr.readObject();
+ JsonArray results = obj.getJsonArray("data");
+ for (JsonObject result : results.getValuesAs(JsonObject.class)) {
+ JsonValue value = result.get("from");
+ if (value != null && value instanceof JsonObject) {
+ System.out.print(((JsonObject)value).getString("name", "anon"));
+ }
+ System.out.print(": ");
+ System.out.println(result.getString("message", ""));
+ System.out.println("-----------");
+ }
+ }
+ }
+
+ static InputStream getSearchStream() throws Exception {
+ Properties config = new Properties();
+ config.load(FacebookObjectSearch.class.getResourceAsStream(
+ "/facebookconfig.properties"));
+ final String accessToken = (String)config.get("access_token");
+
+ // Gets the search stream
+ String searchUrl = "https://graph.facebook.com/search?q=tamil&type=post&access_token=";
+ URL url = new URL(searchUrl+accessToken);
+ HttpURLConnection con = (HttpURLConnection)url.openConnection();
+ return con.getInputStream();
+ }
+
+}
diff --git a/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookStreamSearch.java b/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookStreamSearch.java
new file mode 100644
index 0000000..fb0bf19
--- /dev/null
+++ b/demos/facebook/src/main/java/org/glassfish/jsondemos/facebook/FacebookStreamSearch.java
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.facebook;
+
+import javax.json.*;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+import java.io.*;
+
+/**
+ * Parses JSON from facebook graph API using streaming API.
+ * JSON would like :
+ *
+ * {
+ * data: [
+ * { "from" : { "name" : "xxx", ... }, "message: "yyy", ... },
+ * { "from" : { "name" : "ppp", ... }, "message: "qqq", ... },
+ * ...
+ * ],
+ * ...
+ * }
+ *
+ * This codes writes the facebook posts to output as follows:
+ * xxx: yyy
+ * --------
+ * ppp: qqq
+ * --------
+ *
+ * @author Jitendra Kotamraju
+ */
+public class FacebookStreamSearch {
+
+ public static void main(String... args) throws Exception {
+ try (InputStream is = FacebookObjectSearch.getSearchStream();
+ JsonParser parser = Json.createParser(is)) {
+ while (parser.hasNext()) {
+ Event e = parser.next();
+ if (e == Event.KEY_NAME) {
+ switch (parser.getString()) {
+ case "name":
+ parser.next();
+ System.out.print(parser.getString());
+ System.out.print(": ");
+ break;
+ case "message":
+ parser.next();
+ System.out.println(parser.getString());
+ System.out.println("---------");
+ break;
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/demos/facebook/src/main/resources/facebookconfig.properties b/demos/facebook/src/main/resources/facebookconfig.properties
new file mode 100644
index 0000000..d3b4abd
--- /dev/null
+++ b/demos/facebook/src/main/resources/facebookconfig.properties
@@ -0,0 +1 @@
+access_token=
diff --git a/demos/jaxrs/pom.xml b/demos/jaxrs/pom.xml
new file mode 100644
index 0000000..8f04af8
--- /dev/null
+++ b/demos/jaxrs/pom.xml
@@ -0,0 +1,90 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>war</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>jsondemos-jaxrs</artifactId>
+
+ <name>jsondemos-jaxrs</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <finalName>jsondemos-jaxrs</finalName>
+ </build>
+</project>
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ArrayResource.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ArrayResource.java
new file mode 100644
index 0000000..4d7c112
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ArrayResource.java
@@ -0,0 +1,75 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.*;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * JsonArray as parameter and return type for a JAX-RS resource
+ *
+ * @author Jitendra Kotamraju
+ */
+ at Path("/array")
+public class ArrayResource {
+ private static final JsonBuilderFactory bf = Json.createBuilderFactory(null);
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonArray doGet() {
+ return bf.createArrayBuilder()
+ .add(bf.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(bf.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567"))
+ .build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void doPost(JsonArray structure) {
+ System.out.println(structure);
+ }
+
+}
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/DemoApplication.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/DemoApplication.java
new file mode 100644
index 0000000..d5ea4b8
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/DemoApplication.java
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.stream.JsonGenerator;
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A JAX-RS Demo Application using JSON API
+ *
+ * @author Jitendra Kotamraju
+ */
+ at ApplicationPath("/")
+public class DemoApplication extends Application {
+
+ @Override
+ public Set<Class<?>> getClasses() {
+ Set<Class<?>> set = new HashSet<>();
+ set.add(ParserResource.class);
+ set.add(GeneratorResource.class);
+ set.add(ObjectResource.class);
+ set.add(ArrayResource.class);
+ set.add(StructureResource.class);
+
+ return set;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return new HashMap<String, Object>() {{
+ put(JsonGenerator.PRETTY_PRINTING, true);
+ }};
+ }
+}
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/GeneratorResource.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/GeneratorResource.java
new file mode 100644
index 0000000..240e627
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/GeneratorResource.java
@@ -0,0 +1,97 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.Json;
+import javax.json.stream.JsonGenerator;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.StreamingOutput;
+import java.io.OutputStream;
+
+/**
+ * Writes wiki's JSON example in a streaming fashion using JsonGenerator
+ *
+ * @author Jitendra Kotamraju
+ */
+ at Path("/generator")
+public class GeneratorResource {
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public StreamingOutput doGet() {
+ return new StreamingOutput() {
+ public void write(OutputStream os) {
+ writeWikiExample(os);
+ }
+ };
+ }
+
+ // Writes wiki example JSON in a streaming fashion
+ private void writeWikiExample(OutputStream os) {
+ try(JsonGenerator gene = Json.createGenerator(os)) {
+ gene.writeStartObject()
+ .write("firstName", "John")
+ .write("lastName", "Smith")
+ .write("age", 25)
+ .writeStartObject("address")
+ .write("streetAddress", "21 2nd Street")
+ .write("city", "New York")
+ .write("state", "NY")
+ .write("postalCode", "10021")
+ .writeEnd()
+ .writeStartArray("phoneNumber")
+ .writeStartObject()
+ .write("type", "home")
+ .write("number", "212 555-1234")
+ .writeEnd()
+ .writeStartObject()
+ .write("type", "fax")
+ .write("number", "646 555-4567")
+ .writeEnd()
+ .writeEnd()
+ .writeEnd();
+ }
+ }
+
+}
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ObjectResource.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ObjectResource.java
new file mode 100644
index 0000000..2c693d9
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ObjectResource.java
@@ -0,0 +1,85 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.*;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * JsonObject as parameter and return type for a JAX-RS resource
+ * Writes a person's representation as JSON using JsonObject
+ *
+ * @author Jitendra Kotamraju
+ */
+ at Path("/object")
+public class ObjectResource {
+ private static final JsonBuilderFactory bf = Json.createBuilderFactory(null);
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonObject doGet() {
+ return bf.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", bf.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", bf.createArrayBuilder()
+ .add(bf.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(bf.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void doPost(JsonObject structure) {
+ System.out.println(structure);
+ }
+
+}
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ParserResource.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ParserResource.java
new file mode 100644
index 0000000..a4d9992
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/ParserResource.java
@@ -0,0 +1,122 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.Json;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.StreamingOutput;
+import java.io.*;
+import java.net.URL;
+
+/**
+ * Filters JSON from flicker photo search REST API
+ *
+ * {
+ * photos : {
+ * photo: [
+ * { id: "9889087315", secret: "40aeb70c83", server: "3818",farm: 4, ..},
+ * { id: "9889087315", secret: "40aeb70c83", server: "3818",farm: 4, ..}
+ * ...
+ * ],
+ * ...
+ * }
+ * }
+ *
+ * @author Jitendra Kotamraju
+ */
+ at Path("/parser")
+public class ParserResource {
+
+ @GET
+ @Produces("text/html")
+ public StreamingOutput doGet() {
+ return new StreamingOutput() {
+ public void write(OutputStream os) throws IOException {
+ writeFlickerFeed(os);
+ }
+ };
+ }
+
+ private void writeFlickerFeed(OutputStream os) throws IOException {
+ URL url = new URL("http://api.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=221160312e1c22ec60ecf336951b0e77&format=json&nojsoncallback=1&per_page=20");
+ try(InputStream is = url.openStream();
+ JsonParser parser = Json.createParser(is);
+ PrintWriter ps = new PrintWriter(new OutputStreamWriter(os, "UTF-8"))) {
+ String id = null;
+ String server = null;
+ String secret = null;
+
+ ps.println("<html><body>");
+ while(parser.hasNext()) {
+ Event e = parser.next();
+ if (e == Event.KEY_NAME) {
+ String str = parser.getString();
+ switch (str) {
+ case "id" :
+ parser.next();
+ id = parser.getString();
+ break;
+ case "farm" :
+ parser.next();
+ String farm = parser.getString();
+ ps.println("<img src=\"http://farm"+farm+".staticflickr.com/"+server+"/"+id+"_"+secret+".jpg\">");
+ break;
+ case "server" :
+ parser.next();
+ server = parser.getString();
+ break;
+ case "secret" :
+ parser.next();
+ secret = parser.getString();
+ break;
+ }
+ }
+ }
+ ps.println("</body></html>");
+ ps.flush();
+ }
+ }
+
+}
diff --git a/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/StructureResource.java b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/StructureResource.java
new file mode 100644
index 0000000..8a532e2
--- /dev/null
+++ b/demos/jaxrs/src/main/java/org/glassfish/jsondemos/jaxrs/StructureResource.java
@@ -0,0 +1,84 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jaxrs;
+
+import javax.json.*;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+
+/**
+ * JsonStructure as parameter and return type for a JAX-RS resource
+ *
+ * @author Jitendra Kotamraju
+ */
+ at Path("/structure")
+public class StructureResource {
+ private static final JsonBuilderFactory bf = Json.createBuilderFactory(null);
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public JsonStructure doGet() {
+ return bf.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", bf.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", bf.createArrayBuilder()
+ .add(bf.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(bf.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ public void doPost(JsonStructure structure) {
+ System.out.println(structure);
+ }
+
+}
diff --git a/demos/jsonpointer/pom.xml b/demos/jsonpointer/pom.xml
new file mode 100644
index 0000000..5d7d81d
--- /dev/null
+++ b/demos/jsonpointer/pom.xml
@@ -0,0 +1,95 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>jar</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>jsondemos-jsonpointer</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+<!-- mvn exec:java
+-->
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>org.glassfish.jsondemos.jsonpointer.JsonPointerDemo</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/demos/jsonpointer/src/main/java/org/glassfish/jsondemos/jsonpointer/JsonpointerDemo.java b/demos/jsonpointer/src/main/java/org/glassfish/jsondemos/jsonpointer/JsonpointerDemo.java
new file mode 100644
index 0000000..8ae5a68
--- /dev/null
+++ b/demos/jsonpointer/src/main/java/org/glassfish/jsondemos/jsonpointer/JsonpointerDemo.java
@@ -0,0 +1,161 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.jsonpointer;
+
+import javax.json.*;
+import java.io.*;
+
+/**
+ * JsonPointer (http://tools.ietf.org/html/rfc6901) demo with object model API
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonpointerDemo {
+
+ public static void main(String... args) throws Exception {
+ testWiki();
+ testPointer();
+ }
+
+ private static void testWiki() throws IOException {
+ try (InputStream is = JsonpointerDemo.class.getResourceAsStream("/wiki.json");
+ JsonReader rdr = Json.createReader(is)) {
+ JsonObject person = rdr.readObject();
+
+ assertEquals("NY", getString(person, "/address/state"));
+ assertEquals("212 555-1234", getString(person, "/phoneNumber/0/number"));
+ }
+ }
+
+ private static void testPointer() throws IOException {
+ try (InputStream is = JsonpointerDemo.class.getResourceAsStream("/jsonpointer.json");
+ JsonReader rdr = Json.createReader(is)) {
+ JsonObject root = rdr.readObject();
+
+ assertEquals(root, get(root, ""));
+ assertEquals(root.get("foo"), get(root, "/foo"));
+ assertEquals(root.getJsonArray("foo").get(0), get(root, "/foo/0"));
+ assertEquals(root.get(""), get(root, "/"));
+ assertEquals(root.get("a/b"), get(root, "/a~1b"));
+ assertEquals(root.get("c%d"), get(root, "/c%d"));
+ assertEquals(root.get("e^f"), get(root, "/e^f"));
+ assertEquals(root.get("k\"l"), get(root, "/k\"l"));
+ assertEquals(root.get("i\\j"), get(root, "/i\\j"));
+ assertEquals(root.get(" "), get(root, "/ "));
+ assertEquals(root.get("m~n"), get(root, "/m~0n"));
+
+ // Adding a parent to current root and try with it
+ JsonObject doc = Json.createObjectBuilder().add("doc", root).build();
+ root = doc.getJsonObject("doc");
+ assertEquals(doc, get(doc, ""));
+ assertEquals(root.get("foo"), get(doc, "/doc/foo"));
+ assertEquals(root.getJsonArray("foo").get(0), get(doc, "/doc/foo/0"));
+ assertEquals(root.get(""), get(doc, "/doc/"));
+ assertEquals(root.get("a/b"), get(doc, "/doc/a~1b"));
+ assertEquals(root.get("c%d"), get(doc, "/doc/c%d"));
+ assertEquals(root.get("e^f"), get(doc, "/doc/e^f"));
+ assertEquals(root.get("k\"l"), get(doc, "/doc/k\"l"));
+ assertEquals(root.get("i\\j"), get(doc, "/doc/i\\j"));
+ assertEquals(root.get(" "), get(doc, "/doc/ "));
+ assertEquals(root.get("m~n"), get(doc, "/doc/m~0n"));
+ }
+ }
+
+ private static String getString(JsonValue root, String pointer) {
+ return ((JsonString)get(root, pointer)).getString();
+ }
+
+ private static JsonValue get(JsonValue root, String pointer) {
+ if (pointer.isEmpty()) {
+ return root;
+ }
+ if (pointer.charAt(0) != '/') {
+ throw new IllegalArgumentException(
+ "JsonPointer "+pointer+" doesn't start with /");
+ }
+
+ StringBuilder referenceToken = new StringBuilder();
+ for(int i=1; i < pointer.length(); i++) { // 1 to skip first /
+ char ch = pointer.charAt(i);
+ if (ch == '/') {
+ return get(newRoot(root, referenceToken.toString()), pointer.substring(i));
+ } else if (ch == '~') {
+ // handle escaping ~0, ~1
+ if (i+1 == pointer.length()) {
+ throw new IllegalArgumentException("Illegal escaping: expected ~0 or ~1, but got only ~ in pointer="+pointer);
+ }
+ ch = pointer.charAt(++i);
+ if (ch == '0') {
+ referenceToken.append('~');
+ } else if (ch == '1') {
+ referenceToken.append('/');
+ } else {
+ throw new IllegalArgumentException("Illegal escaping: expected ~0 or ~1, but got ~"+ch+" in pointer="+pointer);
+ }
+ } else {
+ referenceToken.append(ch);
+ }
+ }
+ return newRoot(root, referenceToken.toString());
+ }
+
+ private static JsonValue newRoot(JsonValue root, String referenceToken) {
+ if (root instanceof JsonObject) {
+ return ((JsonObject)root).get(referenceToken);
+ } else if (root instanceof JsonArray) {
+ return ((JsonArray)root).get(Integer.parseInt(referenceToken));
+ }
+ throw new IllegalArgumentException("Illegal reference token="+referenceToken+" for value="+root);
+ }
+
+ private static void assertEquals(JsonValue exp, JsonValue got) {
+ if (exp != got) {
+ throw new RuntimeException("Expected = "+exp+" but got = "+got);
+ }
+ }
+
+ private static void assertEquals(String exp, String got) {
+ if (!exp.equals(got)) {
+ throw new RuntimeException("Expected = "+exp+" but got = "+got);
+ }
+ }
+
+}
diff --git a/demos/jsonpointer/src/main/resources/jsonpointer.json b/demos/jsonpointer/src/main/resources/jsonpointer.json
new file mode 100644
index 0000000..937a098
--- /dev/null
+++ b/demos/jsonpointer/src/main/resources/jsonpointer.json
@@ -0,0 +1,12 @@
+{
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+}
diff --git a/demos/jsonpointer/src/main/resources/wiki.json b/demos/jsonpointer/src/main/resources/wiki.json
new file mode 100644
index 0000000..17bb193
--- /dev/null
+++ b/demos/jsonpointer/src/main/resources/wiki.json
@@ -0,0 +1,21 @@
+{
+ "firstName": "John",
+ "lastName": "Smith",
+ "age": 25,
+ "address": {
+ "streetAddress": "21 2nd Street",
+ "city": "New York",
+ "state": "NY",
+ "postalCode": "10021"
+ },
+ "phoneNumber": [
+ {
+ "type": "home",
+ "number": "212 555-1234"
+ },
+ {
+ "type": "fax",
+ "number": "646 555-4567"
+ }
+ ]
+}
diff --git a/demos/pom.xml b/demos/pom.xml
new file mode 100644
index 0000000..efd73e2
--- /dev/null
+++ b/demos/pom.xml
@@ -0,0 +1,78 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <url>http://maven.apache.org</url>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <modules>
+ <module>jaxrs</module>
+ <module>twitter</module>
+ <module>facebook</module>
+ <module>jsonpointer</module>
+ <module>servlet</module>
+ </modules>
+</project>
diff --git a/demos/servlet/pom.xml b/demos/servlet/pom.xml
new file mode 100644
index 0000000..0fdd443
--- /dev/null
+++ b/demos/servlet/pom.xml
@@ -0,0 +1,85 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>war</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>jsondemos-servlet</artifactId>
+
+ <name>jsondemos-servlet</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <finalName>jsondemos-servlet</finalName>
+ </build>
+</project>
diff --git a/demos/servlet/src/main/java/org/glassfish/jsondemos/servlet/ArrayServlet.java b/demos/servlet/src/main/java/org/glassfish/jsondemos/servlet/ArrayServlet.java
new file mode 100644
index 0000000..921f964
--- /dev/null
+++ b/demos/servlet/src/main/java/org/glassfish/jsondemos/servlet/ArrayServlet.java
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.servlet;
+
+import javax.json.*;
+import javax.servlet.*;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.*;
+import java.io.IOException;
+
+/**
+ * Writes a JsonArray using HttpServletResponse#getWriter
+ * http://localhost:8080/jsondemos-servlet/array
+ *
+ * Writes a JsonArray using HttpServletResponse#getOutputStream
+ * http://localhost:8080/jsondemos-servlet/array?stream
+ *
+ *
+ * @author Jitendra Kotamraju
+ */
+ at WebServlet("/array")
+public class ArrayServlet extends HttpServlet {
+ private static final JsonBuilderFactory bf = Json.createBuilderFactory(null);
+ private static final JsonWriterFactory wf = Json.createWriterFactory(null);
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
+ JsonArray array = bf.createArrayBuilder()
+ .add(bf.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(bf.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567"))
+ .build();
+ res.setStatus(HttpServletResponse.SC_OK);
+ res.setContentType("application/json");
+ res.setCharacterEncoding("UTF-8");
+
+ String q = req.getQueryString();
+ boolean isStream = q != null && q.equals("stream");
+ JsonWriter writer = isStream
+ ? wf.createWriter(res.getOutputStream())
+ : wf.createWriter(res.getWriter());
+ writer.write(array);
+ // not closing writer intentionally
+ }
+
+}
diff --git a/demos/twitter/pom.xml b/demos/twitter/pom.xml
new file mode 100644
index 0000000..55f2332
--- /dev/null
+++ b/demos/twitter/pom.xml
@@ -0,0 +1,93 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>demos</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>jar</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>jsondemos-twitter</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <mainClass>org.glassfish.jsondemos.twitter.TwitterObjectSearch</mainClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterObjectSearch.java b/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterObjectSearch.java
new file mode 100644
index 0000000..8ab104d
--- /dev/null
+++ b/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterObjectSearch.java
@@ -0,0 +1,180 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.twitter;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.json.*;
+import javax.xml.bind.DatatypeConverter;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.*;
+
+/**
+ * Parses JSON from twitter search REST API using object model API.
+ * JSON would like :
+ *
+ * {
+ " statuses": [
+ * { ..., "user" : { "name" : "xxx", ...}, "text: "yyy", ... },
+ * { ..., "user" : { "name" : "ppp", ...}, "text: "qqq", ... },
+ * ...
+ * ],
+ * ...
+ * }
+ *
+ * This codes writes the tweets to output as follows:
+ * xxx: yyy
+ * --------
+ * ppp: qqq
+ * --------
+ *
+ * @author Jitendra Kotamraju
+ */
+public class TwitterObjectSearch {
+
+ public static void main(String... args) throws Exception {
+ try (InputStream is = getSearchStream();
+ JsonReader rdr = Json.createReader(is)) {
+
+ JsonObject obj = rdr.readObject();
+ JsonArray results = obj.getJsonArray("statuses");
+ for (JsonObject result : results.getValuesAs(JsonObject.class)) {
+ System.out.print(result.getJsonObject("user").getString("name", "anonymous"));
+ System.out.print(": ");
+ System.out.println(result.get("text"));
+ System.out.println("-----------");
+ }
+
+// All the tweets are collected into Stream<String> and printed
+// obj.getJsonArray("statuses").getValuesAs(JsonObject.class)
+// .stream()
+// .map(v -> v.getString("text"))
+// .forEach(s -> { System.out.println(s); } );
+ }
+ }
+
+ static InputStream getSearchStream() throws Exception {
+ final String searchStr = "#javaone";
+ String searchUrl = "https://api.twitter.com/1.1/search/tweets.json";
+
+ Properties config = new Properties();
+ config.load(TwitterObjectSearch.class.getResourceAsStream(
+ "/twitterconfig.properties"));
+
+ final String consumerKey = (String)config.get("consumer-key");
+ final String consumerSecret = (String)config.get("consumer-secret");
+ final String accessToken = (String)config.get("access-token");
+ final String accessTokenSecret = (String)config.get("access-token-secret");
+ final int timestamp = (int)(System.currentTimeMillis()/1000);
+
+ Map<String, String> map = new TreeMap<String, String>() {{
+ put("count", "100");
+ put("oauth_consumer_key", consumerKey);
+ put("oauth_nonce", "4b25256957d75b6370f33a4501dc5e7e"); // TODO
+ put("oauth_signature_method", "HMAC-SHA1");
+ put("oauth_timestamp", ""+timestamp);
+ put("oauth_token", accessToken);
+ put("oauth_version", "1.0");
+ put("q", searchStr);
+ }};
+
+ // Builds param string
+ StringBuilder paramsBuilder = new StringBuilder();
+ boolean first = true;
+ for(Map.Entry<String, String> e : map.entrySet()) {
+ if (!first) {
+ paramsBuilder.append('&');
+ }
+ first = false;
+ paramsBuilder.append(e.getKey());
+ paramsBuilder.append("=");
+ paramsBuilder.append(URLEncoder.encode(e.getValue(), "UTF-8"));
+ }
+ String paramsString = paramsBuilder.toString();
+
+ // builds signature string
+ StringBuilder signatureBuilder = new StringBuilder();
+ signatureBuilder.append("GET");
+ signatureBuilder.append('&');
+ signatureBuilder.append(URLEncoder.encode(searchUrl, "UTF-8"));
+ signatureBuilder.append('&');
+ signatureBuilder.append(URLEncoder.encode(paramsString, "UTF-8"));
+ String signatureBasedString = signatureBuilder.toString();
+
+ // Create authorization signature
+ Mac m = Mac.getInstance("HmacSHA1");
+ m.init(new SecretKeySpec((consumerSecret+"&"+accessTokenSecret).getBytes(), "HmacSHA1"));
+ m.update(signatureBasedString.getBytes());
+ byte[] res = m.doFinal();
+ final String oauthSig = URLEncoder.encode(DatatypeConverter.printBase64Binary(res), "UTF-8");
+ map.put("oauth_signature", oauthSig);
+ map.remove("count");
+ map.remove("q");
+
+ // Build Authorization header
+ StringBuilder authorizationBuilder = new StringBuilder();
+ authorizationBuilder.append("OAuth ");
+ first = true;
+ for(Map.Entry<String, String> e : map.entrySet()) {
+ if (!first) {
+ authorizationBuilder.append(',');
+ authorizationBuilder.append(' ');
+ }
+ first = false;
+ authorizationBuilder.append(e.getKey());
+ authorizationBuilder.append('=');
+ authorizationBuilder.append('"');
+ authorizationBuilder.append(e.getValue());
+ authorizationBuilder.append('"');
+ }
+
+ // Gets the search stream
+ URL url = new URL(searchUrl+"?q="+URLEncoder.encode(searchStr, "UTF-8")+
+ "&count=100");
+ HttpURLConnection con = (HttpURLConnection)url.openConnection();
+ con.addRequestProperty("Authorization", authorizationBuilder.toString());
+ return con.getInputStream();
+ }
+
+}
diff --git a/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterStreamSearch.java b/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterStreamSearch.java
new file mode 100644
index 0000000..5fbf124
--- /dev/null
+++ b/demos/twitter/src/main/java/org/glassfish/jsondemos/twitter/TwitterStreamSearch.java
@@ -0,0 +1,110 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.jsondemos.twitter;
+
+import javax.json.*;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+import java.io.*;
+
+/**
+ * Parses JSON from twitter search REST API using streaming API.
+ * JSON would like :
+ *
+ * {
+ " statuses": [
+ * { ..., "user" : { "name" : "xxx", ...}, "text: "yyy", ... },
+ * { ..., "user" : { "name" : "ppp", ...}, "text: "qqq", ... },
+ * ...
+ * ],
+ * ...
+ * }
+ *
+ * This codes writes the tweets to output as follows:
+ * xxx: yyy
+ * --------
+ * ppp: qqq
+ * --------
+ *
+ * TODO need to do better, also the last tweet is repeated !
+ *
+ * @author Jitendra Kotamraju
+ */
+public class TwitterStreamSearch {
+
+ public static void main(String... args) throws Exception {
+ try (InputStream is = TwitterObjectSearch.getSearchStream();
+ JsonParser parser = Json.createParser(is)) {
+ int depth = 0;
+ String name = null;
+ String text = null;
+ while (parser.hasNext()) {
+ Event e = parser.next();
+ if (e == Event.KEY_NAME) {
+ switch (parser.getString()) {
+ case "name":
+ if (depth == 3) {
+ parser.next();
+ name = parser.getString();
+ }
+ break;
+ case "text":
+ if (depth == 2) {
+ parser.next();
+ text = parser.getString();
+ }
+ break;
+ }
+ } else if (e == Event.START_OBJECT) {
+ ++depth;
+ } else if (e == Event.END_OBJECT) {
+ --depth;
+ if (depth == 1) {
+ System.out.println(name+": "+text);
+ System.out.println("-----------");
+
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/demos/twitter/src/main/resources/twitterconfig.properties b/demos/twitter/src/main/resources/twitterconfig.properties
new file mode 100644
index 0000000..eae4876
--- /dev/null
+++ b/demos/twitter/src/main/resources/twitterconfig.properties
@@ -0,0 +1,5 @@
+consumer-key=
+consumer-secret=
+access-token=
+access-token-secret=
+
diff --git a/gf/customprovider/pom.xml b/gf/customprovider/pom.xml
new file mode 100644
index 0000000..15bf2c8
--- /dev/null
+++ b/gf/customprovider/pom.xml
@@ -0,0 +1,63 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>providers</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>war</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>customprovider</artifactId>
+
+ <name>customprovider</name>
+
+ <build>
+ <finalName>customprovider</finalName>
+ </build>
+</project>
diff --git a/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestGenerator.java b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestGenerator.java
new file mode 100644
index 0000000..82b2823
--- /dev/null
+++ b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestGenerator.java
@@ -0,0 +1,195 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.customprovider;
+
+import javax.json.JsonException;
+import javax.json.JsonValue;
+import javax.json.stream.JsonGenerator;
+import java.io.IOException;
+import java.io.Writer;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class TestGenerator implements JsonGenerator {
+ private final Writer writer;
+
+ public TestGenerator(Writer writer) {
+ this.writer = writer;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public JsonGenerator writeStartObject() {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator writeStartObject(String name) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, String fieldValue) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, int value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, long value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, double value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, BigInteger value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, BigDecimal value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, boolean value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator writeNull(String name) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(JsonValue value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray() {
+ try {
+ writer.write("[");
+ } catch(IOException ioe) {
+ throw new JsonException("I/O error", ioe);
+ }
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray(String name) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(String name, JsonValue value) {
+ return null;
+ }
+
+ public JsonGenerator write(String value) {
+ return null;
+ }
+
+
+ public JsonGenerator write(int value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(long value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(double value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(BigInteger value) {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator write(BigDecimal value) {
+ return null;
+ }
+
+ public JsonGenerator write(boolean value) {
+ return null;
+ }
+
+ public JsonGenerator writeNull() {
+ return null;
+ }
+
+ @Override
+ public JsonGenerator writeEnd() {
+ try {
+ writer.write("]");
+ } catch(IOException ioe) {
+ throw new JsonException("I/O error", ioe);
+ }
+ return this;
+ }
+
+ public void close() {
+ try {
+ writer.close();
+ } catch(IOException ioe) {
+ throw new JsonException("I/O error", ioe);
+ }
+ }
+
+}
diff --git a/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestProvider.java b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestProvider.java
new file mode 100644
index 0000000..052ef80
--- /dev/null
+++ b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestProvider.java
@@ -0,0 +1,136 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.customprovider;
+
+import javax.json.*;
+import javax.json.spi.JsonProvider;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class TestProvider extends JsonProvider {
+
+ @Override
+ public JsonGenerator createGenerator(Writer writer) {
+ return new TestGenerator(writer);
+ }
+
+ @Override
+ public JsonGenerator createGenerator(OutputStream out) {
+ return null;
+ }
+
+ @Override
+ public JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config) {
+ return null;
+ }
+
+ @Override
+ public JsonReader createReader(Reader reader) {
+ return null;
+ }
+
+ @Override
+ public JsonReader createReader(InputStream in) {
+ return null;
+ }
+
+ @Override
+ public JsonWriter createWriter(Writer writer) {
+ return null;
+ }
+
+ @Override
+ public JsonWriter createWriter(OutputStream out) {
+ return null;
+ }
+
+ @Override
+ public JsonWriterFactory createWriterFactory(Map<String, ?> config) {
+ return null;
+ }
+
+ @Override
+ public JsonReaderFactory createReaderFactory(Map<String, ?> config) {
+ return null;
+ }
+
+ @Override
+ public JsonObjectBuilder createObjectBuilder() {
+ return null;
+ }
+
+ @Override
+ public JsonArrayBuilder createArrayBuilder() {
+ return null;
+ }
+
+ @Override
+ public JsonBuilderFactory createBuilderFactory(Map<String, ?> config) {
+ return null;
+ }
+
+ @Override
+ public JsonParser createParser(Reader reader) {
+ return null;
+ }
+
+ @Override
+ public JsonParser createParser(InputStream in) {
+ return null;
+ }
+
+ @Override
+ public JsonParserFactory createParserFactory(Map<String, ?> config) {
+ return null;
+ }
+
+
+}
diff --git a/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestServlet.java b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestServlet.java
new file mode 100644
index 0000000..fa6a36e
--- /dev/null
+++ b/gf/customprovider/src/main/java/org/glassfish/json/customprovider/TestServlet.java
@@ -0,0 +1,74 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.customprovider;
+
+import javax.servlet.annotation.*;
+import javax.servlet.http.*;
+import javax.servlet.*;
+import java.io.IOException;
+import javax.json.*;
+import javax.json.stream.*;
+import java.io.*;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+ at WebServlet("/json")
+public class TestServlet extends HttpServlet {
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException {
+ try {
+ res.setStatus(200);
+ res.setContentType("application/json");
+ OutputStream os = res.getOutputStream();
+ JsonGenerator generator = Json.createGenerator(new OutputStreamWriter(os));
+ if (!(generator instanceof TestGenerator)) {
+ throw new RuntimeException("MyGenerator is not picked up");
+ }
+ generator.writeStartArray().writeEnd();
+ generator.close();
+ os.close();
+ } catch(IOException ioe) {
+ throw new ServletException(ioe);
+ }
+ }
+
+}
diff --git a/gf/customprovider/src/main/resources/META-INF/services/javax.json.spi.JsonProvider b/gf/customprovider/src/main/resources/META-INF/services/javax.json.spi.JsonProvider
new file mode 100644
index 0000000..0647df2
--- /dev/null
+++ b/gf/customprovider/src/main/resources/META-INF/services/javax.json.spi.JsonProvider
@@ -0,0 +1 @@
+org.glassfish.json.customprovider.TestProvider
diff --git a/gf/defaultprovider/pom.xml b/gf/defaultprovider/pom.xml
new file mode 100644
index 0000000..6d15683
--- /dev/null
+++ b/gf/defaultprovider/pom.xml
@@ -0,0 +1,63 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>providers</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>war</packaging>
+ <url>http://maven.apache.org</url>
+ <artifactId>defaultprovider</artifactId>
+
+ <name>defaultprovider</name>
+
+ <build>
+ <finalName>defaultprovider</finalName>
+ </build>
+</project>
diff --git a/gf/defaultprovider/src/main/java/org/glassfish/json/defaultprovider/TestServlet.java b/gf/defaultprovider/src/main/java/org/glassfish/json/defaultprovider/TestServlet.java
new file mode 100644
index 0000000..ffb59f5
--- /dev/null
+++ b/gf/defaultprovider/src/main/java/org/glassfish/json/defaultprovider/TestServlet.java
@@ -0,0 +1,70 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.defaultprovider;
+
+import javax.servlet.annotation.*;
+import javax.servlet.http.*;
+import javax.servlet.*;
+import java.io.IOException;
+import javax.json.*;
+import javax.json.stream.*;
+import java.io.*;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+ at WebServlet("/json")
+public class TestServlet extends HttpServlet {
+
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException {
+ try {
+ res.setStatus(200);
+ res.setContentType("application/json");
+ OutputStream os = res.getOutputStream();
+ JsonGenerator generator = Json.createGenerator(os);
+ generator.writeStartArray().writeEnd();
+ generator.close();
+ } catch(IOException ioe) {
+ throw new ServletException(ioe);
+ }
+ }
+
+}
diff --git a/gf/pom.xml b/gf/pom.xml
new file mode 100644
index 0000000..5d7a97e
--- /dev/null
+++ b/gf/pom.xml
@@ -0,0 +1,84 @@
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <packaging>pom</packaging>
+ <url>http://maven.apache.org</url>
+ <groupId>org.glassfish.jsonp</groupId>
+ <artifactId>providers</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ </plugin>
+ </plugins>
+ <finalName>customprovider</finalName>
+ </build>
+ <modules>
+ <module>customprovider</module>
+ <module>defaultprovider</module>
+ </modules>
+</project>
diff --git a/impl/pom.xml b/impl/pom.xml
new file mode 100644
index 0000000..bb9cb03
--- /dev/null
+++ b/impl/pom.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.1.0-SNAPSHOT</version>
+ <name>JSR 374 (JSON Processing) Default Provider</name>
+ <description>Default provider for JSR 374:Java API for Processing JSON</description>
+ <url>http://jsonp.java.net</url>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.glassfish.build</groupId>
+ <artifactId>spec-version-maven-plugin</artifactId>
+ <configuration>
+ <spec>
+ <nonFinal>false</nonFinal>
+ <jarType>impl</jarType>
+ <specVersion>${spec_version}</specVersion>
+ <specImplVersion>${spec_impl_version}</specImplVersion>
+ <implVersion>${impl_version}</implVersion>
+ <apiPackage>javax.json</apiPackage>
+ <implNamespace>org.glassfish</implNamespace>
+ </spec>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>set-spec-properties</goal>
+ <goal>check-module</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>sources-as-resources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <resources>
+ <resource>
+ <directory>src/main/java</directory>
+ </resource>
+ </resources>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>unpack-client-sources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <version>${spec_impl_version}</version>
+ <classifier>sources</classifier>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}/sources</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-source-jar</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <classifier>sources</classifier>
+ <classesDirectory>${project.build.directory}/sources</classesDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <includeDependencySources>true</includeDependencySources>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ This plugin is reponsible for packaging artifacts
+ as OSGi bundles. Please refer to
+ http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
+ for more information about how to use this plugin.
+ -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+<!-- TODO: is it spec plugin bug ? the spec.bundle.version returns 1.0 ?
+ <Bundle-Version>${spec.bundle.version}</Bundle-Version>
+-->
+ <Bundle-Version>${spec.implementation.version}</Bundle-Version>
+ <Bundle-SymbolicName>${spec.bundle.symbolic-name}</Bundle-SymbolicName>
+ <Extension-Name>${spec.extension.name}</Extension-Name>
+ <Implementation-Version>${spec.implementation.version}</Implementation-Version>
+ <Specification-Version>${spec.specification.version}</Specification-Version>
+ <Export-Package>${packages.export}</Export-Package>
+ <Private-Package>${packages.private}</Private-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <optional>true</optional>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/impl/src/main/java/org/glassfish/json/BufferPoolImpl.java b/impl/src/main/java/org/glassfish/json/BufferPoolImpl.java
new file mode 100644
index 0000000..eb842d3
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/BufferPoolImpl.java
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * char[] pool that pool instances of char[] which are expensive to create.
+ *
+ * @author Jitendra Kotamraju
+ */
+class BufferPoolImpl implements BufferPool {
+
+ // volatile since multiple threads may access queue reference
+ private volatile WeakReference<ConcurrentLinkedQueue<char[]>> queue;
+
+ /**
+ * Gets a new object from the pool.
+ *
+ * <p>
+ * If no object is available in the pool, this method creates a new one.
+ *
+ * @return
+ * always non-null.
+ */
+ @Override
+ public final char[] take() {
+ char[] t = getQueue().poll();
+ if (t==null)
+ return new char[4096];
+ return t;
+ }
+
+ private ConcurrentLinkedQueue<char[]> getQueue() {
+ WeakReference<ConcurrentLinkedQueue<char[]>> q = queue;
+ if (q != null) {
+ ConcurrentLinkedQueue<char[]> d = q.get();
+ if (d != null)
+ return d;
+ }
+
+ // overwrite the queue
+ ConcurrentLinkedQueue<char[]> d = new ConcurrentLinkedQueue<>();
+ queue = new WeakReference<>(d);
+
+ return d;
+ }
+
+ /**
+ * Returns an object back to the pool.
+ */
+ @Override
+ public final void recycle(char[] t) {
+ getQueue().offer(t);
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java b/impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java
new file mode 100644
index 0000000..c8f7a8f
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java
@@ -0,0 +1,484 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * JsonArrayBuilder implementation
+ *
+ * @author Jitendra Kotamraju
+ * @author Kin-man Chung
+ */
+
+class JsonArrayBuilderImpl implements JsonArrayBuilder {
+ private ArrayList<JsonValue> valueList;
+ private final BufferPool bufferPool;
+
+ JsonArrayBuilderImpl(BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ }
+
+ JsonArrayBuilderImpl(JsonArray array, BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ valueList = new ArrayList<>();
+ valueList.addAll(array);
+ }
+
+ @Override
+ public JsonArrayBuilder add(JsonValue value) {
+ validateValue(value);
+ addValueList(value);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(String value) {
+ validateValue(value);
+ addValueList(new JsonStringImpl(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(BigDecimal value) {
+ validateValue(value);
+ addValueList(JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(BigInteger value) {
+ validateValue(value);
+ addValueList(JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int value) {
+ addValueList(JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(long value) {
+ addValueList(JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(double value) {
+ addValueList(JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(boolean value) {
+ addValueList(value ? JsonValue.TRUE : JsonValue.FALSE);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder addNull() {
+ addValueList(JsonValue.NULL);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(JsonObjectBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+ }
+ addValueList(builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(JsonArrayBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_ARRAY_BUILDER_NULL());
+ }
+ addValueList(builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder addAll(JsonArrayBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_ARRAY_BUILDER_NULL());
+ }
+ if (valueList == null) {
+ valueList = new ArrayList<>();
+ }
+ valueList.addAll(builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, JsonValue value) {
+ validateValue(value);
+ addValueList(index, value);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, String value) {
+ validateValue(value);
+ addValueList(index, new JsonStringImpl(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, BigDecimal value) {
+ validateValue(value);
+ addValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, BigInteger value) {
+ validateValue(value);
+ addValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, int value) {
+ addValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, long value) {
+ addValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, double value) {
+ addValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, boolean value) {
+ addValueList(index, value ? JsonValue.TRUE : JsonValue.FALSE);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder addNull(int index) {
+ addValueList(index, JsonValue.NULL);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, JsonObjectBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+ }
+ addValueList(index, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder add(int index, JsonArrayBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+ }
+ addValueList(index, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, JsonValue value) {
+ validateValue(value);
+ setValueList(index, value);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, String value) {
+ validateValue(value);
+ setValueList(index, new JsonStringImpl(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, BigDecimal value) {
+ validateValue(value);
+ setValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, BigInteger value) {
+ validateValue(value);
+ setValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, int value) {
+ setValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, long value) {
+ setValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, double value) {
+ setValueList(index, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, boolean value) {
+ setValueList(index, value ? JsonValue.TRUE : JsonValue.FALSE);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder setNull(int index) {
+ setValueList(index, JsonValue.NULL);
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, JsonObjectBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+ }
+ setValueList(index, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder set(int index, JsonArrayBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+ }
+ setValueList(index, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonArrayBuilder remove(int index) {
+ if (valueList == null) {
+ throw new IndexOutOfBoundsException();
+ }
+ valueList.remove(index);
+ return this;
+ }
+
+ @Override
+ public JsonArray build() {
+ List<JsonValue> snapshot;
+ if (valueList == null) {
+ snapshot = Collections.emptyList();
+ } else {
+ // Should we trim to minimize storage ?
+ // valueList.trimToSize();
+ snapshot = Collections.unmodifiableList(valueList);
+ }
+ valueList = null;
+ return new JsonArrayImpl(snapshot, bufferPool);
+ }
+
+ private void addValueList(JsonValue value) {
+ if (valueList == null) {
+ valueList = new ArrayList<>();
+ }
+ valueList.add(value);
+ }
+
+ private void addValueList(int index, JsonValue value) {
+ if (valueList == null) {
+ valueList = new ArrayList<>();
+ }
+ valueList.add(index, value);
+ }
+
+ private void setValueList(int index, JsonValue value) {
+ if (valueList == null) {
+ throw new IndexOutOfBoundsException();
+ }
+ valueList.set(index, value);
+ }
+
+ private void validateValue(Object value) {
+ if (value == null) {
+ throw new NullPointerException(JsonMessages.ARRBUILDER_VALUE_NULL());
+ }
+ }
+
+ private static final class JsonArrayImpl extends AbstractList<JsonValue> implements JsonArray {
+ private final List<JsonValue> valueList; // Unmodifiable
+ private final BufferPool bufferPool;
+
+ JsonArrayImpl(List<JsonValue> valueList, BufferPool bufferPool) {
+ this.valueList = valueList;
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public int size() {
+ return valueList.size();
+ }
+
+ @Override
+ public JsonObject getJsonObject(int index) {
+ return (JsonObject)valueList.get(index);
+ }
+
+ @Override
+ public JsonArray getJsonArray(int index) {
+ return (JsonArray)valueList.get(index);
+ }
+
+ @Override
+ public JsonNumber getJsonNumber(int index) {
+ return (JsonNumber)valueList.get(index);
+ }
+
+ @Override
+ public JsonString getJsonString(int index) {
+ return (JsonString)valueList.get(index);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends JsonValue> List<T> getValuesAs(Class<T> clazz) {
+ return (List<T>)valueList;
+ }
+
+ @Override
+ public String getString(int index) {
+ return getJsonString(index).getString();
+ }
+
+ @Override
+ public String getString(int index, String defaultValue) {
+ try {
+ return getString(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public int getInt(int index) {
+ return getJsonNumber(index).intValue();
+ }
+
+ @Override
+ public int getInt(int index, int defaultValue) {
+ try {
+ return getInt(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public boolean getBoolean(int index) {
+ JsonValue jsonValue = get(index);
+ if (jsonValue == JsonValue.TRUE) {
+ return true;
+ } else if (jsonValue == JsonValue.FALSE) {
+ return false;
+ } else {
+ throw new ClassCastException();
+ }
+ }
+
+ @Override
+ public boolean getBoolean(int index, boolean defaultValue) {
+ try {
+ return getBoolean(index);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public boolean isNull(int index) {
+ return valueList.get(index).equals(JsonValue.NULL);
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return ValueType.ARRAY;
+ }
+
+ @Override
+ public JsonValue get(int index) {
+ return valueList.get(index);
+ }
+
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ try (JsonWriter jw = new JsonWriterImpl(sw, bufferPool)) {
+ jw.write(this);
+ }
+ return sw.toString();
+ }
+
+ @Override
+ public JsonArray asJsonArray() {
+ return this;
+ }
+ }
+}
+
diff --git a/impl/src/main/java/org/glassfish/json/JsonBuilderFactoryImpl.java b/impl/src/main/java/org/glassfish/json/JsonBuilderFactoryImpl.java
new file mode 100644
index 0000000..cf2a393
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonBuilderFactoryImpl.java
@@ -0,0 +1,89 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonObject;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonBuilderFactory;
+import javax.json.JsonObjectBuilder;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonBuilderFactoryImpl implements JsonBuilderFactory {
+ private final Map<String, ?> config;
+ private final BufferPool bufferPool;
+
+ JsonBuilderFactoryImpl(BufferPool bufferPool) {
+ this.config = Collections.emptyMap();
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonObjectBuilder createObjectBuilder() {
+ return new JsonObjectBuilderImpl(bufferPool);
+ }
+
+ @Override
+ public JsonObjectBuilder createObjectBuilder(JsonObject object) {
+ return new JsonObjectBuilderImpl(bufferPool);
+ }
+
+ @Override
+ public JsonArrayBuilder createArrayBuilder() {
+ return new JsonArrayBuilderImpl(bufferPool);
+ }
+
+ @Override
+ public JsonArrayBuilder createArrayBuilder(JsonArray array) {
+ return new JsonArrayBuilderImpl(array, bufferPool);
+ }
+
+ @Override
+ public Map<String, ?> getConfigInUse() {
+ return config;
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonGeneratorFactoryImpl.java b/impl/src/main/java/org/glassfish/json/JsonGeneratorFactoryImpl.java
new file mode 100644
index 0000000..f860d67
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonGeneratorFactoryImpl.java
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonGeneratorFactoryImpl implements JsonGeneratorFactory {
+
+ private final boolean prettyPrinting;
+ private final Map<String, ?> config; // unmodifiable map
+ private final BufferPool bufferPool;
+
+ JsonGeneratorFactoryImpl(Map<String, ?> config, boolean prettyPrinting,
+ BufferPool bufferPool) {
+ this.config = config;
+ this.prettyPrinting = prettyPrinting;
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonGenerator createGenerator(Writer writer) {
+ return prettyPrinting
+ ? new JsonPrettyGeneratorImpl(writer, bufferPool)
+ : new JsonGeneratorImpl(writer, bufferPool);
+ }
+
+ @Override
+ public JsonGenerator createGenerator(OutputStream out) {
+ return prettyPrinting
+ ? new JsonPrettyGeneratorImpl(out, bufferPool)
+ : new JsonGeneratorImpl(out, bufferPool);
+ }
+
+ @Override
+ public JsonGenerator createGenerator(OutputStream out, Charset charset) {
+ return prettyPrinting
+ ? new JsonPrettyGeneratorImpl(out, charset, bufferPool)
+ : new JsonGeneratorImpl(out, charset, bufferPool);
+ }
+
+ @Override
+ public Map<String, ?> getConfigInUse() {
+ return config;
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java b/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java
new file mode 100644
index 0000000..2393199
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java
@@ -0,0 +1,709 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerationException;
+import javax.json.stream.JsonGenerator;
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonGeneratorImpl implements JsonGenerator {
+
+ private static final char[] INT_MIN_VALUE_CHARS = "-2147483648".toCharArray();
+ private static final int[] INT_CHARS_SIZE_TABLE = { 9, 99, 999, 9999, 99999,
+ 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE };
+
+ private static final char [] DIGIT_TENS = {
+ '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+ '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
+ '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
+ '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
+ '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
+ '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
+ '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
+ '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
+ '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
+ '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
+ } ;
+
+ private static final char [] DIGIT_ONES = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ } ;
+
+ /**
+ * All possible chars for representing a number as a String
+ */
+ private static final char[] DIGITS = {
+ '0' , '1' , '2' , '3' , '4' , '5' ,
+ '6' , '7' , '8' , '9'
+ };
+
+ private static enum Scope {
+ IN_NONE,
+ IN_OBJECT,
+ IN_ARRAY
+ }
+
+ private final BufferPool bufferPool;
+ private final Writer writer;
+ private Context currentContext = new Context(Scope.IN_NONE);
+ private final Deque<Context> stack = new ArrayDeque<>();
+
+ // Using own buffering mechanism as JDK's BufferedWriter uses synchronized
+ // methods. Also, flushBuffer() is useful when you don't want to actually
+ // flush the underlying output source
+ private final char buf[]; // capacity >= INT_MIN_VALUE_CHARS.length
+ private int len = 0;
+
+ JsonGeneratorImpl(Writer writer, BufferPool bufferPool) {
+ this.writer = writer;
+ this.bufferPool = bufferPool;
+ this.buf = bufferPool.take();
+ }
+
+ JsonGeneratorImpl(OutputStream out, BufferPool bufferPool) {
+ this(out, StandardCharsets.UTF_8, bufferPool);
+ }
+
+ JsonGeneratorImpl(OutputStream out, Charset encoding, BufferPool bufferPool) {
+ this(new OutputStreamWriter(out, encoding), bufferPool);
+ }
+
+ @Override
+ public void flush() {
+ flushBuffer();
+ try {
+ writer.flush();
+ } catch (IOException ioe) {
+ throw new JsonException(JsonMessages.GENERATOR_FLUSH_IO_ERR(), ioe);
+ }
+ }
+
+ @Override
+ public JsonGenerator writeStartObject() {
+ if (currentContext.scope == Scope.IN_OBJECT) {
+ throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ if (currentContext.scope == Scope.IN_NONE && !currentContext.first) {
+ throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_MULTIPLE_TEXT());
+ }
+ writeComma();
+ writeChar('{');
+ stack.push(currentContext);
+ currentContext = new Context(Scope.IN_OBJECT);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartObject(String name) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeChar('{');
+ stack.push(currentContext);
+ currentContext = new Context(Scope.IN_OBJECT);
+ return this;
+ }
+
+ private JsonGenerator writeName(String name) {
+ writeComma();
+ writeEscapedString(name);
+ writeChar(':');
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, String fieldValue) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeEscapedString(fieldValue);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, int value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeInt(value);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, long value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeString(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, double value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ if (Double.isInfinite(value) || Double.isNaN(value)) {
+ throw new NumberFormatException(JsonMessages.GENERATOR_DOUBLE_INFINITE_NAN());
+ }
+ writeName(name);
+ writeString(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, BigInteger value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeString(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, BigDecimal value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeString(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, boolean value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeString(value? "true" : "false");
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeNull(String name) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeString("null");
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(JsonValue value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ switch (value.getValueType()) {
+ case ARRAY:
+ JsonArray array = (JsonArray)value;
+ writeStartArray();
+ for(JsonValue child: array) {
+ write(child);
+ }
+ writeEnd();
+ break;
+ case OBJECT:
+ JsonObject object = (JsonObject)value;
+ writeStartObject();
+ for(Map.Entry<String, JsonValue> member: object.entrySet()) {
+ write(member.getKey(), member.getValue());
+ }
+ writeEnd();
+ break;
+ case STRING:
+ JsonString str = (JsonString)value;
+ write(str.getString());
+ break;
+ case NUMBER:
+ JsonNumber number = (JsonNumber)value;
+ writeValue(number.toString());
+ break;
+ case TRUE:
+ write(true);
+ break;
+ case FALSE:
+ write(false);
+ break;
+ case NULL:
+ writeNull();
+ break;
+ }
+
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray() {
+ if (currentContext.scope == Scope.IN_OBJECT) {
+ throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ if (currentContext.scope == Scope.IN_NONE && !currentContext.first) {
+ throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_MULTIPLE_TEXT());
+ }
+ writeComma();
+ writeChar('[');
+ stack.push(currentContext);
+ currentContext = new Context(Scope.IN_ARRAY);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray(String name) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeName(name);
+ writeChar('[');
+ stack.push(currentContext);
+ currentContext = new Context(Scope.IN_ARRAY);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(String name, JsonValue value) {
+ if (currentContext.scope != Scope.IN_OBJECT) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ switch (value.getValueType()) {
+ case ARRAY:
+ JsonArray array = (JsonArray)value;
+ writeStartArray(name);
+ for(JsonValue child: array) {
+ write(child);
+ }
+ writeEnd();
+ break;
+ case OBJECT:
+ JsonObject object = (JsonObject)value;
+ writeStartObject(name);
+ for(Map.Entry<String, JsonValue> member: object.entrySet()) {
+ write(member.getKey(), member.getValue());
+ }
+ writeEnd();
+ break;
+ case STRING:
+ JsonString str = (JsonString)value;
+ write(name, str.getString());
+ break;
+ case NUMBER:
+ JsonNumber number = (JsonNumber)value;
+ writeValue(name, number.toString());
+ break;
+ case TRUE:
+ write(name, true);
+ break;
+ case FALSE:
+ write(name, false);
+ break;
+ case NULL:
+ writeNull(name);
+ break;
+ }
+ return this;
+ }
+
+ public JsonGenerator write(String value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeComma();
+ writeEscapedString(value);
+ return this;
+ }
+
+
+ public JsonGenerator write(int value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeComma();
+ writeInt(value);
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(long value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeValue(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(double value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ if (Double.isInfinite(value) || Double.isNaN(value)) {
+ throw new NumberFormatException(JsonMessages.GENERATOR_DOUBLE_INFINITE_NAN());
+ }
+ writeValue(String.valueOf(value));
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(BigInteger value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeValue(value.toString());
+ return this;
+ }
+
+ @Override
+ public JsonGenerator write(BigDecimal value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeValue(value.toString());
+ return this;
+ }
+
+ public JsonGenerator write(boolean value) {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeComma();
+ writeString(value ? "true" : "false");
+ return this;
+ }
+
+ public JsonGenerator writeNull() {
+ if (!currentContext.first && currentContext.scope != Scope.IN_ARRAY) {
+ throw new JsonGenerationException(
+ JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+ }
+ writeComma();
+ writeString("null");
+ return this;
+ }
+
+ private void writeValue(String value) {
+ writeComma();
+ writeString(value);
+ }
+
+ private void writeValue(String name, String value) {
+ writeComma();
+ writeEscapedString(name);
+ writeChar(':');
+ writeString(value);
+ }
+
+ @Override
+ public JsonGenerator writeEnd() {
+ if (currentContext.scope == Scope.IN_NONE) {
+ throw new JsonGenerationException("writeEnd() cannot be called in no context");
+ }
+ writeChar(currentContext.scope == Scope.IN_ARRAY ? ']' : '}');
+ currentContext = stack.pop();
+ return this;
+ }
+
+ protected void writeComma() {
+ if (!currentContext.first) {
+ writeChar(',');
+ }
+ currentContext.first = false;
+ }
+
+ private static class Context {
+ boolean first = true;
+ final Scope scope;
+
+ Context(Scope scope) {
+ this.scope = scope;
+ }
+
+ }
+
+ public void close() {
+ if (currentContext.scope != Scope.IN_NONE || currentContext.first) {
+ throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
+ }
+ flushBuffer();
+ try {
+ writer.close();
+ } catch (IOException ioe) {
+ throw new JsonException(JsonMessages.GENERATOR_CLOSE_IO_ERR(), ioe);
+ }
+ bufferPool.recycle(buf);
+ }
+
+ // begin, end-1 indexes represent characters that need not
+ // be escaped
+ //
+ // XXXssssssssssssXXXXXXXXXXXXXXXXXXXXXXrrrrrrrrrrrrrrXXXXXX
+ // ^ ^ ^ ^
+ // | | | |
+ // begin end begin end
+ void writeEscapedString(String string) {
+ writeChar('"');
+ int len = string.length();
+ for(int i = 0; i < len; i++) {
+ int begin = i, end = i;
+ char c = string.charAt(i);
+ // find all the characters that need not be escaped
+ // unescaped = %x20-21 | %x23-5B | %x5D-10FFFF
+ while(c >= 0x20 && c <= 0x10ffff && c != 0x22 && c != 0x5c) {
+ i++; end = i;
+ if (i < len) {
+ c = string.charAt(i);
+ } else {
+ break;
+ }
+ }
+ // Write characters without escaping
+ if (begin < end) {
+ writeString(string, begin, end);
+ if (i == len) {
+ break;
+ }
+ }
+
+ switch (c) {
+ case '"':
+ case '\\':
+ writeChar('\\'); writeChar(c);
+ break;
+ case '\b':
+ writeChar('\\'); writeChar('b');
+ break;
+ case '\f':
+ writeChar('\\'); writeChar('f');
+ break;
+ case '\n':
+ writeChar('\\'); writeChar('n');
+ break;
+ case '\r':
+ writeChar('\\'); writeChar('r');
+ break;
+ case '\t':
+ writeChar('\\'); writeChar('t');
+ break;
+ default:
+ String hex = "000" + Integer.toHexString(c);
+ writeString("\\u" + hex.substring(hex.length() - 4));
+ }
+ }
+ writeChar('"');
+ }
+
+ void writeString(String str, int begin, int end) {
+ while (begin < end) { // source begin and end indexes
+ int no = Math.min(buf.length - len, end - begin);
+ str.getChars(begin, begin + no, buf, len);
+ begin += no; // Increment source index
+ len += no; // Increment dest index
+ if (len >= buf.length) {
+ flushBuffer();
+ }
+ }
+ }
+
+ void writeString(String str) {
+ writeString(str, 0, str.length());
+ }
+
+ void writeChar(char c) {
+ if (len >= buf.length) {
+ flushBuffer();
+ }
+ buf[len++] = c;
+ }
+
+ // Not using Integer.toString() since it creates intermediary String
+ // Also, we want the chars to be copied to our buffer directly
+ void writeInt(int num) {
+ int size;
+ if (num == Integer.MIN_VALUE) {
+ size = INT_MIN_VALUE_CHARS.length;
+ } else {
+ size = (num < 0) ? stringSize(-num) + 1 : stringSize(num);
+ }
+ if (len+size >= buf.length) {
+ flushBuffer();
+ }
+ if (num == Integer.MIN_VALUE) {
+ System.arraycopy(INT_MIN_VALUE_CHARS, 0, buf, len, size);
+ } else {
+ fillIntChars(num, buf, len+size);
+ }
+ len += size;
+ }
+
+ // flushBuffer writes the buffered contents to writer. But incase of
+ // byte stream, an OuputStreamWriter is created and that buffers too.
+ // We may need to call OutputStreamWriter#flushBuffer() using
+ // reflection if that is really required (commented out below)
+ void flushBuffer() {
+ try {
+ if (len > 0) {
+ writer.write(buf, 0, len);
+ len = 0;
+ }
+ } catch (IOException ioe) {
+ throw new JsonException(JsonMessages.GENERATOR_WRITE_IO_ERR(), ioe);
+ }
+ }
+
+// private static final Method flushBufferMethod;
+// static {
+// Method m = null;
+// try {
+// m = OutputStreamWriter.class.getDeclaredMethod("flushBuffer");
+// m.setAccessible(true);
+// } catch (Exception e) {
+// // no-op
+// }
+// flushBufferMethod = m;
+// }
+// void flushBufferOSW() {
+// flushBuffer();
+// if (writer instanceof OutputStreamWriter) {
+// try {
+// flushBufferMethod.invoke(writer);
+// } catch (Exception e) {
+// // no-op
+// }
+// }
+// }
+
+ // Requires positive x
+ private static int stringSize(int x) {
+ for (int i=0; ; i++)
+ if (x <= INT_CHARS_SIZE_TABLE[i])
+ return i+1;
+ }
+
+ /**
+ * Places characters representing the integer i into the
+ * character array buf. The characters are placed into
+ * the buffer backwards starting with the least significant
+ * digit at the specified index (exclusive), and working
+ * backwards from there.
+ *
+ * Will fail if i == Integer.MIN_VALUE
+ */
+ private static void fillIntChars(int i, char[] buf, int index) {
+ int q, r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Generate two digits per iteration
+ while (i >= 65536) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = i - ((q << 6) + (q << 5) + (q << 2));
+ i = q;
+ buf [--charPos] = DIGIT_ONES[r];
+ buf [--charPos] = DIGIT_TENS[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i <= 65536, i);
+ for (;;) {
+ q = (i * 52429) >>> (16+3);
+ r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ buf [--charPos] = DIGITS[r];
+ i = q;
+ if (i == 0) break;
+ }
+ if (sign != 0) {
+ buf [--charPos] = sign;
+ }
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonLocationImpl.java b/impl/src/main/java/org/glassfish/json/JsonLocationImpl.java
new file mode 100644
index 0000000..4d29f1e
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonLocationImpl.java
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.stream.JsonLocation;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonLocationImpl implements JsonLocation {
+ static final JsonLocation UNKNOWN = new JsonLocationImpl(-1, -1, -1);
+
+ private final long columnNo;
+ private final long lineNo;
+ private final long offset;
+
+ JsonLocationImpl(long lineNo, long columnNo, long streamOffset) {
+ this.lineNo = lineNo;
+ this.columnNo = columnNo;
+ this.offset = streamOffset;
+ }
+
+ @Override
+ public long getLineNumber() {
+ return lineNo;
+ }
+
+ @Override
+ public long getColumnNumber() {
+ return columnNo;
+ }
+
+ @Override
+ public long getStreamOffset() {
+ return offset;
+ }
+
+ public String toString() {
+ return "(line no="+lineNo+", column no="+columnNo+", offset="+ offset +")";
+ }
+
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/glassfish/json/JsonMessages.java b/impl/src/main/java/org/glassfish/json/JsonMessages.java
new file mode 100644
index 0000000..39d6d01
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonMessages.java
@@ -0,0 +1,221 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * Defines string formatting method for each constant in the resource file
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonMessages {
+ private static final ResourceBundle BUNDLE =
+ ResourceBundle.getBundle("org.glassfish.json.messages");
+
+ // tokenizer messages
+ static String TOKENIZER_UNEXPECTED_CHAR(int unexpected, JsonLocation location) {
+ return localize("tokenizer.unexpected.char", unexpected, location);
+ }
+
+ static String TOKENIZER_EXPECTED_CHAR(int unexpected, JsonLocation location, char expected) {
+ return localize("tokenizer.expected.char", unexpected, location, expected);
+ }
+
+ static String TOKENIZER_IO_ERR() {
+ return localize("tokenizer.io.err");
+ }
+
+
+ // parser messages
+ static String PARSER_GETSTRING_ERR(JsonParser.Event event) {
+ return localize("parser.getString.err", event);
+ }
+
+ static String PARSER_ISINTEGRALNUMBER_ERR(JsonParser.Event event) {
+ return localize("parser.isIntegralNumber.err", event);
+ }
+
+ static String PARSER_GETINT_ERR(JsonParser.Event event) {
+ return localize("parser.getInt.err", event);
+ }
+
+ static String PARSER_GETLONG_ERR(JsonParser.Event event) {
+ return localize("parser.getLong.err", event);
+ }
+
+ static String PARSER_GETBIGDECIMAL_ERR(JsonParser.Event event) {
+ return localize("parser.getBigDecimal.err", event);
+ }
+
+ static String PARSER_GETARRAY_ERR(JsonParser.Event event) {
+ return localize("parser.getArray.err", event);
+ }
+
+ static String PARSER_GETOBJECT_ERR(JsonParser.Event event) {
+ return localize("parser.getObject.err", event);
+ }
+
+ static String PARSER_GETVALUE_ERR(JsonParser.Event event) {
+ return localize("parser.getValue.err", event);
+ }
+
+ static String PARSER_GETVALUESTREAM_ERR() {
+ return localize("parser.getValueStream.err");
+ }
+
+ static String PARSER_EXPECTED_EOF(JsonTokenizer.JsonToken token) {
+ return localize("parser.expected.eof", token);
+ }
+
+ static String PARSER_TOKENIZER_CLOSE_IO() {
+ return localize("parser.tokenizer.close.io");
+ }
+
+ static String PARSER_INVALID_TOKEN(JsonTokenizer.JsonToken token, JsonLocation location, String expectedTokens) {
+ return localize("parser.invalid.token", token, location, expectedTokens);
+ }
+
+ // generator messages
+ static String GENERATOR_FLUSH_IO_ERR() {
+ return localize("generator.flush.io.err");
+ }
+
+ static String GENERATOR_CLOSE_IO_ERR() {
+ return localize("generator.close.io.err");
+ }
+
+ static String GENERATOR_WRITE_IO_ERR() {
+ return localize("generator.write.io.err");
+ }
+
+ static String GENERATOR_ILLEGAL_METHOD(Object scope) {
+ return localize("generator.illegal.method", scope);
+ }
+
+ static String GENERATOR_DOUBLE_INFINITE_NAN() {
+ return localize("generator.double.infinite.nan");
+ }
+
+ static String GENERATOR_INCOMPLETE_JSON() {
+ return localize("generator.incomplete.json");
+ }
+
+ static String GENERATOR_ILLEGAL_MULTIPLE_TEXT() {
+ return localize("generator.illegal.multiple.text");
+ }
+
+
+
+ // writer messages
+ static String WRITER_WRITE_ALREADY_CALLED() {
+ return localize("writer.write.already.called");
+ }
+
+
+ // reader messages
+ static String READER_READ_ALREADY_CALLED() {
+ return localize("reader.read.already.called");
+ }
+
+
+ // obj builder messages
+ static String OBJBUILDER_NAME_NULL() {
+ return localize("objbuilder.name.null");
+ }
+
+ static String OBJBUILDER_VALUE_NULL() {
+ return localize("objbuilder.value.null");
+ }
+
+ static String OBJBUILDER_OBJECT_BUILDER_NULL() {
+ return localize("objbuilder.object.builder.null");
+ }
+
+ static String OBJBUILDER_ARRAY_BUILDER_NULL() {
+ return localize("objbuilder.array.builder.null");
+ }
+
+
+ // array builder messages
+ static String ARRBUILDER_VALUE_NULL() {
+ return localize("arrbuilder.value.null");
+ }
+
+ static String ARRBUILDER_OBJECT_BUILDER_NULL() {
+ return localize("arrbuilder.object.builder.null");
+ }
+
+ static String ARRBUILDER_ARRAY_BUILDER_NULL() {
+ return localize("arrbuilder.array.builder.null");
+ }
+
+
+ private static String localize(String key, Object ... args) {
+ try {
+ String msg = BUNDLE.getString(key);
+ return MessageFormat.format(msg, args);
+ } catch (Exception e) {
+ return getDefaultMessage(key, args);
+ }
+ }
+
+ private static String getDefaultMessage(String key, Object ... args) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[failed to localize] ");
+ sb.append(key);
+ if (args != null) {
+ sb.append('(');
+ for (int i = 0; i < args.length; ++i) {
+ if (i != 0)
+ sb.append(", ");
+ sb.append(String.valueOf(args[i]));
+ }
+ sb.append(')');
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonNumberImpl.java b/impl/src/main/java/org/glassfish/json/JsonNumberImpl.java
new file mode 100644
index 0000000..11ea448
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonNumberImpl.java
@@ -0,0 +1,263 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonNumber;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * JsonNumber impl. Subclasses provide optimized implementations
+ * when backed by int, long, BigDecimal
+ *
+ * @author Jitendra Kotamraju
+ */
+abstract class JsonNumberImpl implements JsonNumber {
+
+ static JsonNumber getJsonNumber(int num) {
+ return new JsonIntNumber(num);
+ }
+
+ static JsonNumber getJsonNumber(long num) {
+ return new JsonLongNumber(num);
+ }
+
+ static JsonNumber getJsonNumber(BigInteger value) {
+ return new JsonBigDecimalNumber(new BigDecimal(value));
+ }
+
+ static JsonNumber getJsonNumber(double value) {
+ //bigDecimal = new BigDecimal(value);
+ // This is the preferred way to convert double to BigDecimal
+ return new JsonBigDecimalNumber(BigDecimal.valueOf(value));
+ }
+
+ static JsonNumber getJsonNumber(BigDecimal value) {
+ return new JsonBigDecimalNumber(value);
+ }
+
+ // Optimized JsonNumber impl for int numbers.
+ private static final class JsonIntNumber extends JsonNumberImpl {
+ private final int num;
+ private BigDecimal bigDecimal; // assigning it lazily on demand
+
+ JsonIntNumber(int num) {
+ this.num = num;
+ }
+
+ @Override
+ public boolean isIntegral() {
+ return true;
+ }
+
+ @Override
+ public int intValue() {
+ return num;
+ }
+
+ @Override
+ public int intValueExact() {
+ return num;
+ }
+
+ @Override
+ public long longValue() {
+ return num;
+ }
+
+ @Override
+ public long longValueExact() {
+ return num;
+ }
+
+ @Override
+ public double doubleValue() {
+ return num;
+ }
+
+ @Override
+ public BigDecimal bigDecimalValue() {
+ // reference assignments are atomic. At the most some more temp
+ // BigDecimal objects are created
+ BigDecimal bd = bigDecimal;
+ if (bd == null) {
+ bigDecimal = bd = new BigDecimal(num);
+ }
+ return bd;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(num);
+ }
+ }
+
+ // Optimized JsonNumber impl for long numbers.
+ private static final class JsonLongNumber extends JsonNumberImpl {
+ private final long num;
+ private BigDecimal bigDecimal; // assigning it lazily on demand
+
+ JsonLongNumber(long num) {
+ this.num = num;
+ }
+
+ @Override
+ public boolean isIntegral() {
+ return true;
+ }
+
+ @Override
+ public long longValue() {
+ return num;
+ }
+
+ @Override
+ public long longValueExact() {
+ return num;
+ }
+
+ @Override
+ public double doubleValue() {
+ return num;
+ }
+
+ @Override
+ public BigDecimal bigDecimalValue() {
+ // reference assignments are atomic. At the most some more temp
+ // BigDecimal objects are created
+ BigDecimal bd = bigDecimal;
+ if (bd == null) {
+ bigDecimal = bd = new BigDecimal(num);
+ }
+ return bd;
+ }
+
+ @Override
+ public String toString() {
+ return Long.toString(num);
+ }
+
+ }
+
+ // JsonNumber impl using BigDecimal numbers.
+ private static final class JsonBigDecimalNumber extends JsonNumberImpl {
+ private final BigDecimal bigDecimal;
+
+ JsonBigDecimalNumber(BigDecimal value) {
+ this.bigDecimal = value;
+ }
+
+ @Override
+ public BigDecimal bigDecimalValue() {
+ return bigDecimal;
+ }
+
+ }
+
+ @Override
+ public boolean isIntegral() {
+ return bigDecimalValue().scale() == 0;
+ }
+
+ @Override
+ public int intValue() {
+ return bigDecimalValue().intValue();
+ }
+
+ @Override
+ public int intValueExact() {
+ return bigDecimalValue().intValueExact();
+ }
+
+ @Override
+ public long longValue() {
+ return bigDecimalValue().longValue();
+ }
+
+ @Override
+ public long longValueExact() {
+ return bigDecimalValue().longValueExact();
+ }
+
+ @Override
+ public double doubleValue() {
+ return bigDecimalValue().doubleValue();
+ }
+
+ @Override
+ public BigInteger bigIntegerValue() {
+ return bigDecimalValue().toBigInteger();
+ }
+
+ @Override
+ public BigInteger bigIntegerValueExact() {
+ return bigDecimalValue().toBigIntegerExact();
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return ValueType.NUMBER;
+ }
+
+ @Override
+ public int hashCode() {
+ return bigDecimalValue().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj){
+ return true;
+ }
+ if (!(obj instanceof JsonNumber)) {
+ return false;
+ }
+ JsonNumber other = (JsonNumber)obj;
+ return bigDecimalValue().equals(other.bigDecimalValue());
+ }
+
+ @Override
+ public String toString() {
+ return bigDecimalValue().toString();
+ }
+
+}
+
diff --git a/impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java b/impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java
new file mode 100644
index 0000000..bec90b9
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java
@@ -0,0 +1,331 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonArrayBuilder;
+import javax.json.*;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * JsonObjectBuilder implementation
+ *
+ * @author Jitendra Kotamraju
+ * @author Kin-man Chung
+ */
+class JsonObjectBuilderImpl implements JsonObjectBuilder {
+ private Map<String, JsonValue> valueMap;
+ private final BufferPool bufferPool;
+
+ JsonObjectBuilderImpl(BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ }
+
+ JsonObjectBuilderImpl(JsonObject object, BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ valueMap = new LinkedHashMap<>();
+ valueMap.putAll(object);
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, JsonValue value) {
+ validateName(name);
+ validateValue(value);
+ putValueMap(name, value);
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, String value) {
+ validateName(name);
+ validateValue(value);
+ putValueMap(name, new JsonStringImpl(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, BigInteger value) {
+ validateName(name);
+ validateValue(value);
+ putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, BigDecimal value) {
+ validateName(name);
+ validateValue(value);
+ putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, int value) {
+ validateName(name);
+ putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, long value) {
+ validateName(name);
+ putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, double value) {
+ validateName(name);
+ putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, boolean value) {
+ validateName(name);
+ putValueMap(name, value ? JsonValue.TRUE : JsonValue.FALSE);
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder addNull(String name) {
+ validateName(name);
+ putValueMap(name, JsonValue.NULL);
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, JsonObjectBuilder builder) {
+ validateName(name);
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.OBJBUILDER_OBJECT_BUILDER_NULL());
+ }
+ putValueMap(name, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder add(String name, JsonArrayBuilder builder) {
+ validateName(name);
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.OBJBUILDER_ARRAY_BUILDER_NULL());
+ }
+ putValueMap(name, builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder addAll(JsonObjectBuilder builder) {
+ if (builder == null) {
+ throw new NullPointerException(JsonMessages.OBJBUILDER_OBJECT_BUILDER_NULL());
+ }
+ if (valueMap == null) {
+ this.valueMap = new LinkedHashMap<>();
+ }
+ this.valueMap.putAll(builder.build());
+ return this;
+ }
+
+ @Override
+ public JsonObjectBuilder remove(String name) {
+ validateName(name);
+ this.valueMap.remove(name);
+ return this;
+ }
+
+ @Override
+ public JsonObject build() {
+ Map<String, JsonValue> snapshot = (valueMap == null)
+ ? Collections.<String, JsonValue>emptyMap()
+ : Collections.unmodifiableMap(valueMap);
+ valueMap = null;
+ return new JsonObjectImpl(snapshot, bufferPool);
+ }
+
+ private void putValueMap(String name, JsonValue value) {
+ if (valueMap == null) {
+ this.valueMap = new LinkedHashMap<>();
+ }
+ valueMap.put(name, value);
+ }
+
+ private void validateName(String name) {
+ if (name == null) {
+ throw new NullPointerException(JsonMessages.OBJBUILDER_NAME_NULL());
+ }
+ }
+
+ private void validateValue(Object value) {
+ if (value == null) {
+ throw new NullPointerException(JsonMessages.OBJBUILDER_VALUE_NULL());
+ }
+ }
+
+ private static final class JsonObjectImpl extends AbstractMap<String, JsonValue> implements JsonObject {
+ private final Map<String, JsonValue> valueMap; // unmodifiable
+ private final BufferPool bufferPool;
+
+ JsonObjectImpl(Map<String, JsonValue> valueMap, BufferPool bufferPool) {
+ this.valueMap = valueMap;
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonArray getJsonArray(String name) {
+ return (JsonArray)get(name);
+ }
+
+ @Override
+ public JsonObject getJsonObject(String name) {
+ return (JsonObject)get(name);
+ }
+
+ @Override
+ public JsonNumber getJsonNumber(String name) {
+ return (JsonNumber)get(name);
+ }
+
+ @Override
+ public JsonString getJsonString(String name) {
+ return (JsonString)get(name);
+ }
+
+ @Override
+ public String getString(String name) {
+ return getJsonString(name).getString();
+ }
+
+ @Override
+ public String getString(String name, String defaultValue) {
+ try {
+ return getString(name);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public int getInt(String name) {
+ return getJsonNumber(name).intValue();
+ }
+
+ @Override
+ public int getInt(String name, int defaultValue) {
+ try {
+ return getInt(name);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public boolean getBoolean(String name) {
+ JsonValue value = get(name);
+ if (value == null) {
+ throw new NullPointerException();
+ } else if (value == JsonValue.TRUE) {
+ return true;
+ } else if (value == JsonValue.FALSE) {
+ return false;
+ } else {
+ throw new ClassCastException();
+ }
+ }
+
+ @Override
+ public boolean getBoolean(String name, boolean defaultValue) {
+ try {
+ return getBoolean(name);
+ } catch (Exception e) {
+ return defaultValue;
+ }
+ }
+
+ @Override
+ public boolean isNull(String name) {
+ return get(name).equals(JsonValue.NULL);
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return ValueType.OBJECT;
+ }
+
+ @Override
+ public Set<Entry<String, JsonValue>> entrySet() {
+ return valueMap.entrySet();
+ }
+
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ try (JsonWriter jw = new JsonWriterImpl(sw, bufferPool)) {
+ jw.write(this);
+ }
+ return sw.toString();
+ }
+
+ @Override
+ public JsonObject asJsonObject() {
+ return this;
+ }
+
+ @Override
+ public int size() {
+ return valueMap.size();
+ }
+
+ @Override
+ public JsonValue get(Object key) {
+ return valueMap.get(key);
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return valueMap.containsKey(key);
+ }
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonParserFactoryImpl.java b/impl/src/main/java/org/glassfish/json/JsonParserFactoryImpl.java
new file mode 100644
index 0000000..5e1960e
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonParserFactoryImpl.java
@@ -0,0 +1,95 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.stream.JsonParserFactory;
+import javax.json.stream.JsonParser;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonParserFactoryImpl implements JsonParserFactory {
+ private final Map<String, ?> config = Collections.emptyMap();
+ private final BufferPool bufferPool;
+
+ JsonParserFactoryImpl(BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonParser createParser(Reader reader) {
+ return new JsonParserImpl(reader, bufferPool);
+ }
+
+ @Override
+ public JsonParser createParser(InputStream in) {
+ return new JsonParserImpl(in, bufferPool);
+ }
+
+ @Override
+ public JsonParser createParser(InputStream in, Charset charset) {
+ return new JsonParserImpl(in, charset, bufferPool);
+ }
+
+ @Override
+ public JsonParser createParser(JsonArray array) {
+ return new JsonStructureParser(array);
+ }
+
+ @Override
+ public Map<String, ?> getConfigInUse() {
+ return config;
+ }
+
+ @Override
+ public JsonParser createParser(JsonObject object) {
+ return new JsonStructureParser(object);
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java
new file mode 100644
index 0000000..dad8681
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java
@@ -0,0 +1,513 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.*;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import java.io.*;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.stream.*;
+import java.util.function.Consumer;
+
+import org.glassfish.json.JsonTokenizer.JsonToken;
+import org.glassfish.json.api.BufferPool;
+
+/**
+ * JSON parser implementation. NoneContext, ArrayContext, ObjectContext is used
+ * to go to next parser state.
+ *
+ * @author Jitendra Kotamraju
+ * @author Kin-man Chung
+ */
+public class JsonParserImpl implements JsonParser {
+
+ private final BufferPool bufferPool;
+ private Context currentContext = new NoneContext();
+ private Event currentEvent;
+
+ private final Stack stack = new Stack();
+ private final JsonTokenizer tokenizer;
+
+ public JsonParserImpl(Reader reader, BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ tokenizer = new JsonTokenizer(reader, bufferPool);
+ }
+
+ public JsonParserImpl(InputStream in, BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ UnicodeDetectingInputStream uin = new UnicodeDetectingInputStream(in);
+ tokenizer = new JsonTokenizer(new InputStreamReader(uin, uin.getCharset()), bufferPool);
+ }
+
+ public JsonParserImpl(InputStream in, Charset encoding, BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ tokenizer = new JsonTokenizer(new InputStreamReader(in, encoding), bufferPool);
+ }
+
+ public String getString() {
+ if (currentEvent == Event.KEY_NAME || currentEvent == Event.VALUE_STRING
+ || currentEvent == Event.VALUE_NUMBER) {
+ return tokenizer.getValue();
+ }
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETSTRING_ERR(currentEvent));
+ }
+
+ @Override
+ public boolean isIntegralNumber() {
+ if (currentEvent != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_ISINTEGRALNUMBER_ERR(currentEvent));
+ }
+ return tokenizer.isIntegral();
+ }
+
+ @Override
+ public int getInt() {
+ if (currentEvent != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETINT_ERR(currentEvent));
+ }
+ return tokenizer.getInt();
+ }
+
+ boolean isDefinitelyInt() {
+ return tokenizer.isDefinitelyInt();
+ }
+
+ boolean isDefinitelyLong() {
+ return tokenizer.isDefinitelyLong();
+ }
+
+ @Override
+ public long getLong() {
+ if (currentEvent != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETLONG_ERR(currentEvent));
+ }
+ return tokenizer.getLong();
+ }
+
+ @Override
+ public BigDecimal getBigDecimal() {
+ if (currentEvent != Event.VALUE_NUMBER) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETBIGDECIMAL_ERR(currentEvent));
+ }
+ return tokenizer.getBigDecimal();
+ }
+
+ @Override
+ public JsonArray getArray() {
+ if (currentEvent != Event.START_ARRAY) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETARRAY_ERR(currentEvent));
+ }
+ return getArray(new JsonArrayBuilderImpl(bufferPool));
+ }
+
+ @Override
+ public JsonObject getObject() {
+ if (currentEvent != Event.START_OBJECT) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETOBJECT_ERR(currentEvent));
+ }
+ return getObject(new JsonObjectBuilderImpl(bufferPool));
+ }
+
+ @Override
+ public JsonValue getValue() {
+ switch (currentEvent) {
+ case START_ARRAY:
+ return getArray(new JsonArrayBuilderImpl(bufferPool));
+ case START_OBJECT:
+ return getObject(new JsonObjectBuilderImpl(bufferPool));
+ case KEY_NAME:
+ case VALUE_STRING:
+ return new JsonStringImpl(getString());
+ case VALUE_NUMBER:
+ if (isDefinitelyInt()) {
+ return JsonNumberImpl.getJsonNumber(getInt());
+ } else if (isDefinitelyLong()) {
+ return JsonNumberImpl.getJsonNumber(getLong());
+ }
+ return JsonNumberImpl.getJsonNumber(getBigDecimal());
+ case VALUE_TRUE:
+ return JsonValue.TRUE;
+ case VALUE_FALSE:
+ return JsonValue.FALSE;
+ case VALUE_NULL:
+ return JsonValue.NULL;
+ case END_ARRAY:
+ case END_OBJECT:
+ default:
+ throw new IllegalStateException(JsonMessages.PARSER_GETVALUE_ERR(currentEvent));
+ }
+ }
+
+ @Override
+ public Stream<JsonValue> getArrayStream() {
+ if (currentEvent != Event.START_ARRAY) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETARRAY_ERR(currentEvent));
+ }
+ Spliterator<JsonValue> spliterator =
+ new Spliterators.AbstractSpliterator<JsonValue>(Long.MAX_VALUE, Spliterator.ORDERED) {
+ @Override
+ public Spliterator<JsonValue> trySplit() {
+ return null;
+ }
+ @Override
+ public boolean tryAdvance(Consumer<? super JsonValue> action) {
+ if (action == null) {
+ throw new NullPointerException();
+ }
+ if (! hasNext()) {
+ return false;
+ }
+ if (next() == JsonParser.Event.END_ARRAY) {
+ return false;
+ }
+ action.accept(getValue());
+ return true;
+ }
+ };
+ return StreamSupport.stream(spliterator, false);
+ }
+
+ @Override
+ public Stream<Map.Entry<String, JsonValue>> getObjectStream() {
+ if (currentEvent != Event.START_OBJECT) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETOBJECT_ERR(currentEvent));
+ }
+ Spliterator<Map.Entry<String, JsonValue>> spliterator =
+ new Spliterators.AbstractSpliterator<Map.Entry<String, JsonValue>>(Long.MAX_VALUE, Spliterator.ORDERED) {
+ @Override
+ public Spliterator<Map.Entry<String,JsonValue>> trySplit() {
+ return null;
+ }
+ @Override
+ public boolean tryAdvance(Consumer<? super Map.Entry<String, JsonValue>> action) {
+ if (action == null) {
+ throw new NullPointerException();
+ }
+ if (! hasNext()) {
+ return false;
+ }
+ JsonParser.Event e = next();
+ if (e == JsonParser.Event.END_OBJECT) {
+ return false;
+ }
+ if (e != JsonParser.Event.KEY_NAME) {
+ throw new JsonException("internal error");
+ }
+ String key = getString();
+ if (! hasNext()) {
+ throw new JsonException("internal error");
+ }
+ next();
+ JsonValue value = getValue();
+ action.accept(new AbstractMap.SimpleImmutableEntry<String, JsonValue>(key, value));
+ return true;
+ }
+ };
+ return StreamSupport.stream(spliterator, false);
+ }
+
+ @Override
+ public Stream<JsonValue> getValueStream() {
+ if (! (currentContext instanceof NoneContext)) {
+ throw new IllegalStateException(
+ JsonMessages.PARSER_GETVALUESTREAM_ERR());
+ }
+ Spliterator<JsonValue> spliterator =
+ new Spliterators.AbstractSpliterator<JsonValue>(Long.MAX_VALUE, Spliterator.ORDERED) {
+ @Override
+ public Spliterator<JsonValue> trySplit() {
+ return null;
+ }
+ @Override
+ public boolean tryAdvance(Consumer<? super JsonValue> action) {
+ if (action == null) {
+ throw new NullPointerException();
+ }
+ if (! hasNext()) {
+ return false;
+ }
+ next();
+ action.accept(getValue());
+ return true;
+ }
+ };
+ return StreamSupport.stream(spliterator, false);
+ }
+
+ @Override
+ public void skipArray() {
+ Context previousContext = stack.peek();
+ while (hasNext()) {
+ if (next() == JsonParser.Event.END_ARRAY &&
+ previousContext == currentContext) {
+ return;
+ }
+ }
+ }
+
+ @Override
+ public void skipObject() {
+ Context previousContext = stack.peek();
+ while (hasNext()) {
+ if (next() == JsonParser.Event.END_OBJECT &&
+ previousContext == currentContext) {
+ return;
+ }
+ }
+ }
+
+ private JsonArray getArray(JsonArrayBuilder builder) {
+ while(hasNext()) {
+ JsonParser.Event e = next();
+ if (e == JsonParser.Event.END_ARRAY) {
+ return builder.build();
+ }
+ builder.add(getValue());
+ }
+ return null;
+ }
+
+ private JsonObject getObject(JsonObjectBuilder builder) {
+ while(hasNext()) {
+ JsonParser.Event e = next();
+ if (e == JsonParser.Event.END_OBJECT) {
+ return builder.build();
+ }
+ String key = getString();
+ next();
+ builder.add(key, getValue());
+ }
+ return null;
+ }
+
+ @Override
+ public JsonLocation getLocation() {
+ return tokenizer.getLocation();
+ }
+
+ public JsonLocation getLastCharLocation() {
+ return tokenizer.getLastCharLocation();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return tokenizer.hasNextToken();
+ }
+
+ @Override
+ public Event next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return currentEvent = currentContext.getNextEvent();
+ }
+
+ public void close() {
+ try {
+ tokenizer.close();
+ } catch (IOException e) {
+ throw new JsonException(JsonMessages.PARSER_TOKENIZER_CLOSE_IO(), e);
+ }
+ }
+
+ // Using the optimized stack impl as we don't require other things
+ // like iterator etc.
+ private static final class Stack {
+ private Context head;
+
+ private void push(Context context) {
+ context.next = head;
+ head = context;
+ }
+
+ private Context pop() {
+ if (head == null) {
+ throw new NoSuchElementException();
+ }
+ Context temp = head;
+ head = head.next;
+ return temp;
+ }
+
+ private Context peek() {
+ return head;
+ }
+
+ private boolean isEmpty() {
+ return head == null;
+ }
+ }
+
+ private abstract class Context {
+ Context next;
+ abstract Event getNextEvent();
+ }
+
+ private final class NoneContext extends Context {
+ @Override
+ public Event getNextEvent() {
+ // Handle 1. { 2. [ 3. value
+ JsonToken token = tokenizer.nextToken();
+ if (token == JsonToken.CURLYOPEN) {
+ stack.push(currentContext);
+ currentContext = new ObjectContext();
+ return Event.START_OBJECT;
+ } else if (token == JsonToken.SQUAREOPEN) {
+ stack.push(currentContext);
+ currentContext = new ArrayContext();
+ return Event.START_ARRAY;
+ } else if (token.isValue()) {
+ return token.getEvent();
+ }
+ throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]");
+ }
+ }
+
+ private JsonParsingException parsingException(JsonToken token, String expectedTokens) {
+ JsonLocation location = getLastCharLocation();
+ return new JsonParsingException(
+ JsonMessages.PARSER_INVALID_TOKEN(token, location, expectedTokens), location);
+ }
+
+ private final class ObjectContext extends Context {
+ private boolean firstValue = true;
+
+ /*
+ * Some more things could be optimized. For example, instead
+ * tokenizer.nextToken(), one could use tokenizer.matchColonToken() to
+ * match ':'. That might optimize a bit, but will fragment nextToken().
+ * I think the current one is more readable.
+ *
+ */
+ @Override
+ public Event getNextEvent() {
+ // Handle 1. } 2. name:value 3. ,name:value
+ JsonToken token = tokenizer.nextToken();
+ if (currentEvent == Event.KEY_NAME) {
+ // Handle 1. :value
+ if (token != JsonToken.COLON) {
+ throw parsingException(token, "[COLON]");
+ }
+ token = tokenizer.nextToken();
+ if (token.isValue()) {
+ return token.getEvent();
+ } else if (token == JsonToken.CURLYOPEN) {
+ stack.push(currentContext);
+ currentContext = new ObjectContext();
+ return Event.START_OBJECT;
+ } else if (token == JsonToken.SQUAREOPEN) {
+ stack.push(currentContext);
+ currentContext = new ArrayContext();
+ return Event.START_ARRAY;
+ }
+ throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]");
+ } else {
+ // Handle 1. } 2. name 3. ,name
+ if (token == JsonToken.CURLYCLOSE) {
+ currentContext = stack.pop();
+ return Event.END_OBJECT;
+ }
+ if (firstValue) {
+ firstValue = false;
+ } else {
+ if (token != JsonToken.COMMA) {
+ throw parsingException(token, "[COMMA]");
+ }
+ token = tokenizer.nextToken();
+ }
+ if (token == JsonToken.STRING) {
+ return Event.KEY_NAME;
+ }
+ throw parsingException(token, "[STRING]");
+ }
+ }
+
+ }
+
+ private final class ArrayContext extends Context {
+ private boolean firstValue = true;
+
+ // Handle 1. ] 2. value 3. ,value
+ @Override
+ public Event getNextEvent() {
+ JsonToken token = tokenizer.nextToken();
+ if (token == JsonToken.SQUARECLOSE) {
+ currentContext = stack.pop();
+ return Event.END_ARRAY;
+ }
+ if (firstValue) {
+ firstValue = false;
+ } else {
+ if (token != JsonToken.COMMA) {
+ throw parsingException(token, "[COMMA]");
+ }
+ token = tokenizer.nextToken();
+ }
+ if (token.isValue()) {
+ return token.getEvent();
+ } else if (token == JsonToken.CURLYOPEN) {
+ stack.push(currentContext);
+ currentContext = new ObjectContext();
+ return Event.START_OBJECT;
+ } else if (token == JsonToken.SQUAREOPEN) {
+ stack.push(currentContext);
+ currentContext = new ArrayContext();
+ return Event.START_ARRAY;
+ }
+ throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]");
+ }
+
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java b/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java
new file mode 100644
index 0000000..d5a2813
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java
@@ -0,0 +1,122 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.stream.JsonGenerator;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonPrettyGeneratorImpl extends JsonGeneratorImpl {
+ private int indentLevel;
+ private static final String INDENT = " ";
+
+ public JsonPrettyGeneratorImpl(Writer writer, BufferPool bufferPool) {
+ super(writer, bufferPool);
+ }
+
+ public JsonPrettyGeneratorImpl(OutputStream out, BufferPool bufferPool) {
+ super(out, bufferPool);
+ }
+
+ public JsonPrettyGeneratorImpl(OutputStream out, Charset encoding, BufferPool bufferPool) {
+ super(out, encoding, bufferPool);
+ }
+
+ @Override
+ public JsonGenerator writeStartObject() {
+ super.writeStartObject();
+ indentLevel++;
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartObject(String name) {
+ super.writeStartObject(name);
+ indentLevel++;
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray() {
+ super.writeStartArray();
+ indentLevel++;
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeStartArray(String name) {
+ super.writeStartArray(name);
+ indentLevel++;
+ return this;
+ }
+
+ @Override
+ public JsonGenerator writeEnd() {
+ writeNewLine();
+ indentLevel--;
+ writeIndent();
+ super.writeEnd();
+ return this;
+ }
+
+ private void writeIndent() {
+ for(int i=0; i < indentLevel; i++) {
+ writeString(INDENT);
+ }
+ }
+
+ @Override
+ protected void writeComma() {
+ super.writeComma();
+ writeChar('\n');
+ writeIndent();
+ }
+
+ private void writeNewLine() {
+ writeChar('\n');
+ }
+}
\ No newline at end of file
diff --git a/impl/src/main/java/org/glassfish/json/JsonProviderImpl.java b/impl/src/main/java/org/glassfish/json/JsonProviderImpl.java
new file mode 100644
index 0000000..8ec4bc7
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonProviderImpl.java
@@ -0,0 +1,249 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import javax.json.spi.JsonProvider;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * @author Jitendra Kotamraju
+ * @author Kin-man Chung
+ */
+public class JsonProviderImpl extends JsonProvider {
+
+ private final BufferPool bufferPool = new BufferPoolImpl();
+
+ @Override
+ public JsonGenerator createGenerator(Writer writer) {
+ return new JsonGeneratorImpl(writer, bufferPool);
+ }
+
+ @Override
+ public JsonGenerator createGenerator(OutputStream out) {
+ return new JsonGeneratorImpl(out, bufferPool);
+ }
+
+ @Override
+ public JsonParser createParser(Reader reader) {
+ return new JsonParserImpl(reader, bufferPool);
+ }
+
+ @Override
+ public JsonParser createParser(InputStream in) {
+ return new JsonParserImpl(in, bufferPool);
+ }
+
+ @Override
+ public JsonParserFactory createParserFactory(Map<String, ?> config) {
+ BufferPool pool = null;
+ if (config != null && config.containsKey(BufferPool.class.getName())) {
+ pool = (BufferPool)config.get(BufferPool.class.getName());
+ }
+ if (pool == null) {
+ pool = bufferPool;
+ }
+ return new JsonParserFactoryImpl(pool);
+ }
+
+ @Override
+ public JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config) {
+ Map<String, Object> providerConfig;
+ boolean prettyPrinting;
+ BufferPool pool;
+ if (config == null) {
+ providerConfig = Collections.emptyMap();
+ prettyPrinting = false;
+ pool = bufferPool;
+ } else {
+ providerConfig = new HashMap<>();
+ if (prettyPrinting=JsonProviderImpl.isPrettyPrintingEnabled(config)) {
+ providerConfig.put(JsonGenerator.PRETTY_PRINTING, true);
+ }
+ pool = (BufferPool)config.get(BufferPool.class.getName());
+ if (pool != null) {
+ providerConfig.put(BufferPool.class.getName(), pool);
+ } else {
+ pool = bufferPool;
+ }
+ providerConfig = Collections.unmodifiableMap(providerConfig);
+ }
+
+ return new JsonGeneratorFactoryImpl(providerConfig, prettyPrinting, pool);
+ }
+
+ @Override
+ public JsonReader createReader(Reader reader) {
+ return new JsonReaderImpl(reader, bufferPool);
+ }
+
+ @Override
+ public JsonReader createReader(InputStream in) {
+ return new JsonReaderImpl(in, bufferPool);
+ }
+
+ @Override
+ public JsonWriter createWriter(Writer writer) {
+ return new JsonWriterImpl(writer, bufferPool);
+ }
+
+ @Override
+ public JsonWriter createWriter(OutputStream out) {
+ return new JsonWriterImpl(out, bufferPool);
+ }
+
+ @Override
+ public JsonWriterFactory createWriterFactory(Map<String, ?> config) {
+ Map<String, Object> providerConfig;
+ boolean prettyPrinting;
+ BufferPool pool;
+ if (config == null) {
+ providerConfig = Collections.emptyMap();
+ prettyPrinting = false;
+ pool = bufferPool;
+ } else {
+ providerConfig = new HashMap<>();
+ if (prettyPrinting=JsonProviderImpl.isPrettyPrintingEnabled(config)) {
+ providerConfig.put(JsonGenerator.PRETTY_PRINTING, true);
+ }
+ pool = (BufferPool)config.get(BufferPool.class.getName());
+ if (pool != null) {
+ providerConfig.put(BufferPool.class.getName(), pool);
+ } else {
+ pool = bufferPool;
+ }
+ providerConfig = Collections.unmodifiableMap(providerConfig);
+ }
+ return new JsonWriterFactoryImpl(providerConfig, prettyPrinting, pool);
+ }
+
+ @Override
+ public JsonReaderFactory createReaderFactory(Map<String, ?> config) {
+ BufferPool pool = null;
+ if (config != null && config.containsKey(BufferPool.class.getName())) {
+ pool = (BufferPool)config.get(BufferPool.class.getName());
+ }
+ if (pool == null) {
+ pool = bufferPool;
+ }
+ return new JsonReaderFactoryImpl(pool);
+ }
+
+ @Override
+ public JsonObjectBuilder createObjectBuilder() {
+ return new JsonObjectBuilderImpl(bufferPool);
+ }
+
+ @Override
+ public JsonObjectBuilder createObjectBuilder(JsonObject object) {
+ return new JsonObjectBuilderImpl(object, bufferPool);
+ }
+
+ @Override
+ public JsonArrayBuilder createArrayBuilder() {
+ return new JsonArrayBuilderImpl(bufferPool);
+ }
+
+ @Override
+ public JsonArrayBuilder createArrayBuilder(JsonArray array) {
+ return new JsonArrayBuilderImpl(array, bufferPool);
+ }
+
+ @Override
+ public JsonString createValue(String value) {
+ return new JsonStringImpl(value);
+ }
+
+ @Override
+ public JsonNumber createValue(int value) {
+ return JsonNumberImpl.getJsonNumber(value);
+ }
+
+ @Override
+ public JsonNumber createValue(long value) {
+ return JsonNumberImpl.getJsonNumber(value);
+ }
+
+ @Override
+ public JsonNumber createValue(double value) {
+ return JsonNumberImpl.getJsonNumber(value);
+ }
+
+ @Override
+ public JsonNumber createValue(BigInteger value) {
+ return JsonNumberImpl.getJsonNumber(value);
+ }
+
+ @Override
+ public JsonNumber createValue(BigDecimal value) {
+ return JsonNumberImpl.getJsonNumber(value);
+ }
+
+ @Override
+ public JsonBuilderFactory createBuilderFactory(Map<String,?> config) {
+ BufferPool pool = null ;
+ if (config != null && config.containsKey(BufferPool.class.getName())) {
+ pool = (BufferPool)config.get(BufferPool.class.getName());
+ }
+ if (pool == null) {
+ pool = bufferPool;
+ }
+ return new JsonBuilderFactoryImpl(pool);
+ }
+
+ static boolean isPrettyPrintingEnabled(Map<String, ?> config) {
+ return config.containsKey(JsonGenerator.PRETTY_PRINTING);
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonReaderFactoryImpl.java b/impl/src/main/java/org/glassfish/json/JsonReaderFactoryImpl.java
new file mode 100644
index 0000000..24cd162
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonReaderFactoryImpl.java
@@ -0,0 +1,83 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonReaderFactoryImpl implements JsonReaderFactory {
+ private final Map<String, ?> config = Collections.emptyMap();
+ private final BufferPool bufferPool;
+
+ JsonReaderFactoryImpl(BufferPool bufferPool) {
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonReader createReader(Reader reader) {
+ return new JsonReaderImpl(reader, bufferPool);
+ }
+
+ @Override
+ public JsonReader createReader(InputStream in) {
+ return new JsonReaderImpl(in, bufferPool);
+ }
+
+ @Override
+ public JsonReader createReader(InputStream in, Charset charset) {
+ return new JsonReaderImpl(in, charset, bufferPool);
+ }
+
+ @Override
+ public Map<String, ?> getConfigInUse() {
+ return config;
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonReaderImpl.java b/impl/src/main/java/org/glassfish/json/JsonReaderImpl.java
new file mode 100644
index 0000000..5955482
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonReaderImpl.java
@@ -0,0 +1,137 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonParser;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+
+/**
+ * JsonReader impl using parser and builders.
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonReaderImpl implements JsonReader {
+ private final JsonParserImpl parser;
+ private boolean readDone;
+ private final BufferPool bufferPool;
+
+ JsonReaderImpl(Reader reader, BufferPool bufferPool) {
+ parser = new JsonParserImpl(reader, bufferPool);
+ this.bufferPool = bufferPool;
+ }
+
+ JsonReaderImpl(InputStream in, BufferPool bufferPool) {
+ parser = new JsonParserImpl(in, bufferPool);
+ this.bufferPool = bufferPool;
+ }
+
+ JsonReaderImpl(InputStream in, Charset charset, BufferPool bufferPool) {
+ parser = new JsonParserImpl(in, charset, bufferPool);
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonStructure read() {
+ if (readDone) {
+ throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+ }
+ readDone = true;
+ if (parser.hasNext()) {
+ JsonParser.Event e = parser.next();
+ if (e == JsonParser.Event.START_ARRAY) {
+ return parser.getArray();
+ } else if (e == JsonParser.Event.START_OBJECT) {
+ return parser.getObject();
+ }
+ }
+ throw new JsonException("Internal Error");
+ }
+
+ @Override
+ public JsonObject readObject() {
+ if (readDone) {
+ throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+ }
+ readDone = true;
+ if (parser.hasNext()) {
+ parser.next();
+ return parser.getObject();
+ }
+ throw new JsonException("Internal Error");
+ }
+
+ @Override
+ public JsonArray readArray() {
+ if (readDone) {
+ throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+ }
+ readDone = true;
+ if (parser.hasNext()) {
+ parser.next();
+ return parser.getArray();
+ }
+ throw new JsonException("Internal Error");
+ }
+
+ @Override
+ public JsonValue readValue() {
+ if (readDone) {
+ throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+ }
+ readDone = true;
+ if (parser.hasNext()) {
+ parser.next();
+ return parser.getValue();
+ }
+ throw new JsonException("Internal Error");
+ }
+
+ @Override
+ public void close() {
+ readDone = true;
+ parser.close();
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonStringImpl.java b/impl/src/main/java/org/glassfish/json/JsonStringImpl.java
new file mode 100644
index 0000000..425cb7f
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonStringImpl.java
@@ -0,0 +1,132 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonString;
+
+/**
+ * JsonString impl
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonStringImpl implements JsonString {
+
+ private final String value;
+
+ JsonStringImpl(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String getString() {
+ return value;
+ }
+
+ @Override
+ public CharSequence getChars() {
+ return value;
+ }
+
+ @Override
+ public ValueType getValueType() {
+ return ValueType.STRING;
+ }
+
+ @Override
+ public int hashCode() {
+ return getString().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj){
+ return true;
+ }
+ if (!(obj instanceof JsonString)) {
+ return false;
+ }
+ JsonString other = (JsonString)obj;
+ return getString().equals(other.getString());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('"');
+
+ for(int i = 0; i < value.length(); i++) {
+ char c = value.charAt(i);
+ // unescaped = %x20-21 | %x23-5B | %x5D-10FFFF
+ if (c >= 0x20 && c <= 0x10ffff && c != 0x22 && c != 0x5c) {
+ sb.append(c);
+ } else {
+ switch (c) {
+ case '"':
+ case '\\':
+ sb.append('\\'); sb.append(c);
+ break;
+ case '\b':
+ sb.append('\\'); sb.append('b');
+ break;
+ case '\f':
+ sb.append('\\'); sb.append('f');
+ break;
+ case '\n':
+ sb.append('\\'); sb.append('n');
+ break;
+ case '\r':
+ sb.append('\\'); sb.append('r');
+ break;
+ case '\t':
+ sb.append('\\'); sb.append('t');
+ break;
+ default:
+ String hex = "000" + Integer.toHexString(c);
+ sb.append("\\u").append(hex.substring(hex.length() - 4));
+ }
+ }
+ }
+
+ sb.append('"');
+ return sb.toString();
+ }
+}
+
diff --git a/impl/src/main/java/org/glassfish/json/JsonStructureParser.java b/impl/src/main/java/org/glassfish/json/JsonStructureParser.java
new file mode 100644
index 0000000..d4feb6f
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonStructureParser.java
@@ -0,0 +1,271 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.*;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * {@link JsonParser} implementation on top of JsonArray/JsonObject
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonStructureParser implements JsonParser {
+
+ private Scope current;
+ private Event state;
+ private final Deque<Scope> scopeStack = new ArrayDeque<>();
+
+ JsonStructureParser(JsonArray array) {
+ current = new ArrayScope(array);
+ }
+
+ JsonStructureParser(JsonObject object) {
+ current = new ObjectScope(object);
+ }
+
+ @Override
+ public String getString() {
+ if (state == Event.KEY_NAME) {
+ return ((ObjectScope)current).key;
+ } else if (state == Event.VALUE_STRING) {
+ return ((JsonString)current.getJsonValue()).getString();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_GETSTRING_ERR(state));
+ }
+
+ @Override
+ public boolean isIntegralNumber() {
+ if (state == Event.VALUE_NUMBER) {
+ return ((JsonNumber)current.getJsonValue()).isIntegral();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_ISINTEGRALNUMBER_ERR(state));
+ }
+
+ @Override
+ public int getInt() {
+ if (state == Event.VALUE_NUMBER) {
+ return ((JsonNumber)current.getJsonValue()).intValue();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_GETINT_ERR(state));
+ }
+
+ @Override
+ public long getLong() {
+ if (state == Event.VALUE_NUMBER) {
+ return ((JsonNumber)current.getJsonValue()).longValue();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_GETLONG_ERR(state));
+ }
+
+ @Override
+ public BigDecimal getBigDecimal() {
+ if (state == Event.VALUE_NUMBER) {
+ return ((JsonNumber)current.getJsonValue()).bigDecimalValue();
+ }
+ throw new IllegalStateException(JsonMessages.PARSER_GETBIGDECIMAL_ERR(state));
+ }
+
+ @Override
+ public JsonLocation getLocation() {
+ return JsonLocationImpl.UNKNOWN;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !((state == Event.END_OBJECT || state == Event.END_ARRAY) && scopeStack.isEmpty());
+ }
+
+ @Override
+ public Event next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ transition();
+ return state;
+ }
+
+ private void transition() {
+ if (state == null) {
+ state = current instanceof ArrayScope ? Event.START_ARRAY : Event.START_OBJECT;
+ } else {
+ if (state == Event.END_OBJECT || state == Event.END_ARRAY) {
+ current = scopeStack.pop();
+ }
+ if (current instanceof ArrayScope) {
+ if (current.hasNext()) {
+ current.next();
+ state = getState(current.getJsonValue());
+ if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
+ scopeStack.push(current);
+ current = Scope.createScope(current.getJsonValue());
+ }
+ } else {
+ state = Event.END_ARRAY;
+ }
+ } else {
+ // ObjectScope
+ if (state == Event.KEY_NAME) {
+ state = getState(current.getJsonValue());
+ if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
+ scopeStack.push(current);
+ current = Scope.createScope(current.getJsonValue());
+ }
+ } else {
+ if (current.hasNext()) {
+ current.next();
+ state = Event.KEY_NAME;
+ } else {
+ state = Event.END_OBJECT;
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void close() {
+ // no-op
+ }
+
+ private static Event getState(JsonValue value) {
+ switch (value.getValueType()) {
+ case ARRAY:
+ return Event.START_ARRAY;
+ case OBJECT:
+ return Event.START_OBJECT;
+ case STRING:
+ return Event.VALUE_STRING;
+ case NUMBER:
+ return Event.VALUE_NUMBER;
+ case TRUE:
+ return Event.VALUE_TRUE;
+ case FALSE:
+ return Event.VALUE_FALSE;
+ case NULL:
+ return Event.VALUE_NULL;
+ default:
+ throw new JsonException("Unknown value type="+value.getValueType());
+ }
+ }
+
+ private static abstract class Scope implements Iterator {
+ abstract JsonValue getJsonValue();
+
+ static Scope createScope(JsonValue value) {
+ if (value instanceof JsonArray) {
+ return new ArrayScope((JsonArray)value);
+ } else if (value instanceof JsonObject) {
+ return new ObjectScope((JsonObject)value);
+ }
+ throw new JsonException("Cannot be called for value="+value);
+ }
+ }
+
+ private static class ArrayScope extends Scope {
+ private final Iterator<JsonValue> it;
+ private JsonValue value;
+
+ ArrayScope(JsonArray array) {
+ this.it = array.iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public JsonValue next() {
+ value = it.next();
+ return value;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ JsonValue getJsonValue() {
+ return value;
+ }
+
+ }
+
+ private static class ObjectScope extends Scope {
+ private final Iterator<Map.Entry<String, JsonValue>> it;
+ private JsonValue value;
+ private String key;
+
+ ObjectScope(JsonObject object) {
+ this.it = object.entrySet().iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public Map.Entry<String, JsonValue> next() {
+ Map.Entry<String, JsonValue> next = it.next();
+ this.key = next.getKey();
+ this.value = next.getValue();
+ return next;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ JsonValue getJsonValue() {
+ return value;
+ }
+
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonTokenizer.java b/impl/src/main/java/org/glassfish/json/JsonTokenizer.java
new file mode 100644
index 0000000..7bdf38d
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonTokenizer.java
@@ -0,0 +1,610 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonException;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import javax.json.stream.JsonParser.Event;
+
+/**
+ * JSON Tokenizer
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonTokenizer implements Closeable {
+ // Table to look up hex ch -> value (for e.g HEX['F'] = 15, HEX['5'] = 5)
+ private final static int[] HEX = new int[128];
+ static {
+ Arrays.fill(HEX, -1);
+ for (int i='0'; i <= '9'; i++) {
+ HEX[i] = i-'0';
+ }
+ for (int i='A'; i <= 'F'; i++) {
+ HEX[i] = 10+i-'A';
+ }
+ for (int i='a'; i <= 'f'; i++) {
+ HEX[i] = 10+i-'a';
+ }
+ }
+ private final static int HEX_LENGTH = HEX.length;
+
+ private final BufferPool bufferPool;
+
+ private final Reader reader;
+
+ // Internal buffer that is used for parsing. It is also used
+ // for storing current string and number value token
+ private char[] buf;
+
+ // Indexes in buffer
+ //
+ // XXXssssssssssssXXXXXXXXXXXXXXXXXXXXXXrrrrrrrrrrrrrrXXXXXX
+ // ^ ^ ^ ^
+ // | | | |
+ // storeBegin storeEnd readBegin readEnd
+ private int readBegin;
+ private int readEnd;
+ private int storeBegin;
+ private int storeEnd;
+
+ // line number of the current pointer of parsing char
+ private long lineNo = 1;
+
+ // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+ // ^
+ // |
+ // bufferOffset
+ //
+ // offset of the last \r\n or \n. will be used to calculate column number
+ // of a token or an error. This may be outside of the buffer.
+ private long lastLineOffset = 0;
+ // offset in the stream for the start of the buffer, will be used in
+ // calculating JsonLocation's stream offset, column no.
+ private long bufferOffset = 0;
+
+ private boolean minus;
+ private boolean fracOrExp;
+ private BigDecimal bd;
+
+ enum JsonToken {
+ CURLYOPEN(Event.START_OBJECT, false),
+ SQUAREOPEN(Event.START_ARRAY, false),
+ COLON(null, false),
+ COMMA(null, false),
+ STRING(Event.VALUE_STRING, true),
+ NUMBER(Event.VALUE_NUMBER, true),
+ TRUE(Event.VALUE_TRUE, true),
+ FALSE(Event.VALUE_FALSE, true),
+ NULL(Event.VALUE_NULL, true),
+ CURLYCLOSE(Event.END_OBJECT, false),
+ SQUARECLOSE(Event.END_ARRAY, false),
+ EOF(null, false);
+
+ private final JsonParser.Event event;
+ private final boolean value;
+
+ JsonToken(JsonParser.Event event, boolean value) {
+ this.event = event;
+ this.value = value;
+ }
+
+ JsonParser.Event getEvent() {
+ return event;
+ }
+
+ boolean isValue() {
+ return value;
+ }
+ }
+
+ JsonTokenizer(Reader reader, BufferPool bufferPool) {
+ this.reader = reader;
+ this.bufferPool = bufferPool;
+ buf = bufferPool.take();
+ }
+
+ private void readString() {
+ // when inPlace is true, no need to copy chars
+ boolean inPlace = true;
+ storeBegin = storeEnd = readBegin;
+
+ do {
+ // Write unescaped char block within the current buffer
+ if (inPlace) {
+ int ch;
+ while(readBegin < readEnd && ((ch=buf[readBegin]) >= 0x20) && ch != '\\') {
+ if (ch == '"') {
+ storeEnd = readBegin++; // ++ to consume quote char
+ return; // Got the entire string
+ }
+ readBegin++; // consume unescaped char
+ }
+ storeEnd = readBegin;
+ }
+
+ // string may be crossing buffer boundaries and may contain
+ // escaped characters.
+ int ch = read();
+ if (ch >= 0x20 && ch != 0x22 && ch != 0x5c) {
+ if (!inPlace) {
+ buf[storeEnd] = (char)ch;
+ }
+ storeEnd++;
+ continue;
+ }
+ switch (ch) {
+ case '\\':
+ inPlace = false; // Now onwards need to copy chars
+ unescape();
+ break;
+ case '"':
+ return;
+ default:
+ throw unexpectedChar(ch);
+ }
+ } while (true);
+ }
+
+ private void unescape() {
+ int ch = read();
+ switch (ch) {
+ case 'b':
+ buf[storeEnd++] = '\b';
+ break;
+ case 't':
+ buf[storeEnd++] = '\t';
+ break;
+ case 'n':
+ buf[storeEnd++] = '\n';
+ break;
+ case 'f':
+ buf[storeEnd++] = '\f';
+ break;
+ case 'r':
+ buf[storeEnd++] = '\r';
+ break;
+ case '"':
+ case '\\':
+ case '/':
+ buf[storeEnd++] = (char)ch;
+ break;
+ case 'u': {
+ int unicode = 0;
+ for (int i = 0; i < 4; i++) {
+ int ch3 = read();
+ int digit = (ch3 >= 0 && ch3 < HEX_LENGTH) ? HEX[ch3] : -1;
+ if (digit < 0) {
+ throw unexpectedChar(ch3);
+ }
+ unicode = (unicode << 4)|digit;
+ }
+ buf[storeEnd++] = (char)unicode;
+ break;
+ }
+ default:
+ throw unexpectedChar(ch);
+ }
+ }
+
+ // Reads a number char. If the char is within the buffer, directly
+ // reads from the buffer. Otherwise, uses read() which takes care
+ // of resizing, filling up the buf, adjusting the pointers
+ private int readNumberChar() {
+ if (readBegin < readEnd) {
+ return buf[readBegin++];
+ } else {
+ storeEnd = readBegin;
+ return read();
+ }
+ }
+
+ private void readNumber(int ch) {
+ storeBegin = storeEnd = readBegin-1;
+ // sign
+ if (ch == '-') {
+ this.minus = true;
+ ch = readNumberChar();
+ if (ch < '0' || ch >'9') {
+ throw unexpectedChar(ch);
+ }
+ }
+
+ // int
+ if (ch == '0') {
+ ch = readNumberChar();
+ } else {
+ do {
+ ch = readNumberChar();
+ } while (ch >= '0' && ch <= '9');
+ }
+
+ // frac
+ if (ch == '.') {
+ this.fracOrExp = true;
+ int count = 0;
+ do {
+ ch = readNumberChar();
+ count++;
+ } while (ch >= '0' && ch <= '9');
+ if (count == 1) {
+ throw unexpectedChar(ch);
+ }
+ }
+
+ // exp
+ if (ch == 'e' || ch == 'E') {
+ this.fracOrExp = true;
+ ch = readNumberChar();
+ if (ch == '+' || ch == '-') {
+ ch = readNumberChar();
+ }
+ int count;
+ for (count = 0; ch >= '0' && ch <= '9'; count++) {
+ ch = readNumberChar();
+ }
+ if (count == 0) {
+ throw unexpectedChar(ch);
+ }
+ }
+ if (ch != -1) {
+ // Only reset readBegin if eof has not been reached
+ readBegin--;
+ storeEnd = readBegin;
+ }
+ }
+
+ private void readTrue() {
+ int ch1 = read();
+ if (ch1 != 'r') {
+ throw expectedChar(ch1, 'r');
+ }
+ int ch2 = read();
+ if (ch2 != 'u') {
+ throw expectedChar(ch2, 'u');
+ }
+ int ch3 = read();
+ if (ch3 != 'e') {
+ throw expectedChar(ch3, 'e');
+ }
+ }
+
+ private void readFalse() {
+ int ch1 = read();
+ if (ch1 != 'a') {
+ throw expectedChar(ch1, 'a');
+ }
+ int ch2 = read();
+ if (ch2 != 'l') {
+ throw expectedChar(ch2, 'l');
+ }
+ int ch3 = read();
+ if (ch3 != 's') {
+ throw expectedChar(ch3, 's');
+ }
+ int ch4 = read();
+ if (ch4 != 'e') {
+ throw expectedChar(ch4, 'e');
+ }
+ }
+
+ private void readNull() {
+ int ch1 = read();
+ if (ch1 != 'u') {
+ throw expectedChar(ch1, 'u');
+ }
+ int ch2 = read();
+ if (ch2 != 'l') {
+ throw expectedChar(ch2, 'l');
+ }
+ int ch3 = read();
+ if (ch3 != 'l') {
+ throw expectedChar(ch3, 'l');
+ }
+ }
+
+ /*
+ * Could be optimized if the parser uses separate methods to match colon
+ * etc (that would avoid the switch statement cost in certain cases)
+ */
+ JsonToken nextToken() {
+ reset();
+ int ch = read();
+
+ // whitespace
+ while (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d) {
+ if (ch == '\r') {
+ ++lineNo;
+ ch = read();
+ if (ch == '\n') {
+ lastLineOffset = bufferOffset+readBegin;
+ } else {
+ lastLineOffset = bufferOffset+readBegin-1;
+ continue;
+ }
+ } else if (ch == '\n') {
+ ++lineNo;
+ lastLineOffset = bufferOffset+readBegin;
+ }
+ ch = read();
+ }
+
+ switch (ch) {
+ case '"':
+ readString();
+ return JsonToken.STRING;
+ case '{':
+ return JsonToken.CURLYOPEN;
+ case '[':
+ return JsonToken.SQUAREOPEN;
+ case ':':
+ return JsonToken.COLON;
+ case ',':
+ return JsonToken.COMMA;
+ case 't':
+ readTrue();
+ return JsonToken.TRUE;
+ case 'f':
+ readFalse();
+ return JsonToken.FALSE;
+ case 'n':
+ readNull();
+ return JsonToken.NULL;
+ case ']':
+ return JsonToken.SQUARECLOSE;
+ case '}':
+ return JsonToken.CURLYCLOSE;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '-':
+ readNumber(ch);
+ return JsonToken.NUMBER;
+ case -1:
+ return JsonToken.EOF;
+ default:
+ throw unexpectedChar(ch);
+ }
+ }
+
+ boolean hasNextToken() {
+ reset();
+ int ch = peek();
+
+ // whitespace
+ while (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d) {
+ if (ch == '\r') {
+ ++lineNo;
+ ++readBegin;
+ ch = peek();
+ if (ch == '\n') {
+ lastLineOffset = bufferOffset+readBegin+1;
+ } else {
+ lastLineOffset = bufferOffset+readBegin;
+ continue;
+ }
+ } else if (ch == '\n') {
+ ++lineNo;
+ lastLineOffset = bufferOffset+readBegin+1;
+ }
+ ++readBegin;
+ ch = peek();
+ }
+ return ch != -1;
+ }
+
+ private int peek() {
+ try {
+ if (readBegin == readEnd) { // need to fill the buffer
+ int len = fillBuf();
+ if (len == -1) {
+ return -1;
+ }
+ assert len != 0;
+ readBegin = storeEnd;
+ readEnd = readBegin+len;
+ }
+ return buf[readBegin];
+ } catch (IOException ioe) {
+ throw new JsonException(JsonMessages.TOKENIZER_IO_ERR(), ioe);
+ }
+ }
+
+ // Gives the location of the last char. Used for
+ // JsonParsingException.getLocation
+ JsonLocation getLastCharLocation() {
+ // Already read the char, so subtracting -1
+ return new JsonLocationImpl(lineNo, bufferOffset +readBegin-lastLineOffset, bufferOffset +readBegin-1);
+ }
+
+ // Gives the parser location. Used for JsonParser.getLocation
+ JsonLocation getLocation() {
+ return new JsonLocationImpl(lineNo, bufferOffset +readBegin-lastLineOffset+1, bufferOffset +readBegin);
+ }
+
+ private int read() {
+ try {
+ if (readBegin == readEnd) { // need to fill the buffer
+ int len = fillBuf();
+ if (len == -1) {
+ return -1;
+ }
+ assert len != 0;
+ readBegin = storeEnd;
+ readEnd = readBegin+len;
+ }
+ return buf[readBegin++];
+ } catch (IOException ioe) {
+ throw new JsonException(JsonMessages.TOKENIZER_IO_ERR(), ioe);
+ }
+ }
+
+ private int fillBuf() throws IOException {
+ if (storeEnd != 0) {
+ int storeLen = storeEnd-storeBegin;
+ if (storeLen > 0) {
+ // there is some store data
+ if (storeLen == buf.length) {
+ // buffer is full, double the capacity
+ char[] doubleBuf = Arrays.copyOf(buf, 2 * buf.length);
+ bufferPool.recycle(buf);
+ buf = doubleBuf;
+ } else {
+ // Left shift all the stored data to make space
+ System.arraycopy(buf, storeBegin, buf, 0, storeLen);
+ storeEnd = storeLen;
+ storeBegin = 0;
+ bufferOffset += readBegin-storeEnd;
+ }
+ } else {
+ storeBegin = storeEnd = 0;
+ bufferOffset += readBegin;
+ }
+ } else {
+ bufferOffset += readBegin;
+ }
+ // Fill the rest of the buf
+ return reader.read(buf, storeEnd, buf.length-storeEnd);
+ }
+
+ // state associated with the current token is no more valid
+ private void reset() {
+ if (storeEnd != 0) {
+ storeBegin = 0;
+ storeEnd = 0;
+ bd = null;
+ minus = false;
+ fracOrExp = false;
+ }
+ }
+
+ String getValue() {
+ return new String(buf, storeBegin, storeEnd-storeBegin);
+ }
+
+ BigDecimal getBigDecimal() {
+ if (bd == null) {
+ bd = new BigDecimal(buf, storeBegin, storeEnd-storeBegin);
+ }
+ return bd;
+ }
+
+ int getInt() {
+ // no need to create BigDecimal for common integer values (1-9 digits)
+ int storeLen = storeEnd-storeBegin;
+ if (!fracOrExp && (storeLen <= 9 || (minus && storeLen <= 10))) {
+ int num = 0;
+ int i = minus ? 1 : 0;
+ for(; i < storeLen; i++) {
+ num = num * 10 + (buf[storeBegin+i] - '0');
+ }
+ return minus ? -num : num;
+ } else {
+ return getBigDecimal().intValue();
+ }
+ }
+
+ long getLong() {
+ // no need to create BigDecimal for common integer values (1-18 digits)
+ int storeLen = storeEnd-storeBegin;
+ if (!fracOrExp && (storeLen <= 18 || (minus && storeLen <= 19))) {
+ long num = 0;
+ int i = minus ? 1 : 0;
+ for(; i < storeLen; i++) {
+ num = num * 10 + (buf[storeBegin+i] - '0');
+ }
+ return minus ? -num : num;
+ } else {
+ return getBigDecimal().intValue();
+ }
+ }
+
+ // returns true for common integer values (1-9 digits).
+ // So there are cases it will return false even though the number is int
+ boolean isDefinitelyInt() {
+ int storeLen = storeEnd-storeBegin;
+ return !fracOrExp && (storeLen <= 9 || (minus && storeLen <= 10));
+ }
+
+ // returns true for common long values (1-18 digits).
+ // So there are cases it will return false even though the number is long
+ boolean isDefinitelyLong() {
+ int storeLen = storeEnd-storeBegin;
+ return !fracOrExp && (storeLen <= 18 || (minus && storeLen <= 19));
+ }
+
+ boolean isIntegral() {
+ return !fracOrExp || getBigDecimal().scale() == 0;
+ }
+
+ @Override
+ public void close() throws IOException {
+ reader.close();
+ bufferPool.recycle(buf);
+ }
+
+ private JsonParsingException unexpectedChar(int ch) {
+ JsonLocation location = getLastCharLocation();
+ return new JsonParsingException(
+ JsonMessages.TOKENIZER_UNEXPECTED_CHAR(ch, location), location);
+ }
+
+ private JsonParsingException expectedChar(int unexpected, char expected) {
+ JsonLocation location = getLastCharLocation();
+ return new JsonParsingException(
+ JsonMessages.TOKENIZER_EXPECTED_CHAR(unexpected, location, expected), location);
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonWriterFactoryImpl.java b/impl/src/main/java/org/glassfish/json/JsonWriterFactoryImpl.java
new file mode 100644
index 0000000..51e0b53
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonWriterFactoryImpl.java
@@ -0,0 +1,86 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonWriterFactoryImpl implements JsonWriterFactory {
+ private final Map<String, ?> config; // unmodifiable map
+ private final boolean prettyPrinting;
+ private final BufferPool bufferPool;
+
+ JsonWriterFactoryImpl(Map<String, ?> config, boolean prettyPrinting,
+ BufferPool bufferPool) {
+ this.config = config;
+ this.prettyPrinting = prettyPrinting;
+ this.bufferPool = bufferPool;
+ }
+
+ @Override
+ public JsonWriter createWriter(Writer writer) {
+ return new JsonWriterImpl(writer, prettyPrinting, bufferPool);
+ }
+
+ @Override
+ public JsonWriter createWriter(OutputStream out) {
+ return new JsonWriterImpl(out, prettyPrinting, bufferPool);
+ }
+
+ @Override
+ public JsonWriter createWriter(OutputStream out, Charset charset) {
+ return new JsonWriterImpl(out, charset, prettyPrinting, bufferPool);
+ }
+
+ @Override
+ public Map<String, ?> getConfigInUse() {
+ return config;
+ }
+}
diff --git a/impl/src/main/java/org/glassfish/json/JsonWriterImpl.java b/impl/src/main/java/org/glassfish/json/JsonWriterImpl.java
new file mode 100644
index 0000000..c28e00b
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/JsonWriterImpl.java
@@ -0,0 +1,187 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * JsonWriter impl using generator.
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonWriterImpl implements JsonWriter {
+
+ private final JsonGeneratorImpl generator;
+ private boolean writeDone;
+ private final NoFlushOutputStream os;
+
+ JsonWriterImpl(Writer writer, BufferPool bufferPool) {
+ this(writer, false, bufferPool);
+ }
+
+ JsonWriterImpl(Writer writer, boolean prettyPrinting, BufferPool bufferPool) {
+ generator = prettyPrinting
+ ? new JsonPrettyGeneratorImpl(writer, bufferPool)
+ : new JsonGeneratorImpl(writer, bufferPool);
+ os = null;
+ }
+
+ JsonWriterImpl(OutputStream out, BufferPool bufferPool) {
+ this(out, StandardCharsets.UTF_8, false, bufferPool);
+ }
+
+ JsonWriterImpl(OutputStream out, boolean prettyPrinting, BufferPool bufferPool) {
+ this(out, StandardCharsets.UTF_8, prettyPrinting, bufferPool);
+ }
+
+ JsonWriterImpl(OutputStream out, Charset charset,
+ boolean prettyPrinting, BufferPool bufferPool) {
+ // Decorating the given stream, so that buffered contents can be
+ // written without actually flushing the stream.
+ this.os = new NoFlushOutputStream(out);
+ generator = prettyPrinting
+ ? new JsonPrettyGeneratorImpl(os, charset, bufferPool)
+ : new JsonGeneratorImpl(os, charset, bufferPool);
+ }
+
+ @Override
+ public void writeArray(JsonArray array) {
+ if (writeDone) {
+ throw new IllegalStateException(JsonMessages.WRITER_WRITE_ALREADY_CALLED());
+ }
+ writeDone = true;
+ generator.writeStartArray();
+ for(JsonValue value : array) {
+ generator.write(value);
+ }
+ generator.writeEnd();
+ // Flush the generator's buffered contents. This won't work for byte
+ // streams as intermediary OutputStreamWriter buffers.
+ generator.flushBuffer();
+ // Flush buffered contents but not the byte stream. generator.flush()
+ // does OutputStreamWriter#flushBuffer (package private) and underlying
+ // byte stream#flush(). Here underlying stream's flush() is no-op.
+ if (os != null) {
+ generator.flush();
+ }
+ }
+
+ @Override
+ public void writeObject(JsonObject object) {
+ if (writeDone) {
+ throw new IllegalStateException(JsonMessages.WRITER_WRITE_ALREADY_CALLED());
+ }
+ writeDone = true;
+ generator.writeStartObject();
+ for(Map.Entry<String, JsonValue> e : object.entrySet()) {
+ generator.write(e.getKey(), e.getValue());
+ }
+ generator.writeEnd();
+ // Flush the generator's buffered contents. This won't work for byte
+ // streams as intermediary OutputStreamWriter buffers.
+ generator.flushBuffer();
+ // Flush buffered contents but not the byte stream. generator.flush()
+ // does OutputStreamWriter#flushBuffer (package private) and underlying
+ // byte stream#flush(). Here underlying stream's flush() is no-op.
+ if (os != null) {
+ generator.flush();
+ }
+ }
+
+ @Override
+ public void write(JsonStructure value) {
+ if (value instanceof JsonArray) {
+ writeArray((JsonArray)value);
+ } else {
+ writeObject((JsonObject)value);
+ }
+ }
+
+ @Override
+ public void write(JsonValue value) {
+ if (value instanceof JsonArray) {
+ writeArray((JsonArray)value);
+ } else if (value instanceof JsonObject) {
+ writeObject((JsonObject)value);
+ }
+ if (writeDone) {
+ throw new IllegalStateException(JsonMessages.WRITER_WRITE_ALREADY_CALLED());
+ }
+ writeDone = true;
+ generator.write(value);
+ generator.flushBuffer();
+ if (os != null) {
+ generator.flush();
+ }
+ }
+
+ @Override
+ public void close() {
+ writeDone = true;
+ generator.close();
+ }
+
+ private static final class NoFlushOutputStream extends FilterOutputStream {
+ public NoFlushOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ @Override
+ public void write(byte b[], int off, int len) throws IOException {
+ out.write(b, off ,len);
+ }
+
+ @Override
+ public void flush() {
+ // no-op
+ }
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/UnicodeDetectingInputStream.java b/impl/src/main/java/org/glassfish/json/UnicodeDetectingInputStream.java
new file mode 100644
index 0000000..65ccb98
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/UnicodeDetectingInputStream.java
@@ -0,0 +1,188 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * A filter stream that detects the unicode encoding for the original
+ * stream
+ *
+ * @author Jitendra Kotamraju
+ */
+class UnicodeDetectingInputStream extends FilterInputStream {
+
+ private static final Charset UTF_32LE = Charset.forName("UTF-32LE");
+ private static final Charset UTF_32BE = Charset.forName("UTF-32BE");
+
+ private static final byte FF = (byte)0xFF;
+ private static final byte FE = (byte)0xFE;
+ private static final byte EF = (byte)0xEF;
+ private static final byte BB = (byte)0xBB;
+ private static final byte BF = (byte)0xBF;
+ private static final byte NUL = (byte)0x00;
+
+ private final byte[] buf = new byte[4];
+ private int bufLen;
+ private int curIndex;
+ private final Charset charset;
+
+ UnicodeDetectingInputStream(InputStream is) {
+ super(is);
+ charset = detectEncoding();
+ }
+
+ Charset getCharset() {
+ return charset;
+ }
+
+ private void fillBuf() {
+ int b1;
+ int b2;
+ int b3;
+ int b4;
+
+ try {
+ b1 = in.read();
+ if (b1 == -1) {
+ return;
+ }
+
+ b2 = in.read();
+ if (b2 == -1) {
+ bufLen = 1;
+ buf[0] = (byte)b1;
+ return;
+ }
+
+ b3 = in.read();
+ if (b3 == -1) {
+ bufLen = 2;
+ buf[0] = (byte)b1;
+ buf[1] = (byte)b2;
+ return;
+ }
+
+ b4 = in.read();
+ if (b4 == -1) {
+ bufLen = 3;
+ buf[0] = (byte)b1;
+ buf[1] = (byte)b2;
+ buf[2] = (byte)b3;
+ return;
+ }
+ bufLen = 4;
+ buf[0] = (byte)b1;
+ buf[1] = (byte)b2;
+ buf[2] = (byte)b3;
+ buf[3] = (byte)b4;
+ } catch (IOException ioe) {
+ throw new JsonException("I/O error while auto-detecting the encoding of stream", ioe);
+ }
+ }
+
+ private Charset detectEncoding() {
+ fillBuf();
+ if (bufLen < 2) {
+ throw new JsonException("Cannot auto-detect encoding, not enough chars");
+ } else if (bufLen == 4) {
+ // Use BOM to detect encoding
+ if (buf[0] == NUL && buf[1] == NUL && buf[2] == FE && buf[3] == FF) {
+ curIndex = 4;
+ return UTF_32BE;
+ } else if (buf[0] == FF && buf[1] == FE && buf[2] == NUL && buf[3] == NUL) {
+ curIndex = 4;
+ return UTF_32LE;
+ } else if (buf[0] == FE && buf[1] == FF) {
+ curIndex = 2;
+ return StandardCharsets.UTF_16BE;
+ } else if (buf[0] == FF && buf[1] == FE) {
+ curIndex = 2;
+ return StandardCharsets.UTF_16LE;
+ } else if (buf[0] == EF && buf[1] == BB && buf[2] == BF) {
+ curIndex = 3;
+ return StandardCharsets.UTF_8;
+ }
+ // No BOM, just use JSON RFC's encoding algo to auto-detect
+ if (buf[0] == NUL && buf[1] == NUL && buf[2] == NUL) {
+ return UTF_32BE;
+ } else if (buf[0] == NUL && buf[2] == NUL) {
+ return StandardCharsets.UTF_16BE;
+ } else if (buf[1] == NUL && buf[2] == NUL && buf[3] == NUL) {
+ return UTF_32LE;
+ } else if (buf[1] == NUL && buf[3] == NUL) {
+ return StandardCharsets.UTF_16LE;
+ }
+ }
+ return StandardCharsets.UTF_8;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (curIndex < bufLen) {
+ return buf[curIndex++];
+ }
+ return in.read();
+ }
+
+ @Override
+ public int read(byte b[], int off, int len) throws IOException {
+ if (curIndex < bufLen) {
+ if (len == 0) {
+ return 0;
+ }
+ if (off < 0 || len < 0 || len > b.length -off) {
+ throw new IndexOutOfBoundsException();
+ }
+ int min = Math.min(bufLen-curIndex, len);
+ System.arraycopy(buf, curIndex, b, off, min);
+ curIndex += min;
+ return min;
+ }
+ return in.read(b, off, len);
+ }
+
+}
diff --git a/impl/src/main/java/org/glassfish/json/api/BufferPool.java b/impl/src/main/java/org/glassfish/json/api/BufferPool.java
new file mode 100644
index 0000000..5d54606
--- /dev/null
+++ b/impl/src/main/java/org/glassfish/json/api/BufferPool.java
@@ -0,0 +1,66 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.api;
+
+/**
+ * char[] pool that pool instances of char[] which are expensive to create.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface BufferPool {
+
+ /**
+ * Gets a new char[] object from the pool.
+ *
+ * <p>
+ * If no object is available in the pool, this method creates a new one.
+ *
+ * @return
+ * always non-null.
+ */
+ char[] take();
+
+ /**
+ * Returns an object back to the pool.
+ */
+ void recycle(char[] buf);
+
+}
diff --git a/impl/src/main/resources/org/glassfish/json/messages.properties b/impl/src/main/resources/org/glassfish/json/messages.properties
new file mode 100644
index 0000000..81b0095
--- /dev/null
+++ b/impl/src/main/resources/org/glassfish/json/messages.properties
@@ -0,0 +1,47 @@
+parser.getString.err=JsonParser#getString() is valid only for KEY_NAME, VALUE_STRING, VALUE_NUMBER parser states. \
+ But current parser state is {0}
+parser.isIntegralNumber.err=JsonParser#isIntegralNumber() is valid only for VALUE_NUMBER parser state. \
+ But current parser state is {0}
+parser.getInt.err=JsonParser#getInt() is valid only for VALUE_NUMBER parser state. \
+ But current parser state is {0}
+parser.getLong.err=JsonParser#getLong() is valid only for VALUE_NUMBER parser state. \
+ But current parser state is {0}
+parser.getBigDecimal.err=JsonParser#getBigDecimal() is valid only for VALUE_NUMBER parser state. \
+ But current parser state is {0}
+parser.getArray.err=JsonParser#getArray() or JsonParser#getArrayStream() is valid only for START_ARRAY parser state. \
+ But current parser state is {0}
+parser.getObject.err=JsonParser#getObject() or JsonParser#getObjectStream() is valid only for START_OBJECT parser state. \
+ But current parser state is {0}
+parser.getValue.err=JsonParser#getValue() is valid only for START_ARRAY, START_OBJECT, KEY_NAME, VALUE_STRING, VALUE_NUMBER, VALUE_NULL, VALUE_FALSE, VALUE_TRUE parser states. \
+ But current parser state is {0}
+parser.getValueStream.err=JsonParser#getValueStream() the parser must not be in an array or object. \
+ But current parser state is {0}
+parser.expected.eof=Expected EOF token, but got {0}
+parser.tokenizer.close.io=I/O error while closing JSON tokenizer
+parser.invalid.token=Invalid token={0} at {1}. Expected tokens are: {2}
+
+generator.flush.io.err=I/O error while flushing generated JSON
+generator.close.io.err=I/O error while closing JsonGenerator
+generator.write.io.err=I/O error while writing in JsonGenerator
+generator.illegal.method=Illegal method during JSON generation, \
+ not valid in current context {0}
+generator.double.infinite.nan=double value cannot be Infinite or NaN
+generator.incomplete.json=Generating incomplete JSON
+generator.illegal.multiple.text=Cannot generate more than one JSON text
+
+writer.write.already.called=write/writeObject/writeArray/close method is already called
+
+reader.read.already.called=read/readObject/readArray/close method is already called
+
+objbuilder.name.null=Name in JsonObject's name/value pair cannot be null
+objbuilder.value.null=Value in JsonObject's name/value pair cannot be null
+objbuilder.object.builder.null=Object builder that is used to create a value in JsonObject's name/value pair cannot be null
+objbuilder.array.builder.null=Array builder that is used to create a value in JsonObject's name/value pair cannot be null
+
+arrbuilder.value.null=Cannot invoke add(null) while building JsonArray.
+arrbuilder.object.builder.null=Object builder that is used to add a value to JSON array cannot be null
+arrbuilder.array.builder.null=Array builder that is used to add a value to JSON array cannot be null
+
+tokenizer.unexpected.char=Unexpected char {0} at {1}
+tokenizer.expected.char=Unexpected char {0} at {1}, expecting ''{2}''
+tokenizer.io.err=I/O error while parsing JSON
diff --git a/jaxrs-1x/pom.xml b/jaxrs-1x/pom.xml
new file mode 100644
index 0000000..439f38f
--- /dev/null
+++ b/jaxrs-1x/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jsonp-jaxrs-1x</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.1.0-SNAPSHOT</version>
+ <name>JSR 374 (JSON Processing) Media for JAX-RS 1.1</name>
+ <description>JAX-RS 1.1 MessageBodyReader and MessageBodyWriter to support JsonObject/JsonArray/JsonStructure API of JSR 374:Java API for Processing JSON</description>
+ <url>http://json-processing-spec.java.net</url>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ This plugin is reponsible for packaging artifacts
+ as OSGi bundles. Please refer to
+ http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
+ for more information about how to use this plugin.
+ -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>${impl_version}</Bundle-Version>
+ <Export-Package>org.glassfish.json.jaxrs1x</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyReader.java b/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyReader.java
new file mode 100644
index 0000000..92b25cc
--- /dev/null
+++ b/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyReader.java
@@ -0,0 +1,100 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.jaxrs1x;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.json.Json;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonStructure;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * JAX-RS MessageBodyReader for JsonStructure. This allows
+ * JsonStructure, JsonArray and JsonObject to be a parameter of a
+ * resource method.
+ *
+ * @author Jitendra Kotamraju
+ * @author Blaise Doughan
+ * @author Michal Gajdos
+ */
+ at Provider
+ at Consumes({"application/json", "text/json", "*/*"})
+public class JsonStructureBodyReader implements MessageBodyReader<JsonStructure> {
+ private final JsonReaderFactory rf = Json.createReaderFactory(null);
+
+ private static final String JSON = "json";
+ private static final String PLUS_JSON = "+json";
+
+ @Override
+ public boolean isReadable(Class<?> aClass, Type type,
+ Annotation[] annotations, MediaType mediaType) {
+ return JsonStructure.class.isAssignableFrom(aClass) && supportsMediaType(mediaType);
+ }
+
+ /**
+ * @return true for all media types of the pattern */json and
+ * */*+json.
+ */
+ private static boolean supportsMediaType(final MediaType mediaType) {
+ return mediaType.getSubtype().equals(JSON) || mediaType.getSubtype().endsWith(PLUS_JSON);
+ }
+
+ @Override
+ public JsonStructure readFrom(Class<JsonStructure> jsonStructureClass,
+ Type type, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> stringStringMultivaluedMap,
+ InputStream inputStream) throws IOException, WebApplicationException {
+ try (JsonReader reader = rf.createReader(inputStream)) {
+ return reader.read();
+ }
+ }
+}
diff --git a/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyWriter.java b/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyWriter.java
new file mode 100644
index 0000000..c1ea214
--- /dev/null
+++ b/jaxrs-1x/src/main/java/org/glassfish/json/jaxrs1x/JsonStructureBodyWriter.java
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.jaxrs1x;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonStructure;
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+
+import javax.annotation.PostConstruct;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * JAX-RS MessageBodyWriter for JsonStructure. This allows
+ * JsonStructure, JsonArray and JsonObject to be return type of a
+ * resource method.
+ *
+ * @author Jitendra Kotamraju
+ * @author Blaise Doughan
+ * @author Michal Gajdos
+ */
+ at Provider
+ at Produces({"application/json", "text/json", "*/*"})
+public class JsonStructureBodyWriter implements MessageBodyWriter<JsonStructure> {
+ private static final String JSON = "json";
+ private static final String PLUS_JSON = "+json";
+
+ private JsonWriterFactory wf = Json.createWriterFactory(null);
+
+ @PostConstruct
+ private void init() {
+ wf = Json.createWriterFactory(new HashMap<>());
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> aClass,
+ Type type, Annotation[] annotations, MediaType mediaType) {
+ return JsonStructure.class.isAssignableFrom(aClass) && supportsMediaType(mediaType);
+ }
+
+ /**
+ * @return true for all media types of the pattern */json and
+ * */*+json.
+ */
+ private static boolean supportsMediaType(final MediaType mediaType) {
+ return mediaType.getSubtype().equals(JSON) || mediaType.getSubtype().endsWith(PLUS_JSON);
+ }
+
+ @Override
+ public long getSize(JsonStructure jsonStructure, Class<?> aClass,
+ Type type, Annotation[] annotations, MediaType mediaType) {
+
+ return -1;
+ }
+
+ @Override
+ public void writeTo(JsonStructure jsonStructure, Class<?> aClass, Type type,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> stringObjectMultivaluedMap,
+ OutputStream outputStream) throws IOException, WebApplicationException {
+ try (JsonWriter writer = wf.createWriter(outputStream)) {
+ writer.write(jsonStructure);
+ }
+ }
+}
diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
new file mode 100644
index 0000000..6ce8d6a
--- /dev/null
+++ b/jaxrs/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.glassfish</groupId>
+ <artifactId>jsonp-jaxrs</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.1.0-SNAPSHOT</version>
+ <name>JSR 374 (JSON Processing) Media for JAX-RS</name>
+ <description>JAX-RS MessageBodyReader and MessageBodyWriter to support JsonObject/JsonArray/JsonStructure API of JSR 374:Java API for Processing JSON</description>
+ <url>http://json-processing-spec.java.net</url>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ This plugin is reponsible for packaging artifacts
+ as OSGi bundles. Please refer to
+ http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
+ for more information about how to use this plugin.
+ -->
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Version>${impl_version}</Bundle-Version>
+ <Export-Package>org.glassfish.json.jaxrs</Export-Package>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyReader.java b/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyReader.java
new file mode 100644
index 0000000..fc63488
--- /dev/null
+++ b/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyReader.java
@@ -0,0 +1,99 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.jaxrs;
+
+import javax.json.Json;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonStructure;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * JAX-RS MessageBodyReader for JsonStructure. This allows
+ * JsonStructure, JsonArray and JsonObject to be a parameter of a
+ * resource method.
+ *
+ * @author Jitendra Kotamraju
+ * @author Blaise Doughan
+ * @author Michal Gajdos
+ */
+ at Provider
+ at Consumes({"application/json", "text/json", "*/*"})
+public class JsonStructureBodyReader implements MessageBodyReader<JsonStructure> {
+ private final JsonReaderFactory rf = Json.createReaderFactory(null);
+
+ private static final String JSON = "json";
+ private static final String PLUS_JSON = "+json";
+
+ @Override
+ public boolean isReadable(Class<?> aClass, Type type,
+ Annotation[] annotations, MediaType mediaType) {
+ return JsonStructure.class.isAssignableFrom(aClass) && supportsMediaType(mediaType);
+ }
+
+ /**
+ * @return true for all media types of the pattern */json and
+ * */*+json.
+ */
+ private static boolean supportsMediaType(final MediaType mediaType) {
+ return mediaType.getSubtype().equals(JSON) || mediaType.getSubtype().endsWith(PLUS_JSON);
+ }
+
+ @Override
+ public JsonStructure readFrom(Class<JsonStructure> jsonStructureClass,
+ Type type, Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, String> stringStringMultivaluedMap,
+ InputStream inputStream) throws IOException, WebApplicationException {
+ try (JsonReader reader = rf.createReader(inputStream)) {
+ return reader.read();
+ }
+ }
+}
diff --git a/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyWriter.java b/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyWriter.java
new file mode 100644
index 0000000..425bbaa
--- /dev/null
+++ b/jaxrs/src/main/java/org/glassfish/json/jaxrs/JsonStructureBodyWriter.java
@@ -0,0 +1,119 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.jaxrs;
+
+import javax.annotation.PostConstruct;
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Configuration;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JAX-RS MessageBodyWriter for JsonStructure. This allows
+ * JsonStructure, JsonArray and JsonObject to be return type of a
+ * resource method.
+ *
+ * @author Jitendra Kotamraju
+ * @author Blaise Doughan
+ * @author Michal Gajdos
+ */
+ at Provider
+ at Produces({"application/json", "text/json", "*/*"})
+public class JsonStructureBodyWriter implements MessageBodyWriter<JsonStructure> {
+ private static final String JSON = "json";
+ private static final String PLUS_JSON = "+json";
+
+ private JsonWriterFactory wf = Json.createWriterFactory(null);
+
+ @Context
+ private Configuration config;
+
+ @PostConstruct
+ private void init() {
+ Map<String, Object> props = new HashMap<>();
+ if (config != null && config.getProperties().containsKey(JsonGenerator.PRETTY_PRINTING)) {
+ props.put(JsonGenerator.PRETTY_PRINTING, true);
+ }
+ wf = Json.createWriterFactory(props);
+ }
+
+ @Override
+ public boolean isWriteable(Class<?> aClass,
+ Type type, Annotation[] annotations, MediaType mediaType) {
+ return JsonStructure.class.isAssignableFrom(aClass) && supportsMediaType(mediaType);
+ }
+
+ /**
+ * @return true for all media types of the pattern */json and
+ * */*+json.
+ */
+ private static boolean supportsMediaType(final MediaType mediaType) {
+ return mediaType.getSubtype().equals(JSON) || mediaType.getSubtype().endsWith(PLUS_JSON);
+ }
+
+ @Override
+ public long getSize(JsonStructure jsonStructure, Class<?> aClass,
+ Type type, Annotation[] annotations, MediaType mediaType) {
+
+ return -1;
+ }
+
+ @Override
+ public void writeTo(JsonStructure jsonStructure, Class<?> aClass, Type type,
+ Annotation[] annotations, MediaType mediaType,
+ MultivaluedMap<String, Object> stringObjectMultivaluedMap,
+ OutputStream outputStream) throws IOException, WebApplicationException {
+ try (JsonWriter writer = wf.createWriter(outputStream)) {
+ writer.write(jsonStructure);
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..d96096e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2011-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>net.java</groupId>
+ <artifactId>jvnet-parent</artifactId>
+ <version>5</version>
+ </parent>
+
+ <prerequisites>
+ <maven>3.0</maven>
+ </prerequisites>
+
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <packaging>pom</packaging>
+ <version>1.1</version>
+ <name>JSR 374 (JSON Processing) RI</name>
+ <description>JSR 374:Java API for Processing JSON RI</description>
+ <url>http://jsonp.java.net</url>
+
+ <scm>
+ <connection>scm:git:git://java.net/jsonp~git/api</connection>
+ <developerConnection>scm:git:ssh://kchung@git.java.net/jsonp~git/</developerConnection>
+ <url>http://java.net/projects/jsonp/sources/git/show</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <licenses>
+ <license>
+ <name>
+ Dual license consisting of the CDDL v1.1 and GPL v2
+ </name>
+ <url>https://glassfish.java.net/public/CDDL+GPL_1_1.html</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <organization>
+ <name>Oracle</name>
+ <url>http://www.oracle.com</url>
+ </organization>
+
+ <developers>
+ <developer>
+ <id>kchung</id>
+ <name>Kin-man Chung</name>
+ <organization>Oracle</organization>
+ <roles>
+ <role>lead</role>
+ </roles>
+ </developer>
+ </developers>
+
+ <properties>
+ <api_package>javax.json</api_package>
+ <impl_namespace>org.glassfish</impl_namespace>
+ <spec_version>1.1</spec_version>
+ <spec_impl_version>1.1.0-SNAPSHOT</spec_impl_version>
+ <impl_version>1.1.0-SNAPSHOT</impl_version>
+ <packages.private>org.glassfish.*</packages.private>
+ <packages.export>javax.json.*</packages.export>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.glassfish.copyright</groupId>
+ <artifactId>glassfish-copyright-maven-plugin</artifactId>
+ <version>1.39</version>
+ <configuration>
+ <excludeFile>copyright-exclude</excludeFile>
+ <scm>git</scm>
+ <scmOnly>true</scmOnly>
+ <warn>false</warn>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-release-plugin</artifactId>
+ <version>2.5.1</version>
+ <configuration>
+ <mavenExecutorId>forked-path</mavenExecutorId>
+ <useReleaseProfile>false</useReleaseProfile>
+ <arguments>${release.arguments}</arguments>
+ </configuration>
+ </plugin>
+ </plugins>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.glassfish.build</groupId>
+ <artifactId>spec-version-maven-plugin</artifactId>
+ <version>1.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>2.5.3</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.9.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.2</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <compilerArgument>-Xlint:all</compilerArgument>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>2.5</version>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>2.4</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>2.9</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>2.6</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>wagon-maven-plugin</artifactId>
+ <version>1.0</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>2.6.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.4</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.18.1</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.3.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.5.3</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <version>2.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax</groupId>
+ <artifactId>javaee-web-api</artifactId>
+ <version>7.0</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ <version>${spec_impl_version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <version>${impl_version}</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>jsr311-api</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <modules>
+ <!--
+ <module>api</module>
+ <module>jaxrs</module>
+ -->
+ <module>impl</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>all</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ <module>jaxrs</module>
+ <module>jaxrs-1x</module>
+ <module>tests</module>
+ <module>gf</module>
+ <module>demos</module>
+ <module>bundles</module>
+ </modules>
+ </profile>
+ <profile>
+ <id>licensee</id>
+ <modules>
+ <module>api</module>
+ <module>impl</module>
+ <module>jaxrs</module>
+ <module>jaxrs-1x</module>
+ <module>tests</module>
+ <module>gf</module>
+ <module>demos</module>
+ <module>bundles</module>
+ </modules>
+ </profile>
+ </profiles>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>2.5.3</version>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/tests/pom.xml b/tests/pom.xml
new file mode 100644
index 0000000..40d3938
--- /dev/null
+++ b/tests/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+ Copyright (c) 2012-2015 Oracle and/or its affiliates. All rights reserved.
+
+ The contents of this file are subject to the terms of either the GNU
+ General Public License Version 2 only ("GPL") or the Common Development
+ and Distribution License("CDDL") (collectively, the "License"). You
+ may not use this file except in compliance with the License. You can
+ obtain a copy of the License at
+ https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ or packager/legal/LICENSE.txt. See the License for the specific
+ language governing permissions and limitations under the License.
+
+ When distributing the software, include this License Header Notice in each
+ file and include the License file at packager/legal/LICENSE.txt.
+
+ GPL Classpath Exception:
+ Oracle designates this particular file as subject to the "Classpath"
+ exception as provided by Oracle in the GPL Version 2 section of the License
+ file that accompanied this code.
+
+ Modifications:
+ If applicable, add the following below the License Header, with the fields
+ enclosed by brackets [] replaced by your own identifying information:
+ "Portions Copyright [year] [name of copyright owner]"
+
+ Contributor(s):
+ If you wish your version of this file to be governed by only the CDDL or
+ only the GPL Version 2, indicate your decision by adding "[Contributor]
+ elects to include this software in this distribution under the [CDDL or GPL
+ Version 2] license." If you don't indicate a single choice of license, a
+ recipient has the option to distribute your version of this file under
+ either the CDDL, the GPL Version 2 or to extend the choice of license to
+ its licensees as provided above. However, if you add GPL Version 2 code
+ and therefore, elected the GPL Version 2 license, then the option applies
+ only if the new code is made subject to such option by the copyright
+ holder.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.glassfish</groupId>
+ <artifactId>json</artifactId>
+ <version>1.1</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>jsonp-tests</artifactId>
+ <packaging>jar</packaging>
+ <name>JSR 374 (JSON Processing) Tests</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.json</groupId>
+ <artifactId>javax.json-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish</groupId>
+ <artifactId>javax.json</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonArrayTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonArrayTest.java
new file mode 100644
index 0000000..9ee56b5
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonArrayTest.java
@@ -0,0 +1,138 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.List;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonArrayTest extends TestCase {
+ public JsonArrayTest(String testName) {
+ super(testName);
+ }
+
+ public void testArrayEquals() throws Exception {
+ JsonArray expected = Json.createArrayBuilder()
+ .add(JsonValue.TRUE)
+ .add(JsonValue.FALSE)
+ .add(JsonValue.NULL)
+ .add(Integer.MAX_VALUE)
+ .add(Long.MAX_VALUE)
+ .add(Double.MAX_VALUE)
+ .add(Integer.MIN_VALUE)
+ .add(Long.MIN_VALUE)
+ .add(Double.MIN_VALUE)
+ .build();
+
+ StringWriter sw = new StringWriter();
+ JsonWriter writer = Json.createWriter(sw);
+ writer.writeArray(expected);
+ writer.close();
+
+ JsonReader reader = Json.createReader(new StringReader(sw.toString()));
+ JsonArray actual = reader.readArray();
+ reader.close();
+
+ assertEquals(expected, actual);
+ }
+
+ public void testStringValue() throws Exception {
+ JsonArray array = Json.createArrayBuilder()
+ .add("John")
+ .build();
+ assertEquals("John", array.getString(0));
+ }
+
+ public void testIntValue() throws Exception {
+ JsonArray array = Json.createArrayBuilder()
+ .add(20)
+ .build();
+ assertEquals(20, array.getInt(0));
+ }
+
+ public void testAdd() {
+ JsonArray array = Json.createArrayBuilder().build();
+ try {
+ array.add(JsonValue.FALSE);
+ fail("JsonArray#add() should throw UnsupportedOperationException");
+ } catch(UnsupportedOperationException e) {
+ // Expected
+ }
+ }
+
+ public void testRemove() {
+ JsonArray array = Json.createArrayBuilder().build();
+ try {
+ array.remove(0);
+ fail("JsonArray#remove() should throw UnsupportedOperationException");
+ } catch(UnsupportedOperationException e) {
+ // Expected
+ }
+ }
+
+ public void testNumberView() throws Exception {
+ JsonArray array = Json.createArrayBuilder().add(20).add(10).build();
+
+ List<JsonNumber> numberList = array.getValuesAs(JsonNumber.class);
+ for(JsonNumber num : numberList) {
+ num.intValue();
+ }
+
+ assertEquals(20, array.getInt(0));
+ assertEquals(10, array.getInt(1));
+ }
+
+ public void testArrayBuilderNpe() {
+ try {
+ JsonArray array = Json.createArrayBuilder().add((JsonValue)null).build();
+ fail("JsonArrayBuilder#add(null) should throw NullPointerException");
+ } catch(NullPointerException e) {
+ // Expected
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonBuilderTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonBuilderTest.java
new file mode 100644
index 0000000..f1842c1
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonBuilderTest.java
@@ -0,0 +1,123 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonBuilderTest extends TestCase {
+ public JsonBuilderTest(String testName) {
+ super(testName);
+ }
+
+ public void testEmptyObject() throws Exception {
+ JsonObject empty = Json.createObjectBuilder()
+ .build();
+
+ JsonObjectTest.testEmpty(empty);
+ }
+
+ public void testEmptyArray() throws Exception {
+ JsonArray empty = Json.createArrayBuilder()
+ .build();
+
+ assertTrue(empty.isEmpty());
+ }
+
+ public void testObject() throws Exception {
+ JsonObject person = buildPerson();
+ JsonObjectTest.testPerson(person);
+ }
+
+ public void testNumber() throws Exception {
+ JsonObject person = buildPerson();
+ JsonNumber number = person.getJsonNumber("age");
+ assertEquals(25, number.intValueExact());
+ assertEquals(25, number.intValue());
+ assertTrue(number.isIntegral());
+ JsonObjectTest.testPerson(person);
+ }
+
+ static JsonObject buildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+
+ static JsonObject buildAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+
+ static JsonArray buildPhone() {
+ return Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567"))
+ .build();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonCollectorTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonCollectorTest.java
new file mode 100644
index 0000000..1b69ed0
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonCollectorTest.java
@@ -0,0 +1,185 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/le se for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import org.junit.Test;
+import org.junit.BeforeClass;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.json.*;
+import javax.json.stream.JsonCollectors;
+import java.util.List;
+
+/**
+ * Some JSON query tests/examples, using Java stream operations, with JSON collectors.
+ * @author Kin-man Chung
+ */
+public class JsonCollectorTest {
+
+ static JsonArray contacts;
+
+ @BeforeClass
+ public static void setUpClass() {
+ // The JSON source
+ contacts = (JsonArray) JsonUtil.toJson(
+ "[ " +
+ " { 'name': 'Duke', " +
+ " 'age': 18, " +
+ " 'gender': 'M', " +
+ " 'phones': { " +
+ " 'home': '650-123-4567', " +
+ " 'mobile': '650-234-5678'}}," +
+ " { 'name': 'Jane', " +
+ " 'age': 23, " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '707-999-5555'}}," +
+ " { 'name': 'Joanna', " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '505-333-4444'}} " +
+ " ]");
+ }
+
+ @Test
+ public void testToJsonArray() {
+ /*
+ * Query: retrieve the names of female contacts
+ * Returns a JsonArray of names
+ */
+ JsonArray result = contacts.getValuesAs(JsonObject.class).stream()
+ .filter(x->"F".equals(x.getString("gender")))
+ .map(x-> x.get("name"))
+ .collect(JsonCollectors.toJsonArray());
+ JsonValue expected = JsonUtil.toJson("['Jane','Joanna']");
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testToJsonObject() {
+ /*
+ * Query: retrieve the names and mobile phones of female contacts
+ * Returns a JsonObject of name phones pairs
+ */
+ JsonObject result = contacts.getValuesAs(JsonObject.class).stream()
+ .filter(x->"F".equals(x.getString("gender")))
+ .collect(JsonCollectors.toJsonObject(
+ x->x.asJsonObject().getString("name"),
+ x->x.asJsonObject().getJsonObject("phones").get("mobile")))
+ ;
+ JsonValue expected = JsonUtil.toJson(
+ "{'Jane': '707-999-5555', 'Joanna': '505-333-4444'}");
+ assertEquals(expected, result);
+ }
+
+ @Test
+ public void testGroupBy() {
+ /*
+ * Query: group the contacts according to gender
+ * Returns a JsonObject, with gender/constacts value pairs
+ */
+ JsonObject result = contacts.getValuesAs(JsonObject.class).stream()
+ .collect(JsonCollectors.groupingBy(x->((JsonObject)x).getString("gender")));
+ JsonValue expected = JsonUtil.toJson(
+ "{'F': " +
+ " [ " +
+ " { 'name': 'Jane', " +
+ " 'age': 23, " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '707-999-5555'}}," +
+ " { 'name': 'Joanna', " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '505-333-4444'}} " +
+ " ], " +
+ "'M': " +
+ " [ " +
+ " { 'name': 'Duke', " +
+ " 'age': 18, " +
+ " 'gender': 'M', " +
+ " 'phones': { " +
+ " 'home': '650-123-4567', " +
+ " 'mobile': '650-234-5678'}} " +
+ " ] " +
+ "}");
+
+ assertEquals(result,expected);
+ }
+
+ static int index; //for keeping track of the array index
+ @Test
+ public void testQueryAndPatch() {
+ /*
+ * Query and patch: Increment the ages of contacts with an age entry
+ * PatchBuilder is used for building the necessary JsonPatch.
+ */
+ index = -1;
+ JsonPatchBuilder builder = new JsonPatchBuilder();
+ contacts.getValuesAs(JsonObject.class).stream()
+ .peek(p->index++)
+ .filter(p->p.containsKey("age"))
+ .forEach(p-> builder.replace("/"+index+"/age", p.getInt("age")+1));
+ JsonArray result = builder.apply(contacts);
+
+ JsonValue expected = (JsonArray) JsonUtil.toJson(
+ "[ " +
+ " { 'name': 'Duke', " +
+ " 'age': 19, " +
+ " 'gender': 'M', " +
+ " 'phones': { " +
+ " 'home': '650-123-4567', " +
+ " 'mobile': '650-234-5678'}}," +
+ " { 'name': 'Jane', " +
+ " 'age': 24, " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '707-999-5555'}}," +
+ " { 'name': 'Joanna', " +
+ " 'gender': 'F', " +
+ " 'phones': { " +
+ " 'mobile': '505-333-4444'}} " +
+ " ]");
+
+ assertEquals(expected, result);
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorFactoryTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorFactoryTest.java
new file mode 100644
index 0000000..30ef01a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorFactoryTest.java
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests JsonGeneratorFactory
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonGeneratorFactoryTest extends TestCase {
+
+ public JsonGeneratorFactoryTest(String testName) {
+ super(testName);
+ }
+
+ public void testGeneratorFactory() {
+ JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(null);
+
+ JsonGenerator generator1 = generatorFactory.createGenerator(new StringWriter());
+ generator1.writeStartArray().writeEnd();
+ generator1.close();
+
+ JsonGenerator generator2 = generatorFactory.createGenerator(new StringWriter());
+ generator2.writeStartArray().writeEnd();
+ generator2.close();
+ }
+
+ public void testGeneratorFactoryWithConfig() {
+ Map<String, Object> config = new HashMap<>();
+ config.put(JsonGenerator.PRETTY_PRINTING, true);
+ JsonGeneratorFactory generatorFactory = Json.createGeneratorFactory(config);
+ Map<String, ?> config1 = generatorFactory.getConfigInUse();
+ if (config1.size() != 1) {
+ throw new JsonException("Expecting no of properties=1, got="+config1.size());
+ }
+ assertTrue(config1.containsKey(JsonGenerator.PRETTY_PRINTING));
+
+ JsonGenerator generator1 = generatorFactory.createGenerator(new StringWriter());
+ generator1.writeStartArray().writeEnd();
+ generator1.close();
+
+ JsonGenerator generator2 = generatorFactory.createGenerator(new StringWriter());
+ generator2.writeStartArray().writeEnd();
+ generator2.close();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java
new file mode 100644
index 0000000..ee6436a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java
@@ -0,0 +1,518 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.*;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * {@link JsonGenerator} tests
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonGeneratorTest extends TestCase {
+ public JsonGeneratorTest(String testName) {
+ super(testName);
+ }
+
+ public void testObjectWriter() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ testObject(generator);
+ generator.close();
+ writer.close();
+
+ JsonReader reader = Json.createReader(new StringReader(writer.toString()));
+ JsonObject person = reader.readObject();
+ JsonObjectTest.testPerson(person);
+ }
+
+ public void testObjectStream() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ JsonGenerator generator = Json.createGenerator(out);
+ testObject(generator);
+ generator.close();
+ out.close();
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ JsonReader reader = Json.createReader(in);
+ JsonObject person = reader.readObject();
+ JsonObjectTest.testPerson(person);
+ reader.close();
+ in.close();
+ }
+
+ static void testObject(JsonGenerator generator) throws Exception {
+ generator
+ .writeStartObject()
+ .write("firstName", "John")
+ .write("lastName", "Smith")
+ .write("age", 25)
+ .writeStartObject("address")
+ .write("streetAddress", "21 2nd Street")
+ .write("city", "New York")
+ .write("state", "NY")
+ .write("postalCode", "10021")
+ .writeEnd()
+ .writeStartArray("phoneNumber")
+ .writeStartObject()
+ .write("type", "home")
+ .write("number", "212 555-1234")
+ .writeEnd()
+ .writeStartObject()
+ .write("type", "fax")
+ .write("number", "646 555-4567")
+ .writeEnd()
+ .writeEnd()
+ .writeEnd();
+ }
+
+ public void testArray() throws Exception {
+ Writer sw = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(sw);
+ generator
+ .writeStartArray()
+ .writeStartObject()
+ .write("type", "home")
+ .write("number", "212 555-1234")
+ .writeEnd()
+ .writeStartObject()
+ .write("type", "fax")
+ .write("number", "646 555-4567")
+ .writeEnd()
+ .writeEnd();
+ generator.close();
+ }
+
+ // tests JsonGenerator when JsonValue is used for generation
+ public void testJsonValue() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator
+ .writeStartObject()
+ .write("firstName", "John")
+ .write("lastName", "Smith")
+ .write("age", 25)
+ .write("address", JsonBuilderTest.buildAddress())
+ .write("phoneNumber", JsonBuilderTest.buildPhone())
+ .writeEnd();
+ generator.close();
+ writer.close();
+
+ JsonReader reader = Json.createReader(new StringReader(writer.toString()));
+ JsonObject person = reader.readObject();
+ JsonObjectTest.testPerson(person);
+ }
+
+ public void testArrayString() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartArray().write("string").writeEnd();
+ generator.close();
+ writer.close();
+
+ assertEquals("[\"string\"]", writer.toString());
+ }
+
+ public void testEscapedString() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartArray().write("\u0000").writeEnd();
+ generator.close();
+ writer.close();
+
+ assertEquals("[\"\\u0000\"]", writer.toString());
+ }
+
+ public void testEscapedString1() throws Exception {
+ String expected = "\u0000\u00ff";
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(sw);
+ generator.writeStartArray().write("\u0000\u00ff").writeEnd();
+ generator.close();
+ sw.close();
+
+ JsonReader jr = Json.createReader(new StringReader(sw.toString()));
+ JsonArray array = jr.readArray();
+ String got = array.getString(0);
+ jr.close();
+
+ assertEquals(expected, got);
+ }
+
+ public void testGeneratorEquals() throws Exception {
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(sw);
+ generator.writeStartArray()
+ .write(JsonValue.TRUE)
+ .write(JsonValue.FALSE)
+ .write(JsonValue.NULL)
+ .write(Integer.MAX_VALUE)
+ .write(Long.MAX_VALUE)
+ .write(Double.MAX_VALUE)
+ .write(Integer.MIN_VALUE)
+ .write(Long.MIN_VALUE)
+ .write(Double.MIN_VALUE)
+ .writeEnd();
+ generator.close();
+
+ JsonReader reader = Json.createReader(new StringReader(sw.toString()));
+ JsonArray expected = reader.readArray();
+ reader.close();
+
+ JsonArray actual = Json.createArrayBuilder()
+ .add(JsonValue.TRUE)
+ .add(JsonValue.FALSE)
+ .add(JsonValue.NULL)
+ .add(Integer.MAX_VALUE)
+ .add(Long.MAX_VALUE)
+ .add(Double.MAX_VALUE)
+ .add(Integer.MIN_VALUE)
+ .add(Long.MIN_VALUE)
+ .add(Double.MIN_VALUE)
+ .build();
+
+ assertEquals(expected, actual);
+ }
+
+ public void testPrettyObjectWriter() throws Exception {
+ StringWriter writer = new StringWriter();
+ Map<String, Object> config = new HashMap<>();
+ config.put(JsonGenerator.PRETTY_PRINTING, true);
+ JsonGenerator generator = Json.createGeneratorFactory(config)
+ .createGenerator(writer);
+ testObject(generator);
+ generator.close();
+ writer.close();
+
+ JsonReader reader = Json.createReader(new StringReader(writer.toString()));
+ JsonObject person = reader.readObject();
+ JsonObjectTest.testPerson(person);
+ }
+
+ public void testPrettyObjectStream() throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ Map<String, Object> config = new HashMap<>();
+ config.put(JsonGenerator.PRETTY_PRINTING, true);
+ JsonGenerator generator = Json.createGeneratorFactory(config)
+ .createGenerator(out);
+ testObject(generator);
+ generator.close();
+ out.close();
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ JsonReader reader = Json.createReader(in);
+ JsonObject person = reader.readObject();
+ JsonObjectTest.testPerson(person);
+ reader.close();
+ in.close();
+ }
+
+ public void testGenerationException1() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartObject();
+ try {
+ generator.writeStartObject();
+ fail("Expected JsonGenerationException, writeStartObject() cannot be called more than once");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException2() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartObject();
+ try {
+ generator.writeStartArray();
+ fail("Expected JsonGenerationException, writeStartArray() is valid in no context");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException3() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ try {
+ generator.close();
+ fail("Expected JsonGenerationException, no JSON is generated");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException4() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartArray();
+ try {
+ generator.close();
+ fail("Expected JsonGenerationException, writeEnd() is not called");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException5() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartObject();
+ try {
+ generator.close();
+ fail("Expected JsonGenerationException, writeEnd() is not called");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException6() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartObject().writeEnd();
+ try {
+ generator.writeStartObject();
+ fail("Expected JsonGenerationException, cannot generate one more JSON text");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGenerationException7() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartArray().writeEnd();
+ try {
+ generator.writeStartArray();
+ fail("Expected JsonGenerationException, cannot generate one more JSON text");
+ } catch (JsonGenerationException je) {
+ // Expected exception
+ }
+ }
+
+ public void testGeneratorArrayDouble() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartArray();
+ try {
+ generator.write(Double.NaN);
+ fail("JsonGenerator.write(Double.NaN) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ try {
+ generator.write(Double.POSITIVE_INFINITY);
+ fail("JsonGenerator.write(Double.POSITIVE_INIFINITY) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ try {
+ generator.write(Double.NEGATIVE_INFINITY);
+ fail("JsonGenerator.write(Double.NEGATIVE_INIFINITY) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ generator.writeEnd();
+ generator.close();
+ }
+
+ public void testGeneratorObjectDouble() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(writer);
+ generator.writeStartObject();
+ try {
+ generator.write("foo", Double.NaN);
+ fail("JsonGenerator.write(String, Double.NaN) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ try {
+ generator.write("foo", Double.POSITIVE_INFINITY);
+ fail("JsonGenerator.write(String, Double.POSITIVE_INIFINITY) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ try {
+ generator.write("foo", Double.NEGATIVE_INFINITY);
+ fail("JsonGenerator.write(String, Double.NEGATIVE_INIFINITY) should produce NumberFormatException");
+ } catch (NumberFormatException ne) {
+ // expected
+ }
+ generator.writeEnd();
+ generator.close();
+ }
+
+ public void testIntGenerator() throws Exception {
+ Random r = new Random(System.currentTimeMillis());
+ JsonGeneratorFactory gf = Json.createGeneratorFactory(null);
+ JsonReaderFactory rf = Json.createReaderFactory(null);
+ JsonBuilderFactory bf = Json.createBuilderFactory(null);
+ for(int i=0; i < 100000; i++) {
+ int num = r.nextInt();
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = gf.createGenerator(sw);
+ generator.writeStartArray().write(num).writeEnd().close();
+
+ JsonReader reader = rf.createReader(new StringReader(sw.toString()));
+ JsonArray got = reader.readArray();
+ reader.close();
+
+ JsonArray expected = bf.createArrayBuilder().add(num).build();
+
+ assertEquals(expected, got);
+ }
+ }
+
+ public void testGeneratorBuf() throws Exception {
+ JsonGeneratorFactory gf = Json.createGeneratorFactory(null);
+ JsonReaderFactory rf = Json.createReaderFactory(null);
+ JsonBuilderFactory bf = Json.createBuilderFactory(null);
+ StringBuilder sb = new StringBuilder();
+ int value = 10;
+ for(int i=0; i < 25000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = gf.createGenerator(sw);
+ generator.writeStartObject().write(name, value).writeEnd().close();
+
+ JsonReader reader = rf.createReader(new StringReader(sw.toString()));
+ JsonObject got = reader.readObject();
+ reader.close();
+
+ JsonObject expected = bf.createObjectBuilder().add(name, value).build();
+
+ assertEquals(expected, got);
+ }
+ }
+
+ public void testBufferPoolFeature() {
+ final JsonParserTest.MyBufferPool bufferPool = new JsonParserTest.MyBufferPool(1024);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+
+ JsonGeneratorFactory factory = Json.createGeneratorFactory(config);
+ JsonGenerator generator = factory.createGenerator(new StringWriter());
+ generator.writeStartArray();
+ generator.writeEnd();
+ generator.close();
+ assertTrue(bufferPool.isTakeCalled());
+ assertTrue(bufferPool.isRecycleCalled());
+ }
+
+ public void testBufferSizes() {
+ JsonReaderFactory rf = Json.createReaderFactory(null);
+ JsonBuilderFactory bf = Json.createBuilderFactory(null);
+ for(int size=10; size < 1000; size++) {
+ final JsonParserTest.MyBufferPool bufferPool = new JsonParserTest.MyBufferPool(size);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+ JsonGeneratorFactory gf = Json.createGeneratorFactory(config);
+
+ StringBuilder sb = new StringBuilder();
+ int value = 10;
+ for(int i=0; i < 1500; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = gf.createGenerator(sw);
+ generator.writeStartObject().write(name, value).writeEnd().close();
+
+ JsonReader reader = rf.createReader(new StringReader(sw.toString()));
+ JsonObject got = reader.readObject();
+ reader.close();
+
+ JsonObject expected = bf.createObjectBuilder().add(name, value).build();
+
+ assertEquals(expected, got);
+ }
+
+ }
+ }
+
+ public void testString() throws Exception {
+ escapedString("");
+ escapedString("abc");
+ escapedString("abc\f");
+ escapedString("abc\na");
+ escapedString("abc\tabc");
+ escapedString("abc\n\tabc");
+ escapedString("abc\n\tabc\r");
+ escapedString("\n\tabc\r");
+ escapedString("\bab\tb\rc\\\"\ftesting1234");
+ escapedString("\f\babcdef\tb\rc\\\"\ftesting1234");
+ }
+
+ void escapedString(String expected) throws Exception {
+ StringWriter sw = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(sw);
+ generator.writeStartArray().write(expected).writeEnd();
+ generator.close();
+ sw.close();
+
+ JsonReader jr = Json.createReader(new StringReader(sw.toString()));
+ JsonArray array = jr.readArray();
+ String got = array.getString(0);
+ jr.close();
+
+ assertEquals(expected, got);
+ }
+
+ public void testFlush() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JsonGenerator gen = Json.createGenerator(baos);
+ gen.writeStartObject().writeEnd();
+ gen.flush();
+
+ assertEquals("{}", baos.toString("UTF-8"));
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchDiffTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchDiffTest.java
new file mode 100644
index 0000000..a624df9
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchDiffTest.java
@@ -0,0 +1,136 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonMergePatch;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonMergePatchDiffTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ List<Object[]> examples = new ArrayList<Object[]>();
+ JsonArray data = loadData();
+ for (JsonValue jsonValue : data) {
+ JsonObject test = (JsonObject) jsonValue;
+ Object[] testData = new Object[4];
+ testData[0] = test.get("original");
+ testData[1] = test.get("target");
+ testData[2] = test.get("expected");
+ testData[3] = createExceptionClass((JsonString)test.get("exception"));
+
+ examples.add(testData);
+ }
+
+ return examples;
+ }
+
+ private static Class<? extends Exception> createExceptionClass(
+ JsonString exceptionClassName) throws ClassNotFoundException {
+ if (exceptionClassName != null) {
+ return (Class<? extends Exception>) Class
+ .forName(exceptionClassName.getString());
+ }
+ return null;
+ }
+
+ private static JsonArray loadData() {
+ InputStream testData = JsonPatchTest.class
+ .getResourceAsStream("/jsonmergepatchdiff.json");
+ JsonReader reader = Json.createReader(testData);
+ JsonArray data = (JsonArray) reader.read();
+ return data;
+ }
+
+ private JsonValue original;
+ private JsonValue target;
+ private JsonValue expected;
+ private Class<? extends Exception> expectedException;
+
+ public JsonMergePatchDiffTest(JsonValue original, JsonValue target,
+ JsonValue expected, Class<? extends Exception> expectedException) {
+ super();
+ this.original = original;
+ this.target = target;
+ this.expected = expected;
+ this.expectedException = expectedException;
+ }
+ @Test
+ public void shouldExecuteJsonMergePatchDiffOperationsToJsonDocument() {
+ try {
+ JsonValue output = JsonMergePatch.diff(original, target);
+ assertThat(output, is(expected));
+ assertThat(expectedException, nullValue());
+ } catch (Exception e) {
+ if (expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchTest.java
new file mode 100644
index 0000000..223f0ce
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonMergePatchTest.java
@@ -0,0 +1,138 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonMergePatch;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonMergePatchTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ List<Object[]> examples = new ArrayList<Object[]>();
+ JsonArray data = loadData();
+ for (JsonValue jsonValue : data) {
+ JsonObject test = (JsonObject) jsonValue;
+ Object[] testData = new Object[4];
+ testData[0] = test.get("patch");
+ testData[1] = test.get("target");
+ testData[2] = test.get("expected");
+ testData[3] = createExceptionClass((JsonString)test.get("exception"));
+
+ examples.add(testData);
+ }
+
+ return examples;
+ }
+
+ private static Class<? extends Exception> createExceptionClass(
+ JsonString exceptionClassName) throws ClassNotFoundException {
+ if (exceptionClassName != null) {
+ return (Class<? extends Exception>) Class
+ .forName(exceptionClassName.getString());
+ }
+ return null;
+ }
+
+ private static JsonArray loadData() {
+ InputStream testData = JsonPatchTest.class
+ .getResourceAsStream("/jsonmergepatch.json");
+ JsonReader reader = Json.createReader(testData);
+ JsonArray data = (JsonArray) reader.read();
+ return data;
+ }
+
+ private JsonValue patch;
+ private JsonValue target;
+ private JsonValue expected;
+ private Class<? extends Exception> expectedException;
+
+ public JsonMergePatchTest(JsonValue patch, JsonValue target,
+ JsonValue expected, Class<? extends Exception> expectedException) {
+ super();
+ this.patch = patch;
+ this.target = target;
+ this.expected = expected;
+ this.expectedException = expectedException;
+ }
+
+ @Test
+ public void shouldExecuteJsonMergePatchDiffOperationsToJsonDocument() {
+ try {
+ JsonValue output = JsonMergePatch.mergePatch(target, patch);
+ assertThat(output, is(expected));
+ assertThat(expectedException, nullValue());
+ } catch (Exception e) {
+ if (expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonNumberTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonNumberTest.java
new file mode 100644
index 0000000..8632772
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonNumberTest.java
@@ -0,0 +1,234 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonNumberTest extends TestCase {
+ public JsonNumberTest(String testName) {
+ super(testName);
+ }
+
+ public void testFloating() throws Exception {
+ JsonArray array1 = Json.createArrayBuilder().add(10.4).build();
+ JsonReader reader = Json.createReader(new StringReader("[10.4]"));
+ JsonArray array2 = reader.readArray();
+
+ assertEquals(array1.get(0), array2.get(0));
+ assertEquals(array1, array2);
+ }
+
+ public void testBigDecimal() throws Exception {
+ JsonArray array1 = Json.createArrayBuilder().add(new BigDecimal("10.4")).build();
+ JsonReader reader = Json.createReader(new StringReader("[10.4]"));
+ JsonArray array2 = reader.readArray();
+
+ assertEquals(array1.get(0), array2.get(0));
+ assertEquals(array1, array2);
+ }
+
+ public void testIntNumberType() throws Exception {
+ JsonArray array1 = Json.createArrayBuilder()
+ .add(Integer.MIN_VALUE)
+ .add(Integer.MAX_VALUE)
+ .add(Integer.MIN_VALUE + 1)
+ .add(Integer.MAX_VALUE - 1)
+ .add(12)
+ .add(12l)
+ .add(new BigInteger("0"))
+ .build();
+ testNumberType(array1, true);
+
+ StringReader sr = new StringReader("[" +
+ "-2147483648, " +
+ "2147483647, " +
+ "-2147483647, " +
+ "2147483646, " +
+ "12, " +
+ "12, " +
+ "0 " +
+ "]");
+ JsonReader reader = Json.createReader(sr);
+ JsonArray array2 = reader.readArray();
+ reader.close();
+ testNumberType(array2, true);
+
+ assertEquals(array1, array2);
+ }
+
+ private void testNumberType(JsonArray array, boolean integral) {
+ for (JsonValue value : array) {
+ assertEquals(integral, ((JsonNumber) value).isIntegral());
+ }
+ }
+
+ public void testLongNumberType() throws Exception {
+ JsonArray array1 = Json.createArrayBuilder()
+ .add(Long.MIN_VALUE)
+ .add(Long.MAX_VALUE)
+ .add(Long.MIN_VALUE + 1)
+ .add(Long.MAX_VALUE - 1)
+ .add((long) Integer.MIN_VALUE - 1)
+ .add((long) Integer.MAX_VALUE + 1)
+ .build();
+ testNumberType(array1, true);
+
+ StringReader sr = new StringReader("[" +
+ "-9223372036854775808, " +
+ "9223372036854775807, " +
+ "-9223372036854775807, " +
+ "9223372036854775806, " +
+ "-2147483649, " +
+ "2147483648 " +
+ "]");
+ JsonReader reader = Json.createReader(sr);
+ JsonArray array2 = reader.readArray();
+ reader.close();
+ testNumberType(array2, true);
+
+ assertEquals(array1, array2);
+ }
+
+
+// public void testBigIntegerNumberType() throws Exception {
+// JsonArray array1 = new JsonBuilder()
+// .startArray()
+// .add(new BigInteger("-9223372036854775809"))
+// .add(new BigInteger("9223372036854775808"))
+// .add(new BigInteger("012345678901234567890"))
+// .end()
+// .build();
+// testNumberType(array1, JsonNumber.NumberType.BIG_INTEGER);
+//
+// StringReader sr = new StringReader("[" +
+// "-9223372036854775809, " +
+// "9223372036854775808, " +
+// "12345678901234567890 " +
+// "]");
+// JsonReader reader = new JsonReader(sr);
+// JsonArray array2 = reader.readArray();
+// reader.close();
+// testNumberType(array2, JsonNumber.NumberType.BIG_INTEGER);
+//
+// assertEquals(array1, array2);
+// }
+
+ public void testBigDecimalNumberType() throws Exception {
+ JsonArray array1 = Json.createArrayBuilder()
+ .add(12d)
+ .add(12.0d)
+ .add(12.1d)
+ .add(Double.MIN_VALUE)
+ .add(Double.MAX_VALUE)
+ .build();
+ testNumberType(array1, false);
+
+ StringReader sr = new StringReader("[" +
+ "12.0, " +
+ "12.0, " +
+ "12.1, " +
+ "4.9E-324, " +
+ "1.7976931348623157E+308 " +
+ "]");
+ JsonReader reader = Json.createReader(sr);
+ JsonArray array2 = reader.readArray();
+ reader.close();
+ testNumberType(array2, false);
+
+ assertEquals(array1, array2);
+ }
+
+ public void testMinMax() throws Exception {
+ JsonArray expected = Json.createArrayBuilder()
+ .add(Integer.MIN_VALUE)
+ .add(Integer.MAX_VALUE)
+ .add(Long.MIN_VALUE)
+ .add(Long.MAX_VALUE)
+ .add(Double.MIN_VALUE)
+ .add(Double.MAX_VALUE)
+ .build();
+
+ StringWriter sw = new StringWriter();
+ JsonWriter writer = Json.createWriter(sw);
+ writer.writeArray(expected);
+ writer.close();
+
+ JsonReader reader = Json.createReader(new StringReader(sw.toString()));
+ JsonArray actual = reader.readArray();
+ reader.close();
+
+ assertEquals(expected, actual);
+ }
+
+ public void testLeadingZeroes() {
+ JsonArray array = Json.createArrayBuilder()
+ .add(0012.1d)
+ .build();
+
+ StringWriter sw = new StringWriter();
+ JsonWriter jw = Json.createWriter(sw);
+ jw.write(array);
+ jw.close();
+
+ assertEquals("[12.1]", sw.toString());
+ }
+
+ public void testBigIntegerExact() {
+ try {
+ JsonArray array = Json.createArrayBuilder().add(12345.12345).build();
+ array.getJsonNumber(0).bigIntegerValueExact();
+ fail("Expected Arithmetic exception");
+ } catch (ArithmeticException expected) {
+ // no-op
+ }
+ }
+
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonObjectTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonObjectTest.java
new file mode 100644
index 0000000..2e0a5e3
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonObjectTest.java
@@ -0,0 +1,149 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonObjectTest extends TestCase {
+ public JsonObjectTest(String testName) {
+ super(testName);
+ }
+
+ public void test() {
+ }
+
+ public void testEmptyObjectEquals() throws Exception {
+ JsonObject empty1 = Json.createObjectBuilder()
+ .build();
+
+ JsonObject empty2 = Json.createObjectBuilder()
+ .build();
+
+ assertEquals(empty1, empty2);
+ }
+
+ public void testPersonObjectEquals() throws Exception {
+ JsonObject person1 = JsonBuilderTest.buildPerson();
+ JsonObject person2 = JsonReaderTest.readPerson();
+
+ assertEquals(person1, person2);
+ }
+
+ static void testPerson(JsonObject person) {
+ assertEquals(5, person.size());
+ assertEquals("John", person.getString("firstName"));
+ assertEquals("Smith", person.getString("lastName"));
+ assertEquals(25, person.getJsonNumber("age").intValue());
+ assertEquals(25, person.getInt("age"));
+
+ JsonObject address = person.getJsonObject("address");
+ assertEquals(4, address.size());
+ assertEquals("21 2nd Street", address.getString("streetAddress"));
+ assertEquals("New York", address.getString("city"));
+ assertEquals("NY", address.getString("state"));
+ assertEquals("10021", address.getString("postalCode"));
+
+ JsonArray phoneNumber = person.getJsonArray("phoneNumber");
+ assertEquals(2, phoneNumber.size());
+ JsonObject home = phoneNumber.getJsonObject(0);
+ assertEquals(2, home.size());
+ assertEquals("home", home.getString("type"));
+ assertEquals("212 555-1234", home.getString("number"));
+ assertEquals("212 555-1234", home.getString("number"));
+
+ JsonObject fax = phoneNumber.getJsonObject(1);
+ assertEquals(2, fax.size());
+ assertEquals("fax", fax.getString("type"));
+ assertEquals("646 555-4567", fax.getString("number"));
+
+ assertEquals("\"646 555-4567\"", fax.getJsonString("number").toString());
+ }
+
+ static void testEmpty(JsonObject empty) {
+ assertTrue(empty.isEmpty());
+ }
+
+ public void testClassCastException() {
+ JsonObject obj = Json.createObjectBuilder()
+ .add("foo", JsonValue.FALSE).build();
+ try {
+ obj.getJsonNumber("foo");
+ fail("Expected ClassCastException for casting JsonValue.FALSE to JsonNumber");
+ } catch (ClassCastException ce) {
+ // Expected
+ }
+ }
+
+ public void testPut() {
+ JsonObject obj = Json.createObjectBuilder().add("foo", 1).build();
+ try {
+ obj.put("bar", JsonValue.FALSE);
+ fail("JsonObject#put() should throw UnsupportedOperationException");
+ } catch(UnsupportedOperationException e) {
+ // Expected
+ }
+ }
+
+ public void testRemove() {
+ JsonObject obj = Json.createObjectBuilder().add("foo", 1).build();
+ try {
+ obj.remove("foo");
+ fail("JsonObject#remove() should throw UnsupportedOperationException");
+ } catch(UnsupportedOperationException e) {
+ // Expected
+ }
+ }
+
+ public void testObjectBuilderNpe() {
+ try {
+ JsonObject obj = Json.createObjectBuilder().add(null, 1).build();
+ fail("JsonObjectBuilder#add(null, 1) should throw NullPointerException");
+ } catch(NullPointerException e) {
+ // Expected
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParserFactoryTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserFactoryTest.java
new file mode 100644
index 0000000..614637d
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserFactoryTest.java
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.Json;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Tests JsonParserFactory
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonParserFactoryTest extends TestCase {
+
+ public JsonParserFactoryTest(String testName) {
+ super(testName);
+ }
+
+ public void testParserFactory() {
+ JsonParserFactory parserFactory = Json.createParserFactory(null);
+ JsonParser parser1 = parserFactory.createParser(new StringReader("[]"));
+ parser1.close();
+ JsonParser parser2 = parserFactory.createParser(new StringReader("[]"));
+ parser2.close();
+ }
+
+ public void testParserFactoryWithConfig() {
+ Map<String, ?> config = new HashMap<>();
+ JsonParserFactory parserFactory = Json.createParserFactory(config);
+ JsonParser parser1 = parserFactory.createParser(new StringReader("[]"));
+ parser1.close();
+ JsonParser parser2 = parserFactory.createParser(new StringReader("[]"));
+ parser2.close();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java
new file mode 100644
index 0000000..ea41903
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java
@@ -0,0 +1,769 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+import javax.json.stream.JsonParserFactory;
+import java.io.*;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Random;
+
+import org.glassfish.json.api.BufferPool;
+
+/**
+ * JsonParser Tests
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonParserTest extends TestCase {
+ static final Charset UTF_32LE = Charset.forName("UTF-32LE");
+ static final Charset UTF_32BE = Charset.forName("UTF-32BE");
+
+ public JsonParserTest(String testName) {
+ super(testName);
+ }
+
+ public void testReader() {
+ JsonParser reader = Json.createParser(
+ new StringReader("{ \"a\" : \"b\", \"c\" : null, \"d\" : [null, \"abc\"] }"));
+ reader.close();
+ }
+
+
+ public void testEmptyArrayReader() {
+ JsonParser parser = Json.createParser(new StringReader("[]"));
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStream() {
+ JsonParser parser = Json.createParser(
+ new ByteArrayInputStream(new byte[]{'[', ']'}));
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF8() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(StandardCharsets.UTF_8));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF16LE() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(StandardCharsets.UTF_16LE));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF16BE() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(StandardCharsets.UTF_16BE));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF32LE() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(UTF_32LE));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF32BE() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(UTF_32BE));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamUTF16() {
+ ByteArrayInputStream bin = new ByteArrayInputStream("[]".getBytes(StandardCharsets.UTF_16));
+ JsonParser parser = Json.createParser(bin);
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStreamWithConfig() {
+ Map<String, ?> config = new HashMap<>();
+ JsonParser parser = Json.createParserFactory(config).createParser(
+ new ByteArrayInputStream(new byte[]{'[', ']'}));
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStructure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createArrayBuilder().build());
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStructureWithConfig() {
+ Map<String, ?> config = new HashMap<>();
+ JsonParser parser = Json.createParserFactory(config).createParser(
+ Json.createArrayBuilder().build());
+ testEmptyArray(parser);
+ parser.close();
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ static void testEmptyArray(JsonParser parser) {
+ while (parser.hasNext()) {
+ parser.next();
+ }
+ }
+
+
+ public void testEmptyArrayReaderIterator() {
+ JsonParser parser = Json.createParser(new StringReader("[]"));
+ testEmptyArrayIterator(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayStructureIterator() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createArrayBuilder().build());
+ testEmptyArrayIterator(parser);
+ parser.close();
+ }
+
+ static void testEmptyArrayIterator(JsonParser parser) {
+ assertEquals(true, parser.hasNext());
+ assertEquals(true, parser.hasNext());
+ assertEquals(Event.START_ARRAY, parser.next());
+
+ assertEquals(true, parser.hasNext());
+ assertEquals(true, parser.hasNext());
+ assertEquals(Event.END_ARRAY, parser.next());
+
+ assertEquals(false, parser.hasNext());
+ assertEquals(false, parser.hasNext());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ }
+ }
+
+
+ public void testEmptyArrayIterator2Reader() {
+ JsonParser parser = Json.createParser(new StringReader("[]"));
+ testEmptyArrayIterator2(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayIterator2Structure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createArrayBuilder().build());
+ testEmptyArrayIterator2(parser);
+ parser.close();
+ }
+
+ static void testEmptyArrayIterator2(JsonParser parser) {
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ }
+ }
+
+ public void testEmptyArrayIterator3Reader() {
+ JsonParser parser = Json.createParser(new StringReader("[]"));
+ testEmptyArrayIterator3(parser);
+ parser.close();
+ }
+
+ public void testEmptyArrayIterator3Structure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createArrayBuilder().build());
+ testEmptyArrayIterator3(parser);
+ parser.close();
+ }
+
+ static void testEmptyArrayIterator3(JsonParser parser) {
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ assertEquals(false, parser.hasNext());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ }
+ }
+
+
+ // Tests empty object
+ public void testEmptyObjectReader() {
+ JsonParser parser = Json.createParser(new StringReader("{}"));
+ testEmptyObject(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectStream() {
+ JsonParser parser = Json.createParser(
+ new ByteArrayInputStream(new byte[]{'{', '}'}));
+ testEmptyObject(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectStructure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createObjectBuilder().build());
+ testEmptyObject(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectStructureWithConfig() {
+ Map<String, ?> config = new HashMap<>();
+ JsonParser parser = Json.createParserFactory(config).createParser(
+ Json.createObjectBuilder().build());
+ testEmptyObject(parser);
+ parser.close();
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ static void testEmptyObject(JsonParser parser) {
+ while (parser.hasNext()) {
+ parser.next();
+ }
+ }
+
+
+ public void testEmptyObjectIteratorReader() {
+ JsonParser parser = Json.createParser(new StringReader("{}"));
+ testEmptyObjectIterator(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectIteratorStructure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createObjectBuilder().build());
+ testEmptyObjectIterator(parser);
+ parser.close();
+ }
+
+ static void testEmptyObjectIterator(JsonParser parser) {
+ assertEquals(true, parser.hasNext());
+ assertEquals(true, parser.hasNext());
+ assertEquals(Event.START_OBJECT, parser.next());
+
+ assertEquals(true, parser.hasNext());
+ assertEquals(true, parser.hasNext());
+ assertEquals(Event.END_OBJECT, parser.next());
+
+ assertEquals(false, parser.hasNext());
+ assertEquals(false, parser.hasNext());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ }
+ }
+
+
+ public void testEmptyObjectIterator2Reader() {
+ JsonParser parser = Json.createParser(new StringReader("{}"));
+ testEmptyObjectIterator2(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectIterator2Structure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createObjectBuilder().build());
+ testEmptyObjectIterator2(parser);
+ parser.close();
+ }
+
+ static void testEmptyObjectIterator2(JsonParser parser) {
+ assertEquals(Event.START_OBJECT, parser.next());
+ assertEquals(Event.END_OBJECT, parser.next());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ }
+ }
+
+
+ public void testEmptyObjectIterator3Reader() {
+ JsonParser parser = Json.createParser(new StringReader("{}"));
+ testEmptyObjectIterator3(parser);
+ parser.close();
+ }
+
+ public void testEmptyObjectIterator3Structure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createObjectBuilder().build());
+ testEmptyObjectIterator3(parser);
+ parser.close();
+ }
+
+ static void testEmptyObjectIterator3(JsonParser parser) {
+ assertEquals(Event.START_OBJECT, parser.next());
+ assertEquals(Event.END_OBJECT, parser.next());
+ assertEquals(false, parser.hasNext());
+ try {
+ parser.next();
+ fail("Should have thrown a NoSuchElementException");
+ } catch (NoSuchElementException ne) {
+ // expected
+ }
+ }
+
+
+ public void testWikiIteratorReader() throws Exception {
+ JsonParser parser = Json.createParser(wikiReader());
+ testWikiIterator(parser);
+ parser.close();
+ }
+
+ public void testWikiIteratorStructure() throws Exception {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ JsonBuilderTest.buildPerson());
+ testWikiIterator(parser);
+ parser.close();
+ }
+
+ @SuppressWarnings("UnusedDeclaration")
+ static void testWikiIterator(JsonParser parser) throws Exception {
+ while (parser.hasNext()) {
+ parser.next();
+ }
+ }
+
+ public void testWikiInputStream() throws Exception {
+ JsonParser parser = Json.createParser(wikiStream());
+ testWiki(parser);
+ parser.close();
+ }
+
+ public void testWikiInputStreamUTF16LE() throws Exception {
+ ByteArrayInputStream bin = new ByteArrayInputStream(wikiString()
+ .getBytes(StandardCharsets.UTF_16LE));
+ JsonParser parser = Json.createParser(bin);
+ testWiki(parser);
+ parser.close();
+ }
+
+ public void testWikiReader() throws Exception {
+ JsonParser parser = Json.createParser(wikiReader());
+ testWiki(parser);
+ parser.close();
+ }
+
+ public void testWikiStructure() throws Exception {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ JsonBuilderTest.buildPerson());
+ testWiki(parser);
+ parser.close();
+ }
+
+ static void testWiki(JsonParser parser) {
+
+ Event event = parser.next();
+ assertEquals(Event.START_OBJECT, event);
+
+ testObjectStringValue(parser, "firstName", "John");
+ testObjectStringValue(parser, "lastName", "Smith");
+
+ event = parser.next();
+ assertEquals(Event.KEY_NAME, event);
+ assertEquals("age", parser.getString());
+
+ event = parser.next();
+ assertEquals(Event.VALUE_NUMBER, event);
+ assertEquals(25, parser.getInt());
+ assertEquals(25, parser.getLong());
+ assertEquals(25, parser.getBigDecimal().intValue());
+ assertTrue( parser.isIntegralNumber());
+
+ event = parser.next();
+ assertEquals(Event.KEY_NAME, event);
+ assertEquals("address", parser.getString());
+
+ event = parser.next();
+ assertEquals(Event.START_OBJECT, event);
+
+
+ testObjectStringValue(parser, "streetAddress", "21 2nd Street");
+ testObjectStringValue(parser, "city", "New York");
+ testObjectStringValue(parser, "state", "NY");
+ testObjectStringValue(parser, "postalCode", "10021");
+
+ event = parser.next();
+ assertEquals(Event.END_OBJECT, event);
+
+ event = parser.next();
+ assertEquals(Event.KEY_NAME, event);
+ assertEquals("phoneNumber", parser.getString());
+
+ event = parser.next();
+ assertEquals(Event.START_ARRAY, event);
+ event = parser.next();
+ assertEquals(Event.START_OBJECT, event);
+ testObjectStringValue(parser, "type", "home");
+ testObjectStringValue(parser, "number", "212 555-1234");
+ event = parser.next();
+ assertEquals(Event.END_OBJECT, event);
+
+ event = parser.next();
+ assertEquals(Event.START_OBJECT, event);
+ testObjectStringValue(parser, "type", "fax");
+ testObjectStringValue(parser, "number", "646 555-4567");
+ event = parser.next();
+ assertEquals(Event.END_OBJECT, event);
+ event = parser.next();
+ assertEquals(Event.END_ARRAY, event);
+
+ event = parser.next();
+ assertEquals(Event.END_OBJECT, event);
+ }
+
+ static void testObjectStringValue(JsonParser parser, String name, String value) {
+ Event event = parser.next();
+ assertEquals(Event.KEY_NAME, event);
+ assertEquals(name, parser.getString());
+
+ event = parser.next();
+ assertEquals(Event.VALUE_STRING, event);
+ assertEquals(value, parser.getString());
+ }
+
+ public void testNestedArrayReader() {
+ JsonParser parser = Json.createParser(new StringReader("[[],[[]]]"));
+ testNestedArray(parser);
+ parser.close();
+ }
+
+ public void testNestedArrayStructure() {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ Json.createArrayBuilder()
+ .add(Json.createArrayBuilder())
+ .add(Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()))
+ .build());
+ testNestedArray(parser);
+ parser.close();
+ }
+
+ static void testNestedArray(JsonParser parser) {
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.START_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ assertEquals(Event.END_ARRAY, parser.next());
+ assertEquals(false, parser.hasNext());
+ assertEquals(false, parser.hasNext());
+ }
+
+ public void testExceptionsReader() throws Exception {
+ JsonParser parser = Json.createParser(wikiReader());
+ testExceptions(parser);
+ parser.close();
+ }
+
+ public void testExceptionsStructure() throws Exception {
+ JsonParser parser = Json.createParserFactory(null).createParser(
+ JsonBuilderTest.buildPerson());
+ testExceptions(parser);
+ parser.close();
+ }
+
+ static void testExceptions(JsonParser parser) {
+
+ Event event = parser.next();
+ assertEquals(Event.START_OBJECT, event);
+
+ try {
+ parser.getString();
+ fail("JsonParser#getString() should have thrown exception in START_OBJECT state");
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+
+ try {
+ parser.isIntegralNumber();
+ fail("JsonParser#getNumberType() should have thrown exception in START_OBJECT state");
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+
+ try {
+ parser.getInt();
+ fail("JsonParser#getInt() should have thrown exception in START_OBJECT state");
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+
+ try {
+ parser.getLong();
+ fail("JsonParser#getLong() should have thrown exception in START_OBJECT state");
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+
+ try {
+ parser.getBigDecimal();
+ fail("JsonParser#getBigDecimal() should have thrown exception in START_OBJECT state");
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ }
+
+ static String wikiString() {
+ java.util.Scanner scanner = new java.util.Scanner(wikiReader())
+ .useDelimiter("\\A");
+ String str = scanner.hasNext() ? scanner.next() : "";
+ scanner.close();
+ return str;
+ }
+
+ static InputStream wikiStream() {
+ return JsonParserTest.class.getResourceAsStream("/wiki.json");
+ }
+
+ static Reader wikiReader() {
+ return new InputStreamReader(
+ JsonParserTest.class.getResourceAsStream("/wiki.json"), StandardCharsets.UTF_8);
+ }
+
+ public void testIntNumber() {
+ JsonParserFactory factory = Json.createParserFactory(null);
+
+ Random r = new Random(System.currentTimeMillis());
+
+ for(int i=0; i < 100000; i++) {
+ long num = i%2 == 0 ? r.nextInt() : r.nextLong();
+ JsonParser parser = factory.createParser(new StringReader("["+num+"]"));
+ parser.next();
+ parser.next();
+ assertEquals("Fails for num="+num, new BigDecimal(num).intValue(), parser.getInt());
+ parser.close();
+ }
+
+ }
+
+ static class MyBufferPool implements BufferPool {
+ private boolean takeCalled;
+ private boolean recycleCalled;
+ private final char[] buf;
+
+ MyBufferPool(int size) {
+ buf = new char[size];
+ }
+
+ @Override
+ public char[] take() {
+ takeCalled = true;
+ return buf;
+ }
+
+ @Override
+ public void recycle(char[] buf) {
+ recycleCalled = true;
+ }
+
+ boolean isTakeCalled() {
+ return takeCalled;
+ }
+
+ boolean isRecycleCalled() {
+ return recycleCalled;
+ }
+ }
+
+ public void testBufferPoolFeature() {
+ final MyBufferPool bufferPool = new MyBufferPool(1024);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+
+ JsonParserFactory factory = Json.createParserFactory(config);
+ JsonParser parser = factory.createParser(new StringReader("[]"));
+ parser.next();
+ parser.next();
+ parser.close();
+ assertTrue(bufferPool.isTakeCalled());
+ assertTrue(bufferPool.isRecycleCalled());
+ }
+
+ public void testBufferSizes() {
+ Random r = new Random(System.currentTimeMillis());
+ for(int size=100; size < 1000; size++) {
+ final MyBufferPool bufferPool = new MyBufferPool(size);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+ JsonParserFactory factory = Json.createParserFactory(config);
+
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 1000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ long num = i%2 == 0 ? r.nextInt() : r.nextLong();
+ String str = "{\""+name+"\":["+num+"]}";
+ JsonParser parser = factory.createParser(new StringReader(str));
+ parser.next();
+ parser.next();
+ assertEquals("Fails for " + str, name, parser.getString());
+ parser.next();
+ parser.next();
+ assertEquals("Fails for "+str, new BigDecimal(num).intValue(), parser.getInt());
+ parser.close();
+ }
+ }
+ }
+
+ // Tests for string starting on buffer boundary (JSONP-15)
+ // xxxxxxx"xxxxxxxxx"
+ // ^
+ // |
+ // 4096
+ public void testStringUsingStandardBuffer() throws Throwable {
+ JsonParserFactory factory = Json.createParserFactory(null);
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 40000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ String str = "{\""+name+"\":\""+name+"\"}";
+ try {
+ JsonParser parser = factory.createParser(new StringReader(str));
+ parser.next();
+ parser.next();
+ assertEquals("Fails for size="+i, name, parser.getString());
+ parser.next();
+ assertEquals("Fails for size="+i, name, parser.getString());
+ parser.close();
+ } catch (Throwable e) {
+ throw new Throwable("Failed for size="+i, e);
+ }
+ }
+ }
+
+ // Tests for int starting on buffer boundary
+ // xxxxxxx"xxxxxxxxx"
+ // ^
+ // |
+ // 4096
+ public void testIntegerUsingStandardBuffer() throws Throwable {
+ Random r = new Random(System.currentTimeMillis());
+ JsonParserFactory factory = Json.createParserFactory(null);
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 40000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ int num = r.nextInt();
+ String str = "{\""+name+"\":"+num+"}";
+ try {
+ JsonParser parser = factory.createParser(new StringReader(str));
+ parser.next();
+ parser.next();
+ assertEquals("Fails for size="+i, name, parser.getString());
+ parser.next();
+ assertEquals("Fails for size="+i, num, parser.getInt());
+ parser.close();
+ } catch (Throwable e) {
+ throw new Throwable("Failed for size="+i, e);
+ }
+ }
+ }
+
+ public void testStringUsingBuffers() throws Throwable {
+ for(int size=20; size < 500; size++) {
+ final MyBufferPool bufferPool = new MyBufferPool(size);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+ JsonParserFactory factory = Json.createParserFactory(config);
+
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 1000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ String str = "{\""+name+"\":\""+name+"\"}";
+ JsonLocation location;
+ try {
+ JsonParser parser = factory.createParser(new StringReader(str));
+ parser.next();
+ parser.next();
+ assertEquals("name fails for buffer size="+size+" name length="+i, name, parser.getString());
+ location = parser.getLocation();
+ assertEquals("Stream offset fails for buffer size="+size+" name length="+i,
+ name.length()+3, location.getStreamOffset());
+ assertEquals("Column value fails for buffer size="+size+" name length="+i,
+ name.length()+4, location.getColumnNumber());
+ assertEquals("Line value fails for buffer size="+size+" name length="+i,
+ 1, location.getLineNumber());
+
+ parser.next();
+ assertEquals("value fails for buffer size="+size+" name length="+i, name, parser.getString());
+ location = parser.getLocation();
+ assertEquals("Stream offset fails for buffer size="+size+" name length="+i, 2*name.length()+6, location.getStreamOffset());
+ assertEquals("Column value fails for buffer size="+size+" name length="+i,
+ 2*name.length()+7, location.getColumnNumber());
+ assertEquals("Line value fails for buffer size="+size+" name length="+i,
+ 1, location.getLineNumber());
+ parser.close();
+ } catch (Throwable e) {
+ throw new Throwable("Failed for buffer size="+size+" name length="+i, e);
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParsingExceptionTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParsingExceptionTest.java
new file mode 100644
index 0000000..6e86179
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonParsingExceptionTest.java
@@ -0,0 +1,179 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.Json;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import java.io.StringReader;
+
+/**
+ * JsonParsingException Tests
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonParsingExceptionTest extends TestCase {
+
+ public void testWrongJson() {
+ // testMalformedJson("", null); Allowed in 1.1
+ }
+
+ public void testWrongJson1() {
+ // testMalformedJson("{}{}", null); Allowed in 1.1
+ }
+
+ public void testWrongJson2() {
+ // testMalformedJson("{", null); Allowed in 1.1
+ }
+
+ public void testWrongJson3() {
+ testMalformedJson("{[]", null);
+ }
+
+ public void testWrongJson4() {
+ testMalformedJson("{]", null);
+ }
+
+ public void testWrongJson5() {
+ testMalformedJson("{\"a\":[]]", null);
+ }
+
+ public void testWrongJson6() {
+ testMalformedJson("[ {}, [] }", null);
+ }
+
+ public void testWrongJson61() {
+ testMalformedJson("[ {}, {} }", null);
+ }
+
+ public void testWrongJson7() {
+ testMalformedJson("{ \"a\" : {}, \"b\": {} ]", null);
+ }
+
+ public void testWrongJson8() {
+ testMalformedJson("{ \"a\" : {}, \"b\": [] ]", null);
+ }
+
+ public void testWrongUnicode() {
+ testMalformedJson("[ \"\\uX00F\" ]", null);
+ testMalformedJson("[ \"\\u000Z\" ]", null);
+ testMalformedJson("[ \"\\u000\" ]", null);
+ testMalformedJson("[ \"\\u00\" ]", null);
+ testMalformedJson("[ \"\\u0\" ]", null);
+ testMalformedJson("[ \"\\u\" ]", null);
+ testMalformedJson("[ \"\\u\"", null);
+ testMalformedJson("[ \"\\", null);
+ }
+
+ public void testControlChar() {
+ testMalformedJson("[ \"\u0000\" ]", null);
+ testMalformedJson("[ \"\u000c\" ]", null);
+ testMalformedJson("[ \"\u000f\" ]", null);
+ testMalformedJson("[ \"\u001F\" ]", null);
+ testMalformedJson("[ \"\u001f\" ]", null);
+ }
+
+ public void testLocation1() {
+ testMalformedJson("x", new MyLocation(1, 1, 0));
+ testMalformedJson("{]", new MyLocation(1, 2, 1));
+ testMalformedJson("[}", new MyLocation(1, 2, 1));
+ testMalformedJson("[a", new MyLocation(1, 2, 1));
+ testMalformedJson("[nuLl]", new MyLocation(1, 4, 3));
+ testMalformedJson("[falsE]", new MyLocation(1, 6, 5));
+ // testMalformedJson("[][]", new MyLocation(1, 3, 2)); allowed in 1.1
+ testMalformedJson("[1234L]", new MyLocation(1, 6, 5));
+ }
+
+ public void testLocation2() {
+ testMalformedJson("[null\n}", new MyLocation(2, 1, 6));
+ testMalformedJson("[null\r\n}", new MyLocation(2, 1, 7));
+ testMalformedJson("[null\n, null\n}", new MyLocation(3, 1, 13));
+ testMalformedJson("[null\r\n, null\r\n}", new MyLocation(3, 1, 15));
+ }
+
+ private void testMalformedJson(String json, JsonLocation expected) {
+ try (JsonParser parser = Json.createParser(new StringReader(json))) {
+ while (parser.hasNext()) {
+ parser.next();
+ }
+ fail("Expected to throw JsonParsingException for " + json);
+ } catch (JsonParsingException je) {
+ // Expected
+ if (expected != null) {
+ JsonLocation got = je.getLocation();
+ assertEquals(expected.getLineNumber(), got.getLineNumber());
+ assertEquals(expected.getColumnNumber(), got.getColumnNumber());
+ assertEquals(expected.getStreamOffset(), got.getStreamOffset());
+ }
+ }
+ }
+
+ private static class MyLocation implements JsonLocation {
+ private final long columnNo;
+ private final long lineNo;
+ private final long streamOffset;
+
+ MyLocation(long lineNo, long columnNo, long streamOffset) {
+ this.lineNo = lineNo;
+ this.columnNo = columnNo;
+ this.streamOffset = streamOffset;
+ }
+
+ @Override
+ public long getLineNumber() {
+ return lineNo;
+ }
+
+ @Override
+ public long getColumnNumber() {
+ return columnNo;
+ }
+
+ @Override
+ public long getStreamOffset() {
+ return streamOffset;
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPatchBuilderTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPatchBuilderTest.java
new file mode 100644
index 0000000..5474c4a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPatchBuilderTest.java
@@ -0,0 +1,106 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonPatchBuilder;
+
+import org.junit.Test;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+public class JsonPatchBuilderTest {
+
+ @Test
+ public void shouldBuildJsonPatchExpressionUsingJsonPatchBuilder() {
+ JsonPatchBuilder patchBuilder = new JsonPatchBuilder();
+ JsonObject result = patchBuilder.add("/email", "john at example.com")
+ .replace("/age", 30)
+ .remove("/phoneNumber")
+ .test("/firstName", "John")
+ .copy("/address/lastName", "/lastName")
+ .apply(buildPerson());
+ assertThat(result, is(expectedBuildPerson()));
+
+ }
+
+ static JsonObject expectedBuildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("email", "john at example.com")
+ .add("age", 30)
+ .add("address", Json.createObjectBuilder()
+ .add("lastName", "Smith")
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .build();
+ }
+
+ static JsonObject buildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPatchDiffTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPatchDiffTest.java
new file mode 100644
index 0000000..bf48247
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPatchDiffTest.java
@@ -0,0 +1,138 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonPatch;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPatchDiffTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ List<Object[]> examples = new ArrayList<Object[]>();
+ JsonArray data = loadData();
+ for (JsonValue jsonValue : data) {
+ JsonObject test = (JsonObject) jsonValue;
+ Object[] testData = new Object[4];
+ testData[0] = test.get("original");
+ testData[1] = test.get("target");
+ testData[2] = test.get("expected");
+ testData[3] = createExceptionClass((JsonString)test.get("exception"));
+
+ examples.add(testData);
+ }
+
+ return examples;
+ }
+
+ private static Class<? extends Exception> createExceptionClass(
+ JsonString exceptionClassName) throws ClassNotFoundException {
+ if (exceptionClassName != null) {
+ return (Class<? extends Exception>) Class
+ .forName(exceptionClassName.getString());
+ }
+ return null;
+ }
+
+ private static JsonArray loadData() {
+ InputStream testData = JsonPatchTest.class
+ .getResourceAsStream("/jsonpatchdiff.json");
+ JsonReader reader = Json.createReader(testData);
+ JsonArray data = (JsonArray) reader.read();
+ return data;
+ }
+
+ private JsonStructure original;
+ private JsonStructure target;
+ private JsonValue expected;
+ private Class<? extends Exception> expectedException;
+
+ public JsonPatchDiffTest(JsonStructure original, JsonStructure target,
+ JsonValue expected, Class<? extends Exception> expectedException) {
+ super();
+ this.original = original;
+ this.target = target;
+ this.expected = expected;
+ this.expectedException = expectedException;
+ }
+
+ @Test
+ public void shouldExecuteJsonPatchDiffOperationsToJsonDocument() {
+ try {
+ JsonArray diff = JsonPatch.diff(this.original, this.target);
+ assertThat(diff, is(expected));
+ assertThat(expectedException, nullValue());
+ } catch (Exception e) {
+ if (expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPatchTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPatchTest.java
new file mode 100644
index 0000000..a832a36
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPatchTest.java
@@ -0,0 +1,142 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonPatch;
+import javax.json.JsonReader;
+import javax.json.JsonString;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPatchTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ List<Object[]> examples = new ArrayList<>();
+ JsonArray data = loadData();
+ for (JsonValue jsonValue : data) {
+ JsonObject test = (JsonObject) jsonValue;
+ Object[] testData = new Object[4];
+ testData[0] = createPatchArray(test.get("op"));
+ testData[1] = test.get("target");
+ testData[2] = test.get("expected");
+ testData[3] = createExceptionClass((JsonString)test.get("exception"));
+
+ examples.add(testData);
+ }
+
+ return examples;
+ }
+
+ private static Class<? extends Exception> createExceptionClass(
+ JsonString exceptionClassName) throws ClassNotFoundException {
+ if (exceptionClassName != null) {
+ return (Class<? extends Exception>) Class
+ .forName(exceptionClassName.getString());
+ }
+ return null;
+ }
+
+ private static JsonArray createPatchArray(JsonValue object) {
+ return Json.createArrayBuilder().add(object).build();
+ }
+
+ private static JsonArray loadData() {
+ InputStream testData = JsonPatchTest.class
+ .getResourceAsStream("/jsonpatch.json");
+ JsonReader reader = Json.createReader(testData);
+ return (JsonArray) reader.read();
+ }
+
+ private JsonArray patch;
+ private JsonStructure target;
+ private JsonValue expected;
+ private Class<? extends Exception> expectedException;
+
+ public JsonPatchTest(JsonArray patch, JsonStructure target,
+ JsonValue expected, Class<? extends Exception> expectedException) {
+ super();
+ this.patch = patch;
+ this.target = target;
+ this.expected = expected;
+ this.expectedException = expectedException;
+ }
+
+ @Test
+ public void shouldExecuteJsonPatchOperationsToJsonDocument() {
+ try {
+ JsonPatch patch = new JsonPatch(this.patch);
+ JsonStructure output = patch.apply(target);
+ assertThat(output, is(expected));
+ assertThat(expectedException, nullValue());
+ } catch (Exception e) {
+ if (expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPointerAddOperationTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPointerAddOperationTest.java
new file mode 100644
index 0000000..71c3db0
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPointerAddOperationTest.java
@@ -0,0 +1,227 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPointerAddOperationTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ return Arrays.asList(new Object[][] {
+ {buildSimpleAddPatch(), buildAddress(), buildExpectedAddress() },
+ {buildComplexAddPatch(), buildPerson(), buildExpectedPerson()},
+ {buildArrayAddPatchInPosition(), buildPerson(), buildExpectedPersonConcreteArrayPosition()},
+ {buildArrayAddPatchInLastPosition(), buildPerson(), buildExpectedPersonArrayLastPosition()}
+ });
+ }
+
+ private JsonObject pathOperation;
+ private JsonStructure target;
+ private JsonValue expectedResult;
+
+ public JsonPointerAddOperationTest(JsonObject pathOperation,
+ JsonStructure target, JsonValue expectedResult) {
+ super();
+ this.pathOperation = pathOperation;
+ this.target = target;
+ this.expectedResult = expectedResult;
+ }
+
+ @Test
+ public void shouldAddElementsToExistingJsonDocument() {
+ JsonPointer pointer = new JsonPointer(pathOperation.getString("path"));
+ JsonObject modified = (JsonObject) pointer.add(target, pathOperation.get("value"));
+ assertThat(modified, is(expectedResult));
+ }
+
+ static JsonObject buildAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildComplexAddPatch() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/address/streetAddress")
+ .add("value", "myaddress")
+ .build();
+ }
+ static JsonObject buildSimpleAddPatch() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/streetAddress")
+ .add("value", "myaddress")
+ .build();
+ }
+ static JsonObject buildArrayAddPatchInPosition() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/phoneNumber/0")
+ .add("value", Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234"))
+ .build();
+ }
+ static JsonObject buildArrayAddPatchInLastPosition() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/phoneNumber/-")
+ .add("value", Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234"))
+ .build();
+ }
+ static JsonObject buildExpectedAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "myaddress")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildExpectedPersonConcreteArrayPosition() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add((Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234")))
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildExpectedPersonArrayLastPosition() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567"))
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234")))
+ .build();
+ }
+ static JsonObject buildExpectedPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "myaddress")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPointerRemoveOperationTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPointerRemoveOperationTest.java
new file mode 100644
index 0000000..7bc41ca
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPointerRemoveOperationTest.java
@@ -0,0 +1,181 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPointerRemoveOperationTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ return Arrays.asList(new Object[][] {
+ {buildSimpleRemovePatch(), buildAddress(), buildExpectedRemovedAddress() },
+ {buildComplexRemovePatch(), buildPerson(), buildExpectedPersonWithoutStreetAddress()},
+ {buildArrayRemovePatchInPosition(), buildPerson(), buildPersonWithoutFirstPhone()}
+ });
+ }
+
+ private JsonObject pathOperation;
+ private JsonStructure target;
+ private JsonValue expectedResult;
+
+ public JsonPointerRemoveOperationTest(JsonObject pathOperation,
+ JsonObject target, JsonValue expectedResult) {
+ super();
+ this.pathOperation = pathOperation;
+ this.target = target;
+ this.expectedResult = expectedResult;
+ }
+
+ @Test
+ public void shouldRemoveElementsToExistingJsonDocument() {
+ JsonPointer pointer = new JsonPointer(pathOperation.getString("path"));
+ JsonObject modified = (JsonObject) pointer.remove(target);
+ assertThat(modified, is(expectedResult));
+ }
+
+ static JsonObject buildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildComplexRemovePatch() {
+ return Json.createObjectBuilder()
+ .add("op", "remove")
+ .add("path", "/address/streetAddress")
+ .build();
+ }
+ static JsonObject buildSimpleRemovePatch() {
+ return Json.createObjectBuilder()
+ .add("op", "remove")
+ .add("path", "/streetAddress")
+ .build();
+ }
+ static JsonObject buildArrayRemovePatchInPosition() {
+ return Json.createObjectBuilder()
+ .add("op", "remove")
+ .add("path", "/phoneNumber/0")
+ .build();
+ }
+ static JsonObject buildExpectedRemovedAddress() {
+ return Json.createObjectBuilder()
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildPersonWithoutFirstPhone() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildExpectedPersonWithoutStreetAddress() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPointerReplaceOperationTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPointerReplaceOperationTest.java
new file mode 100644
index 0000000..b41bfd1
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPointerReplaceOperationTest.java
@@ -0,0 +1,225 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPointerReplaceOperationTest {
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ return Arrays.asList(new Object[][] {
+ {buildSimpleReplacePatch(), buildAddress(), buildExpectedAddress(), null},
+ {buildComplexReplacePatch(), buildPerson(), buildExpectedPerson(), null},
+ {buildArrayReplacePatchInPosition(), buildPerson(), buildExpectedPersonConcreteArrayPosition(), null},
+ {buildArrayAddPatchInLastPosition(), buildPerson(), null, JsonException.class},
+ {buildNoneExistingReplacePatch(), buildAddress(), null, JsonException.class}
+ });
+ }
+
+ private JsonObject pathOperation;
+ private JsonStructure target;
+ private JsonValue expectedResult;
+ private Class<? extends Exception> expectedException;
+
+ public JsonPointerReplaceOperationTest(JsonObject pathOperation,
+ JsonStructure target, JsonValue expectedResult, Class<? extends Exception> expectedException) {
+ super();
+ this.pathOperation = pathOperation;
+ this.target = target;
+ this.expectedResult = expectedResult;
+ this.expectedException = expectedException;
+ }
+
+ @Test
+ public void shouldReplaceElementsToExistingJsonDocument() {
+ try {
+ JsonPointer pointer = new JsonPointer(pathOperation.getString("path"));
+ JsonObject modified = (JsonObject) pointer.replace(target, pathOperation.get("value"));
+ assertThat(modified, is(expectedResult));
+ assertThat(expectedException, nullValue());
+ } catch(Exception e) {
+ if(expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+
+ static JsonObject buildAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildComplexReplacePatch() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/address/streetAddress")
+ .add("value", "myaddress")
+ .build();
+ }
+ static JsonObject buildSimpleReplacePatch() {
+ return Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", "/streetAddress")
+ .add("value", "myaddress")
+ .build();
+ }
+ static JsonObject buildNoneExistingReplacePatch() {
+ return Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", "/notexists")
+ .add("value", "myaddress")
+ .build();
+ }
+ static JsonObject buildArrayReplacePatchInPosition() {
+ return Json.createObjectBuilder()
+ .add("op", "replace")
+ .add("path", "/phoneNumber/0")
+ .add("value", Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234"))
+ .build();
+ }
+ static JsonObject buildArrayAddPatchInLastPosition() {
+ return Json.createObjectBuilder()
+ .add("op", "add")
+ .add("path", "/phoneNumber/-")
+ .add("value", Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234"))
+ .build();
+ }
+ static JsonObject buildExpectedAddress() {
+ return Json.createObjectBuilder()
+ .add("streetAddress", "myaddress")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021")
+ .build();
+ }
+ static JsonObject buildPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildExpectedPersonConcreteArrayPosition() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "21 2nd Street")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add((Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "200 555-1234")))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+ static JsonObject buildExpectedPerson() {
+ return Json.createObjectBuilder()
+ .add("firstName", "John")
+ .add("lastName", "Smith")
+ .add("age", 25)
+ .add("address", Json.createObjectBuilder()
+ .add("streetAddress", "myaddress")
+ .add("city", "New York")
+ .add("state", "NY")
+ .add("postalCode", "10021"))
+ .add("phoneNumber", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("type", "home")
+ .add("number", "212 555-1234"))
+ .add(Json.createObjectBuilder()
+ .add("type", "fax")
+ .add("number", "646 555-4567")))
+ .build();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPointerTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPointerTest.java
new file mode 100644
index 0000000..f04707a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonPointerTest.java
@@ -0,0 +1,132 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.instanceOf;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Arrays;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonPointer;
+import javax.json.JsonReader;
+import javax.json.JsonValue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author Alex Soto
+ *
+ */
+ at RunWith(Parameterized.class)
+public class JsonPointerTest {
+
+ private static JsonObject rfc6901Example;
+
+ @Parameters(name = "{index}: ({0})={1}")
+ public static Iterable<Object[]> data() throws Exception {
+ rfc6901Example = JsonPointerTest.readRfc6901Example();
+ return Arrays.asList(new Object[][] {
+ {new JsonPointer(""), rfc6901Example, null },
+ {new JsonPointer("/foo"), rfc6901Example.getJsonArray("foo"), null},
+ {new JsonPointer("/foo/0"), rfc6901Example.getJsonArray("foo").get(0), null},
+ {new JsonPointer("/foo/5"), null, JsonException.class},
+ {new JsonPointer("/p/1"), null, JsonException.class},
+ {new JsonPointer("/"), rfc6901Example.getJsonNumber(""), null},
+ {new JsonPointer("/a~1b"), rfc6901Example.getJsonNumber("a/b"), null},
+ {new JsonPointer("/m~0n"), rfc6901Example.getJsonNumber("m~n"), null},
+ {new JsonPointer("/c%d"), rfc6901Example.getJsonNumber("c%d"), null},
+ {new JsonPointer("/e^f"), rfc6901Example.getJsonNumber("e^f"), null},
+ {new JsonPointer("/g|h"), rfc6901Example.getJsonNumber("g|h"), null},
+ {new JsonPointer("/i\\j"), rfc6901Example.getJsonNumber("i\\j"), null},
+ {new JsonPointer("/k\"l"), rfc6901Example.getJsonNumber("k\"l"), null},
+ {new JsonPointer("/ "), rfc6901Example.getJsonNumber(" "), null},
+ {new JsonPointer("/notexists"), null, JsonException.class},
+ {new JsonPointer("/s/t"), null, JsonException.class},
+ {new JsonPointer("/o"), JsonObject.NULL, null}
+ });
+ }
+
+ private JsonPointer pointer;
+ private JsonValue expected;
+ private Class<? extends Exception> expectedException;
+
+ public JsonPointerTest(JsonPointer pointer, JsonValue expected, Class<? extends Exception> expectedException) {
+ super();
+ this.pointer = pointer;
+ this.expected = expected;
+ this.expectedException = expectedException;
+ }
+
+ @Test
+ public void shouldEvaluateJsonPointerExpressions() {
+ try {
+ JsonValue result = pointer.getValue(rfc6901Example);
+ assertThat(result, is(expected));
+ assertThat(expectedException, nullValue());
+ } catch(Exception e) {
+ if(expectedException == null) {
+ fail(e.getMessage());
+ } else {
+ assertThat(e, instanceOf(expectedException));
+ }
+ }
+ }
+
+ static JsonObject readRfc6901Example() throws Exception {
+ Reader rfc6901Reader = new InputStreamReader(JsonReaderTest.class.getResourceAsStream("/rfc6901.json"));
+ JsonReader reader = Json.createReader(rfc6901Reader);
+ JsonValue value = reader.readObject();
+ reader.close();
+ return (JsonObject) value;
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonReaderTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonReaderTest.java
new file mode 100644
index 0000000..92a989a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonReaderTest.java
@@ -0,0 +1,232 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import javax.json.JsonValue;
+
+import org.glassfish.json.api.BufferPool;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonReaderTest extends TestCase {
+ public JsonReaderTest(String testName) {
+ super(testName);
+ }
+
+ public void testObject() throws Exception {
+ JsonObject person = readPerson();
+ JsonObjectTest.testPerson(person);
+ }
+
+ public void testEscapedString() throws Exception {
+ // u00ff is escaped once, not escaped once
+ JsonReader reader = Json.createReader(new StringReader("[\"\\u0000\\u00ff\u00ff\"]"));
+ JsonArray array = reader.readArray();
+ reader.close();
+ String str = array.getString(0);
+ assertEquals("\u0000\u00ff\u00ff", str);
+ }
+
+ public void testPrimitiveIntNumbers() {
+ String[] borderlineCases = new String[]{
+ "214748364",
+ Integer.toString(Integer.MAX_VALUE),
+ Long.toString(Integer.MAX_VALUE + 1L),
+ "-214748364",
+ Integer.toString(Integer.MIN_VALUE),
+ Long.toString(Integer.MIN_VALUE - 1L)
+ };
+ for (String num : borderlineCases) {
+ JsonReader reader = Json.createReader(new StringReader("["+num+"]"));
+ try {
+ JsonArray array = reader.readArray();
+ JsonNumber value = (JsonNumber) array.get(0);
+ assertEquals("Fails for num="+num, new BigInteger(num).longValue(), value.longValue());
+ } finally {
+ reader.close();
+ }
+ }
+ }
+
+ public void testPrimitiveLongNumbers() {
+ String[] borderlineCases = new String[]{
+ "922337203685477580",
+ Long.toString(Long.MAX_VALUE),
+ new BigInteger(Long.toString(Long.MAX_VALUE)).add(BigInteger.ONE).toString(),
+ "-922337203685477580",
+ Long.toString(Long.MIN_VALUE),
+ new BigInteger(Long.toString(Long.MIN_VALUE)).subtract(BigInteger.ONE).toString()
+ };
+ for (String num : borderlineCases) {
+ JsonReader reader = Json.createReader(new StringReader("["+num+"]"));
+ try {
+ JsonArray array = reader.readArray();
+ JsonNumber value = (JsonNumber) array.get(0);
+ assertEquals("Fails for num="+num, new BigInteger(num), value.bigIntegerValueExact());
+ } finally {
+ reader.close();
+ }
+ }
+ }
+
+ public void testUnknownFeature() throws Exception {
+ Map<String, Object> config = new HashMap<>();
+ config.put("foo", true);
+ JsonReaderFactory factory = Json.createReaderFactory(config);
+ factory.createReader(new StringReader("{}"));
+ Map<String, ?> config1 = factory.getConfigInUse();
+ if (config1.size() > 0) {
+ fail("Shouldn't have any config in use");
+ }
+ }
+
+ public void testIllegalStateExcepton() throws Exception {
+ JsonReader reader = Json.createReader(new StringReader("{}"));
+ reader.readObject();
+ try {
+ reader.readObject();
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ reader.close();
+
+ reader = Json.createReader(new StringReader("[]"));
+ reader.readArray();
+ try {
+ reader.readArray();
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ reader.close();
+
+ reader = Json.createReader(new StringReader("{}"));
+ reader.read();
+ try {
+ reader.read();
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ reader.close();
+ }
+
+ static JsonObject readPerson() throws Exception {
+ Reader wikiReader = new InputStreamReader(JsonReaderTest.class.getResourceAsStream("/wiki.json"));
+ JsonReader reader = Json.createReader(wikiReader);
+ JsonValue value = reader.readObject();
+ reader.close();
+ return (JsonObject) value;
+ }
+
+ // JSONP-23 cached empty string is not reset
+ public void testEmptyStringUsingStandardBuffer() throws Throwable {
+ JsonReaderFactory factory = Json.createReaderFactory(null);
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 40000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ String str = "[1, \"\", \""+name+"\", \"\", \""+name+"\", \"\", 100]";
+ try {
+ JsonReader reader = factory.createReader(new StringReader(str));
+ JsonArray array = reader.readArray();
+ assertEquals(1, array.getInt(0));
+ assertEquals("", array.getString(1));
+ assertEquals(name, array.getString(2));
+ assertEquals("", array.getString(3));
+ assertEquals(name, array.getString(4));
+ assertEquals("", array.getString(5));
+ assertEquals(100, array.getInt(6));
+ reader.close();
+ } catch (Throwable t) {
+ throw new Throwable("Failed for name length="+i, t);
+ }
+ }
+ }
+
+ // JSONP-23 cached empty string is not reset
+ public void testEmptyStringUsingBuffers() throws Throwable {
+ for(int size=20; size < 500; size++) {
+ final JsonParserTest.MyBufferPool bufferPool = new JsonParserTest.MyBufferPool(size);
+ Map<String, Object> config = new HashMap<String, Object>() {{
+ put(BufferPool.class.getName(), bufferPool);
+ }};
+ JsonReaderFactory factory = Json.createReaderFactory(config);
+
+ StringBuilder sb = new StringBuilder();
+ for(int i=0; i < 1000; i++) {
+ sb.append('a');
+ String name = sb.toString();
+ String str = "[1, \"\", \""+name+"\", \"\", \""+name+"\", \"\", 100]";
+ try {
+ JsonReader reader = factory.createReader(new StringReader(str));
+ JsonArray array = reader.readArray();
+ assertEquals(1, array.getInt(0));
+ assertEquals("", array.getString(1));
+ assertEquals(name, array.getString(2));
+ assertEquals("", array.getString(3));
+ assertEquals(name, array.getString(4));
+ assertEquals("", array.getString(5));
+ assertEquals(100, array.getInt(6));
+ reader.close();
+ } catch (Throwable t) {
+ throw new Throwable("Failed for buffer size="+size+" name length="+i, t);
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonSamplesParsingTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonSamplesParsingTest.java
new file mode 100644
index 0000000..0664a39
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonSamplesParsingTest.java
@@ -0,0 +1,89 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.stream.JsonParser;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * JsonParser tests for sample files
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonSamplesParsingTest extends TestCase {
+
+ public void testSampleFiles() {
+ String[] fileNames = {
+ "facebook.json", "facebook1.json", "facebook2.json",
+ "twitter.json"
+ };
+ for(String fileName: fileNames) {
+ try {
+ testSampleFile(fileName);
+ } catch(Exception e) {
+ throw new JsonException("Exception while parsing "+fileName, e);
+ }
+ }
+ }
+
+ private void testSampleFile(String fileName) {
+ Reader reader = new InputStreamReader(
+ JsonSamplesParsingTest.class.getResourceAsStream("/"+fileName), StandardCharsets.UTF_8);
+ JsonParser parser = null;
+ try {
+ parser = Json.createParser(reader);
+ while(parser.hasNext()) {
+ parser.next();
+ }
+ } finally {
+ if (parser != null) {
+ parser.close();
+ }
+ }
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonStringTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonStringTest.java
new file mode 100644
index 0000000..1f63c2a
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonStringTest.java
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import java.io.StringReader;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonStringTest extends TestCase {
+ public JsonStringTest(String testName) {
+ super(testName);
+ }
+
+ // tests JsonString#toString()
+ public void testToString() throws Exception {
+ escapedString("");
+ escapedString("abc");
+ escapedString("abc\f");
+ escapedString("abc\na");
+ escapedString("abc\tabc");
+ escapedString("abc\n\tabc");
+ escapedString("abc\n\tabc\r");
+ escapedString("\n\tabc\r");
+ escapedString("\bab\tb\rc\\\"\ftesting1234");
+ escapedString("\f\babcdef\tb\rc\\\"\ftesting1234");
+ escapedString("\u0000\u00ff");
+ escapedString("abc\"\\/abc");
+ }
+
+ void escapedString(String str) throws Exception {
+ JsonArray exp = Json.createArrayBuilder().add(str).build();
+ String parseStr = "["+exp.get(0).toString()+"]";
+ JsonReader jr = Json.createReader(new StringReader(parseStr));
+ JsonArray got = jr.readArray();
+ assertEquals(exp, got);
+ jr.close();
+ }
+
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java
new file mode 100644
index 0000000..0923eef
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java
@@ -0,0 +1,193 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import javax.json.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonWriterTest extends TestCase {
+ public JsonWriterTest(String testName) {
+ super(testName);
+ }
+
+ public void testObject() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonWriter jsonWriter = Json.createWriter(writer);
+ jsonWriter.writeObject(Json.createObjectBuilder().build());
+ jsonWriter.close();
+ writer.close();
+
+ assertEquals("{}", writer.toString());
+ }
+
+ public void testArray() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonWriter jsonWriter = Json.createWriter(writer);
+ jsonWriter.writeArray(Json.createArrayBuilder().build());
+ jsonWriter.close();
+ writer.close();
+
+ assertEquals("[]", writer.toString());
+ }
+
+ public void testNumber() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonWriter jsonWriter = Json.createWriter(writer);
+ jsonWriter.writeArray(Json.createArrayBuilder().add(10).build());
+ jsonWriter.close();
+ writer.close();
+
+ assertEquals("[10]", writer.toString());
+ }
+
+ public void testDoubleNumber() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonWriter jsonWriter = Json.createWriter(writer);
+ jsonWriter.writeArray(Json.createArrayBuilder().add(10.5).build());
+ jsonWriter.close();
+ writer.close();
+
+ assertEquals("[10.5]", writer.toString());
+ }
+
+ public void testArrayString() throws Exception {
+ StringWriter writer = new StringWriter();
+ JsonWriter jsonWriter = Json.createWriter(writer);
+ jsonWriter.writeArray(Json.createArrayBuilder().add("string").build());
+ jsonWriter.close();
+ writer.close();
+
+ assertEquals("[\"string\"]", writer.toString());
+ }
+
+ public void testIllegalStateExcepton() throws Exception {
+ JsonObject obj = Json.createObjectBuilder().build();
+ JsonArray array = Json.createArrayBuilder().build();
+
+ JsonWriter writer = Json.createWriter(new StringWriter());
+ writer.writeObject(obj);
+ try {
+ writer.writeObject(obj);
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ writer.close();
+
+ writer = Json.createWriter(new StringWriter());
+ writer.writeArray(array);
+ try {
+ writer.writeArray(array);
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ writer.close();
+
+ writer = Json.createWriter(new StringWriter());
+ writer.write(array);
+ try {
+ writer.writeArray(array);
+ } catch (IllegalStateException expected) {
+ // no-op
+ }
+ writer.close();
+ }
+
+ public void testNoCloseWriteObjectToStream() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JsonWriter writer = Json.createWriter(baos);
+ writer.write(Json.createObjectBuilder().build());
+ // not calling writer.close() intentionally
+ assertEquals("{}", baos.toString("UTF-8"));
+ }
+
+ public void testNoCloseWriteObjectToWriter() throws Exception {
+ StringWriter sw = new StringWriter();
+ JsonWriter writer = Json.createWriter(sw);
+ writer.write(Json.createObjectBuilder().build());
+ // not calling writer.close() intentionally
+ assertEquals("{}", sw.toString());
+ }
+
+ public void testNoCloseWriteArrayToStream() throws Exception {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JsonWriter writer = Json.createWriter(baos);
+ writer.write(Json.createArrayBuilder().build());
+ // not calling writer.close() intentionally
+ assertEquals("[]", baos.toString("UTF-8"));
+ }
+
+ public void testNoCloseWriteArrayToWriter() throws Exception {
+ StringWriter sw = new StringWriter();
+ JsonWriter writer = Json.createWriter(sw);
+ writer.write(Json.createArrayBuilder().build());
+ // not calling writer.close() intentionally
+ assertEquals("[]", sw.toString());
+ }
+
+ public void testClose() throws Exception {
+ MyByteStream baos = new MyByteStream();
+ JsonWriter writer = Json.createWriter(baos);
+ writer.write(Json.createObjectBuilder().build());
+ writer.close();
+ assertEquals("{}", baos.toString("UTF-8"));
+ assertTrue(baos.isClosed());
+ }
+
+ private static final class MyByteStream extends ByteArrayOutputStream {
+ boolean closed;
+
+ boolean isClosed() {
+ return closed;
+ }
+
+ public void close() throws IOException {
+ super.close();
+ closed = true;
+ }
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/RFC7159Test.java b/tests/src/test/java/org/glassfish/json/tests/RFC7159Test.java
new file mode 100644
index 0000000..73404fd
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/RFC7159Test.java
@@ -0,0 +1,126 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import org.junit.Test;
+import org.junit.BeforeClass;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import java.io.StringWriter;
+import java.io.StringReader;
+
+/**
+ * @author Kin-man Chung
+ */
+public class RFC7159Test {
+
+ @Test
+ public void testCreatValues() {
+ JsonArrayBuilder builder = Json.createArrayBuilder();
+ JsonArray array = builder.add(Json.createValue("someString"))
+ .add(Json.createValue(100))
+ .add(Json.createValue(12345.6789))
+ .build();
+ builder = Json.createArrayBuilder();
+ JsonArray expected = builder.add("someString")
+ .add(100)
+ .add(12345.6789)
+ .build();
+ assertEquals(expected, array);
+ }
+
+ @Test
+ public void testReadValues() {
+ JsonReader reader = Json.createReader(new StringReader("\"someString\""));
+ JsonArrayBuilder builder = Json.createArrayBuilder();
+ builder.add(reader.readValue());
+ reader = Json.createReader(new StringReader("100"));
+ builder.add(reader.readValue());
+ reader = Json.createReader(new StringReader("12345.6789"));
+ builder.add(reader.readValue());
+ JsonArray array = builder.build();
+ builder = Json.createArrayBuilder();
+ JsonArray expected = builder.add("someString")
+ .add(100)
+ .add(12345.6789)
+ .build();
+ assertEquals(expected, array);
+ }
+
+ @Test
+ public void testWriteValues() {
+ StringWriter stringWriter = new StringWriter();
+ JsonWriter writer = Json.createWriter(stringWriter);
+ writer.write(Json.createValue("someString"));
+ assertEquals("\"someString\"", stringWriter.toString());
+
+ stringWriter = new StringWriter();
+ writer = Json.createWriter(stringWriter);
+ writer.write(Json.createValue(100));
+ assertEquals("100", stringWriter.toString());
+
+ stringWriter = new StringWriter();
+ writer = Json.createWriter(stringWriter);
+ writer.write(Json.createValue(12345.6789));
+ assertEquals("12345.6789", stringWriter.toString());
+ }
+
+ @Test
+ public void testGeneratorValues() {
+ StringWriter stringWriter = new StringWriter();
+ JsonGenerator generator = Json.createGenerator(stringWriter);
+ generator.write("someString").close();
+ assertEquals("\"someString\"", stringWriter.toString());
+
+ stringWriter = new StringWriter();
+ generator = Json.createGenerator(stringWriter);
+ generator.write(100).close();
+ assertEquals("100", stringWriter.toString());
+
+ stringWriter = new StringWriter();
+ generator = Json.createGenerator(stringWriter);
+ generator.write(12345.6789).close();
+ assertEquals("12345.6789", stringWriter.toString());
+ }
+}
diff --git a/tests/src/test/java/org/glassfish/json/tests/ToJsonTest.java b/tests/src/test/java/org/glassfish/json/tests/ToJsonTest.java
new file mode 100644
index 0000000..417fb5e
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/ToJsonTest.java
@@ -0,0 +1,82 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import org.junit.Test;
+import org.junit.BeforeClass;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import javax.json.*;
+
+/**
+ * @author Kin-man Chung
+ */
+public class ToJsonTest {
+
+ @Test
+ public void testToJson() {
+ assertEquals(Json.createValue("someString"), JsonUtil.toJson("'someString'"));
+ assertEquals(Json.createValue("some'thing"), JsonUtil.toJson("'some\\'thing'"));
+ assertEquals(Json.createValue("some\"thing"), JsonUtil.toJson("'some\\\"thing'"));
+ JsonArrayBuilder builder = Json.createArrayBuilder();
+ JsonArray array = builder
+ .add(Json.createObjectBuilder()
+ .add("name", "John")
+ .add("age", 35)
+ .add("educations", Json.createArrayBuilder()
+ .add("Gunn High")
+ .add("UC Berkeley")))
+ .add(Json.createObjectBuilder()
+ .add("name", "Jane")
+ .add("educations", Json.createArrayBuilder()
+ .add("Oxford")))
+ .build();
+ JsonValue expected = JsonUtil.toJson(
+ "[ { 'name': 'John', " +
+ "'age': 35, " +
+ "'educations': ['Gunn High', 'UC Berkeley'] }, " +
+ " { 'name': 'Jane', " +
+ "'educations': ['Oxford']}]");
+ assertEquals(expected, array);
+ }
+}
+
diff --git a/tests/src/test/java/org/glassfish/json/tests/TwitterSearchTest.java b/tests/src/test/java/org/glassfish/json/tests/TwitterSearchTest.java
new file mode 100644
index 0000000..0bb28d9
--- /dev/null
+++ b/tests/src/test/java/org/glassfish/json/tests/TwitterSearchTest.java
@@ -0,0 +1,99 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.tests;
+
+import junit.framework.TestCase;
+
+import javax.json.*;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParser.Event;
+import java.io.*;
+import java.net.URL;
+
+/**
+ * JsonParser Tests using twitter search API
+ *
+ * @author Jitendra Kotamraju
+ */
+public class TwitterSearchTest extends TestCase {
+
+ public void test() {
+ // dummy test so that junit doesn't complain
+ }
+
+ public void xtestStreamTwitter() throws Exception {
+ URL url = new URL("http://search.twitter.com/search.json?q=%23java&rpp=100");
+ InputStream is = url.openStream();
+ JsonParser parser = Json.createParser(is);
+
+ while(parser.hasNext()) {
+ Event e = parser.next();
+ if (e == Event.KEY_NAME) {
+ if (parser.getString().equals("from_user")) {
+ parser.next();
+ System.out.print(parser.getString());
+ System.out.print(": ");
+ } else if (parser.getString().equals("text")) {
+ parser.next();
+ System.out.println(parser.getString());
+ System.out.println("---------");
+ }
+ }
+ }
+ parser.close();
+ }
+
+ public void xtestObjectTwitter() throws Exception {
+ URL url = new URL("http://search.twitter.com/search.json?q=%23java&rpp=100");
+ InputStream is = url.openStream();
+ JsonReader rdr = Json.createReader(is);
+ JsonObject obj = rdr.readObject();
+ JsonArray results = obj.getJsonArray("results");
+ for(JsonObject result : results.getValuesAs(JsonObject.class)) {
+ System.out.print(result.get("from_user"));
+ System.out.print(": ");
+ System.out.println(result.get("text"));
+ System.out.println("-----------");
+ }
+ rdr.close();
+ }
+
+}
diff --git a/tests/src/test/resources/facebook.json b/tests/src/test/resources/facebook.json
new file mode 100644
index 0000000..de667eb
--- /dev/null
+++ b/tests/src/test/resources/facebook.json
@@ -0,0 +1,668 @@
+{
+ "data": [
+ {
+ "id": "540450616_10151581659930617",
+ "from": {
+ "name": "Ankit Mehta",
+ "id": "540450616"
+ },
+ "message": "Times flies so fast as Tomorrow will be completing one week in India and still missing uk and my home 5 egret house and friends like andria, chital, Charmi, Kushal, and munjal. Hope to see you guys soon in india. But on the other side happy to be back with my mom dad and sis and my sweet home after very long long time.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for iPhone",
+ "namespace": "fbiphone",
+ "id": "6628568379"
+ },
+ "created_time": "2013-07-26T22:33:09+0000",
+ "updated_time": "2013-07-26T22:33:09+0000"
+ },
+ {
+ "id": "143528829157622_184268238417014",
+ "from": {
+ "category": "Author",
+ "name": "Kabi Kisi Ko Mukamal Janha Nahi Milta",
+ "id": "143528829157622"
+ },
+ "message": "Top 10 Masajid Of\nd World With Capacity\nof Namaziis\n...\n1. KHANA-e-KABA\n(MASJID ALHARAM)\n13,50,000\n2. MASJID-E-NABVI\n7,98,000\n3. MASJID AL MAKKAH\nKualalumpur , Malaysia\n5,38,000\n4. MASJID AL\nSIDDQUE-e-AKBAR\nParis , France\n4,95,000\n5. JAMIA UMER\nFAROOQ\nWashington , USA\n4,50,000\n6. ISLAMIC RESEARCH\nCENTRE,\nWorkshire, Uk\n4,30,000\n7. HISTORIC MOSQUE\nNew Delhi India\n4,00,000\n8. SHAH FAHAD MASJID\nRiyadh, Saudia Arabia\n3,70,000\n9. SHAH FAISAL M [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/143528829157622/posts/184268238417014"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:33:03+0000",
+ "updated_time": "2013-07-26T22:33:03+0000"
+ },
+ {
+ "id": "540006262732189_558758910856924",
+ "from": {
+ "category": "Community",
+ "name": "BLUE Team",
+ "id": "540006262732189"
+ },
+ "message": "India-Zimbabwe 4th ODI postponed due to elections\n\nThe fourth one-day international of the ongoing series between India and Zimbabwe has been postponed by a day due to general elections in the African country.\nThe match will now be played at the Queens Sports Club, Bulawayo, on August 1 instead ofthe original date of July 31.\n\"The fourth ODI of the ongoing series between India and Zimbabwe has been postponed by a day on account of Elections in Zimbabwe,\" a BCCI [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/540006262732189/posts/558758910856924"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:33:00+0000",
+ "updated_time": "2013-07-26T22:33:00+0000"
+ },
+ {
+ "id": "485447954806489_625747810776502",
+ "from": {
+ "category": "Bank/financial institution",
+ "name": "Payday loan business owners collection advice",
+ "id": "485447954806489"
+ },
+ "message": "about viagra super active http://about.viagra.super.active.medoonll4.appspot.com/#about-viagra-super-active\nviagra covered insurance http://viagra.covered.insurance.medoonll4.appspot.com/#viagra-covered-insurance\nhalf a viagra pill http://half.a.viagra.pill.medoonll4.appspot.com/#half-a-viagra-pill\ncanada buy cialis soft http://canada.buy.cialis.soft.medoonll4.appspot.com/#canada-buy-cialis-soft\nimpotence treatments vitamins http://impotence.treatments.vitamins.m [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/485447954806489/posts/625747810776502"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Seesmic",
+ "id": "23723376453"
+ },
+ "created_time": "2013-07-26T22:32:58+0000",
+ "updated_time": "2013-07-26T22:32:58+0000"
+ },
+ {
+ "id": "682077629_10151750832397630",
+ "from": {
+ "name": "Angela Aline Black",
+ "id": "682077629"
+ },
+ "message": "20. The economic success of the Mughals in India was dependent upon \n\n \n \nA. the success of external markets. \nB. low levels of taxation. \nC. success of exporters. \nD. economic success of subjects under their rule",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:32:55+0000",
+ "updated_time": "2013-07-26T22:32:55+0000"
+ },
+ {
+ "id": "100002907425513_442348052538772",
+ "from": {
+ "name": "Sanjay Suneja Insan",
+ "id": "100002907425513"
+ },
+ "message": "dhan-dhan \"SATGURU\" tera hi aasra, Menu bhule na serjan hara bhul jawe sari duniya , sari duniya sari duniya ,.. Ghar kam bhul k paap c karda kaal di vagar dho k khap khap marda , kaal desh vich kuchh nahi hamara k bhul jave sari dunia ... ( shabad . vinti bhajan, dera sacha sauda, sirsa, haryana, india )",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:32:46+0000",
+ "updated_time": "2013-07-26T22:32:46+0000"
+ },
+ {
+ "id": "571804039505307_634527159899661",
+ "from": {
+ "category": "Community",
+ "name": "\u0e2a\u0e32\u0e27\u0e19\u0e49\u0e2d\u0e22\u0e15\u0e01\u0e19\u0e49\u0e33",
+ "id": "571804039505307"
+ },
+ "message": "drive without auto insurance http://how.much.auto.insurance.do.i.need.2013.insurancecheapautocar.appspot.com is auto insurance tax deductible http://how.much.auto.insurance.do.i.need.in.new.york.insurancecheapautocar.appspot.com auto insurance in bradenton http://how.much.auto.insurance.deductible.insurancecheapautocar.appspot.com whats the cheapest car insurance in kentucky http://how.much.auto.insurance.coverage.is.enough.insurancecheapautocar.appspot.com edmonton [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/571804039505307/posts/634527159899661"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "DoubleQ",
+ "namespace": "doubleqapp",
+ "id": "417924791618438"
+ },
+ "created_time": "2013-07-26T22:32:41+0000",
+ "updated_time": "2013-07-26T22:32:41+0000"
+ },
+ {
+ "id": "100002550173862_479466595481675",
+ "from": {
+ "name": "Duygu K\u00f6sem",
+ "id": "100002550173862"
+ },
+ "message": "Bug\u00fcn g\u00fclden ben hatice merve kubra gubnesliparkta rezil olduk hep bu kubranin so\u011fuk espirileri y\u00fcz\u00fcnden :( ;( ;( donerken bide o yetmedi india yi s\u00f6yleye s\u00f6yleye geldik sonra bi \u00e7ocuk bana laf att\u0131 bende ba\u011f\u0131rd\u0131m g\u00fclden benim taklidimi yapt\u0131 g\u00fclmekten yarildim merveyle kubra baska alemlerdeydi yani bug\u00fcn g\u00fczelde olsa i\u011fren\u00e7 bi g\u00fcnd\u00fc",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:32:36+0000",
+ "updated_time": "2013-07-26T22:32:36+0000"
+ },
+ {
+ "id": "318123048285301_448973998533538",
+ "from": {
+ "category": "Bank/financial institution",
+ "name": "Usa realty and loans san diego ca",
+ "id": "318123048285301"
+ },
+ "message": "tadalafil cialis from india http://tadalafil.cialis.from.india.medoonll4.appspot.com/#tadalafil-cialis-from-india\npropecia online pharmacy http://propecia.online.pharmacy.medoonll4.appspot.com/#propecia-online-pharmacy\nviagra 0.74 http://viagra.0.74.medoonll4.appspot.com/#viagra-0.74\nfree viagra on nhs http://free.viagra.on.nhs.medoonll4.appspot.com/#free-viagra-on-nhs\nviagra spicy foods http://viagra.spicy.foods.medoonll4.appspot.com/#viagra-spicy-foods\ngetting [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/318123048285301/posts/448973998533538"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Status Shuffle",
+ "namespace": "status-shuffle",
+ "id": "8109791468"
+ },
+ "created_time": "2013-07-26T22:32:30+0000",
+ "updated_time": "2013-07-26T22:32:30+0000"
+ },
+ {
+ "id": "100001499151848_548923935167573",
+ "from": {
+ "name": "Piyush Tiwari",
+ "id": "100001499151848"
+ },
+ "message": "MP High-Court District Legal Aid Officer posts July-2013\nPosted: 26 Jul 2013 09:04 AM PDT\nPublished for http://www.SarkariNaukriBlog.com \nHigh Court of Madhya Pradesh, Jabalpur\n\nRecruitment of District Legal Aid Officer \n\nOnline Applications are invited at MPOnline Portal from Indian Citizens for posts in Madhya Pradesh State Legal Service Authority through the Online preliminary exam - on 15/09/2013 and final exam on 27/10/2013 :\nDistrict Legal Aid Office [...]
+ "picture": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQAntDPz9j06aZeb&w=154&h=154&url=http\u00253A\u00252F\u00252Fbuttons.blogger.com\u00252Fbloggerbutton1.gif",
+ "link": "http://www.sarkarinaukriblog.com/",
+ "name": "\u0938\u0930\u0915\u093e\u0930\u0940 \u0928\u094c\u0915\u0930\u0940 - Government Jobs India - Sarkari Naukri -- www.SarkariNaukriBlog.com",
+ "caption": "www.sarkarinaukriblog.com",
+ "description": "www.SarkariNaukriBlog.com - Website about all Sarkari and Government Jobs in Central/State Government, Universities, Public Sector Companies and Banks, jobs, vacancy, opportunity, Government, Government of India, Recruitment, State Government, Central Government, India",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "link",
+ "created_time": "2013-07-26T22:32:14+0000",
+ "updated_time": "2013-07-26T22:32:14+0000"
+ },
+ {
+ "id": "679382908744276_698464940169406",
+ "from": {
+ "category": "Community",
+ "name": "Tinnitustreatmentreviews",
+ "id": "679382908744276"
+ },
+ "message": "Top 10 Dating Site India http://bit.ly/1bWKegR",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/679382908744276/posts/698464940169406"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "twitterfeed",
+ "id": "131732509879"
+ },
+ "created_time": "2013-07-26T22:32:13+0000",
+ "updated_time": "2013-07-26T22:32:13+0000"
+ },
+ {
+ "id": "563417097011729_597056126981159",
+ "from": {
+ "category": "Entertainer",
+ "name": "Jiya Na Jaye Tum Bin,",
+ "id": "563417097011729"
+ },
+ "message": "Jai ho india mata\n\nbatao ye kiska nara hai jo ki fb me fast time lagaya tha.",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/563417097011729/posts/597056126981159"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:32:10+0000",
+ "updated_time": "2013-07-26T22:32:10+0000"
+ },
+ {
+ "id": "425879394186297_441042339336669",
+ "from": {
+ "category": "Health/beauty",
+ "name": "Tinnitus Treatment",
+ "id": "425879394186297"
+ },
+ "message": "Top 10 Dating Site India http://bit.ly/1bWKegR",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/425879394186297/posts/441042339336669"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "twitterfeed",
+ "id": "131732509879"
+ },
+ "created_time": "2013-07-26T22:32:07+0000",
+ "updated_time": "2013-07-26T22:32:07+0000"
+ },
+ {
+ "id": "100004032192846_293648487446222",
+ "from": {
+ "name": "Kumar Chettri",
+ "id": "100004032192846"
+ },
+ "message": "India vs Zim Ind . 294 runs ind win by 58 run S Dhawan 116 man of the match total matcha 5 ind win 2 matcha cantaune",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:31:53+0000",
+ "updated_time": "2013-07-26T22:31:53+0000"
+ },
+ {
+ "id": "197080493647669_611425628879818",
+ "from": {
+ "category": "Community",
+ "name": "Live Cricket Scores - Indian Cricket Team",
+ "id": "197080493647669"
+ },
+ "message": "India-Zimbabwe 4th ODI postponed due to elections\n\nThe fourth one-day international of the ongoing series between India and Zimbabwe has been postponed by a day due to general elections in the African country.\nThe match will now be played at the Queens Sports Club, Bulawayo, on August 1 instead ofthe original date of July 31.\n\"The fourth ODI of the ongoing series between India and Zimbabwe has been postponed by a day on account of Elections in Zimbabwe,\" a BCCI [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/197080493647669/posts/611425628879818"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:31:40+0000",
+ "updated_time": "2013-07-26T22:31:40+0000"
+ },
+ {
+ "id": "100003164088972_418256498289816",
+ "from": {
+ "name": "Nandkumar Sonawane",
+ "id": "100003164088972"
+ },
+ "message": "near SH-30, Jawhar, India http://her.is/UTmqa",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Nokia",
+ "id": "27694818115"
+ },
+ "created_time": "2013-07-26T22:31:39+0000",
+ "updated_time": "2013-07-26T22:31:39+0000"
+ },
+ {
+ "id": "690368524_10151553117193525",
+ "from": {
+ "name": "Louise Kempson",
+ "id": "690368524"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Adrian Murphy",
+ "id": "503204091"
+ }
+ ]
+ },
+ "with_tags": {
+ "data": [
+ {
+ "name": "Adrian Murphy",
+ "id": "503204091"
+ }
+ ]
+ },
+ "message": "Geography lesson!! Sri Lanka isn't in India?! Who knew!!!",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for iPhone",
+ "namespace": "fbiphone",
+ "id": "6628568379"
+ },
+ "created_time": "2013-07-26T22:31:38+0000",
+ "updated_time": "2013-07-26T22:31:38+0000"
+ },
+ {
+ "id": "442583219125645_577412425642723",
+ "from": {
+ "category": "Bank/financial institution",
+ "name": "Payday cookie recipe",
+ "id": "442583219125645"
+ },
+ "message": "viagra australia legality http://viagra.australia.legality.medoonll4.appspot.com/#viagra-australia-legality\npristiq and viagra http://pristiq.and.viagra.medoonll4.appspot.com/#pristiq-and-viagra\nhigh blood pressure and cialis http://high.blood.pressure.and.cialis.medoonll4.appspot.com/#high-blood-pressure-and-cialis\ngeneric viagra fast shipping http://generic.viagra.fast.shipping.medoonll4.appspot.com/#generic-viagra-fast-shipping\nnatural where to buy viagra http [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/442583219125645/posts/577412425642723"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Status Shuffle",
+ "namespace": "status-shuffle",
+ "id": "8109791468"
+ },
+ "created_time": "2013-07-26T22:31:37+0000",
+ "updated_time": "2013-07-26T22:31:37+0000"
+ },
+ {
+ "id": "197080493647669_611425615546486",
+ "from": {
+ "category": "Community",
+ "name": "Live Cricket Scores - Indian Cricket Team",
+ "id": "197080493647669"
+ },
+ "message": "The fourth one-day international of the ongoing series between India and Zimbabwe has been postponed by a day due to general elections in the African country.\nThe match will now be played at the Queens Sports Club, Bulawayo, on August 1 instead ofthe original date of July 31.\n\"The fourth ODI of the ongoing series between India and Zimbabwe has been postponed by a day on account of Elections in Zimbabwe,\" a BCCI release said.\nIndia lead the series 1-0 after defea [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/197080493647669/posts/611425615546486"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:31:36+0000",
+ "updated_time": "2013-07-26T22:31:36+0000"
+ },
+ {
+ "id": "100002173676538_496486443767140",
+ "from": {
+ "name": "Mely T\u00fa Mu\u00f1eca Kaulitz",
+ "id": "100002173676538"
+ },
+ "message": "SAB\u00cdAS QUE...\n\nUn hombre se casa con 60 mujeres para venderlas como esposas. Esto en India.\n\nOhmaigash D:",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:31:36+0000",
+ "updated_time": "2013-07-26T22:31:36+0000"
+ },
+ {
+ "id": "398559080202364_590956980962572",
+ "from": {
+ "category": "Website",
+ "name": "Dinamani Newspaper Advertising Rate Card",
+ "id": "398559080202364"
+ },
+ "message": "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd 30-\u0bb2\u0bcd \u0b9c\u0bbf\u0b9a\u0bbe\u0b9f\u0bcd-7 \u0b9a\u0bc6\u0baf\u0bb1\u0bcd\u0b95\u0bc8\u0b95\u0bcd\u0b95\u0bcb\u0bb3\u0bcd \u0b8f\u0bb5\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0bae\u0bcd: \u0b9c\u0bbf\u0b9a\u0bbe\u0b9f\u0bcd-7 \u0ba4\u0b95\u0bb5\u0bb2\u0bcd \u0ba4\u0bca\u0b9f\u0bb0\u0bcd\u0baa\u0bc1 \u0b9a\u0bc6\u0baf\u0bb1\u0bcd\u0b95\u0bc8\u0b95\u0bcd\u0b95\u0bcb\u0bb3\u0bcd \u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd 30-\u0b86\u0bae [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/398559080202364/posts/590956980962572"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "dlvr.it",
+ "namespace": "dlvr_it",
+ "id": "232775914688"
+ },
+ "created_time": "2013-07-26T22:31:34+0000",
+ "updated_time": "2013-07-26T22:31:34+0000"
+ },
+ {
+ "id": "100000175145713_699273473421818",
+ "from": {
+ "name": "Hector Alejandro Maison",
+ "id": "100000175145713"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Gerardo Weiss",
+ "id": "1217744630"
+ },
+ {
+ "name": "Romina Vanesa Derkazarian",
+ "id": "100000607833589"
+ },
+ {
+ "name": "Silvia Vila",
+ "id": "100001156712376"
+ },
+ {
+ "name": "Karina Andrade",
+ "id": "100002349217549"
+ },
+ {
+ "name": "Rosana India Diaz",
+ "id": "1615243489"
+ },
+ {
+ "name": "Marisol Baudi",
+ "id": "1103426604"
+ },
+ {
+ "name": "Ezequiel G. Mazzaglia",
+ "id": "1125217966"
+ },
+ {
+ "name": "Sol Canabal",
+ "id": "537758845"
+ }
+ ]
+ },
+ "message": "El wpp para pc! http://tinyurl.com/luct4pf \n \n \nGerardo Weiss Romina Vanesa Derkazarian Silvia Vila Karina Andrade Rosana India Diaz Marisol Baudi Ezequiel G. Mazzaglia Sol Canabal",
+ "message_tags": {
+ "50": [
+ {
+ "id": "1217744630",
+ "name": "Gerardo Weiss",
+ "type": "user",
+ "offset": 50,
+ "length": 13
+ }
+ ],
+ "64": [
+ {
+ "id": "100000607833589",
+ "name": "Romina Vanesa Derkazarian",
+ "type": "user",
+ "offset": 64,
+ "length": 25
+ }
+ ],
+ "90": [
+ {
+ "id": "100001156712376",
+ "name": "Silvia Vila",
+ "type": "user",
+ "offset": 90,
+ "length": 11
+ }
+ ],
+ "102": [
+ {
+ "id": "100002349217549",
+ "name": "Karina Andrade",
+ "type": "user",
+ "offset": 102,
+ "length": 14
+ }
+ ],
+ "117": [
+ {
+ "id": "1615243489",
+ "name": "Rosana India Diaz",
+ "type": "user",
+ "offset": 117,
+ "length": 17
+ }
+ ],
+ "135": [
+ {
+ "id": "1103426604",
+ "name": "Marisol Baudi",
+ "type": "user",
+ "offset": 135,
+ "length": 13
+ }
+ ],
+ "149": [
+ {
+ "id": "1125217966",
+ "name": "Ezequiel G. Mazzaglia",
+ "type": "user",
+ "offset": 149,
+ "length": 21
+ }
+ ],
+ "171": [
+ {
+ "id": "537758845",
+ "name": "Sol Canabal",
+ "type": "user",
+ "offset": 171,
+ "length": 11
+ }
+ ]
+ },
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:31:33+0000",
+ "updated_time": "2013-07-26T22:31:33+0000"
+ },
+ {
+ "id": "100000899336674_609156702457635",
+ "from": {
+ "name": "Quanaxhuato Guanajuato Capital",
+ "id": "100000899336674"
+ },
+ "message": "Casa Museo Gene Byron presenta a Sarodya D\u00fao, m\u00fasica cl\u00e1sica del norte de la India con Juan Casta\u00f1on (Sarod), Alvaro Rubio (Tabla) este s\u00e1bado 27 de julio. Fecha: S\u00e1bado 27 de julio de 2013 Lugar: Museo Casa Gene Byron Calle Real de Marfil s/n \u2026",
+ "picture": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQC4Q2z5tnxaTZXI&w=154&h=154&url=http\u00253A\u00252F\u00252Fwww.quanaxhuato.com\u00252Fwp-content\u00252Fuploads\u00252F2013\u00252F07\u00252Fsoradya-duo.jpg",
+ "link": "http://feedproxy.google.com/~r/quanaxhuato/~3/5vzY1BI52Jw/",
+ "name": "Sarodya D\u00fao en Casa Museo Gene Byron",
+ "caption": " ",
+ "description": " ",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "link",
+ "application": {
+ "name": "RSS Graffiti",
+ "namespace": "rssgraffiti",
+ "id": "45439413586"
+ },
+ "created_time": "2013-07-26T22:31:29+0000",
+ "updated_time": "2013-07-26T22:31:29+0000"
+ },
+ {
+ "id": "100003619053341_337301659733800",
+ "from": {
+ "name": "Shahidul Islam",
+ "id": "100003619053341"
+ },
+ "message": "goooooood morng india.............................................................................................................................",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:31:29+0000",
+ "updated_time": "2013-07-26T22:31:29+0000"
+ },
+ {
+ "id": "1128196456_10201384414708835",
+ "from": {
+ "name": "Don Dean",
+ "id": "1128196456"
+ },
+ "message": "So I just got a call from 23-456-7890. LOL. Really? I am not that stupid. \n\nI looked it up on the net and it appears to be some jerks from India masking their number.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:31:22+0000",
+ "updated_time": "2013-07-26T22:31:22+0000"
+ }
+ ],
+ "paging": {
+ "previous": "https://graph.facebook.com/search?q=india&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&since=1374877989&__previous=1",
+ "next": "https://graph.facebook.com/search?q=india&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&until=1374877881"
+ }
+}
\ No newline at end of file
diff --git a/tests/src/test/resources/facebook1.json b/tests/src/test/resources/facebook1.json
new file mode 100644
index 0000000..2979cbb
--- /dev/null
+++ b/tests/src/test/resources/facebook1.json
@@ -0,0 +1,911 @@
+{
+ "data": [
+ {
+ "id": "122422087906853_227097804105947",
+ "from": {
+ "category": "Bank/financial institution",
+ "name": "Aig loan fast",
+ "id": "122422087906853"
+ },
+ "message": "fda approved viagra generic http://fda.approved.viagra.generic.medoonll4.appspot.com/#fda-approved-viagra-generic\nviagra effects on heart http://viagra.effects.on.heart.medoonll4.appspot.com/#viagra-effects-on-heart\nviagra pediatric patients http://viagra.pediatric.patients.medoonll4.appspot.com/#viagra-pediatric-patients\nviagra to last longer http://viagra.to.last.longer.medoonll4.appspot.com/#viagra-to-last-longer\ncialis maximum dosage http://cialis.maximum.dos [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/122422087906853/posts/227097804105947"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Seesmic",
+ "id": "23723376453"
+ },
+ "created_time": "2013-07-26T22:45:54+0000",
+ "updated_time": "2013-07-26T22:45:54+0000"
+ },
+ {
+ "id": "1666380100_4883502259849",
+ "from": {
+ "name": "Nigel Alexander Hector Cox",
+ "id": "1666380100"
+ },
+ "message": "Oh the world is silly. I'm \"writing\" this on a machine I know had a direct hand in the shithole-growth on what we call Africa, and most likely caused the handlessness of a few small children in China, and one politician quietly murdered for some grant for some factory.\n\nFood for thought.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:52+0000",
+ "updated_time": "2013-07-26T22:45:52+0000"
+ },
+ {
+ "id": "110599592396837_375832709206856",
+ "from": {
+ "category": "Outdoor gear/sporting goods",
+ "category_list": [
+ {
+ "id": "2231",
+ "name": "Outdoor Gear/Sporting Goods"
+ }
+ ],
+ "name": "TheSurvivalPlace.com",
+ "id": "110599592396837"
+ },
+ "message": "http://thesurvivalplaceblog.com/2013/07/22/strong-earthquake-kills-at-least-20-injures-291-in-china/",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/110599592396837/posts/375832709206856"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:51+0000",
+ "updated_time": "2013-07-26T22:45:51+0000"
+ },
+ {
+ "id": "100003106280210_432881790158693",
+ "from": {
+ "name": "Ana Tirado",
+ "id": "100003106280210"
+ },
+ "message": "Aqi biendo como la china le parrcha la bici a su ermano lolo todo aprende q bien t qiero mi ni\u00f1a",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:45:50+0000",
+ "updated_time": "2013-07-26T22:45:50+0000"
+ },
+ {
+ "id": "100003229064633_416569718460660",
+ "from": {
+ "name": "Knock Cozzolino",
+ "id": "100003229064633"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Diego Gimenez",
+ "id": "685962347"
+ },
+ {
+ "name": "Jorge Dario Arias",
+ "id": "100004471920716"
+ },
+ {
+ "name": "Mauro Javier Munoz",
+ "id": "100002279697654"
+ }
+ ]
+ },
+ "message": "EL EQUIPO DE MAURICIO MU\u00d1OZ EN CHINA, Diego Gimenez, Jorge Dario Arias y Mauro Javier Munoz",
+ "message_tags": {
+ "38": [
+ {
+ "id": "685962347",
+ "name": "Diego Gimenez",
+ "type": "user",
+ "offset": 38,
+ "length": 13
+ }
+ ],
+ "53": [
+ {
+ "id": "100004471920716",
+ "name": "Jorge Dario Arias",
+ "type": "user",
+ "offset": 53,
+ "length": 17
+ }
+ ],
+ "73": [
+ {
+ "id": "100002279697654",
+ "name": "Mauro Javier Munoz",
+ "type": "user",
+ "offset": 73,
+ "length": 18
+ }
+ ]
+ },
+ "story": "Knock Cozzolino shared Mauro Javier Munoz's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100003229064633",
+ "name": "Knock Cozzolino",
+ "offset": 0,
+ "length": 15,
+ "type": "user"
+ }
+ ],
+ "23": [
+ {
+ "id": "100002279697654",
+ "name": "Mauro Javier Munoz",
+ "offset": 23,
+ "length": 18,
+ "type": "user"
+ }
+ ]
+ },
+ "picture": "https://photos-b.xx.fbcdn.net/hphotos-frc3/1000522_486002284819090_2134343969_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=486002284819090&set=p.486002284819090&type=1",
+ "name": "Mauro Javier Munoz's Photos",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Mauro Javier Munoz",
+ "href": "https://www.facebook.com/mauro.j.munoz"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "486002284819090",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:45:45+0000",
+ "updated_time": "2013-07-26T22:45:45+0000"
+ },
+ {
+ "id": "122010004502691_551826251521062",
+ "from": {
+ "category": "Public figure",
+ "name": "Honduras........ acusa, accuses, klagt an!!!!",
+ "id": "122010004502691"
+ },
+ "message": "10 claves del caso Snowden\n\nKeymer \u00c1vila\n\n\u201cGuerra es Paz, Libertad es Esclavitud, Ignorancia es Fuerza\u201d\nGeorge Orwell, 1984.\n\nDesde hace m\u00e1s de un mes Snowden ha ocupado los primeros lugares de la agenda medi\u00e1tica global, generando debates que van desde la preocupaci\u00f3n por la vigilancia y el control orwelliano estadounidense sobre todos nosotros, pasando por la digna respuesta de los pa\u00edses que integran el ALBA y el MERCOSUR [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/122010004502691/posts/551826251521062"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:44+0000",
+ "updated_time": "2013-07-26T22:45:44+0000"
+ },
+ {
+ "id": "100004367196754_215172981971607",
+ "from": {
+ "name": "Kunkudj Prados Ecatepec",
+ "id": "100004367196754"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Ana Laura Lara Rubio",
+ "id": "1734864003"
+ }
+ ]
+ },
+ "message": "Tema deidcado a LA China DE Prados Sibonera de Coraza!",
+ "message_tags": {
+ "16": [
+ {
+ "id": "1734864003",
+ "name": "LA China DE Prados",
+ "type": "user",
+ "offset": 16,
+ "length": 18
+ }
+ ]
+ },
+ "picture": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQDYVhgFOAp_DAfD&w=130&h=130&url=http\u00253A\u00252F\u00252Fi1.ytimg.com\u00252Fvi\u00252FkAXSDN-7UoM\u00252Fhqdefault.jpg\u00253Ffeature\u00253Dog",
+ "link": "http://www.youtube.com/watch?v=kAXSDN-7UoM&feature=c4-overview&list=UUHmfBBElcAKW-dFWDcpKlKQ",
+ "source": "http://www.youtube.com/v/kAXSDN-7UoM?version=3&autohide=1&autoplay=1",
+ "name": "Angelica Maria - Cumbia Pe\u00f1onera - Sonido Siboney",
+ "description": "los Ritmos Mas contagiantes de la cabina",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yj/r/v2OnaTyTQZE.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "video",
+ "created_time": "2013-07-26T22:45:44+0000",
+ "updated_time": "2013-07-26T22:45:44+0000"
+ },
+ {
+ "id": "1540166294_10201686839482997",
+ "from": {
+ "name": "Paolita Cudris Pc",
+ "id": "1540166294"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Elvin Josue Carrillo Mor\u00f3n",
+ "id": "1507666078"
+ },
+ {
+ "name": "Jose Miguel",
+ "id": "613794554"
+ },
+ {
+ "name": "Erika Becerra",
+ "id": "823349493"
+ },
+ {
+ "name": "Yuyiiz ZTefannii Piiko",
+ "id": "100001601847641"
+ },
+ {
+ "name": "Maritza Paez Beltran",
+ "id": "632626664"
+ },
+ {
+ "name": "Little China",
+ "id": "100002591925985"
+ },
+ {
+ "name": "C Johan Morantes",
+ "id": "1132217007"
+ },
+ {
+ "name": "Shaddai Barbosa Riobo",
+ "id": "100000895847288"
+ }
+ ]
+ },
+ "message": "Cambia de color el face! lo puse aca! , [ http://tinyurl.com/naw3zjv ] \n \n \n Elvin Josue Carrillo Mor\u00f3n Jose Miguel Erika Becerra Yuyiiz ZTefannii Piiko Maritza Paez Beltran Little China C Johan Morantes Shaddai Barbosa Riobo",
+ "message_tags": {
+ "77": [
+ {
+ "id": "1507666078",
+ "name": "Elvin Josue Carrillo Mor\u00f3n",
+ "type": "user",
+ "offset": 77,
+ "length": 26
+ }
+ ],
+ "104": [
+ {
+ "id": "613794554",
+ "name": "Jose Miguel",
+ "type": "user",
+ "offset": 104,
+ "length": 11
+ }
+ ],
+ "116": [
+ {
+ "id": "823349493",
+ "name": "Erika Becerra",
+ "type": "user",
+ "offset": 116,
+ "length": 13
+ }
+ ],
+ "130": [
+ {
+ "id": "100001601847641",
+ "name": "Yuyiiz ZTefannii Piiko",
+ "type": "user",
+ "offset": 130,
+ "length": 22
+ }
+ ],
+ "153": [
+ {
+ "id": "632626664",
+ "name": "Maritza Paez Beltran",
+ "type": "user",
+ "offset": 153,
+ "length": 20
+ }
+ ],
+ "174": [
+ {
+ "id": "100002591925985",
+ "name": "Little China",
+ "type": "user",
+ "offset": 174,
+ "length": 12
+ }
+ ],
+ "187": [
+ {
+ "id": "1132217007",
+ "name": "C Johan Morantes",
+ "type": "user",
+ "offset": 187,
+ "length": 16
+ }
+ ],
+ "204": [
+ {
+ "id": "100000895847288",
+ "name": "Shaddai Barbosa Riobo",
+ "type": "user",
+ "offset": 204,
+ "length": 21
+ }
+ ]
+ },
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:41+0000",
+ "updated_time": "2013-07-26T22:45:41+0000"
+ },
+ {
+ "id": "100000665277344_615242961841207",
+ "from": {
+ "name": "Adam Bucks",
+ "id": "100000665277344"
+ },
+ "message": "Selling my Ddrum Defiant drum set. Asking 2500.00. Its a 7 peace metallic blue set with evens ec2 heads. Bass drum has Evans emad heads with kick port. The Drum pedals are pearl demon drive double bass pedals with slug beaters. HiHat is a signature series pasty 14 inch sitting on a Iron Cobra pedal. 8\" bell. 18\" Wuhan China crash brand new and a 22\" signature series pasty dark ride. The whole drum set sits on a Gilraltar are three 3 sided Rack. Serious inquires on [...]
+ "story": "Adam Bucks added 9 photos.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100000665277344",
+ "name": "Adam Bucks",
+ "offset": 0,
+ "length": 10,
+ "type": "user"
+ }
+ ]
+ },
+ "picture": "https://fbcdn-photos-b-a.akamaihd.net/hphotos-ak-ash4/1004890_615242605174576_1287468617_t.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=615242605174576&set=pcb.615242961841207&type=1&relevant_count=9",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yx/r/og8V99JVf8G.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "615242605174576",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:45:33+0000",
+ "updated_time": "2013-07-26T22:45:33+0000"
+ },
+ {
+ "id": "100002254483609_494575483960930",
+ "from": {
+ "name": "Paulo Roberto",
+ "id": "100002254483609"
+ },
+ "message": "Hey voc\u00ea! Isso voc\u00ea mesmo! \nEst\u00e1 desempregada? Suas contas est\u00e3o se acumulando e j\u00e1 n\u00e3o sabe mais o que fazer? \nSeus problemas acabaram! V\u00e1 trabalhar na China.............kkkkkkkkk................",
+ "story": "Paulo Roberto shared Rodarte Rodarte Vajalegre's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100002254483609",
+ "name": "Paulo Roberto",
+ "offset": 0,
+ "length": 13,
+ "type": "user"
+ }
+ ],
+ "21": [
+ {
+ "id": "1695923199",
+ "name": "Rodarte Rodarte Vajalegre",
+ "offset": 21,
+ "length": 25,
+ "type": "user"
+ }
+ ]
+ },
+ "picture": "https://photos-b.xx.fbcdn.net/hphotos-prn2/969179_3346674681104_1612467651_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=3346674681104&set=p.3346674681104&type=1",
+ "name": "Rodarte Rodarte Vajalegre's Photos",
+ "caption": "PRAS DESEMPREGADAS!!\r\nEsta foto \u00e9 real. \u00c9 de um banco de esperma na Rep\u00fablica Popular da China! E esta profiss\u00e3o, \"punheteira\", existe mesmo! N\u00e3o s\u00e3o enfermeiras, n\u00e3o s\u00e3o t\u00e9cnicas de sa\u00fade... chamam-se mesmo punheteiras! \u00e9 uma profiss\u00e3o reconhecida l\u00e1.\r\nCom o desemprego que por aqui h\u00e1... quem sabe se n\u00e3o poderia ser criada, tamb\u00e9m por c\u00e1, esta bonita carreira... punheteira...",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Rodarte Rodarte Vajalegre",
+ "href": "https://www.facebook.com/rvajalegre"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "3346674681104",
+ "application": {
+ "name": "Links",
+ "id": "2309869772"
+ },
+ "created_time": "2013-07-26T22:45:33+0000",
+ "updated_time": "2013-07-26T22:45:33+0000"
+ },
+ {
+ "id": "100003046176727_395443013900568",
+ "from": {
+ "name": "Erivan Bezerra Nogueira Sq\u00e9",
+ "id": "100003046176727"
+ },
+ "message": "Nem aqui,nem na china, nem nos quintos dos infernos o Feliciano se parece ou tem atitudes parecidas com o Papa Francisco. A diferen\u00e7a maior \u00e9 que o Papa \u00e9 POP e o Feliciano \u00e9 BOFE enrustido amargurado \u00e9 um Felix da vida.",
+ "story": "Erivan Bezerra Nogueira Sq\u00e9 shared VEJA's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100003046176727",
+ "name": "Erivan Bezerra Nogueira Sq\u00e9",
+ "offset": 0,
+ "length": 27,
+ "type": "user"
+ }
+ ],
+ "35": [
+ {
+ "id": "109597815616",
+ "name": "VEJA",
+ "offset": 35,
+ "length": 4,
+ "type": "page"
+ }
+ ]
+ },
+ "picture": "https://fbcdn-photos-a-a.akamaihd.net/hphotos-ak-prn1/1012031_10151581119795617_2038524269_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=10151581119795617&set=a.437129710616.201723.109597815616&type=1",
+ "name": "Timeline Photos",
+ "caption": "Via Radar On-line - Lauro Jardim\r\n\r\nFeliciano diz ter opini\u00f5es id\u00eanticas \u00e0s do papa, afirma sofrer discrimina\u00e7\u00e3o religiosa e dispara contra a Globo \r\n\r\nhttp://abr.ai/19myD9U",
+ "properties": [
+ {
+ "name": "By",
+ "text": "VEJA",
+ "href": "https://www.facebook.com/Veja?ref=stream"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "10151581119795617",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:45:31+0000",
+ "updated_time": "2013-07-26T22:45:31+0000"
+ },
+ {
+ "id": "1497407200_10201694734198935",
+ "from": {
+ "name": "Ce Bo",
+ "id": "1497407200"
+ },
+ "message": "Finally fight day! Feels like I have been here for an eternity. One more night in China, then the real fun and adventure begins.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for iPhone",
+ "namespace": "fbiphone",
+ "id": "6628568379"
+ },
+ "created_time": "2013-07-26T22:45:25+0000",
+ "updated_time": "2013-07-26T22:45:25+0000"
+ },
+ {
+ "id": "100003501063649_365536560239710",
+ "from": {
+ "name": "Arinanxspenza Ygcllalucintadamai",
+ "id": "100003501063649"
+ },
+ "message": "KISAH HUMOR\n\nCowo : sayang.. cintamu ke aku seperti apa sih?\n \n\nCewe : cintaku padamu bagaikan..\naku HP, dan kamu itu kartu nya :) jadi tanpa mu aku tidak ada arti nya sayang.\n\nCowo : so sweet..kmu memang plg bisa beb.\n\nCewe : (dlm hati) trima kasih ya allah dia ga tau klo hp CHINA biza dua kartu : D\nJdi masih biza tuk selingkuh...",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:45:20+0000",
+ "updated_time": "2013-07-26T22:45:20+0000"
+ },
+ {
+ "id": "100001365510268_529312920457554",
+ "from": {
+ "name": "Sai Naits",
+ "id": "100001365510268"
+ },
+ "message": "God made everything that has life, rest everything is made in China :)",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:18+0000",
+ "updated_time": "2013-07-26T22:45:18+0000"
+ },
+ {
+ "id": "524393002_10151606435213003",
+ "from": {
+ "name": "Brian Lee",
+ "id": "524393002"
+ },
+ "message": "Prepare for MALAYSIA TOUR SOON.\nPrepare for TAIWAN TOUR Aug \nPrepare for CHINA GZ TOUR Aug \nPrepare for THE FLIT NEW ALBUM PROMOTION.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:17+0000",
+ "updated_time": "2013-07-26T22:45:17+0000"
+ },
+ {
+ "id": "1023318038_10200667959914417",
+ "from": {
+ "name": "David J. Derrick",
+ "id": "1023318038"
+ },
+ "message": "THERMITE BERMITES!\n\n BITES HOES ASSES AND HAGS TOO THEE HAIG!\n\nSILVER STTEN GOES WITH ALL GOLD \n\nONE BUSHEB ZEMMERMAN!\n\nI MAN THE SUPER MAN ON THEE HIGH SEEG HIEL!\n \nTOO ALL HAIG JUDGES AND BUILD 7 BERMITE & COMPANY SKUNK WORKS DRONMES BUZZ BOMBS\n\nAND ALL JUDGMENTS TOO THE GREATFUL DEAD OF BLOODY UNIONS AND ALL STEWARDS !\n\nOF ALL BERMITES !!\n\n ! ON DIIS! DOCKET DOCUMENTED \n\nAND DOCTOR OF ROCK DOCTORS!\nE.L.P.!\n\n DEMENTOS ROARING ON T [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:16+0000",
+ "updated_time": "2013-07-26T22:45:16+0000"
+ },
+ {
+ "id": "100006366426692_1394277100794491",
+ "from": {
+ "name": "Sohaib Khan",
+ "id": "100006366426692"
+ },
+ "message": "Pappu China Ke Tour Pe Gayatha\nWaha Usne Ek X-ray Chashma Liya.\nChashma Lagane Se Har Koi Nanga Nazar\nAata Tha :P\nPappu Ghar Aaya To Wife Ko Apne Ek Dost\nKe Sath Apne Bed Pe Nanga Dekha,\nUsne Foran Chashme Ko Utara,\nPhir Bhi Dono Nange Nazar Aaye,\nPappu Gusse Se Chashma Fenkta Hua Bola:\nYe Hi Musibat Hai China Ke Saman Ki,\nKoi Guarranty Nahi Hoti,\nJaldi Kharab Ho Jati Hai\nHa Ha Ha , Thoko Like",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:45:15+0000",
+ "updated_time": "2013-07-26T22:45:15+0000"
+ },
+ {
+ "id": "100000560416322_667722833256391",
+ "from": {
+ "name": "Marta Georgina Vasquez",
+ "id": "100000560416322"
+ },
+ "message": "El Mundo y la Argentina\nVersi\u00f3n para imprimir Versi\u00f3n para imprimir\n\nDos noticias de extraordinaria envergadura conmovieron al mundo de los agronegocios. La primera, la venta de Smithfield Foods, la mayor empresa dedicada a la producci\u00f3n de cerdos en los Estados Unidos, a Suanghui International Holdings Ltd, la mayor distribuidora de alimentos de la provincia china de Henan. La segunda se concret\u00f3 en Brasil: all\u00ed, JBS adquiri\u00f3 la ope [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:45:12+0000",
+ "updated_time": "2013-07-26T22:45:12+0000"
+ },
+ {
+ "id": "1057554989_10201127331719566",
+ "from": {
+ "name": "Jimoff Foxytrail",
+ "id": "1057554989"
+ },
+ "message": "From China with love\nRK3188 tha ultimate powah",
+ "picture": "https://fbcdn-photos-h-a.akamaihd.net/hphotos-ak-prn2/971398_10201127310479035_1515442909_t.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=10201127310479035&set=pcb.10201127331719566&type=1&relevant_count=2",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "10201127310479035",
+ "created_time": "2013-07-26T22:45:11+0000",
+ "updated_time": "2013-07-26T22:45:11+0000"
+ },
+ {
+ "id": "100000795753342_548363101866877",
+ "from": {
+ "name": "Natashia Dunn",
+ "id": "100000795753342"
+ },
+ "message": "\"Did you know in China it remains illegal for anyone to worship outside of the state controlled official churches? And in 2012, the Chinese government spent more money on policing and monitoring its own people than on the entire Chinese military? This alarming development, which began in 2010, is indicative of the ever-rising level of surveillance, restrictions, and control over the Chinese population that keeps true religious freedom for the countries millions of C [...]
+ "story": "Natashia Dunn shared International Christian Concern's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100000795753342",
+ "name": "Natashia Dunn",
+ "offset": 0,
+ "length": 13,
+ "type": "user"
+ }
+ ],
+ "21": [
+ {
+ "id": "19437907453",
+ "name": "International Christian Concern",
+ "offset": 21,
+ "length": 31,
+ "type": "page"
+ }
+ ]
+ },
+ "picture": "https://fbcdn-photos-g-a.akamaihd.net/hphotos-ak-frc1/999080_10151959662667454_487300395_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=10151959662667454&set=a.154879247453.116636.19437907453&type=1",
+ "name": "Timeline Photos",
+ "caption": "ICC SPECIAL REPORT | Is #China Still Persecuting Christians? \n\nDid you know in China it remains illegal for anyone to worship outside of the state controlled official churches? And in 2012, the Chinese government spent more money on policing and monitoring its own people than on the entire Chinese military? This alarming development, which began in 2010, is indicative of the ever-rising level of surveillance, restrictions, and control over the Chinese population th [...]
+ "properties": [
+ {
+ "name": "By",
+ "text": "International Christian Concern",
+ "href": "https://www.facebook.com/persecuted?ref=stream"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "10151959662667454",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:45:07+0000",
+ "updated_time": "2013-07-26T22:45:07+0000"
+ },
+ {
+ "id": "100000474770512_696412553717897",
+ "from": {
+ "name": "Hiram Guevara Mireles",
+ "id": "100000474770512"
+ },
+ "message": "Jane y la china...",
+ "story": "Hiram Guevara Mireles shared a photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100000474770512",
+ "name": "Hiram Guevara Mireles",
+ "offset": 0,
+ "length": 21,
+ "type": "user"
+ }
+ ]
+ },
+ "picture": "https://fbcdn-photos-c-a.akamaihd.net/hphotos-ak-ash3/45072_696397510386068_1206903966_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=696397510386068&set=p.696397510386068&type=1",
+ "name": "Hiram Guevara Mireles's Photos",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Hiram Guevara Mireles",
+ "href": "https://www.facebook.com/elchee.guevaramireles"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "696397510386068",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:45:00+0000",
+ "updated_time": "2013-07-26T22:45:00+0000"
+ },
+ {
+ "id": "100000776749057_545215052181048",
+ "from": {
+ "name": "Gloria Tadili-Gamo",
+ "id": "100000776749057"
+ },
+ "message": "CHINA",
+ "story": "Gloria Tadili-Gamo shared Mysterious Things in The World's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100000776749057",
+ "name": "Gloria Tadili-Gamo",
+ "offset": 0,
+ "length": 18,
+ "type": "user"
+ }
+ ],
+ "26": [
+ {
+ "id": "257620137692376",
+ "name": "Mysterious Things in The World",
+ "offset": 26,
+ "length": 30,
+ "type": "page"
+ }
+ ]
+ },
+ "picture": "https://photos-a.xx.fbcdn.net/hphotos-prn2/1075732_401373079983747_1793775658_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=401373079983747&set=a.257929444328112.60568.257620137692376&type=1",
+ "name": "Timeline Photos",
+ "caption": "Houses in Sichuan, China.",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Mysterious Things in The World",
+ "href": "https://www.facebook.com/pages/Mysterious-Things-in-The-World/257620137692376?ref=stream"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "401373079983747",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:44:58+0000",
+ "updated_time": "2013-07-26T22:44:58+0000"
+ },
+ {
+ "id": "100006362920608_1394283104127107",
+ "from": {
+ "name": "Tim NetherlandsMogens",
+ "id": "100006362920608"
+ },
+ "message": "(GOD DAMN IT... Slept with Austria cause im awesome... I WAS ONE DAY AWAY FROM ICELAND OR PRUSSIA!!! *FLIPS EUROPE*)\nCooked with China because he got all Pedo? O.o.... well okaaayyy... ",
+ "story": "Tim NetherlandsMogens shared Hetalia Yaoi's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100006362920608",
+ "name": "Tim NetherlandsMogens",
+ "offset": 0,
+ "length": 21,
+ "type": "user"
+ }
+ ],
+ "29": [
+ {
+ "id": "533981726665359",
+ "name": "Hetalia Yaoi",
+ "offset": 29,
+ "length": 12,
+ "type": "page"
+ }
+ ]
+ },
+ "picture": "https://photos-a.xx.fbcdn.net/hphotos-ash4/1045214_556988204364711_219381721_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=556988204364711&set=a.534003813329817.1073741829.533981726665359&type=1",
+ "name": "Timeline Photos",
+ "caption": "( got handcuffed for life with England because he was scared ) - admin niiko",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Hetalia Yaoi",
+ "href": "https://www.facebook.com/pages/Hetalia-Yaoi/533981726665359?ref=stream"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "556988204364711",
+ "application": {
+ "name": "Photos",
+ "id": "2305272732"
+ },
+ "created_time": "2013-07-26T22:44:58+0000",
+ "updated_time": "2013-07-26T22:44:58+0000"
+ },
+ {
+ "id": "143419139071479_515030865243636",
+ "from": {
+ "category": "Teacher",
+ "name": "Profesor Gonzalo Rodrigo Mel\u00e9ndez",
+ "id": "143419139071479"
+ },
+ "message": "Se conmemora el 60 aniversario del Asalto al Cuartel Moncada (1953), primer gran acto del proceso insurreccional del Movimiento 26 de julio que posibilit\u00f3 el triunfo revolucionario en Cuba 6 a\u00f1os m\u00e1s tarde....\n \nSe conmemora el 60 aniversario del Asalto al Cuartel Moncada (1953), primer gran acto del proceso insurreccional del Movimiento 26 de julio que posibilit\u00f3 el triunfo revolucionario en Cuba 6 a\u00f1os m\u00e1s tarde. Lo primero que quere [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/143419139071479/posts/515030865243636"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:44:57+0000",
+ "updated_time": "2013-07-26T22:44:57+0000"
+ },
+ {
+ "id": "596665924_10151496285490925",
+ "from": {
+ "name": "Julio Cesar Mendivil Moroyoqui",
+ "id": "596665924"
+ },
+ "message": "COMIDA CHINA PLAZA SENDERO!!!!!!",
+ "story": "Julio Cesar Mendivil Moroyoqui shared Karlita Vargas's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "596665924",
+ "name": "Julio Cesar Mendivil Moroyoqui",
+ "offset": 0,
+ "length": 30,
+ "type": "user"
+ }
+ ],
+ "38": [
+ {
+ "id": "100002045694903",
+ "name": "Karlita Vargas",
+ "offset": 38,
+ "length": 14,
+ "type": "user"
+ }
+ ]
+ },
+ "picture": "https://photos-a.xx.fbcdn.net/hphotos-prn1/59203_491218377623014_476883201_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=491218377623014&set=p.491218377623014&type=1",
+ "name": "Karlita Vargas's Photos",
+ "caption": "Compartan, es lo que sirven de comer en la COMIDA CHINA en PLAZA SENDERO... Compartan por favor",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Karlita Vargas",
+ "href": "https://www.facebook.com/karlita.vargas.397"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "491218377623014",
+ "application": {
+ "name": "Links",
+ "id": "2309869772"
+ },
+ "created_time": "2013-07-26T22:44:50+0000",
+ "updated_time": "2013-07-26T22:44:50+0000"
+ }
+ ],
+ "paging": {
+ "previous": "https://graph.facebook.com/search?q=china&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&since=1374878754&__previous=1",
+ "next": "https://graph.facebook.com/search?q=china&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&until=1374878689"
+ }
+}
\ No newline at end of file
diff --git a/tests/src/test/resources/facebook2.json b/tests/src/test/resources/facebook2.json
new file mode 100644
index 0000000..b1b0ae5
--- /dev/null
+++ b/tests/src/test/resources/facebook2.json
@@ -0,0 +1,555 @@
+{
+ "data": [
+ {
+ "id": "100004872312380_180849772087432",
+ "from": {
+ "name": "Eleyn Emerald Lopez",
+ "id": "100004872312380"
+ },
+ "message": "bago na pala ang fb hindi ako nainform lol",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:57:09+0000",
+ "updated_time": "2013-07-26T22:57:09+0000"
+ },
+ {
+ "id": "100003186250897_430526510396887",
+ "from": {
+ "name": "Elisa Cabusbusan",
+ "id": "100003186250897"
+ },
+ "message": "Marami sa atin na gusto magkaroon ng additional income...tama??\r\nDahil sa panahon ngayon,,hindi cla kuntento sa tinatawag nting single income...\r\nAba gusto mo bang malaman kung paano??\r\nPls.panoorin nyo ito at tiyak malaking tulong sa buhay ntin at sa mga frnds ntin na gusto rin kumita...",
+ "picture": "https://fbexternal-a.akamaihd.net/safe_image.php?d=AQCMWRgVZjKdzdzh&w=130&h=130&url=http\u00253A\u00252F\u00252Fi1.ytimg.com\u00252Fvi\u00252FWWAlCiFTa_0\u00252Fmaxresdefault.jpg\u00253Ffeature\u00253Dog",
+ "link": "http://www.youtube.com/watch?v=WWAlCiFTa_0&sns=fb",
+ "source": "http://www.youtube.com/v/WWAlCiFTa_0?autohide=1&version=3&autoplay=1",
+ "name": "Elisa Cabusbusan",
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yj/r/v2OnaTyTQZE.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "video",
+ "application": {
+ "name": "Share_bookmarklet",
+ "id": "5085647995"
+ },
+ "created_time": "2013-07-26T22:57:08+0000",
+ "updated_time": "2013-07-26T22:57:08+0000"
+ },
+ {
+ "id": "283855334990816_582660281776985",
+ "from": {
+ "category": "Community",
+ "name": "Tagpuan ng Mga Inlove at Brokenhearted",
+ "id": "283855334990816"
+ },
+ "message": "Hindi mo naman kailangan ang sobrang bless sing yan tibok ng puso mo ay sapat na..kaya ugaliin paggising sa umaga manalangin magpasalamat sa panginoon kung ang puso mo ay tumitibok pa para harapin ang bagong pag-asa.\n\nGandang umaga!!!\nHoney!!!",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/283855334990816/posts/582660281776985"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:57:05+0000",
+ "updated_time": "2013-07-26T22:57:05+0000"
+ },
+ {
+ "id": "100002130420335_502681236479553",
+ "from": {
+ "name": "Sally Tavares",
+ "id": "100002130420335"
+ },
+ "message": "Minsan ang taong nagbibigay sayo ng iNis,\nAy ang taong mahaL mo kaya hindi mo matiis !",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:57:00+0000",
+ "updated_time": "2013-07-26T22:57:00+0000"
+ },
+ {
+ "id": "100002431768892_490719781019076",
+ "from": {
+ "name": "Lorlyn Umas-as",
+ "id": "100002431768892"
+ },
+ "message": "Kung Mahal Mo Sya Hinding Hindi Ka Titingin Sa Iba Pwera Na Lang Kung malandi Ka.",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:56:58+0000",
+ "updated_time": "2013-07-26T22:56:58+0000"
+ },
+ {
+ "id": "100006081401204_1403689419843758",
+ "from": {
+ "name": "Ai Shi Teru J",
+ "id": "100006081401204"
+ },
+ "message": "Cass!! hindi ko na i p pm sayo to para mabasa rin nya!! matanda ka sakin Cass dapat act like a grown up woman... ikaw naman kuya JC did you ever forget that hurting girls can be like hurting your mother? 6 na suntok sa muka? namamagang muka at mga labi napapaiayak na lang ako sa pinsan ko eh!! ang akala ko ALIEN ka kasi iba ka sa mga lalake pero hindi masasabi ko lang na 1\u0025 lang ng lalake ang hindi nananakit!! pasalamat ka at nasa states mommy ko at si tita, at [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for iPhone",
+ "namespace": "fbiphone",
+ "id": "6628568379"
+ },
+ "created_time": "2013-07-26T22:56:54+0000",
+ "updated_time": "2013-07-26T22:56:54+0000"
+ },
+ {
+ "id": "100000312507455_605031206183957",
+ "from": {
+ "name": "Noel Taguimacon Aligoy",
+ "id": "100000312507455"
+ },
+ "message": "Kung may pagsubok na dumarating sa buhay mo...magpasalamat ka sa Diyos at humingi ng gabay sa Kanya.. kasi hindi ka bibigyan ng pagsubok na hindi mo kaya at hindi ka Niya iiwanan basta't tawagin mo lang Siya",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:56:47+0000",
+ "updated_time": "2013-07-26T22:56:47+0000"
+ },
+ {
+ "id": "100000701715522_623161457717239",
+ "from": {
+ "name": "Ittaqillah Ya Ikhwan",
+ "id": "100000701715522"
+ },
+ "message": "check list ya ikhwaan sa pag nag aayuno sa mundo ng fb:\n\u221a no chatting sa pm, lalo sa hindi mahram,\n\u221a no browsing sa mga pages na nagkakasala ka.\n\u221a no posting ng mga bagay na nagkakasala ka.\n\u221a no tsikahan o panlilibak sa wall man o pm\n\u2193\u2193\u2193\u2193\u2193\u2193\u2193\u2193\n\npero teka muna, pagkatapos ng iftar?\n\nbakit lahat ng ito ay nagiging HALAL na rin?\n\n[paalala lamang sa aking sarili at sa mga kapatid kong mahal]",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:56:45+0000",
+ "updated_time": "2013-07-26T22:56:45+0000"
+ },
+ {
+ "id": "100000091490096_633636329982744",
+ "from": {
+ "name": "Jorjohn Bautista",
+ "id": "100000091490096"
+ },
+ "message": "Umuwi ako at naisipan ko siyang tawagan, naiiisp ko na ang kanyang isasagot... hindi ako nagkamali... salamat sa iyong pakikisama sa akin kahit na alam kong puro sablay, ngunit ngayong nakausap na kita ako ay naliwanagan... salamat sa iyo, madami akong napagtanto sa aking sarili marami pala akong paniniwala na akala ko ay tama... salamat dahil ako ay iyong minahal, hanggang duon na lang aking mahal ako ay hahayo sa ibang bersikulo ng aking buhay baon ang iyong mga p [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:56:44+0000",
+ "updated_time": "2013-07-26T22:56:44+0000"
+ },
+ {
+ "id": "100003852196693_277640522374352",
+ "from": {
+ "name": "Lienzion Lamis Gomid",
+ "id": "100003852196693"
+ },
+ "message": "Ang ex q hindi nagrply sa txt q..natakot n pagalitan q..anu kaya ang ginawa nya sa cp q...ex q hindi m talaga inigatan ang cp q ha...alam muna n love q ang cp q....aammm...\n\nJay egam buhea\"",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:56:36+0000",
+ "updated_time": "2013-07-26T22:56:36+0000"
+ },
+ {
+ "id": "100001367121966_525989724123260",
+ "from": {
+ "name": "Kemin Guialal",
+ "id": "100001367121966"
+ },
+ "message": "Mahulog ka na ng paulit-ulit sa KANAL.\n\nWag lang sa tao na HINDI KA MAHAL!\n\n#BOOM !\n\n\u30c4kEmin_Lamang\u10e6",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:56:32+0000",
+ "updated_time": "2013-07-26T22:56:32+0000"
+ },
+ {
+ "id": "100004631591701_205164966314555",
+ "from": {
+ "name": "Mylene Loyola",
+ "id": "100004631591701"
+ },
+ "message": "Manalangin tayo\n\nPanginoon,Thank you for all the blessing for all the guidance, inilalayo nyo po kami sa kapahamakan,maraming maraming salamat po Panginoon. Alam po namin Panginoon kami'y makasalanan na kahit kung minsan nakakagawa kami ng hindi maganda sa paningin ninyo andiyan pa rin kayo parating nakagabay at handang tumulong sa oras ng aming pangangailangan, I'm so sorry Lord that I have been going on our own way instead of your way, thank you Lord for dying to [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:56:27+0000",
+ "updated_time": "2013-07-26T22:56:27+0000"
+ },
+ {
+ "id": "399128610155939_545572068844925",
+ "from": {
+ "category": "Bank/financial institution",
+ "name": "Direct loans service repayment",
+ "id": "399128610155939"
+ },
+ "message": "impotence homeopathy http://impotence.homeopathy.medoonll4.appspot.com/#impotence-homeopathy\nviagra available in uk http://viagra.available.in.uk.medoonll4.appspot.com/#viagra-available-in-uk\nwhat is pink viagra http://what.is.pink.viagra.medoonll4.appspot.com/#what-is-pink-viagra\nviagra men dont need http://viagra.men.dont.need.medoonll4.appspot.com/#viagra-men-dont-need\ncialis quitting http://cialis.quitting.medoonll4.appspot.com/#cialis-quitting\nviagra pain m [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/399128610155939/posts/545572068844925"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "PostCron",
+ "namespace": "postcron",
+ "id": "178106548898871"
+ },
+ "created_time": "2013-07-26T22:56:26+0000",
+ "updated_time": "2013-07-26T22:56:26+0000"
+ },
+ {
+ "id": "100005927225164_142683769272530",
+ "from": {
+ "name": "Godwin Gliane",
+ "id": "100005927225164"
+ },
+ "to": {
+ "data": [
+ {
+ "name": "Jett Romerson Pagayon",
+ "id": "100001728618316"
+ },
+ {
+ "name": "Noel Godwin Gliane Alaurin",
+ "id": "100003306814234"
+ }
+ ]
+ },
+ "message": "Jett Romerson Pagayon.. sabi ko po sayo..\nilang beses na.. hindi kita marereplayan\ndito sa account nato kasi blocked nga to..\n\nadd moto para mareplayan kita \u2192 Noel Godwin Gliane Alaurin",
+ "message_tags": {
+ "0": [
+ {
+ "id": "100001728618316",
+ "name": "Jett Romerson Pagayon",
+ "type": "user",
+ "offset": 0,
+ "length": 21
+ }
+ ],
+ "159": [
+ {
+ "id": "100003306814234",
+ "name": "Noel Godwin Gliane Alaurin",
+ "type": "user",
+ "offset": 159,
+ "length": 26
+ }
+ ]
+ },
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:56:16+0000",
+ "updated_time": "2013-07-26T22:56:16+0000"
+ },
+ {
+ "id": "100003192774512_417021401747615",
+ "from": {
+ "name": "Criszel Isiderio",
+ "id": "100003192774512"
+ },
+ "message": "huh!3days nalng b-day n ng aking pinakakamahal n inay ko.....anu kaya ma ihanda?i want to celebrate..but ayw nya,sayang daw..inay talga minsan nga lng......he...hindi man xa ang gagastus eh....ako man...",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:56:15+0000",
+ "updated_time": "2013-07-26T22:56:15+0000"
+ },
+ {
+ "id": "184003048420213_223788021108382",
+ "from": {
+ "category": "Just for fun",
+ "name": "Wag kang PAASA , please? ang sakit eh",
+ "id": "184003048420213"
+ },
+ "message": "\"Being UNIQUE is SPECIAL, so be PROUD of YOURSELF. :-D\"\n\n-Good MORNING ! :-D\n-Hindi pa nga nag ALMUSAL facebook agad ..\n-hit like sa mga online ..\n-comment your cp number ...\n-PLUG kita .. :-D\n-first 5 only ... \n\n#adminyou\u003C3",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/184003048420213/posts/223788021108382"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:56:14+0000",
+ "updated_time": "2013-07-26T22:56:14+0000",
+ "likes": {
+ "data": [
+ {
+ "id": "100003043439049",
+ "name": "Jericka Larize Gonzales"
+ }
+ ],
+ "paging": {
+ "cursors": {
+ "after": "MTAwMDAzMDQzNDM5MDQ5",
+ "before": "MTAwMDAzMDQzNDM5MDQ5"
+ }
+ }
+ }
+ },
+ {
+ "id": "256621417799622_368172799977816",
+ "from": {
+ "category": "Community",
+ "name": "Davonaire-Inspirational\"\"",
+ "id": "256621417799622"
+ },
+ "message": "Ang pagsisinungaling ay isang talento. Talento na sana hindi na lang naimbento\n\n\u2665Cat's Eye\u2665",
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/256621417799622/posts/368172799977816"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Pages Manager for Android",
+ "namespace": "fbpagemgr_android",
+ "id": "121876164619130"
+ },
+ "created_time": "2013-07-26T22:56:13+0000",
+ "updated_time": "2013-07-26T22:56:13+0000"
+ },
+ {
+ "id": "100000282765695_643110372375049",
+ "from": {
+ "name": "Rochel Uniatic",
+ "id": "100000282765695"
+ },
+ "message": "\u201cFall in love when you\u2019re ready, hindi lang dahil gusto mong gumanti.\u201d",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Facebook for iPad",
+ "namespace": "fbipad_",
+ "id": "173847642670370"
+ },
+ "created_time": "2013-07-26T22:56:07+0000",
+ "updated_time": "2013-07-26T22:56:07+0000"
+ },
+ {
+ "id": "100001859593999_517392921666023",
+ "from": {
+ "name": "Eloisa Balingit",
+ "id": "100001859593999"
+ },
+ "message": "Sa lahat ng nakakabasa nito, swerte tayo. Know why? Kapag umalis ka ng bahay at napatambay ka sa lugar tulad ng sakayan ng Jeep. May makikita kang mga barker ng jeep na patuloy ang pagsigaw para maambunan ng limang pisong barya. Tumingin ka sa kanan eh may Ale na nagtitinda ng Palamig at sa harapan mo naman eh may lalakeng nagtitinda ng Pinya. Then uuwi ka ng bahay niyo may makakasalubong kang nagtitinda ng Yakult at hila ang karitela na puno ng Yakult. At paglagpas [...]
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:56:04+0000",
+ "updated_time": "2013-07-26T22:56:04+0000"
+ },
+ {
+ "id": "100003240641743_405753266209358",
+ "from": {
+ "name": "X-nhor Utto",
+ "id": "100003240641743"
+ },
+ "message": "gnyan ang ugali ni sahod CAPITAL- Yan! Heto na tayo ito ang iniiwasan ng karamihan yung capital. Lagi natin tatandaan sa lahat ng bagay sa mundo kahit hindi negosyo lahat may tinatawag na capital o investments. Walang libre!\n\nSaan ka naman nakakita ng libreng negosyo? Aber nga? \n\nKapag ba naghahanap ka ng trabaho sa palagay mo wala kang invested capital? O diba gumagawa ka ng paraan para makagawa ng Resume or Biodata para maipadala mo sa mga companies na gusto mo [...]
+ "story": "X-nhor Utto shared Tambayan OFW- international's photo.",
+ "story_tags": {
+ "0": [
+ {
+ "id": "100003240641743",
+ "name": "X-nhor Utto",
+ "offset": 0,
+ "length": 11,
+ "type": "user"
+ }
+ ],
+ "19": [
+ {
+ "id": "100624236677885",
+ "name": "Tambayan OFW- international",
+ "offset": 19,
+ "length": 27,
+ "type": "page"
+ }
+ ]
+ },
+ "picture": "https://fbcdn-photos-b-a.akamaihd.net/hphotos-ak-frc3/969021_539010139505957_910074166_s.jpg",
+ "link": "https://www.facebook.com/photo.php?fbid=539010139505957&set=a.404265802980392.89616.100624236677885&type=1",
+ "name": "Timeline Photos",
+ "caption": "Im pretty sure maraming makakarelate dito. . .hahaha\n\n\n\nADMIN KYLIE",
+ "properties": [
+ {
+ "name": "By",
+ "text": "Tambayan OFW- international",
+ "href": "https://www.facebook.com/tambayanofwinternational?ref=stream"
+ }
+ ],
+ "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif",
+ "privacy": {
+ "value": ""
+ },
+ "type": "photo",
+ "object_id": "539010139505957",
+ "application": {
+ "name": "Facebook for Android",
+ "namespace": "fbandroid",
+ "id": "350685531728"
+ },
+ "created_time": "2013-07-26T22:56:04+0000",
+ "updated_time": "2013-07-26T22:56:04+0000"
+ },
+ {
+ "id": "1756587770_3252058117771",
+ "from": {
+ "name": "Benjamin Cabrera",
+ "id": "1756587770"
+ },
+ "message": "BAKIT HINDI KA CRUSH NG CRUSH MO>>>>>>wahahah Trailer palaNg laughtriP nah!!!!",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:55:56+0000",
+ "updated_time": "2013-07-26T22:55:56+0000"
+ },
+ {
+ "id": "100000842245724_582493961788673",
+ "from": {
+ "name": "Rachel Rances Deang",
+ "id": "100000842245724"
+ },
+ "message": "happy 99th anniv to all Iglesia Ni Cristo members and happy 92nd aniv local ng Caloocan... Praise God...Glorify Him to this wonderful moments and to all His Blessings to us...Hindi Niya Pinabayaan n mga Tapat na Lingkod Nya Kailanman...",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "186529194704290"
+ },
+ "created_time": "2013-07-26T22:55:38+0000",
+ "updated_time": "2013-07-26T22:55:38+0000"
+ },
+ {
+ "id": "100004589527871_205505996279050",
+ "from": {
+ "name": "Nhel Pellazo",
+ "id": "100004589527871"
+ },
+ "message": "IKAW NA MANLOLOKO !]\n \n Haha wag tamaan ganyan tlga\n HINDI MAIWASAN KALANDIAN o KAKATIHAN NG ???? EWAN HAHA :D",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:55:37+0000",
+ "updated_time": "2013-07-26T22:55:37+0000"
+ },
+ {
+ "id": "100001151882595_538033689578356",
+ "from": {
+ "name": "Nhorjannah Mansor Gumbay",
+ "id": "100001151882595"
+ },
+ "message": "DAPAT SA ISANG RELASYUN AY HINDI GANTIHAN KAPAG NAGKAMALI KA\nDAPAT MATUTU KANG HUMINGI NG KAPATAWARAN AT MAPAGKUMBABA\nHINDI YUNG KONTING PROBLEMA LANG\nHAHALUNGKATIN MU LAHAT NG KASALANAN NIYA.......",
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "application": {
+ "name": "Mobile",
+ "id": "2915120374"
+ },
+ "created_time": "2013-07-26T22:55:34+0000",
+ "updated_time": "2013-07-26T22:55:34+0000"
+ },
+ {
+ "id": "445630152202723_446027772162961",
+ "from": {
+ "category": "Community",
+ "name": "Be\u015fir Sezgin",
+ "id": "445630152202723"
+ },
+ "message": "\u00c7ocuk Dikmi\u015f Sa\u00e7Lar\u0131 Hindi Gibi ,\nGiymi\u015f ConverserLeri Birde K\u00fcpe Takm\u0131\u015f .\nTamam \u0130\u015fte 10 Numara Adam Daha Y\u00fcrek M\u00fcrek \u00d6nemLi De\u011fiL .\nK\u0131zLar Pe\u015finde Pervane 1-2 Ay Sonrada ALdat\u0131Ld\u0131m ,\nTerkediLdim , ErkekLer B\u00f6yLe ErkekLer \u015e\u00f6yLee\nEee K\u0131z\u0131m Sen Ka\u015f\u0131nd\u0131n Sen Adama De\u011fiL AksesuarLara Kap\u0131Ld\u0131n.\nSonrada Piyasada DeLikanL\u01 [...]
+ "actions": [
+ {
+ "name": "Comment",
+ "link": "https://www.facebook.com/445630152202723/posts/446027772162961"
+ }
+ ],
+ "privacy": {
+ "value": ""
+ },
+ "type": "status",
+ "created_time": "2013-07-26T22:55:32+0000",
+ "updated_time": "2013-07-26T22:55:32+0000"
+ }
+ ],
+ "paging": {
+ "previous": "https://graph.facebook.com/search?q=hindi&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&since=1374879429&__previous=1",
+ "next": "https://graph.facebook.com/search?q=hindi&type=post&access_token=CAADysJa3mtcBADbzkQdT8LjgTNAJEZAZC36Ol7PwArlMIwLlDeDv1bn415WRGYIg3TCOlGMDpmtA7tWhFkSHZBuqtkUivghE7ZBtNSDabwFUt9hRZCeqA3uh5ttXBahQJAbCjrONcmfu9Kf4KQKUl&limit=25&until=1374879331"
+ }
+}
\ No newline at end of file
diff --git a/tests/src/test/resources/jsonmergepatch.json b/tests/src/test/resources/jsonmergepatch.json
new file mode 100644
index 0000000..3b90e5f
--- /dev/null
+++ b/tests/src/test/resources/jsonmergepatch.json
@@ -0,0 +1,103 @@
+[
+ {
+ "target": {},
+ "patch": {"a": {"b":"c"}},
+ "expected": {"a":{"b":"c"}}
+ },
+ {
+ "target": {},
+ "patch": {"a":{"bb":{"ccc":null}}},
+ "expected": {"a":{"bb":{}}}
+ },
+ {
+ "target": {"a":"foo"},
+ "patch": "bar",
+ "expected": "bar"
+ },
+ {
+ "target": {"a":"foo"},
+ "patch": null,
+ "expected": null
+ },
+ {
+ "target": {"a": {"b":"c"}},
+ "patch": {"a": {"b":"d", "c":null}},
+ "expected": {"a": {"b":"d"}}
+ },
+ {
+ "target": { "c": "d" },
+ "patch": { "a": "b" },
+ "expected": { "a": "b", "c": "d" }
+ },
+ {
+ "target": { "a": { "d": 2 } },
+ "patch": { "a": { "d": 1 } },
+ "expected": { "a": { "d": 1 } }
+ },
+ {
+ "target": { "a": "b", "c": "d" },
+ "patch": { "c": null },
+ "expected": { "a": "b" }
+ },
+ {
+ "target": { "a": { "b": "c", "d": null} },
+ "patch": { "a": { "d": null} },
+ "expected": { "a": { "b": "c" } }
+ },
+ {
+ "target": {
+ "a": { "b": "c" },
+ "d": "e"
+ },
+ "patch": {
+ "a": 1000010002020389.8787987983
+ },
+ "expected": {
+ "a": 1000010002020389.8787987983,
+ "d": "e"
+ }
+ },
+ {
+ "target": { "a": "b" },
+ "patch": { "c": [ null ] },
+ "expected": { "a": "b", "c": [ null ] }
+ },
+ {
+ "target": { "a": { "b": null, "d": 3}, "e": -1 },
+ "patch": { "a": { "b": "c", "d": null } },
+ "expected": { "a": { "b": "c" }, "e": -1 }
+ },
+ {
+ "target": [1,2],
+ "patch": { "a": "b", "c": null },
+ "expected": { "a": "b"}
+ },
+ {
+ "target": {
+ "title": "Goodbye!",
+ "author": {
+ "givenName": "John",
+ "familyName": "Doe"
+ },
+ "tags": [ "example", "sample" ],
+ "content": "This will be unchanged"
+ },
+ "patch": {
+ "title": "Hello!",
+ "phoneNumber": "+01-123-456-7890",
+ "author": {
+ "familyName": null
+ },
+ "tags": [ "example" ]
+ },
+ "expected": {
+ "title": "Hello!",
+ "author": {
+ "givenName": "John"
+ },
+ "tags": [ "example" ],
+ "content": "This will be unchanged",
+ "phoneNumber": "+01-123-456-7890"
+ }
+ }
+]
\ No newline at end of file
diff --git a/tests/src/test/resources/jsonmergepatchdiff.json b/tests/src/test/resources/jsonmergepatchdiff.json
new file mode 100644
index 0000000..ac6c91d
--- /dev/null
+++ b/tests/src/test/resources/jsonmergepatchdiff.json
@@ -0,0 +1,60 @@
+[
+ {
+ "original": {
+ "title": "Goodbye!",
+ "author": {
+ "givenName": "John",
+ "familyName": "Doe"
+ },
+ "tags": [ "example", "sample" ],
+ "content": "This will be unchanged"
+ },
+ "expected": {
+ "title": "Hello!",
+ "phoneNumber": "+01-123-456-7890",
+ "author": {
+ "familyName": null
+ },
+ "tags": [ "example" ]
+ },
+ "target": {
+ "title": "Hello!",
+ "author": {
+ "givenName": "John"
+ },
+ "tags": [ "example" ],
+ "content": "This will be unchanged",
+ "phoneNumber": "+01-123-456-7890"
+ }
+ },
+ {
+ "original": {},
+ "expected": {"a": {"b":"c"}},
+ "target": {"a":{"b":"c"}}
+ },
+ {
+ "original": {"a":"foo"},
+ "expected": "bar",
+ "target": "bar"
+ },
+ {
+ "original": {"a":"foo"},
+ "expected": null,
+ "target": null
+ },
+ {
+ "original": { "c": "d" },
+ "expected": { "a": "b" },
+ "target": { "a": "b", "c": "d" }
+ },
+ {
+ "original": { "a": { "d": 2 } },
+ "expected": { "a": { "d": 1 } },
+ "target": { "a": { "d": 1 } }
+ },
+ {
+ "original": { "a": "b", "c": "d" },
+ "expected": { "c": null },
+ "target": { "a": "b" }
+ }
+]
\ No newline at end of file
diff --git a/tests/src/test/resources/jsonpatch.json b/tests/src/test/resources/jsonpatch.json
new file mode 100644
index 0000000..7fd7683
--- /dev/null
+++ b/tests/src/test/resources/jsonpatch.json
@@ -0,0 +1,214 @@
+[
+ {
+ "op": { "op": "test", "path": "/a/1", "value": "hello" },
+ "target": { "a": [ null, "hello", "world" ] },
+ "expected": { "a": [ null, "hello", "world" ] }
+ },
+ {
+ "op": { "op": "test", "path": "/x", "value": {} },
+ "target": [ 1, 2 ],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "test", "path": "", "value": true },
+ "target": [ 1, 2 ],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "test", "path": "/x", "value": -30.000 },
+ "target": { "x": -29.020 },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "replace", "path": "", "value": false },
+ "target": { "x": { "a": "b", "y": {} } },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "replace", "path": "/x/y", "value": "hello" },
+ "target": { "x": { "a": "b", "y": {} } },
+ "expected": { "x": { "a": "b", "y": "hello" } }
+ },
+ {
+ "op": { "op": "replace", "path": "/0/2", "value": "x" },
+ "target": [ [ "a", "b", "c"], "d", "e" ],
+ "expected": [ [ "a", "b", "x" ], "d", "e" ]
+ },
+ {
+ "op": { "op": "replace", "path": "/x/0", "value": null },
+ "target": { "x": [ "y", "z" ], "foo": "bar" },
+ "expected": { "x": [ null, "z" ], "foo": "bar" }
+ },
+ {
+ "op": { "op": "replace", "path": "/x/y", "value": 42 },
+ "target": { "x": {} },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "remove", "path": "/x/y" },
+ "target": { "x": { "a": "b", "y": {} } },
+ "expected": { "x": { "a": "b" } }
+ },
+ {
+ "op": { "op": "remove", "path": "/0/2" },
+ "target": [ [ "a", "b", "c"], "d", "e" ],
+ "expected": [ [ "a", "b" ], "d", "e" ]
+ },
+ {
+ "op": { "op": "remove", "path": "/x/0" },
+ "target": { "x": [ "y", "z" ], "foo": "bar" },
+ "expected": { "x": [ "z" ], "foo": "bar" }
+ },
+ {
+ "op": { "op": "remove", "path": "/x/y" },
+ "target": { "x": {} },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "move", "from": "/x/a", "path": "/x/b" },
+ "target": { "x": { "a": "helo" } },
+ "expected": { "x": { "b": "helo" } }
+ },
+ {
+ "op": { "op": "move", "from": "/x/a", "path": "/x/a" },
+ "target": { "x": { "a": "helo" } },
+ "expected": { "x": { "a": "helo" } }
+ },
+ {
+ "op": { "op": "move", "from": "/0", "path": "/0/x" },
+ "target": [ "victim", {}, {} ],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "move", "from": "/0", "path": "/-" },
+ "target": [ 0, 1, 2 ],
+ "expected": [ 1, 2, 0 ]
+ },
+ {
+ "op": { "op": "move", "from": "/a", "path": "/b/2" },
+ "target": { "a": "helo", "b": [ 1, 2, 3, 4 ] },
+ "expected": { "b": [ 1, 2, "helo", 3, 4 ] }
+ },
+ {
+ "op": { "op": "move", "from": "/a", "path": "/a/b" },
+ "target": {},
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "move", "from": "/a", "path": "/b/c" },
+ "target": { "a": "b" },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "copy", "from": "/a", "path": "/b" },
+ "target": { "a": 1 },
+ "expected": { "a": 1, "b": 1 }
+ },
+ {
+ "op": { "op": "copy", "from": "/a", "path": "/b" },
+ "target": { "a": 1, "b": false },
+ "expected": { "a": 1, "b": 1 }
+ },
+ {
+ "op": { "op": "copy", "from": "/0", "path": "/-" },
+ "target": [ 1, 2, 3, 4 ],
+ "expected": [ 1, 2, 3, 4, 1 ]
+ },
+ {
+ "op": { "op": "copy", "from": "/0", "path": "/0" },
+ "target": [ true ],
+ "expected": [ true, true ]
+ },
+ {
+ "op": { "op": "copy", "from": "/a", "path": "/b" },
+ "target": {},
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "copy", "from": "/a", "path": "/b/c" },
+ "target": { "a": 1 },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/a/b/c", "value": 1 },
+ "target": { "a": "b" },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/~1", "value": 1 },
+ "target": [],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/3", "value": 1 },
+ "target": [ 1, 2 ],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/-2", "value": 1 },
+ "target": [ 1, 2 ],
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/foo/f", "value": "bar" },
+ "target": { "foo": "bar" },
+ "exception": "javax.json.JsonException"
+ },
+ {
+ "op": { "op": "add", "path": "/a", "value": "b" },
+ "target": {},
+ "expected": { "a": "b" }
+ },
+ {
+ "op": { "op": "add", "path": "/a", "value": 1 },
+ "target": { "a": "b" },
+ "expected": { "a": 1 }
+ },
+ {
+ "op": { "op": "add", "path": "/array/-", "value": 1 },
+ "target": { "array": [ 2, null, {}, 1 ] },
+ "expected": { "array": [ 2, null, {}, 1, 1 ] }
+ },
+ {
+ "op": { "op": "add", "path": "/array/2", "value": "hello" },
+ "target": { "array": [ 2, null, {}, 1] },
+ "expected": { "array": [ 2, null, "hello", {}, 1 ] }
+ },
+ {
+ "op": { "op": "add", "path": "/obj/inner/b", "value": [ 1, 2 ] },
+ "target": {
+ "obj": {
+ "inner": {
+ "a": "hello"
+ }
+ }
+ },
+ "expected": {
+ "obj": {
+ "inner": {
+ "a": "hello",
+ "b": [ 1, 2 ]
+ }
+ }
+ }
+ },
+ {
+ "op": { "op": "add", "path": "/obj/inner/b", "value": [ 1, 2 ] },
+ "target": {
+ "obj": {
+ "inner": {
+ "a": "hello",
+ "b": "world"
+ }
+ }
+ },
+ "expected": {
+ "obj": {
+ "inner": {
+ "a": "hello",
+ "b": [ 1, 2 ]
+ }
+ }
+ }
+ }
+]
diff --git a/tests/src/test/resources/jsonpatchdiff.json b/tests/src/test/resources/jsonpatchdiff.json
new file mode 100644
index 0000000..ce3be5f
--- /dev/null
+++ b/tests/src/test/resources/jsonpatchdiff.json
@@ -0,0 +1,132 @@
+[
+ {
+ "original": {"a":"b"},
+ "target": {"a":"b"},
+ "expected": []
+ },
+ {
+ "original": [ 1, 2, 3 ],
+ "target": [ 1, 2, 3, 4, 5 ],
+ "expected": [
+ {"op":"add","path":"/4","value":5},
+ {"op":"add","path":"/3","value":4}
+ ]
+ },
+ {
+ "original": [1,2,3,4,5],
+ "target": [1,3,4],
+ "expected": [
+ { "op": "remove", "path": "/4"},
+ { "op": "remove", "path": "/1"}
+ ]
+ },
+ {
+ "original": [1,2,3,4,5,6],
+ "target": [1,7,3,4,8,5],
+ "expected": [
+ { "op": "remove", "path": "/5"},
+ { "op": "add", "path": "/4", "value": 8},
+ { "op": "replace", "path": "/1", "value": 7}
+ ]
+ },
+ {
+ "original": [ 1, 2, 3 ],
+ "target": [ 1 ],
+ "expected": [
+ { "op": "remove", "path": "/2" },
+ { "op": "remove", "path": "/1" }
+ ]
+ },
+ {
+ "original": { "a": "b", "c": "d" },
+ "target": { "a": "b" },
+ "expected": [
+ { "op": "remove", "path": "/c" }
+ ]
+ },
+ {
+ "original": { "a": 1 },
+ "target": { "a": 1, "c": 2, "b": 3, "d": 4 },
+ "expected": [
+ { "op": "add", "path": "/c", "value": 2 },
+ { "op": "add", "path": "/b", "value": 3 },
+ { "op": "add", "path": "/d", "value": 4 }
+ ]
+ },
+ {
+ "original": { "a": null },
+ "target": { "a": 6 },
+ "expected": [
+ { "op": "replace", "path": "/a", "value": 6 }
+ ]
+ },
+ {
+ "original": [ 1, 2, 3 ],
+ "target": { "hello": "world" },
+ "expected": [
+ { "op": "replace", "path": "", "value": { "hello": "world" } }
+ ]
+ },
+ {
+ "original": {
+ "a": "b",
+ "c": {
+ "d": "e"
+ }
+ },
+ "target": {
+ "a": "b",
+ "c": {
+ "d": 1,
+ "e": "f"
+ }
+ },
+ "expected": [
+ { "op": "replace", "path": "/c/d", "value": 1 },
+ { "op": "add", "path": "/c/e", "value": "f" }
+ ]
+ },
+ {
+ "original": {
+ "a": [ 1, 2, 3 ]
+ },
+ "target": {
+ "a": [ "b", 2, 3, 4 ]
+ },
+ "expected": [
+ { "op": "add", "path": "/a/3", "value": 4 },
+ { "op": "replace", "path": "/a/0", "value": "b" }
+ ]
+ },
+ {
+ "original": [ { "a": "b" }, "foo", { "bar": null } ],
+ "target": [ { "a": "b", "c": "d" }, "foo", { "bar": "baz" } ],
+ "expected": [
+ { "op": "replace", "path": "/2/bar", "value": "baz" },
+ { "op": "add", "path": "/0/c", "value": "d" }
+ ]
+ },
+ {
+ "original": [ 1, [ 2, 3 ], 4 ],
+ "target": [ "x", [ 2, 3, "y" ], 4 ],
+ "expected": [
+ { "op": "add", "path": "/1/2", "value": "y" },
+ { "op": "replace", "path": "/0", "value": "x" }
+ ]
+ },
+ {
+ "original": { "a": "b" },
+ "target": { "c": "b" },
+ "expected": [
+ { "op": "remove", "path": "/a"},
+ { "op": "add", "path": "/c", "value": "b"}
+ ]
+ },
+ {
+ "original": {"a": "c"},
+ "target": {"a": "c", "d": "c"},
+ "expected": [
+ { "op": "add", "path": "/d", "value": "c" }
+ ]
+ }
+]
diff --git a/tests/src/test/resources/rfc6901.json b/tests/src/test/resources/rfc6901.json
new file mode 100644
index 0000000..170147b
--- /dev/null
+++ b/tests/src/test/resources/rfc6901.json
@@ -0,0 +1,20 @@
+ {
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8,
+ "o" : null,
+ "p": {
+ "q":"r"
+ },
+ "s": [ {
+ "t":"u"
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/tests/src/test/resources/twitter.json b/tests/src/test/resources/twitter.json
new file mode 100644
index 0000000..677f2b9
--- /dev/null
+++ b/tests/src/test/resources/twitter.json
@@ -0,0 +1,2 @@
+{"statuses":[{"metadata":{"result_type":"recent","iso_language_code":"de"},"created_at":"Fri Jul 26 19:31:26 +0000 2013","id":360844831439855616,"id_str":"360844831439855616","text":"Hiring ••► Pre-Sales Consultant ☛ http://t.co/fjlOd8PhcQ #Java #JUnit #Python #PHP #XML #XSLT #SOAP #REST #SAML #Node","source":"<a href=\"http://www.socialoomph.com\" rel=\"nofollow\">SocialOomph</a>","truncated":false,"in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":null, [...]
+
diff --git a/tests/src/test/resources/wiki.json b/tests/src/test/resources/wiki.json
new file mode 100644
index 0000000..17bb193
--- /dev/null
+++ b/tests/src/test/resources/wiki.json
@@ -0,0 +1,21 @@
+{
+ "firstName": "John",
+ "lastName": "Smith",
+ "age": 25,
+ "address": {
+ "streetAddress": "21 2nd Street",
+ "city": "New York",
+ "state": "NY",
+ "postalCode": "10021"
+ },
+ "phoneNumber": [
+ {
+ "type": "home",
+ "number": "212 555-1234"
+ },
+ {
+ "type": "fax",
+ "number": "646 555-4567"
+ }
+ ]
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libjsonp-java.git
More information about the pkg-java-commits
mailing list