diff --git a/README.md b/README.md index de488b6..5290ca8 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,9 @@ # JSON Processing (JSON-P) -This projects contains API and Reference Implementation (RI) of JSR-374. -The Java API for JSON Processing provides portable APIs to parse, generate, transform, and query JSON documents. - -## Build -Use the following command: -```bash -mvn -U -C clean install -Dnon.final=true -``` - -## Licensing - -### JSON-P API -[Java API for JSON Processing 1.1 specification license](https://jcp.org/aboutJava/communityprocess/licenses/jsr374/JSR_374-Spec-Java_API_for_JSON_Proc-1.1-11.25.14.pdf) - -### JSON-P RI - -Commercial use: - -The RI will be available for commercial use under the [CDDL 1.1](https://oss.oracle.com/licenses/CDDL+GPL-1.1) open source license, the [GPLv2 with Classpath Exception](https://oss.oracle.com/licenses/CDDL+GPL-1.1) open source license, or this [license](https://jcp.org/aboutJava/communityprocess/licenses/jsr374/OCSL-JSR_374-Java_API_for_JSON_Processing-1.1-AttachD-11.25.14.pdf). - -Non-Commercial use: - -The RI will be available for non-Commercial use under the [CDDL 1.1](https://oss.oracle.com/licenses/CDDL+GPL-1.1) open source license or the [GPLv2 with Classpath Exception](https://oss.oracle.com/licenses/CDDL+GPL-1.1) open source license. - +:warning: This project is now part of the EE4J initiative. This repository has been archived as all activities are now happening in the [corresponding Eclipse repository](https://github.com/eclipse-ee4j/jsonp). See [here](https://www.eclipse.org/ee4j/status.php) for the overall EE4J transition status. ## Links -- JSON-P official web site: https://javaee.github.io/jsonp -- JSR-374 page on JCP site: https://jcp.org/en/jsr/detail?id=374 \ No newline at end of file + +- Eclipse Project for JSON Processing: https://projects.eclipse.org/projects/ee4j.jsonp +- Discussion groups: jsonp-dev@eclipse.org +- JSR-367 page on JCP site: https://jcp.org/en/jsr/detail?id=374 diff --git a/api/pom.xml b/api/pom.xml index 4c13dbc..71e90f3 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011-2018 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 @@ -58,6 +58,11 @@ JSR 374 (JSON Processing) API API module of JSR 374:Java API for Processing JSON https://javaee.github.io/jsonp + + + javax.json.* + + @@ -76,7 +81,7 @@ -Oracle and/or its affiliates. All Rights Reserved. Use is subject to @@ -138,7 +143,7 @@ ${spec.implementation.version} ${spec.specification.version} ${packages.export} - Java API for JSON Processing (JSON-P) ${spec.version} + Java API for JSON Processing (JSON-P) ${spec_version} diff --git a/api/src/main/java/javax/json/EmptyArray.java b/api/src/main/java/javax/json/EmptyArray.java new file mode 100644 index 0000000..03afdbe --- /dev/null +++ b/api/src/main/java/javax/json/EmptyArray.java @@ -0,0 +1,136 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 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://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or 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 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.AbstractList; +import java.util.Collections; +import java.util.List; +import java.util.RandomAccess; + +/** + * Private implementation of immutable {@link JsonArray}. + * + * @author Lukas Jungmann + */ +final class EmptyArray extends AbstractList implements JsonArray, Serializable, RandomAccess { + + private static final long serialVersionUID = 7295439472061642859L; + + @Override + public JsonValue get(int index) { + throw new IndexOutOfBoundsException("Index: " + index); + } + + @Override + public int size() { + return 0; + } + + @Override + public JsonObject getJsonObject(int index) { + return (JsonObject) get(index); + } + + @Override + public JsonArray getJsonArray(int index) { + return (JsonArray) get(index); + } + + @Override + public JsonNumber getJsonNumber(int index) { + return (JsonNumber) get(index); + } + + @Override + public JsonString getJsonString(int index) { + return (JsonString) get(index); + } + + @Override + public List getValuesAs(Class clazz) { + return Collections.emptyList(); + } + + @Override + public String getString(int index) { + return getJsonString(index).getString(); + } + + @Override + public String getString(int index, String defaultValue) { + return defaultValue; + } + + @Override + public int getInt(int index) { + return getJsonNumber(index).intValue(); + } + + @Override + public int getInt(int index, int defaultValue) { + return defaultValue; + } + + @Override + public boolean getBoolean(int index) { + return get(index) == JsonValue.TRUE; + } + + @Override + public boolean getBoolean(int index, boolean defaultValue) { + return defaultValue; + } + + @Override + public boolean isNull(int index) { + return get(index) == JsonValue.NULL; + } + + @Override + public ValueType getValueType() { + return ValueType.ARRAY; + } + + // Preserves singleton property + private Object readResolve() { + return JsonValue.EMPTY_JSON_ARRAY; + } +} diff --git a/api/src/main/java/javax/json/EmptyObject.java b/api/src/main/java/javax/json/EmptyObject.java new file mode 100644 index 0000000..d7f4d02 --- /dev/null +++ b/api/src/main/java/javax/json/EmptyObject.java @@ -0,0 +1,126 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 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://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or 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 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.AbstractMap; +import java.util.Collections; +import java.util.Set; + +/** + * Private implementation of immutable {@link JsonObject}. + * + * @author Lukas Jungmann + */ +final class EmptyObject extends AbstractMap implements JsonObject, Serializable { + + private static final long serialVersionUID = -1461653546889072583L; + + @Override + public Set> entrySet() { + return Collections.>emptySet(); + } + + @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) { + return defaultValue; + } + + @Override + public int getInt(String name) { + return getJsonNumber(name).intValue(); + } + + @Override + public int getInt(String name, int defaultValue) { + return defaultValue; + } + + @Override + public boolean getBoolean(String name) { + throw new NullPointerException(); + } + + @Override + public boolean getBoolean(String name, boolean defaultValue) { + return defaultValue; + } + + @Override + public boolean isNull(String name) { + throw new NullPointerException(); + } + + @Override + public ValueType getValueType() { + return ValueType.OBJECT; + } + + // Preserves singleton property + private Object readResolve() { + return JsonValue.EMPTY_JSON_OBJECT; + } +} diff --git a/api/src/main/java/javax/json/JsonArray.java b/api/src/main/java/javax/json/JsonArray.java index 90d6281..ae0fc2b 100644 --- a/api/src/main/java/javax/json/JsonArray.java +++ b/api/src/main/java/javax/json/JsonArray.java @@ -291,7 +291,7 @@ default List getValuesAs(Function func) { * * @param index index of the JSON null value * @return return true if the value at the specified location is - * {@code JsonValue.NUL}, otherwise false + * {@code JsonValue.NULL}, 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 index 8501543..8a06a11 100644 --- a/api/src/main/java/javax/json/JsonArrayBuilder.java +++ b/api/src/main/java/javax/json/JsonArrayBuilder.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013-2018 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 @@ -94,7 +94,7 @@ * * * - *

This class does not allow null to be used as a + *

This class does not allow null to be used as a * value while building the JSON array * * @see JsonObjectBuilder diff --git a/api/src/main/java/javax/json/JsonException.java b/api/src/main/java/javax/json/JsonException.java index 14cc927..cade328 100644 --- a/api/src/main/java/javax/json/JsonException.java +++ b/api/src/main/java/javax/json/JsonException.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011-2018 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 @@ -67,7 +67,7 @@ public JsonException(String 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 null value is + * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) */ diff --git a/api/src/main/java/javax/json/JsonObjectBuilder.java b/api/src/main/java/javax/json/JsonObjectBuilder.java index 30198a7..d076c96 100644 --- a/api/src/main/java/javax/json/JsonObjectBuilder.java +++ b/api/src/main/java/javax/json/JsonObjectBuilder.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013-2018 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 @@ -110,7 +110,7 @@ * * * - *

This class does not allow null to be used as a name or + *

This class does not allow null to be used as a name or * value while building the JSON object * * @see JsonArrayBuilder diff --git a/api/src/main/java/javax/json/JsonValue.java b/api/src/main/java/javax/json/JsonValue.java index 9b9a5e2..72d93da 100644 --- a/api/src/main/java/javax/json/JsonValue.java +++ b/api/src/main/java/javax/json/JsonValue.java @@ -43,11 +43,11 @@ /** * JsonValue represents an immutable JSON value. * - * + * *

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} + * {@code true} ({@link JsonValue#TRUE JsonValue.TRUE}), {@code false} * ({@link JsonValue#FALSE JsonValue.FALSE}), * or {@code null} ({@link JsonValue#NULL JsonValue.NULL}). */ @@ -55,17 +55,17 @@ public interface JsonValue { /** * The empty JSON object. - * + * * @since 1.1 */ - static final JsonObject EMPTY_JSON_OBJECT = Json.createObjectBuilder().build(); + static final JsonObject EMPTY_JSON_OBJECT = new EmptyObject(); /** * The empty JSON array. - * + * * @since 1.1 */ - static final JsonArray EMPTY_JSON_ARRAY = Json.createArrayBuilder().build(); + static final JsonArray EMPTY_JSON_ARRAY = new EmptyArray(); /** * Indicates the type of a {@link JsonValue} object. diff --git a/api/src/main/java/javax/json/stream/JsonGenerationException.java b/api/src/main/java/javax/json/stream/JsonGenerationException.java index 9fbc2b0..a34a3ad 100644 --- a/api/src/main/java/javax/json/stream/JsonGenerationException.java +++ b/api/src/main/java/javax/json/stream/JsonGenerationException.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -69,7 +69,7 @@ public JsonGenerationException(String 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 null value is + * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) */ diff --git a/api/src/main/java/javax/json/stream/JsonParsingException.java b/api/src/main/java/javax/json/stream/JsonParsingException.java index d8b99e6..6d3fad6 100644 --- a/api/src/main/java/javax/json/stream/JsonParsingException.java +++ b/api/src/main/java/javax/json/stream/JsonParsingException.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -73,7 +73,7 @@ public JsonParsingException(String message, JsonLocation location) { * @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 null value is + * {@link #getCause()} method). (A null value is * permitted, and indicates that the cause is nonexistent or * unknown.) * @param location the location of the incorrect JSON diff --git a/api/src/main/javadoc/overview.html b/api/src/main/javadoc/overview.html index 77ff8d1..525683a 100644 --- a/api/src/main/javadoc/overview.html +++ b/api/src/main/javadoc/overview.html @@ -1,4 +1,46 @@ + + The Java API for JSON Processing provides portable APIs to parse, generate, transform, and query JSON using the diff --git a/bundles/licensee/pom.xml b/bundles/licensee/pom.xml index 8b4da27..2fd933a 100755 --- a/bundles/licensee/pom.xml +++ b/bundles/licensee/pom.xml @@ -45,7 +45,7 @@ org.glassfish json-bundles - 1.1.0-SNAPSHOT + 1.2-SNAPSHOT json-licensee-bundle diff --git a/bundles/ri/pom.xml b/bundles/ri/pom.xml index 52b06b1..ffcf243 100755 --- a/bundles/ri/pom.xml +++ b/bundles/ri/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012-2018 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 @@ -50,66 +50,97 @@ json-ri-bundle - RI bundle + RI Distribution zip bundle pom + + javax.json + javax.json-api + + + org.glassfish + javax.json + org.glassfish javax.json + module + + + org.glassfish + jsonp-jaxrs - - - - org.apache.maven.plugins - maven-dependency-plugin - - - copy - generate-sources - - copy - - - false - - - org.glassfish - javax.json - jar - false - ${assembly.directory} - - - - - - - - maven-assembly-plugin - - javax.json-ri-${impl_version} - - src/main/assembly/archive.xml - - false - - - - make-assembly - package - - single - - - - - - - - - ${project.build.directory}/assembly - + + + + default-setup + + (,9) + true + + + + + maven-assembly-plugin + + + make-assembly-jdk8 + package + + single + + + javax.json-ri-jdk8-${impl_version} + + src/main/assembly/archive-jdk8.xml + + false + + + + + + + + + jdk9-setup + + [9,) + + + + org.glassfish + javax.json + module + ${project.version} + + + + + + maven-assembly-plugin + + + make-assembly + package + + single + + + javax.json-ri-${impl_version} + + src/main/assembly/archive.xml + + false + + + + + + + + diff --git a/bundles/ri/src/main/assembly/archive-jdk8.xml b/bundles/ri/src/main/assembly/archive-jdk8.xml new file mode 100644 index 0000000..9f9112f --- /dev/null +++ b/bundles/ri/src/main/assembly/archive-jdk8.xml @@ -0,0 +1,85 @@ + + + + dist + + zip + + + + src/main/resources/README.txt + + true + + + src/main/resources/LICENSE.txt + + + + + + false + api + + javax.json:javax.json-api:* + + + + false + standalone + + org.glassfish:javax.json + + + org.glassfish:javax.json:jar:module:* + + + + false + jaxrs + + org.glassfish:jsonp-jaxrs* + + + + diff --git a/bundles/ri/src/main/assembly/archive.xml b/bundles/ri/src/main/assembly/archive.xml index 83ba35e..e66fd4f 100755 --- a/bundles/ri/src/main/assembly/archive.xml +++ b/bundles/ri/src/main/assembly/archive.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013-2018 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 @@ -45,17 +45,42 @@ zip - - - src/main/resources + + + src/main/resources/README.txt - - - target/assembly + true + + + src/main/resources/LICENSE.txt + + + + + + false + mods + + javax.json:javax.json-api:* + org.glassfish:javax.json:jar:module:* + + + + false + standalone + + org.glassfish:javax.json + + + org.glassfish:javax.json:jar:module:* + + + + false + jaxrs - *.jar + org.glassfish:jsonp-jaxrs* - lib - - + + diff --git a/bundles/ri/src/main/resources/README.txt b/bundles/ri/src/main/resources/README.txt index a0ab717..99d63d0 100644 --- a/bundles/ri/src/main/resources/README.txt +++ b/bundles/ri/src/main/resources/README.txt @@ -1,13 +1,51 @@ -* javax.json-1.1.jar contains both "JSR 374 : Java API for JSON Processing 1.1" API and its default provider implementation. Keep it in classpath for both compiling and running your application. +* standalone/javax.json-${project.version}.jar contains both "JSR 374 : Java API for JSON Processing 1.1" API + and its default provider implementation. Keep it in classpath for both compiling and running your application. + Automatic module name is: 'java.json' + +For running on JPMS, following modules are provided: +* mods/javax.json-api-${project.version}.jar - 'java.json' module containing only API classes +* mods/javax.json-${project.version}-module.jar - 'org.glassfish.java.json' module containing implementation + +Integration with JAX-RS: Java API for RESTful Web Services (JAX-RS) is provided through +* jaxrs/jsonp-jaxrs-${project.version}.jar + + +IMPORTANT NOTE: module names are not yet final and may change in the future releases + * If you are running with maven, you can use the following maven coordinates: +for standalone reference implementation which includes APIs and implementation classes: + + org.glassfish + javax.json + ${project.version} + + +for APIs: + + javax.json + javax.json-api + ${project.version} + + +for implementation only: org.glassfish javax.json - 1.1 + module + ${project.version} -* GlassFish 5.x already bundles latest JSON Processing implementation and JAX-RS integration module. If you deploy an application with GlassFish 5.x, your application (war/ear) doesn't have to bundle the ri jar. +for JAX-RS integration module: + + org.glassfish + jsonp-jaxrs + ${project.version} + + + +* GlassFish 5.x already bundles latest JSON Processing implementation and JAX-RS integration module. +If you deploy an application with GlassFish 5.x, your application (war/ear) doesn't have to bundle APIs nor the ri jar. * Samples can be run from https://github.com/javaee/glassfish-samples diff --git a/copyright-exclude b/copyright-exclude index 1a8820e..3fb6681 100644 --- a/copyright-exclude +++ b/copyright-exclude @@ -1,8 +1,9 @@ .json +.md /copyright-exclude /copyright.txt /META-INF/services -overview.html speclicense.html /bundles/ri/src/main/resources/LICENSE.txt /bundles/ri/src/main/resources/README.txt +/LICENSE.txt \ No newline at end of file diff --git a/demos/customprovider-jdk9/pom.xml b/demos/customprovider-jdk9/pom.xml index fc286c4..7d07203 100644 --- a/demos/customprovider-jdk9/pom.xml +++ b/demos/customprovider-jdk9/pom.xml @@ -106,8 +106,8 @@ - org.glassfish - javax.json + javax.json + javax.json-api junit diff --git a/demos/customprovider-jdk9/src/main/jdk9/module-info.java b/demos/customprovider-jdk9/src/main/jdk9/module-info.java index 94b06bc..bf07a91 100644 --- a/demos/customprovider-jdk9/src/main/jdk9/module-info.java +++ b/demos/customprovider-jdk9/src/main/jdk9/module-info.java @@ -39,7 +39,7 @@ */ module org.glassfish.java.json.demos.customprovider { - requires org.glassfish.java.json; + requires transitive java.json; exports org.glassfish.json.customprovider; provides javax.json.spi.JsonProvider with org.glassfish.json.customprovider.TestProvider; } diff --git a/demos/facebook/pom.xml b/demos/facebook/pom.xml index 17c4a36..f69411d 100644 --- a/demos/facebook/pom.xml +++ b/demos/facebook/pom.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012-2018 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 @@ -100,12 +100,18 @@ jdk9-setup - 9 + [9,) + + javax.json + javax.json-api + compile + org.glassfish javax.json + module compile diff --git a/demos/jsonpointer/pom.xml b/demos/jsonpointer/pom.xml index 2719468..6f40704 100644 --- a/demos/jsonpointer/pom.xml +++ b/demos/jsonpointer/pom.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013-2018 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 @@ -100,12 +100,18 @@ jdk9-setup - 9 + [9,) + + javax.json + javax.json-api + compile + org.glassfish javax.json + module compile diff --git a/demos/pom.xml b/demos/pom.xml index 68be010..4b4a52a 100644 --- a/demos/pom.xml +++ b/demos/pom.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012-2018 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 @@ -84,7 +84,7 @@ jdk9-all - 9 + [9,) jaxrs diff --git a/demos/twitter/pom.xml b/demos/twitter/pom.xml index c2331b6..764670f 100644 --- a/demos/twitter/pom.xml +++ b/demos/twitter/pom.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012-2018 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 @@ -88,12 +88,18 @@ jdk9-setup - 9 + [9,) + + javax.json + javax.json-api + compile + org.glassfish javax.json + module compile diff --git a/gf/pom.xml b/gf/pom.xml index af1c117..d831c85 100644 --- a/gf/pom.xml +++ b/gf/pom.xml @@ -2,7 +2,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012-2018 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 @@ -77,7 +77,7 @@ customprovider - customprovider - defaultprovider + customprovider + defaultprovider diff --git a/impl/pom.xml b/impl/pom.xml index 7117fa4..2b69407 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011-2018 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 @@ -59,74 +59,88 @@ Default provider for JSR 374:Java API for Processing JSON https://javaee.github.io/jsonp + + org.glassfish.json + javax.json.*,org.glassfish.json.api + + - org.apache.maven.plugins - maven-dependency-plugin + org.glassfish.build + spec-version-maven-plugin + + + ${non.final} + impl + ${spec_version} + ${new_spec_version} + ${new_spec_impl_version} + ${impl_version} + ${new_impl_version} + ${api_package} + ${impl_namespace} + + - unpack-client-sources - generate-sources - unpack + set-spec-properties + check-module - - - - javax.json - javax.json-api - ${project.version} - sources - false - ${project.build.directory}/sources - javax/json/** - - - - org.codehaus.mojo - build-helper-maven-plugin + org.apache.maven.plugins + maven-source-plugin + + true + + + + org.apache.maven.plugins + maven-resources-plugin - add-x-sources - generate-sources + sources-as-resources + package - add-source + copy-resources - - ${project.build.directory}/sources - + + + src/main/java + + + ${project.build.directory}/sources - org.glassfish.build - spec-version-maven-plugin - - - ${non.final} - impl - ${spec_version} - ${new_spec_version} - ${new_spec_impl_version} - ${impl_version} - ${new_impl_version} - javax.json - org.glassfish - - + org.apache.maven.plugins + maven-dependency-plugin + unpack-client-sources + package - set-spec-properties - check-module + unpack + + + + javax.json + javax.json-api + ${spec_impl_version} + sources + false + ${project.build.directory}/sources + + + @@ -149,6 +163,9 @@ org.apache.maven.plugins maven-javadoc-plugin + + true + attach-javadocs @@ -168,17 +185,27 @@ org.apache.felix maven-bundle-plugin true - - - ${spec.bundle.version} - ${spec.bundle.symbolic-name} - ${spec.extension.name} - ${spec.implementation.version} - ${spec.specification.version} - ${packages.export} - ${packages.private} - - + + + default-bundle + + bundle + + + + ${spec.bundle.version} + ${spec.bundle.symbolic-name} + ${spec.extension.name} + ${spec.implementation.version} + ${spec.specification.version} + ${packages.export} + ${packages.private} + java.json + <_donotcopy>.*services.* + + + + @@ -194,28 +221,37 @@ jdk9-setup - 9 + [9,) - - org.apache.maven.plugins - maven-javadoc-plugin - - false - - org.apache.felix maven-bundle-plugin - - - target/classes/module-info.class - - + + + main-artifact-module + + bundle + + + module + + ${spec.bundle.version} + ${spec.bundle.symbolic-name}.module + ${spec.extension.name} + ${spec.implementation.version} + ${spec.specification.version} + org.glassfish.json.api + ${packages.private} + {maven-resources},target/classes/module-info.class + + + + - + \ No newline at end of file diff --git a/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java b/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java index c1bfe04..f111644 100644 --- a/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonGeneratorImpl.java @@ -293,6 +293,7 @@ public JsonGenerator write(JsonValue value) { case NUMBER: JsonNumber number = (JsonNumber)value; writeValue(number.toString()); + popFieldContext(); break; case TRUE: write(true); @@ -504,12 +505,16 @@ public JsonGenerator writeEnd() { } protected void writeComma() { - if (!currentContext.first && currentContext.scope != Scope.IN_FIELD) { + if (isCommaAllowed()) { writeChar(','); } currentContext.first = false; } + boolean isCommaAllowed() { + return !currentContext.first && currentContext.scope != Scope.IN_FIELD; + } + protected void writeColon() { writeChar(':'); } diff --git a/impl/src/main/java/org/glassfish/json/JsonMessages.java b/impl/src/main/java/org/glassfish/json/JsonMessages.java index a195431..3f92eec 100644 --- a/impl/src/main/java/org/glassfish/json/JsonMessages.java +++ b/impl/src/main/java/org/glassfish/json/JsonMessages.java @@ -269,8 +269,8 @@ static String PATCH_MOVE_TARGET_NULL(String from) { return localize("patch.move.target.null", from); } - static String PATCH_TEST_FAILED() { - return localize("patch.test.failed"); + static String PATCH_TEST_FAILED(String path, String value) { + return localize("patch.test.failed", path, value); } static String PATCH_ILLEGAL_OPERATION(String operation) { diff --git a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java index e432c9e..56c9781 100644 --- a/impl/src/main/java/org/glassfish/json/JsonParserImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonParserImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2024 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 @@ -78,27 +78,39 @@ */ public class JsonParserImpl implements JsonParser { + /** + * Configuration property to limit maximum level of nesting when being parsing JSON string. + * Default value is set to {@code 1000}. + */ + public static String MAX_DEPTH = "org.eclipse.parsson.maxDepth"; + + /** Default maximum level of nesting. */ + private static final int DEFAULT_MAX_DEPTH = 1000; + private final BufferPool bufferPool; private Context currentContext = new NoneContext(); private Event currentEvent; - private final Stack stack = new Stack(); + private final Stack stack; private final JsonTokenizer tokenizer; public JsonParserImpl(Reader reader, BufferPool bufferPool) { this.bufferPool = bufferPool; tokenizer = new JsonTokenizer(reader, bufferPool); + stack = new Stack(propertyStringToInt(MAX_DEPTH, DEFAULT_MAX_DEPTH)); } public JsonParserImpl(InputStream in, BufferPool bufferPool) { this.bufferPool = bufferPool; UnicodeDetectingInputStream uin = new UnicodeDetectingInputStream(in); tokenizer = new JsonTokenizer(new InputStreamReader(uin, uin.getCharset()), bufferPool); + stack = new Stack(propertyStringToInt(MAX_DEPTH, DEFAULT_MAX_DEPTH)); } public JsonParserImpl(InputStream in, Charset encoding, BufferPool bufferPool) { this.bufferPool = bufferPool; tokenizer = new JsonTokenizer(new InputStreamReader(in, encoding), bufferPool); + stack = new Stack(propertyStringToInt(MAX_DEPTH, DEFAULT_MAX_DEPTH)); } @Override @@ -306,6 +318,7 @@ public void skipArray() { if (currentEvent == Event.START_ARRAY) { currentContext.skip(); currentContext = stack.pop(); + currentEvent = Event.END_ARRAY; } } @@ -314,6 +327,7 @@ public void skipObject() { if (currentEvent == Event.START_OBJECT) { currentContext.skip(); currentContext = stack.pop(); + currentEvent = Event.END_OBJECT; } } @@ -352,7 +366,18 @@ public JsonLocation getLastCharLocation() { @Override public boolean hasNext() { - return tokenizer.hasNextToken(); + if (stack.isEmpty() && (currentEvent != null && currentEvent.compareTo(Event.KEY_NAME) > 0)) { + JsonToken token = tokenizer.nextToken(); + if (token != JsonToken.EOF) { + throw new JsonParsingException(JsonMessages.PARSER_EXPECTED_EOF(token), + getLastCharLocation()); + } + return false; + } else if (!stack.isEmpty() && !tokenizer.hasNextToken()) { + currentEvent = currentContext.getNextEvent(); + return false; + } + return true; } @Override @@ -375,9 +400,19 @@ public void close() { // Using the optimized stack impl as we don't require other things // like iterator etc. private static final class Stack { + private int size = 0; + private final int limit; + + private Stack(int size) { + this.limit = size; + } + private Context head; private void push(Context context) { + if (++size >= limit) { + throw new RuntimeException("Input is too deeply nested " + size); + } context.next = head; head = context; } @@ -386,6 +421,7 @@ private Context pop() { if (head == null) { throw new NoSuchElementException(); } + size--; Context temp = head; head = head.next; return temp; @@ -451,7 +487,16 @@ private final class ObjectContext extends Context { public Event getNextEvent() { // Handle 1. } 2. name:value 3. ,name:value JsonToken token = tokenizer.nextToken(); - if (currentEvent == Event.KEY_NAME) { + if (token == JsonToken.EOF) { + switch (currentEvent) { + case START_OBJECT: + throw parsingException(token, "[STRING, CURLYCLOSE]"); + case KEY_NAME: + throw parsingException(token, "[COLON]"); + default: + throw parsingException(token, "[COMMA, CURLYCLOSE]"); + } + } else if (currentEvent == Event.KEY_NAME) { // Handle 1. :value if (token != JsonToken.COLON) { throw parsingException(token, "[COLON]"); @@ -516,6 +561,14 @@ private final class ArrayContext extends Context { @Override public Event getNextEvent() { JsonToken token = tokenizer.nextToken(); + if (token == JsonToken.EOF) { + switch (currentEvent) { + case START_ARRAY: + throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]"); + default: + throw parsingException(token, "[COMMA, CURLYCLOSE]"); + } + } if (token == JsonToken.SQUARECLOSE) { currentContext = stack.pop(); return Event.END_ARRAY; @@ -560,4 +613,7 @@ void skip() { } } -} + static int propertyStringToInt(String propertyName, int defaultValue) throws JsonException { + return Integer.getInteger(propertyName, defaultValue); + } +} \ No newline at end of file diff --git a/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java b/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java index 240176f..5a31b2c 100644 --- a/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java @@ -193,7 +193,7 @@ private JsonStructure apply(JsonStructure target, JsonObject operation) { return pointer.add(from.remove(target), from.getValue(target)); case TEST: if (! getValue(operation).equals(pointer.getValue(target))) { - throw new JsonException(JsonMessages.PATCH_TEST_FAILED()); + throw new JsonException(JsonMessages.PATCH_TEST_FAILED(operation.getString("path"), getValue(operation).toString())); } return target; default: @@ -289,32 +289,42 @@ private void diffArray(String path, JsonArray source, JsonArray target) { } } - 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)); - } - } - } + emit(path, source, target, c, m, n); + } + + private void emit(final String path, + final JsonArray source, + final JsonArray target, + final int[][] c, + final int i, + final int j) { + if (i == 0) { + if (j > 0) { + emit(path, source, target, c, i, j - 1); + builder.add(path + '/' + (j - 1), target.get(j - 1)); + } + } else if (j == 0) { + if (i > 0) { + builder.remove(path + '/' + (i - 1)); + emit(path, source, target, c, i - 1, j); + } + } else if ((c[i][j] & 1) == 1) { + emit(path, source, target, c, i - 1, j - 1); + } else { + final int f = c[i][j-1] >> 1; + final int g = c[i-1][j] >> 1; + if (f > g) { + emit(path, source, target, c, i, j - 1); + builder.add(path + '/' + (j - 1), target.get(j - 1)); + } else if (f < g) { + builder.remove(path + '/' + (i - 1)); + emit(path, source, target, c, i - 1, j); + } else { // f == g) { + diff(path + '/' + (i - 1), source.get(i - 1), + target.get(j - 1)); + emit(path, source, target, c, i - 1, j - 1); + } + } } } } diff --git a/impl/src/main/java/org/glassfish/json/JsonPointerImpl.java b/impl/src/main/java/org/glassfish/json/JsonPointerImpl.java index 95e42e3..149dcc2 100644 --- a/impl/src/main/java/org/glassfish/json/JsonPointerImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonPointerImpl.java @@ -273,6 +273,9 @@ private NodeReference[] getReferences(JsonStructure target) { JsonArray array = (JsonArray) value; references[s-i-1] = NodeReference.of(array, index); if (i < s-1 && index != -1) { + if (index >= array.size()) { + throw new JsonException(JsonMessages.NODEREF_ARRAY_INDEX_ERR(index, array.size())); + } // The last array index in the path can have index value of -1 // ("-" in the JSON pointer) value = array.get(index); diff --git a/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java b/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java index dcf45b8..0e58a8e 100644 --- a/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonPrettyGeneratorImpl.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -112,8 +112,10 @@ private void writeIndent() { @Override protected void writeComma() { super.writeComma(); - writeChar('\n'); - writeIndent(); + if (isCommaAllowed()) { + writeChar('\n'); + writeIndent(); + } } @Override diff --git a/impl/src/main/jdk9/module-info.java b/impl/src/main/jdk9/module-info.java index fb3d58c..85e8dd9 100644 --- a/impl/src/main/jdk9/module-info.java +++ b/impl/src/main/jdk9/module-info.java @@ -39,9 +39,7 @@ */ module org.glassfish.java.json { - exports javax.json; - exports javax.json.spi; - exports javax.json.stream; + requires transitive java.json; exports org.glassfish.json.api; - uses javax.json.spi.JsonProvider; -} + provides javax.json.spi.JsonProvider with org.glassfish.json.JsonProviderImpl; +} \ No newline at end of file diff --git a/impl/src/main/resources/META-INF/services/javax.json.spi.JsonProvider b/impl/src/main/resources/META-INF/services/javax.json.spi.JsonProvider new file mode 100644 index 0000000..52f1a6b --- /dev/null +++ b/impl/src/main/resources/META-INF/services/javax.json.spi.JsonProvider @@ -0,0 +1 @@ +org.glassfish.json.JsonProviderImpl diff --git a/impl/src/main/resources/org/glassfish/json/messages.properties b/impl/src/main/resources/org/glassfish/json/messages.properties index a924010..42ebcc9 100644 --- a/impl/src/main/resources/org/glassfish/json/messages.properties +++ b/impl/src/main/resources/org/glassfish/json/messages.properties @@ -107,6 +107,6 @@ noderef.array.index.err=An array item index is out of range. Index: {0}, Size: { patch.must.be.array=A JSON Patch must be an array of JSON Objects patch.move.proper.prefix=The ''{0}'' path of the patch operation ''move'' is a proper prefix of the ''{1}'' path patch.move.target.null=The ''{0}'' path of the patch operation ''move'' does not exist in target object -patch.test.failed=The JSON Patch operation ''test'' failed +patch.test.failed=The JSON Patch operation ''test'' failed for path ''{0}'' and value ''{1}'' patch.illegal.operation=Illegal value for the op member of the JSON Patch operation: ''{0}'' patch.member.missing=The JSON Patch operation ''{0}'' must contain a ''{1}'' member diff --git a/jaxrs-1x/pom.xml b/jaxrs-1x/pom.xml index a86a23a..7a9ef69 100644 --- a/jaxrs-1x/pom.xml +++ b/jaxrs-1x/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013-2018 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 @@ -108,7 +108,7 @@ jdk9-setup - 9 + [9,) diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml index db1e385..34629de 100644 --- a/jaxrs/pom.xml +++ b/jaxrs/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2013-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2013-2018 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 @@ -96,6 +96,7 @@ javax.ws.rs javax.ws.rs-api + provided javax.json @@ -108,7 +109,7 @@ jdk9-setup - 9 + [9,) diff --git a/pom.xml b/pom.xml index 122075e..3326349 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011-2018 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 @@ -100,11 +100,9 @@ org.glassfish 1.1 1.2 - 1.1 - 1.1 + 1.1.4 + 1.1.4 1.2 - org.glassfish.* - javax.json.* false @@ -114,14 +112,9 @@ org.apache.maven.plugins maven-compiler-plugin - - org.apache.maven.plugins - maven-source-plugin - org.glassfish.copyright glassfish-copyright-maven-plugin - 1.40 copyright.txt copyright-exclude @@ -130,10 +123,22 @@ false + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar-no-fork + + + + org.apache.maven.plugins maven-release-plugin - 2.5.1 forked-path false @@ -149,46 +154,40 @@ spec-version-maven-plugin 1.2 + + org.glassfish.copyright + glassfish-copyright-maven-plugin + 1.46 + org.apache.felix maven-bundle-plugin - 3.2.0 - - - biz.aQute.bnd - biz.aQute.bndlib - 3.3.0 - - + 3.5.0 + + + <_noee>true + + org.codehaus.mojo build-helper-maven-plugin - 1.9.1 + 3.0.0 org.apache.maven.plugins maven-javadoc-plugin - 3.0.0-M1 + 3.0.1 org.apache.maven.plugins maven-source-plugin 3.0.1 - - - attach-sources - verify - - jar-no-fork - - - org.apache.maven.plugins maven-compiler-plugin - 3.6.0 + 3.7.0 1.8 1.8 @@ -200,32 +199,32 @@ org.apache.maven.plugins maven-war-plugin - 3.1.0 + 3.2.1 org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.1.0 org.apache.maven.plugins maven-dependency-plugin - 3.0.0 + 3.1.0 org.apache.maven.plugins maven-resources-plugin - 3.0.2 + 3.1.0 org.codehaus.mojo wagon-maven-plugin - 1.0 + 2.0.0 org.apache.maven.plugins maven-clean-plugin - 3.0.0 + 3.1.0 org.apache.maven.plugins @@ -240,22 +239,34 @@ org.apache.maven.plugins maven-site-plugin - 3.6 + 3.7.1 org.apache.maven.plugins maven-surefire-plugin - 2.19.1 + 2.22.0 org.codehaus.mojo exec-maven-plugin - 1.5.0 + 1.6.0 org.apache.maven.plugins maven-assembly-plugin - 3.0.0 + 3.1.0 + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + + org.apache.maven.scm + maven-scm-provider-gitexe + 1.9.5 + + @@ -284,6 +295,17 @@ javax.json ${project.version} + + org.glassfish + javax.json + module + ${project.version} + + + org.glassfish + jsonp-jaxrs + ${project.version} + javax.ws.rs jsr311-api @@ -311,7 +333,7 @@ jdk9-setup - 9 + [9,) @@ -344,15 +366,6 @@ - - org.apache.felix - maven-bundle-plugin - - - <_failok>true - - - @@ -380,7 +393,7 @@ jdk9-all - 9 + [9,) api @@ -450,7 +463,7 @@ org.codehaus.mojo findbugs-maven-plugin - 2.5.3 + 3.0.5 diff --git a/tests/src/test/java/org/glassfish/json/JsonParserImplTest.java b/tests/src/test/java/org/glassfish/json/JsonParserImplTest.java new file mode 100644 index 0000000..95618b3 --- /dev/null +++ b/tests/src/test/java/org/glassfish/json/JsonParserImplTest.java @@ -0,0 +1,90 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2024 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://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or 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 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 static org.junit.Assert.assertEquals; + +import javax.json.JsonException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class JsonParserImplTest { + + private String previousValue; + + @Before + public void before() { + previousValue = System.getProperty(JsonParserImpl.MAX_DEPTH); + System.getProperties().remove(JsonParserImpl.MAX_DEPTH); + } + + @After + public void after() { + if (previousValue != null) { + System.setProperty(JsonParserImpl.MAX_DEPTH, previousValue); + } else { + System.getProperties().remove(JsonParserImpl.MAX_DEPTH); + } + } + + @Test + public void undefined() { + System.getProperties().remove(JsonParserImpl.MAX_DEPTH); + int result = JsonParserImpl.propertyStringToInt(JsonParserImpl.MAX_DEPTH, -1); + assertEquals(-1, result); + } + + @Test + public void notInteger() { + System.setProperty(JsonParserImpl.MAX_DEPTH, "String"); + int result = JsonParserImpl.propertyStringToInt(JsonParserImpl.MAX_DEPTH, -10); + assertEquals(-10, result); + } + + @Test + public void integer() { + System.setProperty(JsonParserImpl.MAX_DEPTH, "10"); + int result = JsonParserImpl.propertyStringToInt(JsonParserImpl.MAX_DEPTH, -1); + assertEquals(10, result); + } +} diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java index f32cef2..6b05634 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonGeneratorTest.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -235,6 +235,31 @@ public void testPrettyObjectWriter() throws Exception { JsonObjectTest.testPerson(person); } + public void testPrettyPrinting() throws Exception { + String[][] lines = {{"firstName", "John"}, {"lastName", "Smith"}}; + StringWriter writer = new StringWriter(); + Map config = new HashMap<>(); + config.put(JsonGenerator.PRETTY_PRINTING, true); + JsonGenerator generator = Json.createGeneratorFactory(config) + .createGenerator(writer); + generator.writeStartObject() + .write("firstName", "John") + .write("lastName", "Smith") + .writeEnd(); + generator.close(); + writer.close(); + BufferedReader reader = new BufferedReader(new StringReader(writer.toString().trim())); + int numberOfLines = 0; + String line; + while ((line = reader.readLine()) != null) { + numberOfLines++; + if (numberOfLines > 1 && numberOfLines < 4) { + assertTrue(line.contains("\"" + lines[numberOfLines - 2][0] + "\": \"" + lines[numberOfLines - 2][1] + "\"")); + } + } + assertEquals(4, numberOfLines); + } + public void testPrettyObjectStream() throws Exception { ByteArrayOutputStream out = new ByteArrayOutputStream(); Map config = new HashMap<>(); diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonNestingTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonNestingTest.java new file mode 100644 index 0000000..e02becb --- /dev/null +++ b/tests/src/test/java/org/glassfish/json/tests/JsonNestingTest.java @@ -0,0 +1,117 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2024 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://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or 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 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.Json; +import javax.json.stream.JsonParser; +import org.junit.Test; + +import java.io.StringReader; + +public class JsonNestingTest { + + @Test(expected = RuntimeException.class) + public void testArrayNestingException() { + String json = createDeepNestedDoc(500); + try (JsonParser parser = Json.createParser(new StringReader(json))) { + while (parser.hasNext()) { + JsonParser.Event ev = parser.next(); + if (JsonParser.Event.START_ARRAY == ev) { + parser.getArray(); + } + } + } + } + + @Test + public void testArrayNesting() { + String json = createDeepNestedDoc(499); + try (JsonParser parser = Json.createParser(new StringReader(json))) { + while (parser.hasNext()) { + JsonParser.Event ev = parser.next(); + if (JsonParser.Event.START_ARRAY == ev) { + parser.getArray(); + } + } + } + } + + @Test(expected = RuntimeException.class) + public void testObjectNestingException() { + String json = createDeepNestedDoc(500); + try (JsonParser parser = Json.createParser(new StringReader(json))) { + while (parser.hasNext()) { + JsonParser.Event ev = parser.next(); + if (JsonParser.Event.START_OBJECT == ev) { + parser.getObject(); + } + } + } + } + + @Test + public void testObjectNesting() { + String json = createDeepNestedDoc(499); + try (JsonParser parser = Json.createParser(new StringReader(json))) { + while (parser.hasNext()) { + JsonParser.Event ev = parser.next(); + if (JsonParser.Event.START_OBJECT == ev) { + parser.getObject(); + } + } + } + } + + private static String createDeepNestedDoc(final int depth) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = 0; i < depth; i++) { + sb.append("{ \"a\": ["); + } + sb.append(" \"val\" "); + for (int i = 0; i < depth; i++) { + sb.append("]}"); + } + sb.append("]"); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java index 7c8bacc..38008f4 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonParserTest.java @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright (c) 2012-2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012-2018 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 @@ -60,6 +60,7 @@ import java.util.NoSuchElementException; import java.util.Random; import java.util.Scanner; +import javax.json.stream.JsonParsingException; import org.glassfish.json.api.BufferPool; @@ -787,4 +788,64 @@ public void testStringUsingBuffers() throws Throwable { } } -} + public void testExceptionsFromHasNext() { + checkExceptionFromHasNext("{"); + checkExceptionFromHasNext("{\"key\""); + checkExceptionFromHasNext("{\"name\" : \"prop\""); + checkExceptionFromHasNext("{\"name\" : 3"); + checkExceptionFromHasNext("{\"name\" : true"); + checkExceptionFromHasNext("{\"name\" : null"); + checkExceptionFromHasNext("{\"name\" : {\"$eq\":\"cdc\"}"); + checkExceptionFromHasNext("{\"name\" : [{\"$eq\":\"cdc\"}]"); + checkExceptionFromHasNext("["); + checkExceptionFromHasNext("{\"name\" : [{\"key\" : [[{\"a\" : 1}]"); + checkExceptionFromHasNext("{\"unique\":true,\"name\":\"jUnitTestIndexNeg005\", \"fields\":[{\"order\":-1,\"path\":\"city.zip\"}"); + } + + public void testEOFFromHasNext() { + checkExceptionFromHasNext("{ \"d\" : 1 } 2 3 4"); + checkExceptionFromHasNext("[ {\"d\" : 1 }] 2 3 4"); + checkExceptionFromHasNext("1 2 3 4"); + checkExceptionFromHasNext("null 2 3 4"); + } + + public void testExceptionsFromNext() { + checkExceptionFromNext("{\"name\" : fal"); + checkExceptionFromNext("{\"name\" : nu"); + checkExceptionFromNext("{\"name\" : \"pro"); + checkExceptionFromNext("{\"key\":"); + checkExceptionFromNext("fal"); + } + + private void checkExceptionFromHasNext(String input) { + try (JsonParser parser = Json.createParser(new StringReader(input))) { + try { + while (parser.hasNext()) { + try { + parser.next(); + } catch (Throwable t1) { + fail("Exception should occur from hasNext() for '" + input + "'"); + } + } + } catch (JsonParsingException t) { + //this is OK + return; + } + } + fail(); + } + + private void checkExceptionFromNext(String input) { + try (JsonParser parser = Json.createParser(new StringReader(input))) { + while (parser.hasNext()) { + try { + parser.next(); + } catch (JsonParsingException t) { + //this is OK + return; + } + } + } + fail(); + } +} \ No newline at end of file diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonPatchBugsTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonPatchBugsTest.java new file mode 100644 index 0000000..978670d --- /dev/null +++ b/tests/src/test/java/org/glassfish/json/tests/JsonPatchBugsTest.java @@ -0,0 +1,69 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright (c) 2017 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://oss.oracle.com/licenses/CDDL+GPL-1.1 + * or 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 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.Json; +import javax.json.JsonArray; +import javax.json.JsonException; +import javax.json.JsonPatch; +import org.junit.Test; + +/** + * + * @author lukas + */ +public class JsonPatchBugsTest { + + // https://github.com/javaee/jsonp/issues/58 + @Test(expected = JsonException.class) + public void applyThrowsJsonException() { + JsonArray array = Json.createArrayBuilder() + .add(Json.createObjectBuilder() + .add("name", "Bob") + .build()) + .build(); + JsonPatch patch = Json.createPatchBuilder() + .replace("/0/name", "Bobek") + .replace("/1/name", "Vila Amalka") + .build(); + JsonArray result = patch.apply(array); + } +} diff --git a/tests/src/test/java/org/glassfish/json/tests/JsonValueTest.java b/tests/src/test/java/org/glassfish/json/tests/JsonValueTest.java index 09c2dab..1a22eac 100644 --- a/tests/src/test/java/org/glassfish/json/tests/JsonValueTest.java +++ b/tests/src/test/java/org/glassfish/json/tests/JsonValueTest.java @@ -37,7 +37,6 @@ * only if the new code is made subject to such option by the copyright * holder. */ - package org.glassfish.json.tests; import java.io.ByteArrayInputStream; @@ -45,6 +44,9 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.util.Collections; +import javax.json.JsonObject; +import javax.json.JsonString; import javax.json.JsonValue; import org.junit.Assert; import org.junit.Test; @@ -55,6 +57,99 @@ */ public class JsonValueTest { + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetJsonObjectIdx() { + JsonValue.EMPTY_JSON_ARRAY.getJsonObject(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetJsonArrayIdx() { + JsonValue.EMPTY_JSON_ARRAY.getJsonArray(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetJsonNumberIdx() { + JsonValue.EMPTY_JSON_ARRAY.getJsonNumber(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetJsonStringIdx() { + JsonValue.EMPTY_JSON_ARRAY.getJsonString(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetStringIdx() { + JsonValue.EMPTY_JSON_ARRAY.getString(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetIntIdx() { + JsonValue.EMPTY_JSON_ARRAY.getInt(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayGetBooleanIdx() { + JsonValue.EMPTY_JSON_ARRAY.getBoolean(0); + } + + @Test(expected = IndexOutOfBoundsException.class) + public void arrayIsNull() { + JsonValue.EMPTY_JSON_ARRAY.isNull(0); + } + + @Test + public void arrayMethods() { + Assert.assertEquals(JsonValue.ValueType.ARRAY, JsonValue.EMPTY_JSON_ARRAY.getValueType()); + Assert.assertEquals(Collections.emptyList(), JsonValue.EMPTY_JSON_ARRAY.getValuesAs(JsonObject.class)); + Assert.assertEquals(Collections.emptyList(), JsonValue.EMPTY_JSON_ARRAY.getValuesAs(JsonString::getString)); + Assert.assertEquals(true, JsonValue.EMPTY_JSON_ARRAY.getBoolean(0, true)); + Assert.assertEquals(42, JsonValue.EMPTY_JSON_ARRAY.getInt(0, 42)); + Assert.assertEquals("Sasek", JsonValue.EMPTY_JSON_ARRAY.getString(0, "Sasek")); + } + + @Test(expected = UnsupportedOperationException.class) + public void arrayIsImmutable() { + JsonValue.EMPTY_JSON_ARRAY.add(JsonValue.EMPTY_JSON_OBJECT); + } + + @Test(expected = NullPointerException.class) + public void objectGetString() { + JsonValue.EMPTY_JSON_OBJECT.getString("normalni string"); + } + + @Test(expected = NullPointerException.class) + public void objectGetInt() { + JsonValue.EMPTY_JSON_OBJECT.getInt("hledej cislo"); + } + + @Test(expected = NullPointerException.class) + public void objectGetBoolean() { + JsonValue.EMPTY_JSON_OBJECT.getBoolean("booo"); + } + + @Test(expected = NullPointerException.class) + public void objectIsNull() { + JsonValue.EMPTY_JSON_OBJECT.isNull("???"); + } + + @Test + public void objectMethods() { + Assert.assertNull(JsonValue.EMPTY_JSON_OBJECT.getJsonArray("pole")); + Assert.assertNull(JsonValue.EMPTY_JSON_OBJECT.getJsonObject("objekt")); + Assert.assertNull(JsonValue.EMPTY_JSON_OBJECT.getJsonNumber("cislo")); + Assert.assertNull(JsonValue.EMPTY_JSON_OBJECT.getJsonString("divnej string")); + + Assert.assertEquals("ja jo", JsonValue.EMPTY_JSON_OBJECT.getString("nejsem tu", "ja jo")); + Assert.assertEquals(false, JsonValue.EMPTY_JSON_OBJECT.getBoolean("najdes mne", false)); + Assert.assertEquals(98, JsonValue.EMPTY_JSON_OBJECT.getInt("spatnej dotaz", 98)); + } + + + @Test(expected = UnsupportedOperationException.class) + public void objectImmutable() { + JsonValue.EMPTY_JSON_OBJECT.put("klauni", JsonValue.EMPTY_JSON_ARRAY); + } + @Test public void serialization() { byte[] data = serialize(JsonValue.TRUE); @@ -68,6 +163,14 @@ public void serialization() { data = serialize(JsonValue.NULL); value = deserialize(JsonValue.class, data); Assert.assertEquals(JsonValue.NULL, value); + + data = serialize(JsonValue.EMPTY_JSON_ARRAY); + value = deserialize(JsonValue.class, data); + Assert.assertEquals(JsonValue.EMPTY_JSON_ARRAY, value); + + data = serialize(JsonValue.EMPTY_JSON_OBJECT); + value = deserialize(JsonValue.class, data); + Assert.assertEquals(JsonValue.EMPTY_JSON_OBJECT, value); } private byte[] serialize(Object o) { diff --git a/tests/src/test/resources/jsonpatchdiff.json b/tests/src/test/resources/jsonpatchdiff.json index ce3be5f..529b79e 100644 --- a/tests/src/test/resources/jsonpatchdiff.json +++ b/tests/src/test/resources/jsonpatchdiff.json @@ -8,8 +8,8 @@ "original": [ 1, 2, 3 ], "target": [ 1, 2, 3, 4, 5 ], "expected": [ - {"op":"add","path":"/4","value":5}, - {"op":"add","path":"/3","value":4} + {"op":"add","path":"/3","value":4}, + {"op":"add","path":"/4","value":5} ] }, { @@ -25,8 +25,8 @@ "target": [1,7,3,4,8,5], "expected": [ { "op": "remove", "path": "/5"}, - { "op": "add", "path": "/4", "value": 8}, - { "op": "replace", "path": "/1", "value": 7} + { "op": "replace", "path": "/1", "value": 7}, + { "op": "add", "path": "/4", "value": 8} ] }, { @@ -94,8 +94,8 @@ "a": [ "b", 2, 3, 4 ] }, "expected": [ - { "op": "add", "path": "/a/3", "value": 4 }, - { "op": "replace", "path": "/a/0", "value": "b" } + { "op": "replace", "path": "/a/0", "value":"b" }, + { "op": "add", "path": "/a/3", "value":4 } ] }, { @@ -128,5 +128,33 @@ "expected": [ { "op": "add", "path": "/d", "value": "c" } ] + }, + { + "original": [-1, 0, 1, 3, 4], + "target": [5, 0], + "expected": [ + { "path" : "/4", "op" : "remove"}, + { "path" : "/3", "op" : "remove"}, + { "path" : "/2", "op" : "remove"}, + { "value" : 5, "path" : "/0", "op" : "replace" } + ] + }, + { + "original": [0], + "target": [0, 1, 2, 3, 4], + "expected": [ + { "path" : "/1", "value" : 1, "op" : "add" }, + { "path" : "/2", "value" : 2, "op" : "add" }, + { "value" : 3, "path" : "/3", "op" : "add" }, + { "op" : "add", "path" : "/4", "value" : 4 } + ] + }, + { + "original": [0, 2, 4], + "target": [0, 1, 2, 3, 4], + "expected": [ + { "path" : "/1", "value" : 1, "op" : "add" }, + { "value" : 3, "op" : "add", "path" : "/3" } + ] } ]