[JOHNZON-325] jsonp-strict module
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/DefaultJsonPointerFactory.java b/johnzon-core/src/main/java/org/apache/johnzon/core/DefaultJsonPointerFactory.java
new file mode 100644
index 0000000..152f029
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/DefaultJsonPointerFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.core;
+
+import org.apache.johnzon.core.spi.JsonPointerFactory;
+
+import javax.json.JsonPointer;
+import javax.json.spi.JsonProvider;
+
+public class DefaultJsonPointerFactory implements JsonPointerFactory {
+ @Override
+ public JsonPointer createPointer(final JsonProvider provider, final String path) {
+ return new JsonPointerImpl(provider, path);
+ }
+}
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
index 390c438..41ceedf 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
@@ -29,6 +29,7 @@
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.json.JsonPatch;
+import javax.json.JsonPointer;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import javax.json.spi.JsonProvider;
@@ -147,9 +148,11 @@
static class PatchValue {
private final JsonProvider provider;
private final JsonPatch.Operation operation;
- private final JsonPointerImpl path;
- private final JsonPointerImpl from;
+ private final JsonPointer path;
+ private final JsonPointer from;
private final JsonValue value;
+ private final String pathPtr;
+ private final String fromPtr;
private volatile String str;
private volatile JsonObject json;
@@ -162,11 +165,13 @@
final JsonValue value) {
this.provider = provider;
this.operation = operation;
- this.path = new JsonPatchPointerImpl(provider, path);
+ this.path = provider.createPointer(path);
+ this.pathPtr = path;
+ this.fromPtr = from;
// ignore from if we do not need it
if (operation == JsonPatch.Operation.MOVE || operation == JsonPatch.Operation.COPY) {
- this.from = new JsonPatchPointerImpl(provider, from);
+ this.from = provider.createPointer(from);
} else {
this.from = null;
}
@@ -233,10 +238,10 @@
if (json == null) {
JsonObjectBuilder builder = provider.createObjectBuilder()
.add("op", operation.name().toLowerCase())
- .add("path", path.getJsonPointer());
+ .add("path", pathPtr);
- if (from != null) {
- builder.add("from", from.getJsonPointer());
+ if (fromPtr != null) {
+ builder.add("from", fromPtr);
}
if (value != null) {
@@ -250,24 +255,4 @@
return json;
}
}
-
- public static class JsonPatchPointerImpl extends JsonPointerImpl {
-
- /**
- * Constructs and initializes a JsonPointer.
- *
- * @param provider the JsonProvider
- * @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 JsonPatchPointerImpl(final JsonProvider provider, final String jsonPointer) {
- super(provider, jsonPointer);
- }
-
- @Override
- protected int minusShift() {
- return 1;
- }
- }
}
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
index 2f1a76d..036986e 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
@@ -499,7 +499,7 @@
* @return the shift to apply on minus. For pointer, it's 0 because we need the element right after the last.
*/
protected int minusShift() {
- return 0;
+ return 1;
}
private void validateJsonPointer(JsonValue target, int size) throws NullPointerException, JsonException {
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
index 282f286..c3147d9 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
@@ -18,6 +18,8 @@
*/
package org.apache.johnzon.core;
+import org.apache.johnzon.core.spi.JsonPointerFactory;
+
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
@@ -27,7 +29,9 @@
import java.math.BigInteger;
import java.util.Collection;
import java.util.Map;
+import java.util.ServiceLoader;
import java.util.function.Supplier;
+import java.util.stream.StreamSupport;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
@@ -52,6 +56,8 @@
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParserFactory;
+import static java.util.Comparator.comparing;
+
public class JsonProviderImpl extends JsonProvider implements Serializable {
private final Supplier<BufferStrategy.BufferProvider<char[]>> bufferProvider = new Cached<>(() ->
BufferStrategyFactory.valueOf(System.getProperty(AbstractJsonFactory.BUFFER_STRATEGY, "QUEUE"))
@@ -63,6 +69,13 @@
private final JsonWriterFactory writerFactory = new JsonWriterFactoryImpl(null);
private final Supplier<JsonBuilderFactory> builderFactory = new Cached<>(() ->
new JsonBuilderFactoryImpl(null, bufferProvider.get()));
+ private final JsonPointerFactory jsonPointerFactory;
+
+ public JsonProviderImpl() {
+ jsonPointerFactory = StreamSupport.stream(ServiceLoader.load(JsonPointerFactory.class).spliterator(), false)
+ .min(comparing(JsonPointerFactory::ordinal))
+ .orElseGet(DefaultJsonPointerFactory::new);
+ }
@Override
public JsonParser createParser(final InputStream in) {
@@ -203,7 +216,7 @@
@Override
public JsonPointer createPointer(String path) {
- return new JsonPointerImpl(this, path);
+ return jsonPointerFactory.createPointer(this, path);
}
@Override
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/spi/JsonPointerFactory.java b/johnzon-core/src/main/java/org/apache/johnzon/core/spi/JsonPointerFactory.java
new file mode 100644
index 0000000..1b0a51a
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/spi/JsonPointerFactory.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.core.spi;
+
+import javax.json.JsonPointer;
+import javax.json.spi.JsonProvider;
+
+public interface JsonPointerFactory {
+ JsonPointer createPointer(JsonProvider provider, String path);
+
+ default int ordinal() {
+ return 0;
+ }
+}
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
index f9e782c..8389f41 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
@@ -455,8 +455,7 @@
assertEquals("[[\"bar\",\"baz\"]]", result.toString()); // [["bar","baz"]]
}
- @Test(expected = JsonException.class)
- public void testRemoveLastArrayElement() {
+ public void testRemoveLastArrayElementWithPatch() {
JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/0/-");
JsonStructure target = Json.createArrayBuilder()
.add(Json.createArrayBuilder()
@@ -468,90 +467,6 @@
assertEquals("[[\"bar\",\"qux\"]]", result.toString()); // [["bar","qux"]]
}
- public void testRemoveLastArrayElementWithPatch() {
- JsonPointerImpl jsonPointer = new JsonPatchImpl.JsonPatchPointerImpl(JsonProvider.provider(), "/0/-");
- JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
-
- JsonStructure result = jsonPointer.remove(target);
- assertEquals("[[\"bar\",\"qux\"]]", result.toString()); // [["bar","qux"]]
- }
-
- @Test(expected = JsonException.class)
- public void testGetLastArrayElementSimple() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")
- .build();
-
- jsonPointer.getValue(target);
- }
-
- @Test(expected = JsonException.class)
- public void testGetLastArrayElement() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
-
- jsonPointer.getValue(target);
- }
-
- @Test(expected = JsonException.class)
- public void testGetLastArrayElement2() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/0/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
-
- jsonPointer.getValue(target);
- }
-
- @Test(expected = JsonException.class)
- public void testReplaceLastArrayElementSimple() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")
- .build();
-
- jsonPointer.replace(target, new JsonStringImpl("won't work"));
- }
-
- @Test(expected = JsonException.class)
- public void testReplaceLastArrayElement() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
-
- jsonPointer.replace(target, new JsonStringImpl("won't work"));
- }
-
- @Test(expected = JsonException.class)
- public void testReplaceLastArrayElement2() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/0/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
-
- jsonPointer.replace(target, new JsonStringImpl("won't work"));
- }
-
@Test
public void testAddLastArrayElementSimple() {
final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
@@ -591,22 +506,9 @@
assertEquals("[[\"bar\",\"qux\",\"baz\",\"xyz\"]]", result.toString());
}
- @Test(expected = JsonException.class)
- public void testRemoveLastArrayElementSimple() {
- JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
- JsonStructure target = Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")
- .build();
-
- JsonStructure result = jsonPointer.remove(target);
- assertEquals("[\"bar\",\"qux\"]", result.toString());
- }
-
@Test
public void testRemoveLastArrayElementSimpleWithPatch() {
- JsonPointerImpl jsonPointer = new JsonPatchImpl.JsonPatchPointerImpl(JsonProvider.provider(), "/-");
+ JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
JsonStructure target = Json.createArrayBuilder()
.add("bar")
.add("qux")
@@ -624,17 +526,6 @@
jsonPointer.remove(target);
}
- @Test(expected = JsonException.class)
- public void testRemoveLastArrayElementFromEmpty() {
- final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/0/-");
- final JsonStructure target = Json.createArrayBuilder()
- .add(Json.createArrayBuilder()
- .add("bar")
- .add("qux")
- .add("baz")).build(); // [["bar","qux","baz"]]
- jsonPointer.remove(target);
- }
-
@Test
public void testRemoveObjectMember() {
JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/baz");
diff --git a/johnzon-jsonp-strict/pom.xml b/johnzon-jsonp-strict/pom.xml
new file mode 100644
index 0000000..04a9ee7
--- /dev/null
+++ b/johnzon-jsonp-strict/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<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">
+ <parent>
+ <artifactId>johnzon</artifactId>
+ <groupId>org.apache.johnzon</groupId>
+ <version>1.2.9-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>johnzon-jsonp-strict</artifactId>
+ <name>Johnzon :: JSON-P Strict JSON Pointer Implementation (spec compliant)</name>
+ <packaging>bundle</packaging>
+
+ <properties>
+ <staging.directory>${project.parent.reporting.outputDirectory}</staging.directory>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>3.2.2</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <configuration>
+ <instructions>
+ <Import-Package>
+ *
+ </Import-Package>
+ <Require-Capability>
+ osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)"
+ </Require-Capability>
+ <_contract>
+ !JavaAnnotation,
+ !JavaCDI,
+ !JavaJAXRS,
+ JavaJSONP
+ </_contract>
+ <Provide-Capability>osgi.serviceloader;osgi.serviceloader=org.apache.johnzon.core.spi.JsonPointerFactory</Provide-Capability>
+ </instructions>
+ </configuration>
+ <dependencies>
+ <dependency>
+ <groupId>biz.aQute.bnd</groupId>
+ <artifactId>biz.aQute.bndlib</artifactId>
+ <version>4.3.1</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/johnzon-jsonp-strict/src/main/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactory.java b/johnzon-jsonp-strict/src/main/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactory.java
new file mode 100644
index 0000000..915aeb2
--- /dev/null
+++ b/johnzon-jsonp-strict/src/main/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.jsonp.strict;
+
+import org.apache.johnzon.core.JsonPointerImpl;
+import org.apache.johnzon.core.spi.JsonPointerFactory;
+
+import javax.json.JsonPointer;
+import javax.json.spi.JsonProvider;
+
+public class StrictJsonPointerFactory implements JsonPointerFactory {
+ @Override
+ public JsonPointer createPointer(final JsonProvider provider, final String path) {
+ return new StrictJsonPointerImpl(provider, path);
+ }
+
+ private static class StrictJsonPointerImpl extends JsonPointerImpl {
+ public StrictJsonPointerImpl(final JsonProvider provider, final String path) {
+ super(provider, path);
+ }
+
+ protected int minusShift() {
+ return 0;
+ }
+ }
+}
diff --git a/johnzon-jsonp-strict/src/main/resources/META-INF/services/org.apache.johnzon.core.spi.JsonPointerFactory b/johnzon-jsonp-strict/src/main/resources/META-INF/services/org.apache.johnzon.core.spi.JsonPointerFactory
new file mode 100644
index 0000000..088626a
--- /dev/null
+++ b/johnzon-jsonp-strict/src/main/resources/META-INF/services/org.apache.johnzon.core.spi.JsonPointerFactory
@@ -0,0 +1 @@
+org.apache.johnzon.jsonp.strict.StrictJsonPointerFactory
diff --git a/johnzon-jsonp-strict/src/test/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactoryTest.java b/johnzon-jsonp-strict/src/test/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactoryTest.java
new file mode 100644
index 0000000..bd6e0ec
--- /dev/null
+++ b/johnzon-jsonp-strict/src/test/java/org/apache/johnzon/jsonp/strict/StrictJsonPointerFactoryTest.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.jsonp.strict;
+
+import org.apache.johnzon.core.JsonPointerImpl;
+import org.junit.Test;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.spi.JsonProvider;
+
+import static org.junit.Assert.assertEquals;
+
+public class StrictJsonPointerFactoryTest {
+ @Test
+ public void validMinusUsage() {
+ final JsonPointerImpl jsonPointer = new JsonPointerImpl(JsonProvider.provider(), "/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+
+ final JsonStructure result = jsonPointer.add(target, Json.createValue("xyz"));
+ assertEquals("[[\"bar\",\"qux\",\"baz\"],\"xyz\"]", result.toString());
+ }
+
+ @Test(expected = JsonException.class)
+ public void testReplaceLastArrayElement2() {
+ final JsonPointer jsonPointer = Json.createPointer("/0/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+ jsonPointer.replace(target, Json.createValue("won't work"));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testRemoveLastArrayElement() {
+ JsonPointer jsonPointer = Json.createPointer("/0/-");
+ JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+
+ JsonStructure result = jsonPointer.remove(target);
+ assertEquals("[[\"bar\",\"qux\"]]", result.toString()); // [["bar","qux"]]
+ }
+
+ @Test(expected = JsonException.class)
+ public void testReplaceLastArrayElement() {
+ final JsonPointer jsonPointer = Json.createPointer("/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+
+ jsonPointer.replace(target, Json.createValue("won't work"));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testGetLastArrayElementSimple() {
+ final JsonPointer jsonPointer = Json.createPointer("/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")
+ .build();
+
+ jsonPointer.getValue(target);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testGetLastArrayElement2() {
+ final JsonPointer jsonPointer = Json.createPointer("/0/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+
+ jsonPointer.getValue(target);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testRemoveLastArrayElementFromEmpty() {
+ final JsonPointer jsonPointer = Json.createPointer("/0/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+ jsonPointer.remove(target);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testRemoveLastArrayElementSimple() {
+ JsonPointer jsonPointer = Json.createPointer("/-");
+ JsonStructure target = Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")
+ .build();
+
+ JsonStructure result = jsonPointer.remove(target);
+ assertEquals("[\"bar\",\"qux\"]", result.toString());
+ }
+
+ @Test(expected = JsonException.class)
+ public void testGetLastArrayElement() {
+ final JsonPointer jsonPointer = Json.createPointer("/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add(Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")).build(); // [["bar","qux","baz"]]
+
+ jsonPointer.getValue(target);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testReplaceLastArrayElementSimple() {
+ final JsonPointer jsonPointer = Json.createPointer("/-");
+ final JsonStructure target = Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")
+ .build();
+
+ jsonPointer.replace(target, Json.createValue("won't work"));
+ }
+}
diff --git a/pom.xml b/pom.xml
index d64f601..7cd7ce6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,7 @@
<module>johnzon-jsonschema</module>
<module>johnzon-osgi</module>
<module>johnzon-jsonlogic</module>
+ <module>johnzon-jsonp-strict</module>
</modules>
<dependencyManagement>
@@ -150,6 +151,7 @@
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
<configuration>
+ <consoleOutput>true</consoleOutput>
<includes>
<include>src/**/*</include>
<include>pom.xml</include>
@@ -162,7 +164,7 @@
<exclude>*.iws</exclude>
<exclude>*.iml</exclude>
<exclude>*.ipr</exclude>
- <exclude>**/META-INF/services/javax.*</exclude>
+ <exclude>**/META-INF/services/*</exclude>
<exclude>**/*.json</exclude>
<exclude>**/*.yml</exclude>
<exclude>**/bench/*.txt</exclude>
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index 3ee6c0e..52cead3 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -52,6 +52,22 @@
</dependency>
]]></pre>
+### JSON-P Strict Compliance (stable)
+
+<pre class="prettyprint linenums"><![CDATA[
+<dependency>
+ <groupId>org.apache.johnzon</groupId>
+ <artifactId>johnzon-jsonp-strict</artifactId>
+ <version>${johnzon.version}</version>
+</dependency>
+]]></pre>
+
+This module enables to enforce a strict compliance of JsonPointer behavior on `/-` usage.
+Johnzon default implementation enables to use it as "remove last element" when using a remove patch (or not add semantic).
+This module enforces this case to be invalid to be closer to the intended wording of the JSON Pointer underlying specs.
+
+Note that you can even customize this behavior implementing your own `JsonPointerFactory` and changing the ordinal value to take a highest priority.
+
### Mapper (stable)
<pre class="prettyprint linenums"><![CDATA[