You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by st...@apache.org on 2017/02/24 12:07:07 UTC

[01/26] johnzon git commit: JOHNZON-96 implement JSON-P 1.1 API

Repository: johnzon
Updated Branches:
  refs/heads/master d344cbcb8 -> 02993157e


JOHNZON-96 implement JSON-P 1.1 API


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/d396c5bc
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/d396c5bc
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/d396c5bc

Branch: refs/heads/master
Commit: d396c5bc5357f821fbb772022399bf356816de82
Parents: b0af96e
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 19:46:32 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 19:46:32 2016 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonArrayBuilderImpl.java      |  9 ++-
 .../johnzon/core/JsonBuilderFactoryImpl.java    | 13 ++++
 .../apache/johnzon/core/JsonGeneratorImpl.java  | 36 ++++++-----
 .../johnzon/core/JsonObjectBuilderImpl.java     | 24 ++++++-
 .../apache/johnzon/core/JsonProviderImpl.java   | 66 ++++++++++++++++++++
 .../johnzon/mapper/MappingParserImpl.java       |  2 +-
 .../org/apache/johnzon/mapper/MapperTest.java   |  5 +-
 pom.xml                                         |  6 +-
 8 files changed, 136 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
index 913c22a..b8ff582 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
@@ -32,6 +32,13 @@ import java.util.List;
 class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
     private List<JsonValue> tmpList;
 
+    public JsonArrayBuilderImpl() {
+    }
+
+    public JsonArrayBuilderImpl(JsonArray initialData) {
+        tmpList = new ArrayList<>(initialData);
+    }
+
     @Override
     public JsonArrayBuilder add(final JsonValue value) {
         addValue(value);
@@ -104,7 +111,7 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
         }
         
         if(tmpList==null){
-            tmpList=new ArrayList<JsonValue>();
+            tmpList=new ArrayList<>();
         }
         
         tmpList.add(value);

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
index 121f18f..c91014d 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
@@ -25,8 +25,10 @@ import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
 
+import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonBuilderFactory;
+import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 
 class JsonBuilderFactoryImpl implements JsonBuilderFactory {
@@ -56,10 +58,21 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory {
     }
 
     @Override
+    public JsonObjectBuilder createObjectBuilder(JsonObject initialData) {
+        return new JsonObjectBuilderImpl(initialData);
+    }
+
+    @Override
     public JsonArrayBuilder createArrayBuilder() {
         return new JsonArrayBuilderImpl();
     }
 
+
+    @Override
+    public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
+        return new JsonArrayBuilderImpl(initialData);
+    }
+
     @Override
     public Map<String, ?> getConfigInUse() {
         return Collections.unmodifiableMap(internalConfig);

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
index e1371e5..1b8b573 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java
@@ -431,6 +431,26 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     }
 
     @Override
+    public JsonGenerator writeKey(final String key) {
+        final GeneratorState currentState = currentState();
+        if (!currentState.acceptsKey) {
+            throw new JsonGenerationException("state " + currentState + " does not accept a key");
+        }
+        if (currentState == GeneratorState.IN_OBJECT) {
+            justWrite(COMMA_CHAR);
+            writeEol();
+        }
+
+        writeIndent();
+
+        writeCachedKey(key);
+        state.push(GeneratorState.AFTER_KEY);
+        return this;
+    }
+
+
+
+    @Override
     public void close() {
         try {
             if (currentState() != GeneratorState.END) {
@@ -650,22 +670,6 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
         return state.peek();
     }
 
-    private void writeKey(final String key) {
-        final GeneratorState currentState = currentState();
-        if (!currentState.acceptsKey) {
-            throw new IllegalStateException("state " + currentState + " does not accept a key");
-        }
-        if (currentState == GeneratorState.IN_OBJECT) {
-            justWrite(COMMA_CHAR);
-            writeEol();
-        }
-
-        writeIndent();
-
-        writeCachedKey(key);
-        state.push(GeneratorState.AFTER_KEY);
-    }
-
     private void writeValueAsJsonString(final String value) {
         prepareValue();
         final GeneratorState peek = state.peek();

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
index d625383..17cfe17 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
@@ -32,6 +32,14 @@ import java.util.Map;
 class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
     private Map<String, JsonValue> tmpMap;
 
+    public JsonObjectBuilderImpl() {
+    }
+
+    public JsonObjectBuilderImpl(JsonObject initialData) {
+        tmpMap = new LinkedHashMap<>(initialData);
+    }
+
+
     @Override
     public JsonObjectBuilder add(final String name, final JsonValue value) {
         putValue(name, value);
@@ -97,14 +105,26 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
         putValue(name, builder.build());
         return this;
     }
-    
+
+    @Override
+    public JsonObjectBuilder addAll(JsonObjectBuilder builder) {
+        tmpMap.putAll(builder.build());
+        return this;
+    }
+
+    @Override
+    public JsonObjectBuilder remove(String name) {
+        tmpMap.remove(name);
+        return this;
+    }
+
     private void putValue(String name, JsonValue value){
         if(name == null || value == null) {
             throw npe();
         }
         
         if(tmpMap==null){
-            tmpMap=new LinkedHashMap<String, JsonValue>();
+            tmpMap = new LinkedHashMap<>();
         }
         
         tmpMap.put(name, value);

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 d1bbec6..99fd6fc 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
@@ -25,11 +25,17 @@ import java.io.Serializable;
 import java.io.Writer;
 import java.util.Map;
 
+import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonBuilderFactory;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonPatch;
+import javax.json.JsonPatchBuilder;
+import javax.json.JsonPointer;
 import javax.json.JsonReader;
 import javax.json.JsonReaderFactory;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
 import javax.json.JsonWriter;
 import javax.json.JsonWriterFactory;
 import javax.json.spi.JsonProvider;
@@ -116,6 +122,36 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         return DELEGATE.createBuilderFactory(stringMap);
     }
 
+    @Override
+    public JsonPointer createJsonPointer(String path) {
+        return DELEGATE.createJsonPointer(path);
+    }
+
+    @Override
+    public JsonPatch createPatch(JsonStructure source, JsonStructure target) {
+        return DELEGATE.createPatch(source, target);
+    }
+
+    @Override
+    public JsonPatchBuilder createPatchBuilder() {
+        return DELEGATE.createPatchBuilder();
+    }
+
+    @Override
+    public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
+        return DELEGATE.createPatchBuilder(initialData);
+    }
+
+    @Override
+    public JsonValue createMergePatch(JsonValue source, JsonValue target) {
+        return DELEGATE.createMergePatch(source, target);
+    }
+
+    @Override
+    public JsonValue mergePatch(JsonValue source, JsonValue patch) {
+        return DELEGATE.mergePatch(source, patch);
+    }
+
     static class JsonProviderDelegate extends JsonProvider {
         private final JsonReaderFactory readerFactory = new JsonReaderFactoryImpl(null);
         private final JsonParserFactory parserFactory = new JsonParserFactoryImpl(null);
@@ -197,5 +233,35 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         public JsonBuilderFactory createBuilderFactory(final Map<String, ?> config) {
             return (config == null || config.isEmpty()) ? builderFactory : new JsonBuilderFactoryImpl(config);
         }
+
+        @Override
+        public JsonPointer createJsonPointer(String path) {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
+
+        @Override
+        public JsonPatch createPatch(JsonStructure source, JsonStructure target) {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
+
+        @Override
+        public JsonPatchBuilder createPatchBuilder() {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
+
+        @Override
+        public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
+
+        @Override
+        public JsonValue createMergePatch(JsonValue source, JsonValue target) {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
+
+        @Override
+        public JsonValue mergePatch(JsonValue source, JsonValue patch) {
+            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index e731b8f..9164f7a 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -593,7 +593,7 @@ public class MappingParserImpl implements MappingParser {
             } else if (collection.size() == 1) {
                 return Collection.class.cast(EnumSet.of(Enum.class.cast(collection.iterator().next())));
             } else {
-                final List<Enum<?>> list = List.class.cast(collection);
+                final List<Enum> list = List.class.cast(collection);
                 return Collection.class.cast(EnumSet.of(list.get(0), list.subList(1, list.size()).toArray(new Enum[list.size() - 1])));
             }
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
index 594315a..e0330f4 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/MapperTest.java
@@ -184,8 +184,9 @@ public class MapperTest {
             // read
             assertEquals(Boolean.TRUE, simpleMapper.readObject(new ByteArrayInputStream("true".getBytes()), Object.class));
             assertEquals(Boolean.FALSE, simpleMapper.readObject(new ByteArrayInputStream("false".getBytes()), Object.class));
-            assertEquals(1., encodingAwareMapper
-                    .readObject(new ByteArrayInputStream("1".getBytes()), Object.class));
+            assertEquals(1.,
+                         encodingAwareMapper.readObject(new ByteArrayInputStream("1".getBytes()), Object.class),
+                         0.1);
             assertEquals("val", simpleMapper.readObject(new ByteArrayInputStream("\"val\"".getBytes()), Object.class));
             assertEquals(asList("val1", "val2"), simpleMapper.readObject(new ByteArrayInputStream("[\"val1\", \"val2\"]".getBytes()), Object.class));
             assertEquals(new HashMap<String, Object>() {{

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d396c5bc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index e507cc7..f8ca1f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,14 +40,14 @@
   <url>http://johnzon.apache.org</url>
 
   <properties>
-    <jsonspecversion>1.0-alpha-1</jsonspecversion>
+    <jsonspecversion>1.0-SNAPSHOT</jsonspecversion>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <johnzon.site.url>https://svn.apache.org/repos/asf/johnzon/site/publish/</johnzon.site.url>
     <pubsub.url>scm:svn:${johnzon.site.url}</pubsub.url>
     <staging.directory>${project.build.directory}/site</staging.directory>
     <felix.plugin.version>2.5.3</felix.plugin.version>
     <bnd.version.policy>[$(version;==;$(@)),$(version;+;$(@)))</bnd.version.policy>
-    <java-compile.version>1.6</java-compile.version>
+    <java-compile.version>1.8</java-compile.version>
     <cxf.version>3.0.0</cxf.version>
     <javadoc.params /> <!-- for java 8 set disable doclint (by profile) -->
     <checkstyle.version>2.15</checkstyle.version> <!-- checkstyle > 2.15 version do not support java 6 -->
@@ -66,7 +66,7 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
       <version>${jsonspecversion}</version>
       <scope>provided</scope>
     </dependency>


[16/26] johnzon git commit: JOHNZON-97 implemented JsonPatch

Posted by st...@apache.org.
JOHNZON-97 implemented JsonPatch


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/74cb9088
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/74cb9088
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/74cb9088

Branch: refs/heads/master
Commit: 74cb90884b51861361929cb6f5bcb32ca154a96c
Parents: 24fe453
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Thu Nov 24 00:11:42 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Fri Nov 25 14:35:56 2016 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonPatchImpl.java  |  23 +
 .../org/apache/johnzon/core/JsonPatchTest.java  | 920 ++++++++++++++++++-
 2 files changed, 931 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/74cb9088/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
----------------------------------------------------------------------
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 352af88..0aaedf9 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
@@ -22,6 +22,7 @@ package org.apache.johnzon.core;
 import java.util.Arrays;
 import java.util.List;
 
+import javax.json.JsonException;
 import javax.json.JsonPatch;
 import javax.json.JsonPointer;
 import javax.json.JsonStructure;
@@ -42,12 +43,34 @@ class JsonPatchImpl implements JsonPatch {
 
         //X TODO JsonPointer should use generics like JsonPatch
         JsonStructure patched = target;
+
         for (PatchValue patch : patches) {
 
             switch (patch.operation) {
                 case ADD:
                     patched = patch.path.add(patched, patch.value);
                     break;
+                case REMOVE:
+                    patched = patch.path.remove(patched);
+                    break;
+                case REPLACE:
+                    // first remove the existing element and then add the new value
+                    patched = patch.path.add(patch.path.remove(patched), patch.value);
+                    break;
+                case MOVE:
+                    JsonValue valueToMove = patch.from.getValue(patched);
+                    patched = patch.path.add(patch.from.remove(patched), valueToMove);
+                    break;
+                case COPY:
+                    JsonValue toCopy = patch.from.getValue(patched);
+                    patched = patch.path.add(patched, toCopy);
+                    break;
+                case TEST:
+                    JsonValue toTest = patch.path.getValue(patched);
+                    if (!toTest.equals(patch.value)) {
+                        throw new JsonException("JsonPatchOperation.TEST fails! Values are not equal");
+                    }
+                    break;
                 default:
                     throw new IllegalStateException("unsupported operation: " + patch.operation);
             }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/74cb9088/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
index a303893..b4665ed 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
@@ -18,16 +18,22 @@
  */
 package org.apache.johnzon.core;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.StringReader;
-import java.io.StringWriter;
+import org.junit.Test;
 
 import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonException;
 import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import java.io.StringReader;
+import java.io.StringWriter;
 
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
 
 public class JsonPatchTest {
 
@@ -37,21 +43,911 @@ public class JsonPatchTest {
         JsonObject object = Json.createReader(new StringReader("{ \"foo\": \"bar\" }"))
                                 .readObject();
 
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/baz"),
+                                                                             null, // no from
+                                                                             new JsonStringImpl("qux")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertEquals("bar", patched.getString("foo"));
+        assertEquals("qux", patched.getString("baz"));
+
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", toJsonString(patched));
+    }
+
+    @Test
+    public void testAddArrayElementWithIndex() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("baz"))
+                                .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                           Json.createJsonPointer("/baz"),
-                                                                           null, // no from
-                                                                           new JsonStringImpl("qux")));
+                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             null, // no from
+                                                                             new JsonStringImpl("qux")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertNotNull(array);
+        assertEquals("bar", array.getString(0));
+        assertEquals("qux", array.getString(1));
+        assertEquals("baz", array.getString(2));
+
+        assertEquals("{\"foo\":[\"bar\",\"qux\",\"baz\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testAddArrayElementAppend() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("baz"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/foo/-"),
+                                                                             null, // no from
+                                                                             new JsonStringImpl("qux")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertNotNull(array);
+        assertEquals("bar", array.getString(0));
+        assertEquals("baz", array.getString(1));
+        assertEquals("qux", array.getString(2));
+
+        assertEquals("{\"foo\":[\"bar\",\"baz\",\"qux\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testAddArrayElementPlainArray() {
+        JsonArray array = Json.createArrayBuilder()
+                              .add("bar")
+                              .add("baz")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/-"),
+                                                                             null, // no from
+                                                                             new JsonStringImpl("qux")));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertNotSame(array, patched);
+        assertEquals("bar", patched.getString(0));
+        assertEquals("baz", patched.getString(1));
+        assertEquals("qux", patched.getString(2));
+
+        assertEquals("[\"bar\",\"baz\",\"qux\"]", toJsonString(patched));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddNonexistentTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/baz/bat"),
+                                                                             null, // no from
+                                                                             new JsonStringImpl("qux")));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddArrayIndexOutOfBounds() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("bar")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/5"),
+                                                                             null,
+                                                                             new JsonStringImpl("baz")));
+
+        patch.apply(array);
+    }
+
+
+    @Test
+    public void testRemoveObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("baz", "qux")
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/baz"),
+                                                                             null,
+                                                                             null));
 
         JsonObject patched = patch.apply(object);
         assertNotNull(patched);
         assertEquals("bar", patched.getString("foo"));
+        assertFalse("patched JsonObject must no contain \"baz\"", patched.containsKey("baz"));
+
+        assertEquals("{\"foo\":\"bar\"}", toJsonString(patched));
+    }
+
+    @Test
+    public void testRemoveArrayElement() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("qux")
+                                                .add("baz"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             null,
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertNotNull(array);
+        assertEquals(2, array.size());
+        assertEquals("bar", array.getString(0));
+        assertEquals("baz", array.getString(1));
+
+        assertEquals("{\"foo\":[\"bar\",\"baz\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testRemoveArrayElementPlainArray() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("bar")
+                              .add("qux")
+                              .add("baz")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/1"),
+                                                                             null,
+                                                                             null));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertEquals(2, patched.size());
+        assertEquals("bar", patched.getString(0));
+        assertEquals("baz", patched.getString(1));
+
+        assertEquals("[\"bar\",\"baz\"]", toJsonString(patched));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveObjectElementNonexistentTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .add("baz", "qux")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             null,
+                                                                             null));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveArrayElementIndexOutOfBounds() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("bar")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/5"),
+                                                                             null,
+                                                                             null));
+
+        patch.apply(array);
+    }
+
+
+    @Test
+    public void testReplacingObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("baz", "qux")
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                             Json.createJsonPointer("/baz"),
+                                                                             null,
+                                                                             new JsonStringImpl("boo")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+        assertEquals("boo", patched.getString("baz"));
+        assertEquals("bar", patched.getString("foo"));
+
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"boo\"}", toJsonString(patched));
+    }
+
+    @Test
+    public void testReplacingArrayElement() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("qux"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             null,
+                                                                             new JsonStringImpl("boo")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertNotNull(array);
+        assertNotSame(object.getJsonArray("foo"), array);
+        assertEquals(2, array.size());
+        assertEquals("bar", array.getString(0));
+        assertEquals("boo", array.getString(1));
+
+        assertEquals("{\"foo\":[\"bar\",\"boo\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testReplacingArrayElementPlainArray() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("bar")
+                              .add("qux")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                             Json.createJsonPointer("/0"),
+                                                                             null,
+                                                                             new JsonStringImpl("boo")));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertNotSame(array, patched);
+        assertEquals(2, patched.size());
+        assertEquals("boo", patched.getString(0));
+        assertEquals("qux", patched.getString(1));
+
+        assertEquals("[\"boo\",\"qux\"]", toJsonString(patched));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplacingObjectMemberNonexistingTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             null,
+                                                                             new JsonStringImpl("notneeded")));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplacingArrayElementIndexOutOfBounds() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("foo")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                             Json.createJsonPointer("/1"),
+                                                                             null,
+                                                                             new JsonStringImpl("notneeded")));
+
+        patch.apply(array);
+    }
+
+
+    @Test
+    public void testMovingObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createObjectBuilder()
+                                                .add("bar", "baz")
+                                                .add("waldo", "fred"))
+                                .add("qux", Json.createObjectBuilder()
+                                                .add("corge", "grault"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/qux/thud"),
+                                                                             Json.createJsonPointer("/foo/waldo"),
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+
+        JsonObject foo = patched.getJsonObject("foo");
+        assertNotNull(foo);
+        assertEquals("baz", foo.getString("bar"));
+        assertFalse("JsonObject with key 'foo' must not contain 'waldo'", foo.containsKey("waldo"));
+
+        JsonObject qux = patched.getJsonObject("qux");
+        assertNotNull(qux);
+        assertEquals("grault", qux.getString("corge"));
+        assertEquals("fred", qux.getString("thud"));
+
+        assertEquals("{\"foo\":{\"bar\":\"baz\"},\"qux\":{\"corge\":\"grault\",\"thud\":\"fred\"}}", toJsonString(patched));
+    }
+
+    @Test
+    public void testMovingArrayElement() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("all")
+                                                .add("grass")
+                                                .add("cows")
+                                                .add("eat"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/foo/3"),
+                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertNotNull(array);
+        assertEquals("all", array.getString(0));
+        assertEquals("cows", array.getString(1));
+        assertEquals("eat", array.getString(2));
+        assertEquals("grass", array.getString(3));
+
+        assertEquals("{\"foo\":[\"all\",\"cows\",\"eat\",\"grass\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testMovingArrayElementPlainArray() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("two")
+                              .add("three")
+                              .add("four")
+                              .add("one")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/0"),
+                                                                             Json.createJsonPointer("/3"),
+                                                                             null));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertNotSame(array, patched);
+        assertEquals("one", patched.getString(0));
+        assertEquals("two", patched.getString(1));
+        assertEquals("three", patched.getString(2));
+        assertEquals("four", patched.getString(3));
+    }
+
+    @Test
+    public void testMovingArrayElementToObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("one")
+                                                .add("two")
+                                                .add("dog"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/bar"),
+                                                                             Json.createJsonPointer("/foo/2"),
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertEquals(2, patched.size());
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertEquals(2, array.size());
+        assertEquals("one", array.getString(0));
+        assertEquals("two", array.getString(1));
+
+        assertEquals("dog", patched.getString("bar"));
+
+        assertEquals("{\"foo\":[\"one\",\"two\"],\"bar\":\"dog\"}", toJsonString(patched));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testMovingObjectMemberNonexistingFrom() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/baz"),
+                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             null));
+
+        patch.apply(object);
+
+    }
+
+    @Test(expected = JsonException.class)
+    public void testMovingObjectMemberNonexistingTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/nomatch/child"),
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testMovingObjectMemberMoveToSubFrom() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("object", Json.createObjectBuilder()
+                                                   .add("key", "value"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/object/key"),
+                                                                             Json.createJsonPointer("/object"),
+                                                                             null));
+
+        patch.apply(object);
+    }
+
+
+    @Test
+    public void testCopyObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                               .add("foo", "bar")
+                               .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/baz"),
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertEquals(2, patched.size());
+        assertEquals("bar", patched.getString("foo"));
+        assertEquals("bar", patched.getString("baz"));
+
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"bar\"}", toJsonString(patched));
+    }
+
+    @Test
+    public void testCopyArrayMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("baz"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                                 Json.createJsonPointer("/foo/-"),
+                                                                                 Json.createJsonPointer("/foo/0"),
+                                                                                 null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+
+        JsonArray array = patched.getJsonArray("foo");
+        assertEquals(3, array.size());
+        assertEquals("bar", array.getString(0));
+        assertEquals("baz", array.getString(1));
+        assertEquals("bar", array.getString(2));
+
+        assertEquals("{\"foo\":[\"bar\",\"baz\",\"bar\"]}", toJsonString(patched));
+    }
+
+    @Test
+    public void testCopyArrayMemberPlainArray() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("foo")
+                              .add("bar")
+                              .build();
+
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/0"),
+                                                                             Json.createJsonPointer("/1"),
+                                                                             null));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertNotSame(array, patched);
+        assertEquals(3, patched.size());
+        assertEquals("bar", patched.getString(0));
+        assertEquals("foo", patched.getString(1));
+        assertEquals("bar", patched.getString(2));
+
+        assertEquals("[\"bar\",\"foo\",\"bar\"]", toJsonString(patched));
+    }
+
+    @Test
+    public void testCopyObjectMemberToObjectMember() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("name", "Hugo")
+                                .add("partner", Json.createObjectBuilder()
+                                                    .add("name", "Leia")
+                                                    .add("partner", JsonValue.EMPTY_JSON_OBJECT))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/partner/partner/name"),
+                                                                             Json.createJsonPointer("/name"),
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+        assertEquals("Hugo", patched.getString("name"));
+
+        JsonObject partner = patched.getJsonObject("partner");
+        assertEquals("Leia", partner.getString("name"));
+
+        JsonObject parent = partner.getJsonObject("partner");
+        assertEquals(patched.getString("name"), parent.getString("name"));
+
+        assertEquals("{\"name\":\"Hugo\",\"partner\":{\"name\":\"Leia\",\"partner\":{\"name\":\"Hugo\"}}}", toJsonString(patched));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testCopyObjectMemberFromNonexistentTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/notneeded"),
+                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             null));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testCopyObjectMemberToNonexistingTarget() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/path/nomatch"),
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null));
+
+        patch.apply(object);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testCopyArrayMemberFromIndexOutOfBounds() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("foo")
+                              .add("bar")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/-"),
+                                                                             Json.createJsonPointer("/2"),
+                                                                             null));
+
+        patch.apply(array);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testCopyArrayMemberToIndexOutOfBounds() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("foo")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/1"),
+                                                                             Json.createJsonPointer("/-"),
+                                                                             null));
+
+        patch.apply(array);
+    }
+
+
+    @Test
+    public void testTestingObjectMemberValueSuccess() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "qux")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null,
+                                                                             new JsonStringImpl("qux")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertSame(object, patched);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testTestingObjectMemberValueFailed() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "qux")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null,
+                                                                             Json.createArrayBuilder().build()));
+
+        patch.apply(object);
+    }
+
+    @Test
+    public void testTestingArrayAsObjectMemberSuccess() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("name", "Thor")
+                                .add("parents", Json.createArrayBuilder()
+                                                    .add("Odin")
+                                                    .add("Forjgyn"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/parents"),
+                                                                             null,
+                                                                             Json.createArrayBuilder() // yessss, we really want to create a new JsonArray ;)
+                                                                                 .add("Odin")
+                                                                                 .add("Forjgyn")
+                                                                                 .build()));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertSame(object, patched);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testTestingArrayAsObjectMemberFailed() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("magic", "array")
+                                .add("numbers", Json.createArrayBuilder()
+                                                    .add(1)
+                                                    .add(2))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/numbers"),
+                                                                             null,
+                                                                             Json.createArrayBuilder() // different ordering
+                                                                                 .add(2)
+                                                                                 .add(1)
+                                                                                 .build()));
+
+        patch.apply(object);
+    }
+
+    @Test
+    public void testTestingArrayElementSuccess() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", Json.createArrayBuilder()
+                                                .add("bar")
+                                                .add("baz"))
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             null,
+                                                                             new JsonStringImpl("baz")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertSame(object, patched);
+    }
+
+    @Test
+    public void testTestingArrayElementPlainArraySuccess() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add("foo")
+                              .add("bar")
+                              .add("qux")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/2"),
+                                                                             null,
+                                                                             new JsonStringImpl("qux")));
+
+        JsonArray patched = patch.apply(array);
+        assertNotNull(patched);
+        assertSame(array, patched);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testTestingArrayElementPlainArrayFailed() {
+
+        JsonArray array = Json.createArrayBuilder()
+                              .add(1)
+                              .add("2")
+                              .add("qux")
+                              .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/0"),
+                                                                             null,
+                                                                             new JsonStringImpl("bar")));
+
+        patch.apply(array);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testTestingObjectMemeberNonexistentTarget() {
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             null,
+                                                                             JsonValue.EMPTY_JSON_OBJECT));
+
+        patch.apply(JsonValue.EMPTY_JSON_OBJECT);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testTestingArrayElementIndexOutOfBounds() {
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                             Json.createJsonPointer("/3"),
+                                                                             null,
+                                                                             JsonValue.EMPTY_JSON_OBJECT));
+
+        patch.apply(JsonValue.EMPTY_JSON_ARRAY);
+    }
+
+
+    @Test
+    public void testAddObjectMemberAlreadyExists() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("foo", "bar")
+                                .add("baz", "qux")
+                                .build();
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/foo"),
+                                                                             null,
+                                                                             new JsonStringImpl("abcd")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+        assertEquals("abcd", patched.getString("foo"));
         assertEquals("qux", patched.getString("baz"));
 
-        StringWriter writer = new StringWriter();
-        Json.createWriter(writer).write(patched);
+        assertEquals("{\"foo\":\"abcd\",\"baz\":\"qux\"}", toJsonString(patched));
+    }
 
-        assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", writer.toString());
+    @Test
+    public void testAddArrayElementToEmptyArray() {
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/-"),
+                                                                             null,
+                                                                             new JsonStringImpl("foo")));
+
+        JsonArray patched = patch.apply(JsonValue.EMPTY_JSON_ARRAY);
+        assertNotNull(patched);
+        assertEquals(1, patched.size());
+        assertEquals("foo", patched.getString(0));
+    }
+
+    @Test
+    public void testPatchWithMoreOperations() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("family", Json.createObjectBuilder()
+                                                   .add("children", JsonValue.EMPTY_JSON_ARRAY))
+                                .build();
+
+        // i know this can be done with PatchBuilder but
+        // currently it's not implemented and its fun ;)
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/family/father"),
+                                                                             null,
+                                                                             Json.createObjectBuilder()
+                                                                                 .add("name", "Gaio Modry Effect")
+                                                                                 .build()),
+                                                new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             null,
+                                                                             Json.createObjectBuilder()
+                                                                                 .add("name", "Cassius vom Hause Clarabella")
+                                                                                 .build()),
+                                                new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                             Json.createJsonPointer("/family/children/0"),
+                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             null),
+                                                new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             null,
+                                                                             Json.createObjectBuilder()
+                                                                                 .add("name", "Aimee vom Hause Clarabella")
+                                                                                 .build()),
+                                                new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                             Json.createJsonPointer("/pedigree"),
+                                                                             Json.createJsonPointer("/family"),
+                                                                             null),
+                                                new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                             Json.createJsonPointer("/family"),
+                                                                             null,
+                                                                             null));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertNotSame(object, patched);
+
+        JsonObject pedigree = patched.getJsonObject("pedigree");
+        assertEquals("Gaio Modry Effect", pedigree.getJsonObject("father").getString("name"));
+        assertEquals("Aimee vom Hause Clarabella", pedigree.getJsonObject("mother").getString("name"));
+        assertEquals("Cassius vom Hause Clarabella", pedigree.getJsonArray("children").getJsonObject(0).getString("name"));
+
+        assertEquals("{\"pedigree\":{" +
+                     "\"children\":[" +
+                     "{\"name\":\"Cassius vom Hause Clarabella\"}]," +
+                     "\"mother\":{\"name\":\"Aimee vom Hause Clarabella\"}," +
+                     "\"father\":{\"name\":\"Gaio Modry Effect\"}}}", toJsonString(patched));
+    }
+
+
+
+    private static String toJsonString(JsonStructure value) {
+        StringWriter writer = new StringWriter();
+        Json.createWriter(writer).write(value);
+        return writer.toString();
     }
 
 }


[23/26] johnzon git commit: JOHNZON-96 new JsonObjectBuilder features from JSON-P-1.1

Posted by st...@apache.org.
JOHNZON-96 new JsonObjectBuilder features from JSON-P-1.1


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/4b20eaf9
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/4b20eaf9
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/4b20eaf9

Branch: refs/heads/master
Commit: 4b20eaf9ba1bfe033101ddf12fa37f26c904f1ac
Parents: c62932b
Author: Mark Struberg <st...@apache.org>
Authored: Thu Feb 23 16:40:32 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Thu Feb 23 16:40:32 2017 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonBuilderFactoryImpl.java    |  4 ++
 .../johnzon/core/JsonObjectBuilderImpl.java     | 62 +++++++++++-----
 .../apache/johnzon/core/JsonProviderImpl.java   | 12 +++-
 .../org/apache/johnzon/core/SimpleStack.java    |  4 +-
 .../johnzon/core/JsonObjectBuilderImplTest.java | 76 +++++++++++++++++++-
 .../apache/johnzon/core/JsonReaderImplTest.java |  4 +-
 6 files changed, 139 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
index c91014d..6f1f9ba 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
@@ -77,4 +77,8 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory {
     public Map<String, ?> getConfigInUse() {
         return Collections.unmodifiableMap(internalConfig);
     }
+
+    public JsonObjectBuilder createObjectBuilder(Map<String, Object> initialValues) {
+        return new JsonObjectBuilderImpl(initialValues);
+    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
index 17cfe17..d6e8a48 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
@@ -19,6 +19,7 @@
 package org.apache.johnzon.core;
 
 import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
 import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonValue;
@@ -30,16 +31,50 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 
 class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
-    private Map<String, JsonValue> tmpMap;
+    private Map<String, JsonValue> attributeMap = new LinkedHashMap<>();
 
     public JsonObjectBuilderImpl() {
     }
 
     public JsonObjectBuilderImpl(JsonObject initialData) {
-        tmpMap = new LinkedHashMap<>(initialData);
+        attributeMap = new LinkedHashMap<>(initialData);
+    }
+
+    public JsonObjectBuilderImpl(Map<String, Object> initialValues) {
+        this();
+        for (Map.Entry<String, Object> entry : initialValues.entrySet()) {
+            add(entry.getKey(), entry.getValue());
+        }
     }
 
 
+    /**
+     * Internal method to add a value where we do not yet know the type at compile time.
+     */
+    public void add(final String name, final Object value) {
+        if (value instanceof JsonValue) {
+            add(name, (JsonValue) value);
+        } else if (value instanceof BigDecimal) {
+            add(name, (BigDecimal) value);
+        } else if (value instanceof BigInteger) {
+            add(name, (BigInteger) value);
+        } else if (value instanceof Boolean) {
+            add(name, (boolean) value);
+        } else if (value instanceof Double) {
+            add(name, (double) value);
+        } else if (value instanceof Integer) {
+            add(name, (int) value);
+        } else if (value instanceof Long) {
+            add(name, (long) value);
+        } else if (value instanceof String) {
+            add(name, (String) value);
+        } else if (value == null) {
+            addNull(name);
+        } else {
+            throw new JsonException("Illegal JSON type! name=" + name + " type=" + value.getClass());
+        }
+    }
+
     @Override
     public JsonObjectBuilder add(final String name, final JsonValue value) {
         putValue(name, value);
@@ -108,40 +143,35 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
 
     @Override
     public JsonObjectBuilder addAll(JsonObjectBuilder builder) {
-        tmpMap.putAll(builder.build());
+        if (builder instanceof JsonObjectBuilderImpl) {
+            attributeMap.putAll(builder.build());
+        }
         return this;
     }
 
     @Override
     public JsonObjectBuilder remove(String name) {
-        tmpMap.remove(name);
+        attributeMap.remove(name);
         return this;
     }
 
     private void putValue(String name, JsonValue value){
         if(name == null || value == null) {
-            throw npe();
+            throw new NullPointerException("name or value/builder must not be null");
         }
         
-        if(tmpMap==null){
-            tmpMap = new LinkedHashMap<>();
-        }
-        
-        tmpMap.put(name, value);
+        attributeMap.put(name, value);
     }
     
-    private static NullPointerException npe() {
-        return new NullPointerException("name or value/builder must not be null");
-    }
 
     @Override
     public JsonObject build() {
         
-        if(tmpMap==null) {
+        if(attributeMap ==null) {
             return new JsonObjectImpl(Collections.EMPTY_MAP);
         } else {
-            Map<String, JsonValue> dump = (Collections.unmodifiableMap(tmpMap));
-            tmpMap=null;
+            Map<String, JsonValue> dump = (Collections.unmodifiableMap(attributeMap));
+            attributeMap =null;
             return new JsonObjectImpl(dump);
         }
         

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 0eeef2c..de18839 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
@@ -219,7 +219,7 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         private final JsonParserFactory parserFactory = new JsonParserFactoryImpl(null);
         private final JsonGeneratorFactory generatorFactory = new JsonGeneratorFactoryImpl(null);
         private final JsonWriterFactory writerFactory = new JsonWriterFactoryImpl(null);
-        private final JsonBuilderFactory builderFactory = new JsonBuilderFactoryImpl(null);
+        private final JsonBuilderFactoryImpl builderFactory = new JsonBuilderFactoryImpl(null);
 
         @Override
         public JsonParser createParser(final InputStream in) {
@@ -287,6 +287,16 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         }
 
         @Override
+        public JsonObjectBuilder createObjectBuilder(JsonObject jsonObject) {
+            return builderFactory.createObjectBuilder(jsonObject);
+        }
+
+        @Override
+        public JsonObjectBuilder createObjectBuilder(Map<String, Object> initialValues) {
+            return builderFactory.createObjectBuilder(initialValues);
+        }
+
+        @Override
         public JsonArrayBuilder createArrayBuilder() {
             return builderFactory.createArrayBuilder();
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java b/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
index e72540c..74bd14f 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/SimpleStack.java
@@ -53,8 +53,8 @@ class SimpleStack<T> {
 
         }
 
-        Element<T> previous;
-        T payload;
+        private Element<T> previous;
+        private T payload;
 
     }
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
index 098967e..1ba9348 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
@@ -18,18 +18,90 @@
  */
 package org.apache.johnzon.core;
 
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
 import static org.junit.Assert.assertEquals;
 
 import javax.json.Json;
+import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 public class JsonObjectBuilderImplTest {
     @Test
-    public void build() {
+    public void testBuild() {
         final JsonObjectBuilder builder = Json.createObjectBuilder();
         builder.add("a", "b");
-        assertEquals("{\"a\":\"b\"}", builder.build().toString());
+        JsonObject jsonObject = builder.build();
+        assertEquals("{\"a\":\"b\"}", jsonObject.toString());
+
+        JsonObjectBuilder anotherBuilder = Json.createObjectBuilder(jsonObject);
+        anotherBuilder.add("c", "d");
+        assertEquals("{\"a\":\"b\",\"c\":\"d\"}", anotherBuilder.build().toString());
+    }
+
+    @Test
+    public void testCreateObjectBuilderWithMapFlatItems() {
+        Map<String, Object> jsonItems = new HashMap<>();
+
+        {
+            // build up the items
+            jsonItems.put("bigDecimalVal", new BigDecimal(1234567.89));
+            jsonItems.put("bigIntegerVal", BigInteger.valueOf(54321L));
+            jsonItems.put("booleanVal", true);
+            jsonItems.put("doubleVal", 1234567.89d);
+            jsonItems.put("intVal", 4711);
+            jsonItems.put("jsonValueVal", JsonValue.FALSE);
+            jsonItems.put("longVal", 123_456_789L);
+            jsonItems.put("stringVal", "b");
+            jsonItems.put("nullVal", null);
+
+            // there are 9 addXxxx methods with types in JsonObjectBuilder
+            // ensure we have all of them covered
+            // we do not have items with JsonObjectBuilder and JsonArrayBuilder itself
+            Assert.assertEquals(9, jsonItems.size());
+        }
+
+        JsonObjectBuilder builder = Json.createObjectBuilder(jsonItems);
+        JsonObject jsonObject = builder.build();
+
+        Assert.assertEquals(new BigDecimal(1234567.89), jsonObject.getJsonNumber("bigDecimalVal").bigDecimalValue());
+        Assert.assertEquals(BigInteger.valueOf(54321L), jsonObject.getJsonNumber("bigIntegerVal").bigIntegerValue());
+        Assert.assertEquals(true, jsonObject.getBoolean("booleanVal"));
+        Assert.assertEquals(1234567.89d, jsonObject.getJsonNumber("doubleVal").doubleValue(), 0.01d);
+        Assert.assertEquals(4711, jsonObject.getInt("intVal"));
+        Assert.assertEquals(JsonValue.FALSE, jsonObject.get("jsonValueVal"));
+        Assert.assertEquals(123_456_789L, jsonObject.getJsonNumber("longVal").longValue());
+        Assert.assertEquals("b", jsonObject.getString("stringVal"));
+        Assert.assertEquals(true, jsonObject.isNull("nullVal"));
+    }
+
+    @Test
+    public void testAddAll() {
+        final JsonObjectBuilder builder = Json.createObjectBuilder();
+        builder.add("a", "b");
+        builder.add("c", "d");
+
+        final JsonObjectBuilder anotherBuilder = Json.createObjectBuilder();
+        anotherBuilder.addAll(builder);
+
+        assertEquals("{\"a\":\"b\",\"c\":\"d\"}", anotherBuilder.build().toString());
+    }
+
+    @Test
+    public void testRemove() {
+        final JsonObjectBuilder builder = Json.createObjectBuilder();
+        builder.add("a", "b");
+        builder.add("c", "d");
+
+        builder.remove("a");
+
+        assertEquals("{\"c\":\"d\"}", builder.build().toString());
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b20eaf9/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
index e9d3d74..21bb463 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonReaderImplTest.java
@@ -474,7 +474,7 @@ public class JsonReaderImplTest {
     public void testGrowingString() throws Throwable {
         JsonReaderFactory factory = Json.createReaderFactory(null);
         StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < 40000; i++) {
+        for (int i = 0; i < 10000; i++) {
             sb.append('x');
             String growingString = sb.toString();
             String str = "[4, \"\", \"" + growingString + "\", \"\", \"" + growingString + "\", \"\", 400]";
@@ -507,7 +507,7 @@ public class JsonReaderImplTest {
             JsonReaderFactory factory = Json.createReaderFactory(config);
 
             StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < 1000; i++) {
+            for (int i = 0; i < 100; i++) {
                 sb.append('x');
                 String name = sb.toString();
                 String str = "[4, \"\", \"" + name + "\", \"\", \"" + name + "\", \"\", 400]";


[14/26] johnzon git commit: JOHNZON-97 first draft for JsonPointer

Posted by st...@apache.org.
JOHNZON-97 first draft for JsonPointer

still far away from finished - just to check if
i go the right direction


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/b0c19662
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/b0c19662
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/b0c19662

Branch: refs/heads/master
Commit: b0c19662b47002e217d5206c3db6ba6baf41924e
Parents: d04e01e
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Wed Nov 23 21:50:45 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Wed Nov 23 21:50:45 2016 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonPatchImpl.java  |  78 ++++++++++
 .../apache/johnzon/core/JsonPatchOperation.java | 143 +++++++++++++++++++
 .../org/apache/johnzon/core/JsonPatchTest.java  |  57 ++++++++
 3 files changed, 278 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0c19662/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..352af88
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
@@ -0,0 +1,78 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.List;
+
+import javax.json.JsonPatch;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+class JsonPatchImpl implements JsonPatch {
+
+    private final List<PatchValue> patches;
+
+
+    JsonPatchImpl(PatchValue... patches) {
+        this.patches = Arrays.asList(patches);
+    }
+
+
+    @Override
+    public <T extends JsonStructure> T apply(T target) {
+
+        //X TODO JsonPointer should use generics like JsonPatch
+        JsonStructure patched = target;
+        for (PatchValue patch : patches) {
+
+            switch (patch.operation) {
+                case ADD:
+                    patched = patch.path.add(patched, patch.value);
+                    break;
+                default:
+                    throw new IllegalStateException("unsupported operation: " + patch.operation);
+            }
+        }
+
+        //X TODO dirty cast can be removed after JsonPointer uses generics like JsonPatch
+        return (T) patched;
+    }
+
+
+
+    static class PatchValue {
+        private final JsonPatchOperation operation;
+        private final JsonPointer path;
+        private final JsonPointer from;
+        private final JsonValue value;
+
+        PatchValue(JsonPatchOperation operation,
+                   JsonPointer path,
+                   JsonPointer from,
+                   JsonValue value) {
+            this.operation = operation;
+            this.path = path;
+            this.from = from;
+            this.value = value;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0c19662/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchOperation.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchOperation.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchOperation.java
new file mode 100644
index 0000000..75e5c49
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchOperation.java
@@ -0,0 +1,143 @@
+/*
+ * 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;
+
+/**
+ * <p>
+ * available operations for {@link javax.json.JsonPatch}.
+ * </p>
+ * <p>
+ * NOTICE: the behavoir of some operations depends on which {@link javax.json.JsonValue} they are performed.
+ * for details please check the documentation of the very operation.
+ * </p>
+ *
+ * @since 1.1
+ */
+public enum JsonPatchOperation {
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "add"</li>
+     * <li>"path": "path/to/add"</li>
+     * <li>"value": "{@link javax.json.JsonValue}ToAdd"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * if the "path/to" does not exist, this operation will result in an error.<br>
+     * if the "path/to/add" already exists, the value will be <strong>replaced</strong>
+     * </p>
+     * <p>
+     * for {@link javax.json.JsonArray}s the new value will be inserted at the specified index
+     * and the element(s) at/after are shifted to the right. the '-' character is used to append the value
+     * at the and of the {@link javax.json.JsonArray}.
+     * </p>
+     */
+    ADD,
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "remove"</li>
+     * <li>"path": "path/to/remove"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * if the "path/to/remove" does not exist, the operation will fail.
+     * </p>
+     * <p>
+     * for {@link javax.json.JsonArray}s the values after the removed value are shifted to the left
+     * </p>
+     */
+    REMOVE,
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "replace"</li>
+     * <li>"path": "path/to/replace"</li>
+     * <li>"value": "the new {@link javax.json.JsonValue}"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * this operation is identical to {@link #REMOVE} followed by {@link #ADD}
+     * </p>
+     */
+    REPLACE,
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "move"</li>
+     * <li>"from": "path/to/move/from"</li>
+     * <li>"path": "path/to/move/to"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * the operation will fail it the "path/to/move/from" does not exist
+     * </p>
+     * <p>
+     * NOTICE: a location can not be moved into one of it's children. (from /a/b/c to /a/b/c/d)
+     * </p>
+     * <p>
+     * this operation is identical to {@link #REMOVE} from "from" and {@link #ADD} to the "path"
+     * </p>
+     */
+    MOVE,
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "copy"</li>
+     * <li>"from": "path/to/copy/from"</li>
+     * <li>"path": "path/to/add"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * the operation will result in an error if the "from" location does not exist
+     * </p>
+     * <p>
+     * this operation is identical to {@link #ADD} with the "from" value
+     * </p>
+     */
+    COPY,
+
+    /**
+     * <p>
+     * required members are:
+     * <ul>
+     * <li>"op": "test"</li>
+     * <li>"path": "/path/to/test"</li>
+     * <li>"value": "{@link javax.json.JsonValue} to test"</li>
+     * </ul>
+     * </p>
+     * <p>
+     * this operation fails, if the value is NOT equal with the /path/to/test
+     * </p>
+     * <p>
+     * ordering of the elements in a {@link javax.json.JsonObject} is NOT significant however
+     * the position of an element in a {@link javax.json.JsonArray} is significant for equality.
+     * </p>
+     */
+    TEST
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/b0c19662/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
new file mode 100644
index 0000000..a303893
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+
+import org.junit.Test;
+
+public class JsonPatchTest {
+
+    @Test
+    public void testAddObjectMember() {
+
+        JsonObject object = Json.createReader(new StringReader("{ \"foo\": \"bar\" }"))
+                                .readObject();
+
+
+        JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                           Json.createJsonPointer("/baz"),
+                                                                           null, // no from
+                                                                           new JsonStringImpl("qux")));
+
+        JsonObject patched = patch.apply(object);
+        assertNotNull(patched);
+        assertEquals("bar", patched.getString("foo"));
+        assertEquals("qux", patched.getString("baz"));
+
+        StringWriter writer = new StringWriter();
+        Json.createWriter(writer).write(patched);
+
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", writer.toString());
+    }
+
+}


[08/26] johnzon git commit: JOHNZON-95 make JsonPointer an internal class which implements the spec API interface

Posted by st...@apache.org.
JOHNZON-95 make JsonPointer an internal class which implements the spec API interface

txs to Armin Hasler for providing the JsonPointer implementation


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/24b01af8
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/24b01af8
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/24b01af8

Branch: refs/heads/master
Commit: 24b01af8ebe37aa42fb98c2237edf807d5ec7379
Parents: bfdab10
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 21:49:32 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:49:32 2016 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonPointer.java    | 476 -------------------
 .../apache/johnzon/core/JsonPointerImpl.java    | 456 ++++++++++++++++++
 .../apache/johnzon/core/JsonProviderImpl.java   |   2 +-
 .../apache/johnzon/core/JsonPointerTest.java    | 124 ++---
 4 files changed, 519 insertions(+), 539 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/24b01af8/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
deleted file mode 100644
index ca942ef..0000000
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * 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 javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-import javax.json.JsonStructure;
-import javax.json.JsonValue;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * <p>This class is an immutable representation of a JSON Pointer as specified in
- * <a href="http://tools.ietf.org/html/rfc6901">RFC 6901</a>.
- * </p>
- * <p> A JSON Pointer, when applied to a target {@link JsonValue},
- * defines a reference location in the target.</p>
- * <p> An empty JSON Pointer string defines a reference to the target itself.</p>
- * <p> If the JSON Pointer string is non-empty, it must be a sequence
- * of '/' prefixed tokens, and the target must either be a {@link JsonArray}
- * or {@link JsonObject}. If the target is a {@code JsonArray}, the pointer
- * defines a reference to an array element, and the last token specifies the index.
- * If the target is a {@link JsonObject}, the pointer defines a reference to a
- * name/value pair, and the last token specifies the name.
- * </p>
- * <p> The method {@link JsonPointer#getValue getValue()} returns the referenced value.
- * The methods {@link JsonPointer#add add()}, {@link JsonPointer#replace replace()},
- * and {@link JsonPointer#remove remove()} executes the operations specified in
- * <a href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>. </p>
- *
- * @since 1.1
- */
-
-public class JsonPointer {
-
-    private final String jsonPointer;
-    private final List<String> referenceTokens = new ArrayList<String>();
-    private final String lastReferenceToken;
-
-    /**
-     * Constructs and initializes a JsonPointer.
-     *
-     * @param jsonPointer the JSON Pointer string
-     * @throws NullPointerException if {@code jsonPointer} is {@code null}
-     * @throws JsonException        if {@code jsonPointer} is not a valid JSON Pointer
-     */
-    public JsonPointer(String jsonPointer) {
-        if (jsonPointer == null) {
-            throw new NullPointerException("jsonPointer must not be null");
-        }
-        if (!jsonPointer.equals("") && !jsonPointer.startsWith("/")) {
-            throw new JsonException("A non-empty JsonPointer string must begin with a '/'");
-        }
-
-        this.jsonPointer = jsonPointer;
-        String[] encodedReferenceTokens = jsonPointer.split("/", -1);
-
-        for (String encodedReferenceToken : encodedReferenceTokens) {
-            referenceTokens.add(JsonPointerUtil.decode(encodedReferenceToken));
-        }
-        lastReferenceToken = referenceTokens.get(referenceTokens.size() - 1);
-    }
-
-    /**
-     * Compares this {@code JsonPointer} with another object.
-     *
-     * @param obj the object to compare this {@code JsonPointer} against
-     * @return true if the given object is a {@code JsonPointer} with the same
-     * reference tokens as this one, false otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-
-        JsonPointer that = (JsonPointer) obj;
-        return jsonPointer.equals(that.jsonPointer);
-    }
-
-    /**
-     * Returns the hash code value for this {@code JsonPointer} object.
-     * The hash code of this object is defined by the hash codes of it's reference tokens.
-     *
-     * @return the hash code value for this {@code JsonPointer} object
-     */
-    @Override
-    public int hashCode() {
-        return jsonPointer.hashCode();
-    }
-
-    /**
-     * Returns the value at the referenced location in the specified {@code target}
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @return the referenced value in the target.
-     * @throws NullPointerException if {@code target} is null
-     * @throws JsonException        if the referenced value does not exist
-     */
-    public JsonValue getValue(JsonStructure target) {
-        if (target == null) {
-            throw new NullPointerException("target must not be null");
-        }
-        if (isEmptyJsonPointer()) {
-            return target;
-        }
-
-        JsonValue jsonValue = target;
-        for (int i = 1; i < referenceTokens.size(); i++) {
-            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
-        }
-        return jsonValue;
-    }
-
-    /**
-     * Adds or replaces a value at the referenced location in the specified
-     * {@code target} with the specified {@code value}.
-     * <ol>
-     * <li>If the reference is the target (empty JSON Pointer string),
-     * the specified {@code value}, which must be the same type as
-     * specified {@code target}, is returned.</li>
-     * <li>If the reference is an array element, the specified {@code value} is inserted
-     * into the array, at the referenced index. The value currently at that location, and
-     * any subsequent values, are shifted to the right (adds one to the indices).
-     * Index starts with 0. If the reference is specified with a "-", or if the
-     * index is equal to the size of the array, the value is appended to the array.</li>
-     * <li>If the reference is a name/value pair of a {@code JsonObject}, and the
-     * referenced value exists, the value is replaced by the specified {@code value}.
-     * If the value does not exist, a new name/value pair is added to the object.</li>
-     * </ol>
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be added
-     * @return the transformed {@code target} after the value is added.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the reference is an array element and
-     *                              the index is out of range ({@code index < 0 || index > array size}),
-     *                              or if the pointer contains references to non-existing objects or arrays.
-     */
-    public JsonStructure add(JsonStructure target, JsonValue value) {
-        validateAdd(target);
-        if (isEmptyJsonPointer()) {
-            if (value.getClass() != target.getClass()) {
-                throw new JsonException("The value must have the same type as the target");
-            }
-            return (JsonStructure) value;
-        }
-
-        if (target instanceof JsonObject) {
-            return add((JsonObject) target, value);
-        } else {
-            return add((JsonArray) target, value);
-        }
-    }
-
-    /**
-     * Adds or replaces a value at the referenced location in the specified
-     * {@code target} with the specified {@code value}.
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be added
-     * @return the transformed {@code target} after the value is added.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the reference is an array element and
-     *                              the index is out of range ({@code index < 0 || index > array size}),
-     *                              or if the pointer contains references to non-existing objects or arrays.
-     * @see #add(JsonStructure, JsonValue)
-     */
-    public JsonObject add(JsonObject target, JsonValue value) {
-        validateAdd(target);
-
-        return (JsonObject) add(target, 1, referenceTokens.size() - 1, value);
-    }
-
-    /**
-     * Adds or replaces a value at the referenced location in the specified
-     * {@code target} with the specified {@code value}.
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be added
-     * @return the transformed {@code target} after the value is added.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the reference is an array element and
-     *                              the index is out of range ({@code index < 0 || index > array size}),
-     *                              or if the pointer contains references to non-existing objects or arrays.
-     * @see #add(JsonStructure, JsonValue)
-     */
-    public JsonArray add(JsonArray target, JsonValue value) {
-        validateAdd(target);
-
-        return (JsonArray) add(target, 1, referenceTokens.size() - 1, value);
-    }
-
-    /**
-     * Replaces the value at the referenced location in the specified
-     * {@code target} with the specified {@code value}.
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be stored at the referenced location
-     * @return the transformed {@code target} after the value is replaced.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     */
-    public JsonStructure replace(JsonStructure target, JsonValue value) {
-        if (target instanceof JsonObject) {
-            return replace((JsonObject) target, value);
-        } else {
-            return replace((JsonArray) target, value);
-        }
-    }
-
-    /**
-     * Replaces the value at the referenced location in the specified
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be stored at the referenced location
-     * @return the transformed {@code target} after the value is replaced.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     * @see #replace(JsonStructure, JsonValue)
-     */
-    public JsonObject replace(JsonObject target, JsonValue value) {
-        return add(remove(target), value);
-    }
-
-    /**
-     * Replaces the value at the referenced location in the specified
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be stored at the referenced location
-     * @return the transformed {@code target} after the value is replaced.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     * @see #replace(JsonStructure, JsonValue)
-     */
-    public JsonArray replace(JsonArray target, JsonValue value) {
-        return add(remove(target), value);
-    }
-
-    /**
-     * Removes the value at the reference location in the specified {@code target}
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @return the transformed {@code target} after the value is removed.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     */
-    public JsonStructure remove(JsonStructure target) {
-        if (target instanceof JsonObject) {
-            return remove((JsonObject) target);
-        } else {
-            return remove((JsonArray) target);
-        }
-    }
-
-    /**
-     * Removes the value at the reference location in the specified {@code target}
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @return the transformed {@code target} after the value is removed.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     * @see #remove(JsonStructure)
-     */
-    public JsonObject remove(JsonObject target) {
-        validateRemove(target);
-
-        return (JsonObject) remove(target, 1, referenceTokens.size() - 1);
-    }
-
-    /**
-     * Removes the value at the reference location in the specified {@code target}
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @return the transformed {@code target} after the value is removed.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     * @see #remove(JsonStructure)
-     */
-    public JsonArray remove(JsonArray target) {
-        validateRemove(target);
-
-        return (JsonArray) remove(target, 1, referenceTokens.size() - 1);
-    }
-
-    private void validateAdd(JsonValue target) {
-        validateJsonPointer(target, referenceTokens.size() - 1);
-    }
-
-    private void validateRemove(JsonValue target) {
-        validateJsonPointer(target, referenceTokens.size());
-        if (isEmptyJsonPointer()) {
-            throw new JsonException("The reference must not be the target");
-        }
-    }
-
-    private boolean isEmptyJsonPointer() {
-        return jsonPointer.equals("");
-    }
-
-    private JsonValue getValue(JsonValue jsonValue, String referenceToken, int currentPosition, int referencePosition) {
-        if (jsonValue instanceof JsonObject) {
-            JsonObject jsonObject = (JsonObject) jsonValue;
-            jsonValue = jsonObject.get(referenceToken);
-
-            if (jsonValue != null) {
-                return jsonValue;
-            }
-            throw new JsonException("'" + jsonObject + "' contains no value for name '" + referenceToken + "'");
-        } else if (jsonValue instanceof JsonArray) {
-            validateArrayIndex(referenceToken);
-
-            try {
-                JsonArray jsonArray = (JsonArray) jsonValue;
-                int arrayIndex = Integer.parseInt(referenceToken);
-                validateArraySize(jsonArray, arrayIndex, jsonArray.size());
-                return jsonArray.get(arrayIndex);
-            } catch (NumberFormatException e) {
-                throw new JsonException("'" + referenceToken + "' is no valid array index", e);
-            }
-        } else {
-            if (currentPosition != referencePosition) {
-                return jsonValue;
-            }
-            throw new JsonException("'" + jsonValue + "' contains no element for '" + referenceToken + "'");
-        }
-    }
-
-    private JsonValue add(JsonValue jsonValue, int currentPosition, int referencePosition, JsonValue newValue) {
-        if (jsonValue instanceof JsonObject) {
-            JsonObject jsonObject = (JsonObject) jsonValue;
-            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
-
-            if (jsonObject.isEmpty()) {
-                objectBuilder.add(lastReferenceToken, newValue);
-            } else {
-                for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
-                    objectBuilder.add(entry.getKey(), add(entry.getValue(), currentPosition + 1, referencePosition, newValue));
-                    if (currentPosition == referencePosition) {
-                        objectBuilder.add(lastReferenceToken, newValue);
-                    }
-                }
-            }
-            return objectBuilder.build();
-        } else if (jsonValue instanceof JsonArray) {
-            JsonArray jsonArray = (JsonArray) jsonValue;
-            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
-
-            int arrayIndex = -1;
-            if (currentPosition == referencePosition) {
-                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, true);
-            }
-
-            int jsonArraySize = jsonArray.size();
-            for (int i = 0; i <= jsonArraySize; i++) {
-                if (i == arrayIndex) {
-                    arrayBuilder.add(newValue);
-                }
-                if (i == jsonArraySize) {
-                    break;
-                }
-                arrayBuilder.add(add(jsonArray.get(i), currentPosition + 1, referencePosition, newValue));
-            }
-            return arrayBuilder.build();
-        }
-        return jsonValue;
-    }
-
-    private JsonValue remove(JsonValue jsonValue, int currentPosition, int referencePosition) {
-        if (jsonValue instanceof JsonObject) {
-            JsonObject jsonObject = (JsonObject) jsonValue;
-            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
-
-            for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
-                if (currentPosition == referencePosition
-                        && lastReferenceToken.equals(entry.getKey())) {
-                    continue;
-                }
-                objectBuilder.add(entry.getKey(), remove(entry.getValue(), currentPosition + 1, referencePosition));
-            }
-            return objectBuilder.build();
-        } else if (jsonValue instanceof JsonArray) {
-            JsonArray jsonArray = (JsonArray) jsonValue;
-            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
-
-            int arrayIndex = -1;
-            if (currentPosition == referencePosition) {
-                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, false);
-            }
-
-            int jsonArraySize = jsonArray.size();
-            for (int i = 0; i < jsonArraySize; i++) {
-                if (i == arrayIndex) {
-                    continue;
-                }
-                arrayBuilder.add(remove(jsonArray.get(i), currentPosition + 1, referencePosition));
-            }
-            return arrayBuilder.build();
-        }
-        return jsonValue;
-    }
-
-    private int getArrayIndex(String referenceToken, JsonArray jsonArray, boolean addOperation) {
-        if (addOperation && referenceToken.equals("-")) {
-            return jsonArray.size();
-        }
-
-        validateArrayIndex(referenceToken);
-
-        try {
-            int arrayIndex = Integer.parseInt(referenceToken);
-            int arraySize = addOperation ? jsonArray.size() + 1 : jsonArray.size();
-            validateArraySize(jsonArray, arrayIndex, arraySize);
-            return arrayIndex;
-        } catch (NumberFormatException e) {
-            throw new JsonException("'" + referenceToken + "' is no valid array index", e);
-        }
-    }
-
-    private void validateJsonPointer(JsonValue target, int size) throws NullPointerException, JsonException {
-        if (target == null) {
-            throw new NullPointerException("target must not be null");
-        }
-
-        JsonValue jsonValue = target;
-        for (int i = 1; i < size; i++) {
-            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
-        }
-    }
-
-    private void validateArrayIndex(String referenceToken) throws JsonException {
-        if (referenceToken.startsWith("+") || referenceToken.startsWith("-")) {
-            throw new JsonException("An array index must not start with '" + referenceToken.charAt(0) + "'");
-        }
-        if (referenceToken.startsWith("0") && referenceToken.length() > 1) {
-            throw new JsonException("An array index must not start with a leading '0'");
-        }
-    }
-
-    private void validateArraySize(JsonArray jsonArray, int arrayIndex, int arraySize) throws JsonException {
-        if (arrayIndex >= arraySize) {
-            throw new JsonException("'" + jsonArray + "' contains no element for index " + arrayIndex);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/24b01af8/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..25e5ceb
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
@@ -0,0 +1,456 @@
+/*
+ * 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 javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonPointer;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+public class JsonPointerImpl implements JsonPointer {
+
+    private final String jsonPointer;
+    private final List<String> referenceTokens = new ArrayList<String>();
+    private final String lastReferenceToken;
+
+    /**
+     * Constructs and initializes a JsonPointer.
+     *
+     * @param jsonPointer the JSON Pointer string
+     * @throws NullPointerException if {@code jsonPointer} is {@code null}
+     * @throws JsonException        if {@code jsonPointer} is not a valid JSON Pointer
+     */
+    public JsonPointerImpl(String jsonPointer) {
+        if (jsonPointer == null) {
+            throw new NullPointerException("jsonPointer must not be null");
+        }
+        if (!jsonPointer.equals("") && !jsonPointer.startsWith("/")) {
+            throw new JsonException("A non-empty JsonPointer string must begin with a '/'");
+        }
+
+        this.jsonPointer = jsonPointer;
+        String[] encodedReferenceTokens = jsonPointer.split("/", -1);
+
+        for (String encodedReferenceToken : encodedReferenceTokens) {
+            referenceTokens.add(JsonPointerUtil.decode(encodedReferenceToken));
+        }
+        lastReferenceToken = referenceTokens.get(referenceTokens.size() - 1);
+    }
+
+    /**
+     * Compares this {@code JsonPointer} with another object.
+     *
+     * @param obj the object to compare this {@code JsonPointer} against
+     * @return true if the given object is a {@code JsonPointer} with the same
+     * reference tokens as this one, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        JsonPointerImpl that = (JsonPointerImpl) obj;
+        return jsonPointer.equals(that.jsonPointer);
+    }
+
+    /**
+     * Returns the hash code value for this {@code JsonPointer} object.
+     * The hash code of this object is defined by the hash codes of it's reference tokens.
+     *
+     * @return the hash code value for this {@code JsonPointer} object
+     */
+    @Override
+    public int hashCode() {
+        return jsonPointer.hashCode();
+    }
+
+    /**
+     * Returns the value at the referenced location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the referenced value in the target.
+     * @throws NullPointerException if {@code target} is null
+     * @throws JsonException        if the referenced value does not exist
+     */
+    public JsonValue getValue(JsonStructure target) {
+        if (target == null) {
+            throw new NullPointerException("target must not be null");
+        }
+        if (isEmptyJsonPointer()) {
+            return target;
+        }
+
+        JsonValue jsonValue = target;
+        for (int i = 1; i < referenceTokens.size(); i++) {
+            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
+        }
+        return jsonValue;
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     * <ol>
+     * <li>If the reference is the target (empty JSON Pointer string),
+     * the specified {@code value}, which must be the same type as
+     * specified {@code target}, is returned.</li>
+     * <li>If the reference is an array element, the specified {@code value} is inserted
+     * into the array, at the referenced index. The value currently at that location, and
+     * any subsequent values, are shifted to the right (adds one to the indices).
+     * Index starts with 0. If the reference is specified with a "-", or if the
+     * index is equal to the size of the array, the value is appended to the array.</li>
+     * <li>If the reference is a name/value pair of a {@code JsonObject}, and the
+     * referenced value exists, the value is replaced by the specified {@code value}.
+     * If the value does not exist, a new name/value pair is added to the object.</li>
+     * </ol>
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     */
+    public JsonStructure add(JsonStructure target, JsonValue value) {
+        validateAdd(target);
+        if (isEmptyJsonPointer()) {
+            if (value.getClass() != target.getClass()) {
+                throw new JsonException("The value must have the same type as the target");
+            }
+            return (JsonStructure) value;
+        }
+
+        if (target instanceof JsonObject) {
+            return add((JsonObject) target, value);
+        } else {
+            return add((JsonArray) target, value);
+        }
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     * @see #add(JsonStructure, JsonValue)
+     */
+    public JsonObject add(JsonObject target, JsonValue value) {
+        validateAdd(target);
+
+        return (JsonObject) add(target, 1, referenceTokens.size() - 1, value);
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     * @see #add(JsonStructure, JsonValue)
+     */
+    public JsonArray add(JsonArray target, JsonValue value) {
+        validateAdd(target);
+
+        return (JsonArray) add(target, 1, referenceTokens.size() - 1, value);
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure replace(JsonStructure target, JsonValue value) {
+        if (target instanceof JsonObject) {
+            return replace((JsonObject) target, value);
+        } else {
+            return replace((JsonArray) target, value);
+        }
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #replace(JsonStructure, JsonValue)
+     */
+    public JsonObject replace(JsonObject target, JsonValue value) {
+        return add(remove(target), value);
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #replace(JsonStructure, JsonValue)
+     */
+    public JsonArray replace(JsonArray target, JsonValue value) {
+        return add(remove(target), value);
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure remove(JsonStructure target) {
+        if (target instanceof JsonObject) {
+            return remove((JsonObject) target);
+        } else {
+            return remove((JsonArray) target);
+        }
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #remove(JsonStructure)
+     */
+    public JsonObject remove(JsonObject target) {
+        validateRemove(target);
+
+        return (JsonObject) remove(target, 1, referenceTokens.size() - 1);
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #remove(JsonStructure)
+     */
+    public JsonArray remove(JsonArray target) {
+        validateRemove(target);
+
+        return (JsonArray) remove(target, 1, referenceTokens.size() - 1);
+    }
+
+    private void validateAdd(JsonValue target) {
+        validateJsonPointer(target, referenceTokens.size() - 1);
+    }
+
+    private void validateRemove(JsonValue target) {
+        validateJsonPointer(target, referenceTokens.size());
+        if (isEmptyJsonPointer()) {
+            throw new JsonException("The reference must not be the target");
+        }
+    }
+
+    private boolean isEmptyJsonPointer() {
+        return jsonPointer.equals("");
+    }
+
+    private JsonValue getValue(JsonValue jsonValue, String referenceToken, int currentPosition, int referencePosition) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            jsonValue = jsonObject.get(referenceToken);
+
+            if (jsonValue != null) {
+                return jsonValue;
+            }
+            throw new JsonException("'" + jsonObject + "' contains no value for name '" + referenceToken + "'");
+        } else if (jsonValue instanceof JsonArray) {
+            validateArrayIndex(referenceToken);
+
+            try {
+                JsonArray jsonArray = (JsonArray) jsonValue;
+                int arrayIndex = Integer.parseInt(referenceToken);
+                validateArraySize(jsonArray, arrayIndex, jsonArray.size());
+                return jsonArray.get(arrayIndex);
+            } catch (NumberFormatException e) {
+                throw new JsonException("'" + referenceToken + "' is no valid array index", e);
+            }
+        } else {
+            if (currentPosition != referencePosition) {
+                return jsonValue;
+            }
+            throw new JsonException("'" + jsonValue + "' contains no element for '" + referenceToken + "'");
+        }
+    }
+
+    private JsonValue add(JsonValue jsonValue, int currentPosition, int referencePosition, JsonValue newValue) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+
+            if (jsonObject.isEmpty()) {
+                objectBuilder.add(lastReferenceToken, newValue);
+            } else {
+                for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
+                    objectBuilder.add(entry.getKey(), add(entry.getValue(), currentPosition + 1, referencePosition, newValue));
+                    if (currentPosition == referencePosition) {
+                        objectBuilder.add(lastReferenceToken, newValue);
+                    }
+                }
+            }
+            return objectBuilder.build();
+        } else if (jsonValue instanceof JsonArray) {
+            JsonArray jsonArray = (JsonArray) jsonValue;
+            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+
+            int arrayIndex = -1;
+            if (currentPosition == referencePosition) {
+                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, true);
+            }
+
+            int jsonArraySize = jsonArray.size();
+            for (int i = 0; i <= jsonArraySize; i++) {
+                if (i == arrayIndex) {
+                    arrayBuilder.add(newValue);
+                }
+                if (i == jsonArraySize) {
+                    break;
+                }
+                arrayBuilder.add(add(jsonArray.get(i), currentPosition + 1, referencePosition, newValue));
+            }
+            return arrayBuilder.build();
+        }
+        return jsonValue;
+    }
+
+    private JsonValue remove(JsonValue jsonValue, int currentPosition, int referencePosition) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+
+            for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
+                if (currentPosition == referencePosition
+                        && lastReferenceToken.equals(entry.getKey())) {
+                    continue;
+                }
+                objectBuilder.add(entry.getKey(), remove(entry.getValue(), currentPosition + 1, referencePosition));
+            }
+            return objectBuilder.build();
+        } else if (jsonValue instanceof JsonArray) {
+            JsonArray jsonArray = (JsonArray) jsonValue;
+            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+
+            int arrayIndex = -1;
+            if (currentPosition == referencePosition) {
+                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, false);
+            }
+
+            int jsonArraySize = jsonArray.size();
+            for (int i = 0; i < jsonArraySize; i++) {
+                if (i == arrayIndex) {
+                    continue;
+                }
+                arrayBuilder.add(remove(jsonArray.get(i), currentPosition + 1, referencePosition));
+            }
+            return arrayBuilder.build();
+        }
+        return jsonValue;
+    }
+
+    private int getArrayIndex(String referenceToken, JsonArray jsonArray, boolean addOperation) {
+        if (addOperation && referenceToken.equals("-")) {
+            return jsonArray.size();
+        }
+
+        validateArrayIndex(referenceToken);
+
+        try {
+            int arrayIndex = Integer.parseInt(referenceToken);
+            int arraySize = addOperation ? jsonArray.size() + 1 : jsonArray.size();
+            validateArraySize(jsonArray, arrayIndex, arraySize);
+            return arrayIndex;
+        } catch (NumberFormatException e) {
+            throw new JsonException("'" + referenceToken + "' is no valid array index", e);
+        }
+    }
+
+    private void validateJsonPointer(JsonValue target, int size) throws NullPointerException, JsonException {
+        if (target == null) {
+            throw new NullPointerException("target must not be null");
+        }
+
+        JsonValue jsonValue = target;
+        for (int i = 1; i < size; i++) {
+            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
+        }
+    }
+
+    private void validateArrayIndex(String referenceToken) throws JsonException {
+        if (referenceToken.startsWith("+") || referenceToken.startsWith("-")) {
+            throw new JsonException("An array index must not start with '" + referenceToken.charAt(0) + "'");
+        }
+        if (referenceToken.startsWith("0") && referenceToken.length() > 1) {
+            throw new JsonException("An array index must not start with a leading '0'");
+        }
+    }
+
+    private void validateArraySize(JsonArray jsonArray, int arrayIndex, int arraySize) throws JsonException {
+        if (arrayIndex >= arraySize) {
+            throw new JsonException("'" + jsonArray + "' contains no element for index " + arrayIndex);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/24b01af8/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 99fd6fc..e9926f9 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
@@ -236,7 +236,7 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
         @Override
         public JsonPointer createJsonPointer(String path) {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+            return new JsonPointerImpl(path);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/johnzon/blob/24b01af8/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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 9b6c722..7a3d32a 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
@@ -37,17 +37,17 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testConstructorWithJsonPointerNull() {
-        new JsonPointer(null);
+        new JsonPointerImpl(null);
     }
 
     @Test(expected = JsonException.class)
     public void testConstructorWithInvalidJsonPointer() {
-        new JsonPointer("a");
+        new JsonPointerImpl("a");
     }
 
     @Test(expected = NullPointerException.class)
     public void testGetValueWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         jsonPointer.getValue(null);
     }
 
@@ -55,7 +55,7 @@ public class JsonPointerTest {
     public void testGetValueWithWholeDocument() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals(jsonDocument.toString(), result.toString());
     }
@@ -64,7 +64,7 @@ public class JsonPointerTest {
     public void testGetValue0() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("0", result.toString());
     }
@@ -73,7 +73,7 @@ public class JsonPointerTest {
     public void testGetValue1() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/a~1b");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/a~1b");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("1", result.toString());
     }
@@ -82,7 +82,7 @@ public class JsonPointerTest {
     public void testGetValue2() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/c%d");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/c%d");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("2", result.toString());
     }
@@ -91,7 +91,7 @@ public class JsonPointerTest {
     public void testGetValue3() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/e^f");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/e^f");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("3", result.toString());
     }
@@ -100,7 +100,7 @@ public class JsonPointerTest {
     public void testGetValue4() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/g|h");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/g|h");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("4", result.toString());
     }
@@ -109,7 +109,7 @@ public class JsonPointerTest {
     public void testGetValue5() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/i\\j");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/i\\j");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("5", result.toString());
     }
@@ -118,7 +118,7 @@ public class JsonPointerTest {
     public void testGetValue6() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/k\"l");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/k\"l");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("6", result.toString());
     }
@@ -127,7 +127,7 @@ public class JsonPointerTest {
     public void testGetValue7() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/ ");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/ ");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("7", result.toString());
     }
@@ -136,7 +136,7 @@ public class JsonPointerTest {
     public void testGetValue8() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/m~0n");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/m~0n");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("8", result.toString());
     }
@@ -145,7 +145,7 @@ public class JsonPointerTest {
     public void testGetValueWithElementNotExistent() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/fool");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/fool");
         jsonPointer.getValue(jsonDocument);
     }
 
@@ -153,7 +153,7 @@ public class JsonPointerTest {
     public void testGetValueWithWholeJsonArray() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("[\"bar\",\"baz\"]", result.toString());
     }
@@ -162,7 +162,7 @@ public class JsonPointerTest {
     public void testGetValueWithJsonArray() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/0");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/0");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("\"bar\"", result.toString());
     }
@@ -171,7 +171,7 @@ public class JsonPointerTest {
     public void testGetValueWithJsonArrayIndexOutOfRange() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/2");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/2");
         jsonPointer.getValue(jsonDocument);
     }
 
@@ -179,7 +179,7 @@ public class JsonPointerTest {
     public void testGetValueWithJsonArrayIndexNoNumber() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/a");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/a");
         jsonPointer.getValue(jsonDocument);
     }
 
@@ -187,7 +187,7 @@ public class JsonPointerTest {
     public void testGetValueWithJsonArrayLeadingZeroIndex() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/01");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/01");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("\"bar\"", result.toString());
     }
@@ -196,19 +196,19 @@ public class JsonPointerTest {
     public void testGetValueWithJsonArrayInvalidIndex() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/-1");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/-1");
         jsonPointer.getValue(jsonDocument);
     }
 
     @Test(expected = NullPointerException.class)
     public void testAddJsonStructureWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         jsonPointer.add((JsonStructure) null, new JsonStringImpl("qux"));
     }
 
     @Test(expected = JsonException.class)
     public void testAddJsonStructureWithTypeValueNotTypeTarget() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonObject target = Json.createObjectBuilder().build();
         JsonArray value = Json.createArrayBuilder().build();
 
@@ -217,7 +217,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddJsonStructureWithEmptyJsonPointer() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonStructure target = Json.createObjectBuilder().build();
         JsonObject value = Json.createObjectBuilder()
                 .add("foo", "bar").build(); // { "foo": "bar" }
@@ -228,19 +228,19 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testAddJsonObjectWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         jsonPointer.add((JsonObject) null, new JsonStringImpl("qux"));
     }
 
     @Test(expected = NullPointerException.class)
     public void testAddJsonArrayWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         jsonPointer.add((JsonArray) null, new JsonStringImpl("qux"));
     }
 
     @Test(expected = JsonException.class)
     public void testAddArrayElementWithInvalidIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/+");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/+");
         JsonStructure target = Json.createArrayBuilder().build();
 
         jsonPointer.add(target, new JsonStringImpl("qux"));
@@ -248,7 +248,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testAddArrayElementWithIndexOutOfRange() {
-        JsonPointer jsonPointer = new JsonPointer("/1");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1");
         JsonStructure target = Json.createArrayBuilder().build();
 
         jsonPointer.add(target, new JsonStringImpl("qux"));
@@ -256,7 +256,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testAddArrayElementWithLeadingZeroIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/01");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/01");
         JsonStructure target = Json.createArrayBuilder()
                 .add("foo").build();
 
@@ -265,7 +265,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testAddArrayElementWithIndexNoNumber() {
-        JsonPointer jsonPointer = new JsonPointer("/a");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/a");
         JsonStructure target = Json.createArrayBuilder()
                 .add("foo").build();
 
@@ -274,7 +274,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddObject() {
-        JsonPointer jsonPointer = new JsonPointer("/child");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/child");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar").build(); // {"foo":"bar"}
         JsonObject value = Json.createObjectBuilder()
@@ -286,7 +286,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddObjectMember() {
-        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar").build(); // {"foo":"bar"}
 
@@ -296,7 +296,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddFirstObjectMember() {
-        JsonPointer jsonPointer = new JsonPointer("/foo");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo");
         JsonStructure target = Json.createObjectBuilder().build(); // {}
 
         JsonStructure result = jsonPointer.add(target, new JsonStringImpl("bar"));
@@ -305,7 +305,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testAddObjectMemberWithNonexistentTarget() {
-        JsonPointer jsonPointer = new JsonPointer("/baz/bat");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz/bat");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar").build(); // {"foo":"bar"}
 
@@ -314,7 +314,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddReplaceObjectMember() {
-        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz");
         JsonStructure target = Json.createObjectBuilder()
                 .add("baz", "qux")
                 .add("foo", "bar").build(); // {"baz":"qux","foo":"bar"}
@@ -325,7 +325,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddArray() {
-        JsonPointer jsonPointer = new JsonPointer("/0/-");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/0/-");
         JsonStructure target = Json.createArrayBuilder()
                 .add(Json.createArrayBuilder()
                         .add("bar")).build(); // [["bar"]]
@@ -339,7 +339,7 @@ public class JsonPointerTest {
 
     @Test
     public void testAddArrayElement() {
-        JsonPointer jsonPointer = new JsonPointer("/foo/1");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/1");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", Json.createArrayBuilder()
                         .add("bar")
@@ -351,13 +351,13 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testRemoveJsonObjectWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/");
         jsonPointer.remove((JsonObject) null);
     }
 
     @Test(expected = JsonException.class)
     public void testRemoveJsonObjectWithEmptyJsonPointer() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonObject target = Json.createObjectBuilder().build();
 
         jsonPointer.remove(target);
@@ -365,13 +365,13 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testRemoveJsonArrayWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/");
         jsonPointer.remove((JsonArray) null);
     }
 
     @Test(expected = JsonException.class)
     public void testRemoveJsonArrayWithEmptyJsonPointer() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonArray target = Json.createArrayBuilder().build();
 
         jsonPointer.remove(target);
@@ -379,7 +379,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testRemoveArrayElementWithIndexNoNumber() {
-        JsonPointer jsonPointer = new JsonPointer("/foo/a");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/a");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", Json.createArrayBuilder()
                         .add("bar")
@@ -391,7 +391,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testRemoveArrayElementWithIndexOutOfRange() {
-        JsonPointer jsonPointer = new JsonPointer("/foo/3");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/3");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", Json.createArrayBuilder()
                         .add("bar")
@@ -403,7 +403,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testRemoveArrayElementWithInvalidIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/foo/+");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/+");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", Json.createArrayBuilder()
                         .add("bar")
@@ -415,7 +415,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testRemoveArrayElementWithLeadingZeroIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/foo/01");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/foo/01");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", Json.createArrayBuilder()
                         .add("bar")
@@ -427,7 +427,7 @@ public class JsonPointerTest {
 
     @Test
     public void testRemoveArrayElement() {
-        JsonPointer jsonPointer = new JsonPointer("/0/1");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/0/1");
         JsonStructure target = Json.createArrayBuilder()
                 .add(Json.createArrayBuilder()
                         .add("bar")
@@ -440,7 +440,7 @@ public class JsonPointerTest {
 
     @Test
     public void testRemoveObjectMember() {
-        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz");
         JsonStructure target = Json.createObjectBuilder()
                 .add("baz", "qux")
                 .add("foo", "bar").build(); // {"baz":"qux","foo":"bar"}
@@ -451,13 +451,13 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testReplaceJsonObjectWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/");
         jsonPointer.replace((JsonObject) null, new JsonStringImpl("qux"));
     }
 
     @Test(expected = JsonException.class)
     public void testReplaceJsonObjectWithEmptyJsonPointer() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonObject target = Json.createObjectBuilder().build();
 
         jsonPointer.replace(target, new JsonStringImpl("qux"));
@@ -465,13 +465,13 @@ public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
     public void testReplaceJsonArrayWithTargetNull() {
-        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/");
         jsonPointer.replace((JsonArray) null, new JsonStringImpl("qux"));
     }
 
     @Test(expected = JsonException.class)
     public void testReplaceJsonArrayWithEmptyJsonPointer() {
-        JsonPointer jsonPointer = new JsonPointer("");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("");
         JsonArray target = Json.createArrayBuilder().build();
 
         jsonPointer.replace(target, new JsonStringImpl("qux"));
@@ -479,7 +479,7 @@ public class JsonPointerTest {
 
     @Test
     public void testReplaceArrayElement() {
-        JsonPointer jsonPointer = new JsonPointer("/1/1");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1/1");
         JsonStructure target = Json.createArrayBuilder()
                 .add("bar")
                 .add(Json.createArrayBuilder()
@@ -492,7 +492,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceArrayElementWithIndexOutOfRange() {
-        JsonPointer jsonPointer = new JsonPointer("/1/2");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1/2");
         JsonStructure target = Json.createArrayBuilder()
                 .add("bar")
                 .add(Json.createArrayBuilder()
@@ -504,7 +504,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceArrayElementWithIndexNoNumber() {
-        JsonPointer jsonPointer = new JsonPointer("/1/a");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1/a");
         JsonStructure target = Json.createArrayBuilder()
                 .add("bar")
                 .add(Json.createArrayBuilder()
@@ -516,7 +516,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceArrayElementWithLeadingZeroIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/1/01");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1/01");
         JsonStructure target = Json.createArrayBuilder()
                 .add("bar")
                 .add(Json.createArrayBuilder()
@@ -528,7 +528,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceArrayElementWithInvalidIndex() {
-        JsonPointer jsonPointer = new JsonPointer("/1/+");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/1/+");
         JsonStructure target = Json.createArrayBuilder()
                 .add("bar")
                 .add(Json.createArrayBuilder()
@@ -540,7 +540,7 @@ public class JsonPointerTest {
 
     @Test
     public void testReplaceObjectMember() {
-        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar")
                 .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
@@ -551,7 +551,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceObjectMemberWithNonexistentTarget1() {
-        JsonPointer jsonPointer = new JsonPointer("/baz/a");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/baz/a");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar")
                 .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
@@ -562,7 +562,7 @@ public class JsonPointerTest {
 
     @Test(expected = JsonException.class)
     public void testReplaceObjectMemberWithNonexistentTarget2() {
-        JsonPointer jsonPointer = new JsonPointer("/fo");
+        JsonPointerImpl jsonPointer = new JsonPointerImpl("/fo");
         JsonStructure target = Json.createObjectBuilder()
                 .add("foo", "bar")
                 .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
@@ -573,15 +573,15 @@ public class JsonPointerTest {
 
     @Test
     public void testEqualsTrue() {
-        JsonPointer jsonPointer1 = new JsonPointer("/foo/1");
-        JsonPointer jsonPointer2 = new JsonPointer("/foo/1");
+        JsonPointerImpl jsonPointer1 = new JsonPointerImpl("/foo/1");
+        JsonPointerImpl jsonPointer2 = new JsonPointerImpl("/foo/1");
         assertTrue(jsonPointer1.equals(jsonPointer2));
     }
 
     @Test
     public void testEqualsFalse() {
-        JsonPointer jsonPointer1 = new JsonPointer("/foo/1");
-        JsonPointer jsonPointer2 = new JsonPointer("/foo/2");
+        JsonPointerImpl jsonPointer1 = new JsonPointerImpl("/foo/1");
+        JsonPointerImpl jsonPointer2 = new JsonPointerImpl("/foo/2");
         assertFalse(jsonPointer1.equals(jsonPointer2));
     }
 


[17/26] johnzon git commit: JOHNZON-98 implemented JsonPatchBuilder

Posted by st...@apache.org.
JOHNZON-98 implemented JsonPatchBuilder


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/0e4bd488
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/0e4bd488
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/0e4bd488

Branch: refs/heads/master
Commit: 0e4bd4888918bbf46db024bb62139c42de0d1bc0
Parents: 74cb908
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Mon Nov 28 13:14:24 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Mon Nov 28 13:14:24 2016 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonPatchBuilderImpl.java      | 121 ++++-
 .../org/apache/johnzon/core/JsonPatchImpl.java  | 125 +++++-
 .../apache/johnzon/core/JsonPointerImpl.java    |   4 +
 .../johnzon/core/JsonPatchBuilderTest.java      | 440 +++++++++++++++++++
 .../org/apache/johnzon/core/JsonPatchTest.java  | 130 +++---
 5 files changed, 724 insertions(+), 96 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/0e4bd488/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
index a6e7c8a..1dc5ae4 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
@@ -22,110 +22,183 @@ import javax.json.JsonPatch;
 import javax.json.JsonPatchBuilder;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
+import java.util.ArrayList;
+import java.util.List;
 
-public class JsonPatchBuilderImpl implements JsonPatchBuilder {
-    public JsonPatchBuilderImpl() {
-        super();
+class JsonPatchBuilderImpl implements JsonPatchBuilder {
+
+    private final List<JsonPatchImpl.PatchValue> operations;
+
+
+    JsonPatchBuilderImpl() {
+        operations = new ArrayList<>();
     }
 
-    public JsonPatchBuilderImpl(JsonArray initialData) {
-        super();
+    JsonPatchBuilderImpl(JsonArray initialData) {
+        operations = new ArrayList<>(initialData.size());
+
+        for (JsonValue value : initialData) {
+
+            JsonObject operation = (JsonObject) value;
+
+            JsonPatchOperation op = JsonPatchOperation.valueOf(operation.getString("op").toUpperCase());
+            String path = operation.getString("path");
+            String from = operation.getString("from", null);
+            JsonValue jsonValue = operation.get("value");
+
+            operations.add(new JsonPatchImpl.PatchValue(op,
+                                                        path,
+                                                        from,
+                                                        jsonValue));
+        }
     }
 
 
 
+    //X TODO this should get simplified to only one method like JsonPatch
     @Override
     public JsonStructure apply(JsonStructure target) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return build().apply(target);
     }
 
     @Override
     public JsonObject apply(JsonObject target) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return build().apply(target);
     }
 
     @Override
     public JsonArray apply(JsonArray target) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return build().apply(target);
     }
 
+
     @Override
     public JsonPatchBuilder add(String path, JsonValue value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                         path,
+                                                         null,
+                                                         value));
     }
 
     @Override
     public JsonPatchBuilder add(String path, String value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return add(path, toJsonString(value));
     }
 
     @Override
     public JsonPatchBuilder add(String path, int value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return add(path, toJsonNumber(value));
     }
 
     @Override
     public JsonPatchBuilder add(String path, boolean value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return add(path, toJsonBoolean(value));
     }
 
+
     @Override
     public JsonPatchBuilder remove(String path) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                         path,
+                                                         null,
+                                                         null));
     }
 
+
     @Override
     public JsonPatchBuilder replace(String path, JsonValue value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                         path,
+                                                         null,
+                                                         value));
     }
 
     @Override
     public JsonPatchBuilder replace(String path, String value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return replace(path, toJsonString(value));
     }
 
     @Override
     public JsonPatchBuilder replace(String path, int value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return replace(path, toJsonNumber(value));
     }
 
     @Override
     public JsonPatchBuilder replace(String path, boolean value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return replace(path, toJsonBoolean(value));
     }
 
+
     @Override
     public JsonPatchBuilder move(String path, String from) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                         path,
+                                                         from,
+                                                         null));
     }
 
+
     @Override
     public JsonPatchBuilder copy(String path, String from) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                         path,
+                                                         from,
+                                                         null));
     }
 
+
     @Override
     public JsonPatchBuilder test(String path, JsonValue value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                         path,
+                                                         null,
+                                                         value));
     }
 
     @Override
     public JsonPatchBuilder test(String path, String value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return test(path, toJsonString(value));
     }
 
     @Override
     public JsonPatchBuilder test(String path, int value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return test(path, toJsonNumber(value));
     }
 
     @Override
     public JsonPatchBuilder test(String path, boolean value) {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+        return test(path, toJsonBoolean(value));
     }
 
+
     @Override
     public JsonPatch build() {
-        throw new UnsupportedOperationException("JSON-P 1.1");
+
+        // add operations to another list
+        // so we can clear and reuse the builder
+        JsonPatchImpl patch = new JsonPatchImpl(new ArrayList<>(operations));
+        operations.clear();
+
+        return patch;
+
     }
+
+
+    private JsonPatchBuilder addOperation(JsonPatchImpl.PatchValue operation) {
+        operations.add(operation);
+        return this;
+    }
+
+    private static JsonValue toJsonBoolean(boolean value) {
+        return value ? JsonValue.TRUE : JsonValue.FALSE;
+    }
+
+    private static JsonValue toJsonString(String value) {
+        return value == null ? JsonValue.NULL : new JsonStringImpl(value);
+    }
+
+    private static JsonValue toJsonNumber(int value) {
+        return new JsonLongImpl(value);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/0e4bd488/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
----------------------------------------------------------------------
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 0aaedf9..813dba0 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
@@ -20,11 +20,16 @@ package org.apache.johnzon.core;
 
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
 import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
 import javax.json.JsonPatch;
-import javax.json.JsonPointer;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
 
@@ -37,6 +42,14 @@ class JsonPatchImpl implements JsonPatch {
         this.patches = Arrays.asList(patches);
     }
 
+    JsonPatchImpl(List<PatchValue> patches) {
+        if (patches == null) {
+            this.patches = Collections.emptyList();
+        } else {
+            this.patches = Collections.unmodifiableList(patches);
+        }
+    }
+
 
     @Override
     public <T extends JsonStructure> T apply(T target) {
@@ -81,21 +94,119 @@ class JsonPatchImpl implements JsonPatch {
     }
 
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        JsonPatchImpl jsonPatch = (JsonPatchImpl) o;
+
+        return patches.equals(jsonPatch.patches);
+    }
+
+    @Override
+    public int hashCode() {
+        return patches.hashCode();
+    }
+
+
+    JsonArray toJsonArray() {
+
+        JsonArrayBuilder builder = Json.createArrayBuilder();
+        for (PatchValue patch : patches) {
+            builder.add(patch.toJson());
+        }
+
+        return builder.build();
+    }
+
+
 
     static class PatchValue {
         private final JsonPatchOperation operation;
-        private final JsonPointer path;
-        private final JsonPointer from;
+        private final JsonPointerImpl path;
+        private final JsonPointerImpl from;
         private final JsonValue value;
 
         PatchValue(JsonPatchOperation operation,
-                   JsonPointer path,
-                   JsonPointer from,
+                   String path,
+                   String from,
                    JsonValue value) {
             this.operation = operation;
-            this.path = path;
-            this.from = from;
+            this.path = new JsonPointerImpl(path);
+
+            // ignore from if we do not need it
+            if (operation == JsonPatchOperation.MOVE || operation == JsonPatchOperation.COPY) {
+                this.from = new JsonPointerImpl(from);
+            } else {
+                this.from = null;
+            }
+
             this.value = value;
         }
+
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            PatchValue that = (PatchValue) o;
+
+            if (operation != that.operation) {
+                return false;
+            }
+            if (!path.equals(that.path)) {
+                return false;
+            }
+            if (from != null ? !from.equals(that.from) : that.from != null) {
+                return false;
+            }
+            return value != null ? value.equals(that.value) : that.value == null;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = operation.hashCode();
+            result = 31 * result + path.hashCode();
+            result = 31 * result + (from != null ? from.hashCode() : 0);
+            result = 31 * result + (value != null ? value.hashCode() : 0);
+            return result;
+        }
+
+
+        @Override
+        public String toString() {
+            return "{" +
+                   "op: " + operation +
+                   ", path: " + path +
+                   ", from: " + from +
+                   ", value: " + value +
+                   '}';
+        }
+
+        JsonObject toJson() {
+            JsonObjectBuilder builder = Json.createObjectBuilder()
+                                            .add("op", operation.name().toLowerCase())
+                                            .add("path", path.getJsonPointer());
+
+            if (from != null) {
+                builder.add("from", from.getJsonPointer());
+            }
+
+            if (value != null) {
+                builder.add("value", value);
+            }
+
+            return builder.build();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/0e4bd488/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
----------------------------------------------------------------------
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 8057f95..0b01c3d 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
@@ -289,6 +289,10 @@ public class JsonPointerImpl implements JsonPointer {
         return (JsonArray) remove(target, 1, referenceTokens.size() - 1);
     }
 
+    String getJsonPointer() {
+        return jsonPointer;
+    }
+
     private void validateAdd(JsonValue target) {
         validateJsonPointer(target, referenceTokens.size() - 1);
     }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/0e4bd488/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchBuilderTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchBuilderTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchBuilderTest.java
new file mode 100644
index 0000000..7fd2af0
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchBuilderTest.java
@@ -0,0 +1,440 @@
+/*
+ * 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.junit.Test;
+
+import javax.json.Json;
+import javax.json.JsonPatch;
+import javax.json.JsonValue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class JsonPatchBuilderTest {
+
+    @Test
+    public void testPatchBuilderAddString() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/foo",
+                                                                                null,
+                                                                                new JsonStringImpl("bar")));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/foo", "bar")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddStringNull() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/foo",
+                                                                                null,
+                                                                                JsonValue.NULL));
+
+        String nullString = null;
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/foo", nullString)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddJsonObject() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/foo",
+                                                                                null,
+                                                                                Json.createObjectBuilder()
+                                                                                    .add("bar", "qux")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/foo", Json.createObjectBuilder()
+                                                                     .add("bar", "qux")
+                                                                     .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddJsonArray() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/path",
+                                                                                null,
+                                                                                Json.createArrayBuilder()
+                                                                                    .add("test")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/path", Json.createArrayBuilder()
+                                                                      .add("test")
+                                                                      .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddJsonValueNull() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/path",
+                                                                                null,
+                                                                                JsonValue.NULL));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/path", JsonValue.NULL)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddInt() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/foo",
+                                                                                null,
+                                                                                new JsonStringImpl("bar")));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/foo", "bar")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderAddBoolean() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/path/true",
+                                                                                null,
+                                                                                JsonValue.TRUE),
+                                                   new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/path/false",
+                                                                                null,
+                                                                                JsonValue.FALSE));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().add("/path/true", true)
+                                                    .add("/path/false", false)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderAddMissingPath() {
+        new JsonPatchBuilderImpl().add(null, 0);
+    }
+
+
+    @Test
+    public void testPatchBuilderRemove() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                                "/path/to/remove",
+                                                                                null,
+                                                                                null));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().remove("/path/to/remove")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderRemoveMissingPath() {
+        new JsonPatchBuilderImpl().remove(null);
+    }
+
+
+    @Test
+    public void testPatchBuilderReplaceString() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                 "/path/to/replace",
+                                                                                 null,
+                                                                                 new JsonStringImpl("new value")));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().replace("/path/to/replace", "new value")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderReplaceInt() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/replace/me",
+                                                                                null,
+                                                                                new JsonLongImpl(42)));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().replace("/replace/me", 42)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderReplaceBoolean() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/true/to/replace",
+                                                                                null,
+                                                                                JsonValue.FALSE),
+                                                   new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/false/to/replace",
+                                                                                null,
+                                                                                JsonValue.TRUE));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().replace("/true/to/replace", false)
+                                                    .replace("/false/to/replace", true)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderReplaceJsonObject() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/replace/the/object",
+                                                                                null,
+                                                                                Json.createObjectBuilder()
+                                                                                    .add("foo", "bar")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().replace("/replace/the/object", Json.createObjectBuilder()
+                                                                                        .add("foo", "bar")
+                                                                                        .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderReplaceJsonArray() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/replace/my/array",
+                                                                                null,
+                                                                                Json.createArrayBuilder()
+                                                                                    .add("test")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().replace("/replace/my/array", Json.createArrayBuilder()
+                                                                                      .add("test")
+                                                                                      .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderReplaceMissingPath() {
+        new JsonPatchBuilderImpl().replace(null, "ignored");
+    }
+
+
+    @Test
+    public void testPatchBuilderMove() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+                                                                                "/move/to",
+                                                                                "/move/from",
+                                                                                null));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().move("/move/to", "/move/from")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderMoveMissingPath() {
+        new JsonPatchBuilderImpl().move(null, "/ignored");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderMoveMissingFrom() {
+        new JsonPatchBuilderImpl().move("/the/path", null);
+    }
+
+
+    @Test
+    public void testPatchBuilderCopy() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+                                                                                "/to",
+                                                                                "/from",
+                                                                                null));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().copy("/to", "/from")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderCopyMissingPath() {
+        new JsonPatchBuilderImpl().copy(null, "/ignored");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderCopyMissingFrom() {
+        new JsonPatchBuilderImpl().copy("/the/path", null);
+    }
+
+
+    @Test
+    public void testPatchBuilderTestString() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                "/to/test",
+                                                                                null,
+                                                                                new JsonStringImpl("value")));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/to/test", "value")
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderTestBoolean() {
+
+        JsonPatchImpl exptected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                 "/true/to/test",
+                                                                                 null,
+                                                                                 JsonValue.TRUE),
+                                                    new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                 "/false/to/test",
+                                                                                 null,
+                                                                                 JsonValue.FALSE));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/true/to/test", true)
+                                                    .test("/false/to/test", false)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(exptected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderTestInt() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                "/test/int",
+                                                                                null,
+                                                                                new JsonLongImpl(16)));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/test/int", 16)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderTestJsonValue() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                "/test/value",
+                                                                                null,
+                                                                                JsonValue.NULL));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/test/value", JsonValue.NULL)
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderTestJsonObject() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                "/test/the/object",
+                                                                                null,
+                                                                                Json.createObjectBuilder()
+                                                                                    .add("foo", "bar")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/test/the/object", Json.createObjectBuilder()
+                                                                                  .add("foo", "bar")
+                                                                                  .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test
+    public void testPatchBuilderTestJsonArray() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+                                                                                "/test/my/array",
+                                                                                null,
+                                                                                Json.createArrayBuilder()
+                                                                                    .add("element")
+                                                                                    .build()));
+
+        JsonPatch patch = new JsonPatchBuilderImpl().test("/test/my/array", Json.createArrayBuilder()
+                                                                                .add("element")
+                                                                                .build())
+                                                    .build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testPatchBuilderTestMissingPath() {
+        new JsonPatchBuilderImpl().test(null, "ignored");
+    }
+
+
+    @Test
+    public void testPatchBuilderWithinitialData() {
+
+        JsonPatchImpl expected = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+                                                                                "/add/an/object",
+                                                                                null,
+                                                                                Json.createObjectBuilder()
+                                                                                    .add("name", "Cassius")
+                                                                                    .build()),
+                                                   new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+                                                                                "/replace/me",
+                                                                                null,
+                                                                                Json.createArrayBuilder()
+                                                                                    .add(16)
+                                                                                    .add(27)
+                                                                                    .add("test")
+                                                                                    .build()),
+                                                   new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+                                                                                "/remove/it",
+                                                                                null,
+                                                                                null));
+
+        JsonPatch patch = new JsonPatchBuilderImpl(expected.toJsonArray()).build();
+        assertNotNull(patch);
+        assertEquals(expected, patch);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/0e4bd488/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
index b4665ed..7e8ad67 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
@@ -44,7 +44,7 @@ public class JsonPatchTest {
                                 .readObject();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/baz"),
+                                                                             "/baz",
                                                                              null, // no from
                                                                              new JsonStringImpl("qux")));
 
@@ -66,7 +66,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             "/foo/1",
                                                                              null, // no from
                                                                              new JsonStringImpl("qux")));
 
@@ -92,7 +92,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/foo/-"),
+                                                                             "/foo/-",
                                                                              null, // no from
                                                                              new JsonStringImpl("qux")));
 
@@ -116,7 +116,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/-"),
+                                                                             "/-",
                                                                              null, // no from
                                                                              new JsonStringImpl("qux")));
 
@@ -138,7 +138,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/baz/bat"),
+                                                                             "/baz/bat",
                                                                              null, // no from
                                                                              new JsonStringImpl("qux")));
 
@@ -153,7 +153,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/5"),
+                                                                             "/5",
                                                                              null,
                                                                              new JsonStringImpl("baz")));
 
@@ -170,7 +170,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/baz"),
+                                                                             "/baz",
                                                                              null,
                                                                              null));
 
@@ -193,7 +193,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             "/foo/1",
                                                                              null,
                                                                              null));
 
@@ -219,7 +219,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/1"),
+                                                                             "/1",
                                                                              null,
                                                                              null));
 
@@ -241,7 +241,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             "/nomatch",
                                                                              null,
                                                                              null));
 
@@ -256,7 +256,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/5"),
+                                                                             "/5",
                                                                              null,
                                                                              null));
 
@@ -273,7 +273,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
-                                                                             Json.createJsonPointer("/baz"),
+                                                                             "/baz",
                                                                              null,
                                                                              new JsonStringImpl("boo")));
 
@@ -296,7 +296,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
-                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             "/foo/1",
                                                                              null,
                                                                              new JsonStringImpl("boo")));
 
@@ -323,7 +323,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
-                                                                             Json.createJsonPointer("/0"),
+                                                                             "/0",
                                                                              null,
                                                                              new JsonStringImpl("boo")));
 
@@ -345,7 +345,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
-                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             "/nomatch",
                                                                              null,
                                                                              new JsonStringImpl("notneeded")));
 
@@ -360,7 +360,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
-                                                                             Json.createJsonPointer("/1"),
+                                                                             "/1",
                                                                              null,
                                                                              new JsonStringImpl("notneeded")));
 
@@ -380,8 +380,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/qux/thud"),
-                                                                             Json.createJsonPointer("/foo/waldo"),
+                                                                             "/qux/thud",
+                                                                             "/foo/waldo",
                                                                              null));
 
         JsonObject patched = patch.apply(object);
@@ -413,8 +413,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/foo/3"),
-                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             "/foo/3",
+                                                                             "/foo/1",
                                                                              null));
 
         JsonObject patched = patch.apply(object);
@@ -442,8 +442,8 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/0"),
-                                                                             Json.createJsonPointer("/3"),
+                                                                             "/0",
+                                                                             "/3",
                                                                              null));
 
         JsonArray patched = patch.apply(array);
@@ -466,8 +466,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/bar"),
-                                                                             Json.createJsonPointer("/foo/2"),
+                                                                             "/bar",
+                                                                             "/foo/2",
                                                                              null));
 
         JsonObject patched = patch.apply(object);
@@ -492,8 +492,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/baz"),
-                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             "/baz",
+                                                                             "/nomatch",
                                                                              null));
 
         patch.apply(object);
@@ -508,8 +508,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/nomatch/child"),
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/nomatch/child",
+                                                                             "/foo",
                                                                              null));
 
         patch.apply(object);
@@ -524,8 +524,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/object/key"),
-                                                                             Json.createJsonPointer("/object"),
+                                                                             "/object/key",
+                                                                             "/object",
                                                                              null));
 
         patch.apply(object);
@@ -540,8 +540,8 @@ public class JsonPatchTest {
                                .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/baz"),
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/baz",
+                                                                             "/foo",
                                                                              null));
 
         JsonObject patched = patch.apply(object);
@@ -563,8 +563,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                                 Json.createJsonPointer("/foo/-"),
-                                                                                 Json.createJsonPointer("/foo/0"),
+                                                                                 "/foo/-",
+                                                                                 "/foo/0",
                                                                                  null));
 
         JsonObject patched = patch.apply(object);
@@ -589,8 +589,8 @@ public class JsonPatchTest {
 
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/0"),
-                                                                             Json.createJsonPointer("/1"),
+                                                                             "/0",
+                                                                             "/1",
                                                                              null));
 
         JsonArray patched = patch.apply(array);
@@ -615,8 +615,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/partner/partner/name"),
-                                                                             Json.createJsonPointer("/name"),
+                                                                             "/partner/partner/name",
+                                                                             "/name",
                                                                              null));
 
         JsonObject patched = patch.apply(object);
@@ -641,8 +641,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/notneeded"),
-                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             "/notneeded",
+                                                                             "/nomatch",
                                                                              null));
 
         patch.apply(object);
@@ -656,8 +656,8 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/path/nomatch"),
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/path/nomatch",
+                                                                             "/foo",
                                                                              null));
 
         patch.apply(object);
@@ -672,8 +672,8 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/-"),
-                                                                             Json.createJsonPointer("/2"),
+                                                                             "/-",
+                                                                             "/2",
                                                                              null));
 
         patch.apply(array);
@@ -687,8 +687,8 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/1"),
-                                                                             Json.createJsonPointer("/-"),
+                                                                             "/1",
+                                                                             "/-",
                                                                              null));
 
         patch.apply(array);
@@ -703,7 +703,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/foo",
                                                                              null,
                                                                              new JsonStringImpl("qux")));
 
@@ -720,7 +720,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/foo",
                                                                              null,
                                                                              Json.createArrayBuilder().build()));
 
@@ -738,7 +738,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/parents"),
+                                                                             "/parents",
                                                                              null,
                                                                              Json.createArrayBuilder() // yessss, we really want to create a new JsonArray ;)
                                                                                  .add("Odin")
@@ -761,7 +761,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/numbers"),
+                                                                             "/numbers",
                                                                              null,
                                                                              Json.createArrayBuilder() // different ordering
                                                                                  .add(2)
@@ -781,7 +781,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/foo/1"),
+                                                                             "/foo/1",
                                                                              null,
                                                                              new JsonStringImpl("baz")));
 
@@ -800,7 +800,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/2"),
+                                                                             "/2",
                                                                              null,
                                                                              new JsonStringImpl("qux")));
 
@@ -819,7 +819,7 @@ public class JsonPatchTest {
                               .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/0"),
+                                                                             "/0",
                                                                              null,
                                                                              new JsonStringImpl("bar")));
 
@@ -830,7 +830,7 @@ public class JsonPatchTest {
     public void testTestingObjectMemeberNonexistentTarget() {
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/nomatch"),
+                                                                             "/nomatch",
                                                                              null,
                                                                              JsonValue.EMPTY_JSON_OBJECT));
 
@@ -841,7 +841,7 @@ public class JsonPatchTest {
     public void testTestingArrayElementIndexOutOfBounds() {
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
-                                                                             Json.createJsonPointer("/3"),
+                                                                             "/3",
                                                                              null,
                                                                              JsonValue.EMPTY_JSON_OBJECT));
 
@@ -858,7 +858,7 @@ public class JsonPatchTest {
                                 .build();
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/foo"),
+                                                                             "/foo",
                                                                              null,
                                                                              new JsonStringImpl("abcd")));
 
@@ -875,7 +875,7 @@ public class JsonPatchTest {
     public void testAddArrayElementToEmptyArray() {
 
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/-"),
+                                                                             "/-",
                                                                              null,
                                                                              new JsonStringImpl("foo")));
 
@@ -896,33 +896,33 @@ public class JsonPatchTest {
         // i know this can be done with PatchBuilder but
         // currently it's not implemented and its fun ;)
         JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/family/father"),
+                                                                             "/family/father",
                                                                              null,
                                                                              Json.createObjectBuilder()
                                                                                  .add("name", "Gaio Modry Effect")
                                                                                  .build()),
                                                 new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             "/family/mother",
                                                                              null,
                                                                              Json.createObjectBuilder()
                                                                                  .add("name", "Cassius vom Hause Clarabella")
                                                                                  .build()),
                                                 new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
-                                                                             Json.createJsonPointer("/family/children/0"),
-                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             "/family/children/0",
+                                                                             "/family/mother",
                                                                              null),
                                                 new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
-                                                                             Json.createJsonPointer("/family/mother"),
+                                                                             "/family/mother",
                                                                              null,
                                                                              Json.createObjectBuilder()
                                                                                  .add("name", "Aimee vom Hause Clarabella")
                                                                                  .build()),
                                                 new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
-                                                                             Json.createJsonPointer("/pedigree"),
-                                                                             Json.createJsonPointer("/family"),
+                                                                             "/pedigree",
+                                                                             "/family",
                                                                              null),
                                                 new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
-                                                                             Json.createJsonPointer("/family"),
+                                                                             "/family",
                                                                              null,
                                                                              null));
 


[24/26] johnzon git commit: JOHNZON-96 add tests for null checks

Posted by st...@apache.org.
JOHNZON-96 add tests for null checks


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/525da3d8
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/525da3d8
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/525da3d8

Branch: refs/heads/master
Commit: 525da3d82995b5bebcddefb4df40d86e4ffe2598
Parents: 4b20eaf
Author: Mark Struberg <st...@apache.org>
Authored: Thu Feb 23 20:53:33 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Thu Feb 23 20:53:33 2017 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonObjectBuilderImpl.java  |  2 +-
 .../apache/johnzon/core/JsonObjectBuilderImplTest.java  | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/525da3d8/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
index d6e8a48..1b727bd 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectBuilderImpl.java
@@ -167,7 +167,7 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder, Serializable {
     @Override
     public JsonObject build() {
         
-        if(attributeMap ==null) {
+        if(attributeMap == null || attributeMap.isEmpty()) {
             return new JsonObjectImpl(Collections.EMPTY_MAP);
         } else {
             Map<String, JsonValue> dump = (Collections.unmodifiableMap(attributeMap));

http://git-wip-us.apache.org/repos/asf/johnzon/blob/525da3d8/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
index 1ba9348..4954614 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonObjectBuilderImplTest.java
@@ -104,4 +104,16 @@ public class JsonObjectBuilderImplTest {
 
         assertEquals("{\"c\":\"d\"}", builder.build().toString());
     }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullCheckValue() {
+        final JsonObjectBuilder builder = Json.createObjectBuilder();
+        builder.add("a", (Integer) null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testNullCheckName() {
+        final JsonObjectBuilder builder = Json.createObjectBuilder();
+        builder.add(null, "b");
+    }
 }


[05/26] johnzon git commit: Implemented JsonPointer add, replace and remove methods

Posted by st...@apache.org.
Implemented JsonPointer add, replace and remove methods


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/cc830c64
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/cc830c64
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/cc830c64

Branch: refs/heads/master
Commit: cc830c64a4e6a175a02d13ad2ccf5140401530df
Parents: 45faea0
Author: Armin Hasler <ha...@gmail.com>
Authored: Mon Nov 14 10:09:22 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:28:49 2016 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonPointer.java    | 310 ++++++++++----
 .../apache/johnzon/core/JsonPointerTest.java    | 419 ++++++++++++++++++-
 2 files changed, 647 insertions(+), 82 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/cc830c64/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
index af228be..ca942ef 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
@@ -18,11 +18,17 @@
  */
 package org.apache.johnzon.core;
 
+import javax.json.Json;
 import javax.json.JsonArray;
+import javax.json.JsonArrayBuilder;
 import javax.json.JsonException;
 import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>This class is an immutable representation of a JSON Pointer as specified in
@@ -49,7 +55,8 @@ import javax.json.JsonValue;
 public class JsonPointer {
 
     private final String jsonPointer;
-    private final String[] referenceTokens;
+    private final List<String> referenceTokens = new ArrayList<String>();
+    private final String lastReferenceToken;
 
     /**
      * Constructs and initializes a JsonPointer.
@@ -63,11 +70,16 @@ public class JsonPointer {
             throw new NullPointerException("jsonPointer must not be null");
         }
         if (!jsonPointer.equals("") && !jsonPointer.startsWith("/")) {
-            throw new JsonException("A non-empty JSON pointer must begin with a '/'");
+            throw new JsonException("A non-empty JsonPointer string must begin with a '/'");
         }
 
         this.jsonPointer = jsonPointer;
-        referenceTokens = jsonPointer.split("/", -1);
+        String[] encodedReferenceTokens = jsonPointer.split("/", -1);
+
+        for (String encodedReferenceToken : encodedReferenceTokens) {
+            referenceTokens.add(JsonPointerUtil.decode(encodedReferenceToken));
+        }
+        lastReferenceToken = referenceTokens.get(referenceTokens.size() - 1);
     }
 
     /**
@@ -113,43 +125,14 @@ public class JsonPointer {
         if (target == null) {
             throw new NullPointerException("target must not be null");
         }
-
-        if (jsonPointer.equals("")) {
+        if (isEmptyJsonPointer()) {
             return target;
         }
 
         JsonValue jsonValue = target;
-
-        for (int i = 1; i < referenceTokens.length; i++) {
-            String decodedReferenceToken = JsonPointerUtil.decode(referenceTokens[i]);
-
-            if (jsonValue instanceof JsonObject) {
-                JsonObject jsonObject = (JsonObject) jsonValue;
-                jsonValue = jsonObject.get(decodedReferenceToken);
-
-                if (jsonValue == null) {
-                    throw new JsonException("The JsonObject " + jsonObject + " contains no value for token " + decodedReferenceToken);
-                }
-            } else if (jsonValue instanceof JsonArray) {
-                JsonArray jsonArray = (JsonArray) jsonValue;
-
-                try {
-                    int index = Integer.parseInt(decodedReferenceToken);
-                    if (index >= jsonArray.size()) {
-                        throw new JsonException("The JsonArray " + jsonArray + " contains no element for index " + index);
-                    }
-                    if (decodedReferenceToken.startsWith("0") && decodedReferenceToken.length() > 1) {
-                        throw new JsonException("The token " + decodedReferenceToken + " with leading zeros is not allowed to reference an element of a JsonArray");
-                    }
-
-                    jsonValue = jsonArray.get(index);
-                } catch (NumberFormatException e) {
-                    throw new JsonException("The token " + decodedReferenceToken + " for the JsonArray " + jsonArray + " is not a number", e);
-                }
-            }
-
+        for (int i = 1; i < referenceTokens.size(); i++) {
+            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
         }
-
         return jsonValue;
     }
 
@@ -179,35 +162,19 @@ public class JsonPointer {
      *                              or if the pointer contains references to non-existing objects or arrays.
      */
     public JsonStructure add(JsonStructure target, JsonValue value) {
-        return null;
-    }
-
-    /**
-     * Replaces the value at the referenced location in the specified
-     * {@code target} with the specified {@code value}.
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @param value  the value to be stored at the referenced location
-     * @return the transformed {@code target} after the value is replaced.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     */
-    public JsonStructure replace(JsonStructure target, JsonValue value) {
-        return null;
-    }
+        validateAdd(target);
+        if (isEmptyJsonPointer()) {
+            if (value.getClass() != target.getClass()) {
+                throw new JsonException("The value must have the same type as the target");
+            }
+            return (JsonStructure) value;
+        }
 
-    /**
-     * Removes the value at the reference location in the specified {@code target}
-     *
-     * @param target the target referenced by this {@code JsonPointer}
-     * @return the transformed {@code target} after the value is removed.
-     * @throws NullPointerException if {@code target} is {@code null}
-     * @throws JsonException        if the referenced value does not exist,
-     *                              or if the reference is the target.
-     */
-    public JsonStructure remove(JsonStructure target) {
-        return null;
+        if (target instanceof JsonObject) {
+            return add((JsonObject) target, value);
+        } else {
+            return add((JsonArray) target, value);
+        }
     }
 
     /**
@@ -224,7 +191,9 @@ public class JsonPointer {
      * @see #add(JsonStructure, JsonValue)
      */
     public JsonObject add(JsonObject target, JsonValue value) {
-        return (JsonObject) this.add((JsonStructure) target, value);
+        validateAdd(target);
+
+        return (JsonObject) add(target, 1, referenceTokens.size() - 1, value);
     }
 
     /**
@@ -241,7 +210,28 @@ public class JsonPointer {
      * @see #add(JsonStructure, JsonValue)
      */
     public JsonArray add(JsonArray target, JsonValue value) {
-        return (JsonArray) this.add((JsonStructure) target, value);
+        validateAdd(target);
+
+        return (JsonArray) add(target, 1, referenceTokens.size() - 1, value);
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure replace(JsonStructure target, JsonValue value) {
+        if (target instanceof JsonObject) {
+            return replace((JsonObject) target, value);
+        } else {
+            return replace((JsonArray) target, value);
+        }
     }
 
     /**
@@ -253,11 +243,10 @@ public class JsonPointer {
      * @throws NullPointerException if {@code target} is {@code null}
      * @throws JsonException        if the referenced value does not exist,
      *                              or if the reference is the target.
-     *                              {@code target} with the specified {@code value}.
      * @see #replace(JsonStructure, JsonValue)
      */
     public JsonObject replace(JsonObject target, JsonValue value) {
-        return (JsonObject) this.replace((JsonStructure) target, value);
+        return add(remove(target), value);
     }
 
     /**
@@ -269,11 +258,27 @@ public class JsonPointer {
      * @throws NullPointerException if {@code target} is {@code null}
      * @throws JsonException        if the referenced value does not exist,
      *                              or if the reference is the target.
-     *                              {@code target} with the specified {@code value}.
      * @see #replace(JsonStructure, JsonValue)
      */
     public JsonArray replace(JsonArray target, JsonValue value) {
-        return (JsonArray) this.replace((JsonStructure) target, value);
+        return add(remove(target), value);
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure remove(JsonStructure target) {
+        if (target instanceof JsonObject) {
+            return remove((JsonObject) target);
+        } else {
+            return remove((JsonArray) target);
+        }
     }
 
     /**
@@ -287,7 +292,9 @@ public class JsonPointer {
      * @see #remove(JsonStructure)
      */
     public JsonObject remove(JsonObject target) {
-        return (JsonObject) this.remove((JsonStructure) target);
+        validateRemove(target);
+
+        return (JsonObject) remove(target, 1, referenceTokens.size() - 1);
     }
 
     /**
@@ -301,8 +308,169 @@ public class JsonPointer {
      * @see #remove(JsonStructure)
      */
     public JsonArray remove(JsonArray target) {
-        return (JsonArray) this.remove((JsonStructure) target);
+        validateRemove(target);
+
+        return (JsonArray) remove(target, 1, referenceTokens.size() - 1);
+    }
+
+    private void validateAdd(JsonValue target) {
+        validateJsonPointer(target, referenceTokens.size() - 1);
     }
 
+    private void validateRemove(JsonValue target) {
+        validateJsonPointer(target, referenceTokens.size());
+        if (isEmptyJsonPointer()) {
+            throw new JsonException("The reference must not be the target");
+        }
+    }
+
+    private boolean isEmptyJsonPointer() {
+        return jsonPointer.equals("");
+    }
+
+    private JsonValue getValue(JsonValue jsonValue, String referenceToken, int currentPosition, int referencePosition) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            jsonValue = jsonObject.get(referenceToken);
+
+            if (jsonValue != null) {
+                return jsonValue;
+            }
+            throw new JsonException("'" + jsonObject + "' contains no value for name '" + referenceToken + "'");
+        } else if (jsonValue instanceof JsonArray) {
+            validateArrayIndex(referenceToken);
+
+            try {
+                JsonArray jsonArray = (JsonArray) jsonValue;
+                int arrayIndex = Integer.parseInt(referenceToken);
+                validateArraySize(jsonArray, arrayIndex, jsonArray.size());
+                return jsonArray.get(arrayIndex);
+            } catch (NumberFormatException e) {
+                throw new JsonException("'" + referenceToken + "' is no valid array index", e);
+            }
+        } else {
+            if (currentPosition != referencePosition) {
+                return jsonValue;
+            }
+            throw new JsonException("'" + jsonValue + "' contains no element for '" + referenceToken + "'");
+        }
+    }
+
+    private JsonValue add(JsonValue jsonValue, int currentPosition, int referencePosition, JsonValue newValue) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+
+            if (jsonObject.isEmpty()) {
+                objectBuilder.add(lastReferenceToken, newValue);
+            } else {
+                for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
+                    objectBuilder.add(entry.getKey(), add(entry.getValue(), currentPosition + 1, referencePosition, newValue));
+                    if (currentPosition == referencePosition) {
+                        objectBuilder.add(lastReferenceToken, newValue);
+                    }
+                }
+            }
+            return objectBuilder.build();
+        } else if (jsonValue instanceof JsonArray) {
+            JsonArray jsonArray = (JsonArray) jsonValue;
+            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+
+            int arrayIndex = -1;
+            if (currentPosition == referencePosition) {
+                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, true);
+            }
+
+            int jsonArraySize = jsonArray.size();
+            for (int i = 0; i <= jsonArraySize; i++) {
+                if (i == arrayIndex) {
+                    arrayBuilder.add(newValue);
+                }
+                if (i == jsonArraySize) {
+                    break;
+                }
+                arrayBuilder.add(add(jsonArray.get(i), currentPosition + 1, referencePosition, newValue));
+            }
+            return arrayBuilder.build();
+        }
+        return jsonValue;
+    }
+
+    private JsonValue remove(JsonValue jsonValue, int currentPosition, int referencePosition) {
+        if (jsonValue instanceof JsonObject) {
+            JsonObject jsonObject = (JsonObject) jsonValue;
+            JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
+
+            for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
+                if (currentPosition == referencePosition
+                        && lastReferenceToken.equals(entry.getKey())) {
+                    continue;
+                }
+                objectBuilder.add(entry.getKey(), remove(entry.getValue(), currentPosition + 1, referencePosition));
+            }
+            return objectBuilder.build();
+        } else if (jsonValue instanceof JsonArray) {
+            JsonArray jsonArray = (JsonArray) jsonValue;
+            JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
+
+            int arrayIndex = -1;
+            if (currentPosition == referencePosition) {
+                arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, false);
+            }
+
+            int jsonArraySize = jsonArray.size();
+            for (int i = 0; i < jsonArraySize; i++) {
+                if (i == arrayIndex) {
+                    continue;
+                }
+                arrayBuilder.add(remove(jsonArray.get(i), currentPosition + 1, referencePosition));
+            }
+            return arrayBuilder.build();
+        }
+        return jsonValue;
+    }
+
+    private int getArrayIndex(String referenceToken, JsonArray jsonArray, boolean addOperation) {
+        if (addOperation && referenceToken.equals("-")) {
+            return jsonArray.size();
+        }
+
+        validateArrayIndex(referenceToken);
+
+        try {
+            int arrayIndex = Integer.parseInt(referenceToken);
+            int arraySize = addOperation ? jsonArray.size() + 1 : jsonArray.size();
+            validateArraySize(jsonArray, arrayIndex, arraySize);
+            return arrayIndex;
+        } catch (NumberFormatException e) {
+            throw new JsonException("'" + referenceToken + "' is no valid array index", e);
+        }
+    }
+
+    private void validateJsonPointer(JsonValue target, int size) throws NullPointerException, JsonException {
+        if (target == null) {
+            throw new NullPointerException("target must not be null");
+        }
+
+        JsonValue jsonValue = target;
+        for (int i = 1; i < size; i++) {
+            jsonValue = getValue(jsonValue, referenceTokens.get(i), i, referenceTokens.size() - 1);
+        }
+    }
+
+    private void validateArrayIndex(String referenceToken) throws JsonException {
+        if (referenceToken.startsWith("+") || referenceToken.startsWith("-")) {
+            throw new JsonException("An array index must not start with '" + referenceToken.charAt(0) + "'");
+        }
+        if (referenceToken.startsWith("0") && referenceToken.length() > 1) {
+            throw new JsonException("An array index must not start with a leading '0'");
+        }
+    }
+
+    private void validateArraySize(JsonArray jsonArray, int arrayIndex, int arraySize) throws JsonException {
+        if (arrayIndex >= arraySize) {
+            throw new JsonException("'" + jsonArray + "' contains no element for index " + arrayIndex);
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/cc830c64/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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 7750ba6..9b6c722 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
@@ -21,34 +21,38 @@ package org.apache.johnzon.core;
 import org.junit.Test;
 
 import javax.json.Json;
+import javax.json.JsonArray;
 import javax.json.JsonException;
+import javax.json.JsonObject;
 import javax.json.JsonReader;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
 import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class JsonPointerTest {
 
     @Test(expected = NullPointerException.class)
-    public void testConstructorWithNullShouldThrowNullPointerException() {
+    public void testConstructorWithJsonPointerNull() {
         new JsonPointer(null);
     }
 
     @Test(expected = JsonException.class)
-    public void testConstructorWithInvalidJsonPointerShouldThrowJsonException() {
+    public void testConstructorWithInvalidJsonPointer() {
         new JsonPointer("a");
     }
 
     @Test(expected = NullPointerException.class)
-    public void testGetValueWithNullShouldThrowNullPointerException() {
+    public void testGetValueWithTargetNull() {
         JsonPointer jsonPointer = new JsonPointer("");
         jsonPointer.getValue(null);
     }
 
     @Test
-    public void testGetValueWholeDocument() {
+    public void testGetValueWithWholeDocument() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("");
@@ -138,7 +142,7 @@ public class JsonPointerTest {
     }
 
     @Test(expected = JsonException.class)
-    public void testGetValueElementNotExistentShouldThrowJsonException() {
+    public void testGetValueWithElementNotExistent() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("/fool");
@@ -146,7 +150,7 @@ public class JsonPointerTest {
     }
 
     @Test
-    public void testGetValueWholeJsonArray() {
+    public void testGetValueWithWholeJsonArray() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("/foo");
@@ -155,7 +159,7 @@ public class JsonPointerTest {
     }
 
     @Test
-    public void testGetValueJsonArrayElement() {
+    public void testGetValueWithJsonArray() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("/foo/0");
@@ -164,7 +168,7 @@ public class JsonPointerTest {
     }
 
     @Test(expected = JsonException.class)
-    public void testGetValueJsonArrayElementNotExistentShouldThrowJsonException() {
+    public void testGetValueWithJsonArrayIndexOutOfRange() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("/foo/2");
@@ -172,7 +176,7 @@ public class JsonPointerTest {
     }
 
     @Test(expected = JsonException.class)
-    public void testGetValueJsonArrayElementNoNumberShouldThrowJsonException() {
+    public void testGetValueWithJsonArrayIndexNoNumber() {
         JsonStructure jsonDocument = getJsonDocument();
 
         JsonPointer jsonPointer = new JsonPointer("/foo/a");
@@ -180,14 +184,407 @@ public class JsonPointerTest {
     }
 
     @Test(expected = JsonException.class)
-    public void testGetValueJsonArrayElementLeadingZeroShouldThrowJsonException() {
+    public void testGetValueWithJsonArrayLeadingZeroIndex() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointer jsonPointer = new JsonPointer("/foo/001");
+        JsonPointer jsonPointer = new JsonPointer("/foo/01");
         JsonValue result = jsonPointer.getValue(jsonDocument);
         assertEquals("\"bar\"", result.toString());
     }
 
+    @Test(expected = JsonException.class)
+    public void testGetValueWithJsonArrayInvalidIndex() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo/-1");
+        jsonPointer.getValue(jsonDocument);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testAddJsonStructureWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        jsonPointer.add((JsonStructure) null, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddJsonStructureWithTypeValueNotTypeTarget() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonObject target = Json.createObjectBuilder().build();
+        JsonArray value = Json.createArrayBuilder().build();
+
+        jsonPointer.add((JsonStructure) target, value);
+    }
+
+    @Test
+    public void testAddJsonStructureWithEmptyJsonPointer() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonStructure target = Json.createObjectBuilder().build();
+        JsonObject value = Json.createObjectBuilder()
+                .add("foo", "bar").build(); // { "foo": "bar" }
+
+        JsonStructure result = jsonPointer.add(target, value);
+        assertEquals("{\"foo\":\"bar\"}", result.toString());
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testAddJsonObjectWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        jsonPointer.add((JsonObject) null, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testAddJsonArrayWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        jsonPointer.add((JsonArray) null, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddArrayElementWithInvalidIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/+");
+        JsonStructure target = Json.createArrayBuilder().build();
+
+        jsonPointer.add(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddArrayElementWithIndexOutOfRange() {
+        JsonPointer jsonPointer = new JsonPointer("/1");
+        JsonStructure target = Json.createArrayBuilder().build();
+
+        jsonPointer.add(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddArrayElementWithLeadingZeroIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/01");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("foo").build();
+
+        jsonPointer.add(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddArrayElementWithIndexNoNumber() {
+        JsonPointer jsonPointer = new JsonPointer("/a");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("foo").build();
+
+        jsonPointer.add(target, new JsonStringImpl("qux"));
+    }
+
+    @Test
+    public void testAddObject() {
+        JsonPointer jsonPointer = new JsonPointer("/child");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar").build(); // {"foo":"bar"}
+        JsonObject value = Json.createObjectBuilder()
+                .add("grandchild", Json.createObjectBuilder()).build(); // {"grandchild":{}}
+
+        JsonStructure result = jsonPointer.add(target, value);
+        assertEquals("{\"foo\":\"bar\",\"child\":{\"grandchild\":{}}}", result.toString()); // {"foo":"bar","child":{"grandchild":{}}}
+    }
+
+    @Test
+    public void testAddObjectMember() {
+        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar").build(); // {"foo":"bar"}
+
+        JsonStructure result = jsonPointer.add(target, new JsonStringImpl("qux"));
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", result.toString()); // {"foo":"bar","baz":"qux"}
+    }
+
+    @Test
+    public void testAddFirstObjectMember() {
+        JsonPointer jsonPointer = new JsonPointer("/foo");
+        JsonStructure target = Json.createObjectBuilder().build(); // {}
+
+        JsonStructure result = jsonPointer.add(target, new JsonStringImpl("bar"));
+        assertEquals("{\"foo\":\"bar\"}", result.toString()); // {"foo":"bar"}
+    }
+
+    @Test(expected = JsonException.class)
+    public void testAddObjectMemberWithNonexistentTarget() {
+        JsonPointer jsonPointer = new JsonPointer("/baz/bat");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar").build(); // {"foo":"bar"}
+
+        jsonPointer.add(target, new JsonStringImpl("qux"));
+    }
+
+    @Test
+    public void testAddReplaceObjectMember() {
+        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("baz", "qux")
+                .add("foo", "bar").build(); // {"baz":"qux","foo":"bar"}
+
+        JsonStructure result = jsonPointer.add(target, new JsonStringImpl("boo"));
+        assertEquals("{\"baz\":\"boo\",\"foo\":\"bar\"}", result.toString()); // {"baz":"boo","foo":"bar"}
+    }
+
+    @Test
+    public void testAddArray() {
+        JsonPointer jsonPointer = new JsonPointer("/0/-");
+        JsonStructure target = Json.createArrayBuilder()
+                .add(Json.createArrayBuilder()
+                        .add("bar")).build(); // [["bar"]]
+        JsonArray value = Json.createArrayBuilder()
+                .add("abc")
+                .add("def").build();// ["abc","def"]
+
+        JsonStructure result = jsonPointer.add(target, value);
+        assertEquals("[[\"bar\",[\"abc\",\"def\"]]]", result.toString()); // [["bar",["abc","def"]]]
+    }
+
+    @Test
+    public void testAddArrayElement() {
+        JsonPointer jsonPointer = new JsonPointer("/foo/1");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", Json.createArrayBuilder()
+                        .add("bar")
+                        .add("baz")).build(); // {"foo":["bar","baz"]}
+
+        JsonStructure result = jsonPointer.add(target, new JsonStringImpl("qux"));
+        assertEquals("{\"foo\":[\"bar\",\"qux\",\"baz\"]}", result.toString()); // {"foo":["bar","qux","baz"]}
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testRemoveJsonObjectWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("/");
+        jsonPointer.remove((JsonObject) null);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveJsonObjectWithEmptyJsonPointer() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonObject target = Json.createObjectBuilder().build();
+
+        jsonPointer.remove(target);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testRemoveJsonArrayWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("/");
+        jsonPointer.remove((JsonArray) null);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveJsonArrayWithEmptyJsonPointer() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonArray target = Json.createArrayBuilder().build();
+
+        jsonPointer.remove(target);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveArrayElementWithIndexNoNumber() {
+        JsonPointer jsonPointer = new JsonPointer("/foo/a");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", Json.createArrayBuilder()
+                        .add("bar")
+                        .add("qux")
+                        .add("baz")).build(); // {"foo":["bar","qux","baz"]}
+
+        jsonPointer.remove(target);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveArrayElementWithIndexOutOfRange() {
+        JsonPointer jsonPointer = new JsonPointer("/foo/3");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", Json.createArrayBuilder()
+                        .add("bar")
+                        .add("qux")
+                        .add("baz")).build(); // {"foo":["bar","qux","baz"]}
+
+        jsonPointer.remove(target);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveArrayElementWithInvalidIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/foo/+");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", Json.createArrayBuilder()
+                        .add("bar")
+                        .add("qux")
+                        .add("baz")).build(); // {"foo":["bar","qux","baz"]}
+
+        jsonPointer.remove(target);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testRemoveArrayElementWithLeadingZeroIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/foo/01");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", Json.createArrayBuilder()
+                        .add("bar")
+                        .add("qux")
+                        .add("baz")).build(); // {"foo":["bar","qux","baz"]}
+
+        jsonPointer.remove(target);
+    }
+
+    @Test
+    public void testRemoveArrayElement() {
+        JsonPointer jsonPointer = new JsonPointer("/0/1");
+        JsonStructure target = Json.createArrayBuilder()
+                .add(Json.createArrayBuilder()
+                        .add("bar")
+                        .add("qux")
+                        .add("baz")).build(); // [["bar","qux","baz"]]
+
+        JsonStructure result = jsonPointer.remove(target);
+        assertEquals("[[\"bar\",\"baz\"]]", result.toString()); // [["bar","baz"]]
+    }
+
+    @Test
+    public void testRemoveObjectMember() {
+        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("baz", "qux")
+                .add("foo", "bar").build(); // {"baz":"qux","foo":"bar"}
+
+        JsonStructure result = jsonPointer.remove(target);
+        assertEquals("{\"foo\":\"bar\"}", result.toString()); // {"foo":"bar"}
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testReplaceJsonObjectWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("/");
+        jsonPointer.replace((JsonObject) null, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceJsonObjectWithEmptyJsonPointer() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonObject target = Json.createObjectBuilder().build();
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testReplaceJsonArrayWithTargetNull() {
+        JsonPointer jsonPointer = new JsonPointer("/");
+        jsonPointer.replace((JsonArray) null, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceJsonArrayWithEmptyJsonPointer() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonArray target = Json.createArrayBuilder().build();
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test
+    public void testReplaceArrayElement() {
+        JsonPointer jsonPointer = new JsonPointer("/1/1");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("bar")
+                .add(Json.createArrayBuilder()
+                        .add("abc")
+                        .add("def")).build(); // ["bar",["abc","def"]]
+
+        JsonStructure result = jsonPointer.replace(target, new JsonStringImpl("qux"));
+        assertEquals("[\"bar\",[\"abc\",\"qux\"]]", result.toString()); // ["bar",["abc","qux"]]
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceArrayElementWithIndexOutOfRange() {
+        JsonPointer jsonPointer = new JsonPointer("/1/2");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("bar")
+                .add(Json.createArrayBuilder()
+                        .add("abc")
+                        .add("def")).build(); // ["bar",["abc","def"]]
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceArrayElementWithIndexNoNumber() {
+        JsonPointer jsonPointer = new JsonPointer("/1/a");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("bar")
+                .add(Json.createArrayBuilder()
+                        .add("abc")
+                        .add("def")).build(); // ["bar",["abc","def"]]
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceArrayElementWithLeadingZeroIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/1/01");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("bar")
+                .add(Json.createArrayBuilder()
+                        .add("abc")
+                        .add("def")).build(); // ["bar",["abc","def"]]
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceArrayElementWithInvalidIndex() {
+        JsonPointer jsonPointer = new JsonPointer("/1/+");
+        JsonStructure target = Json.createArrayBuilder()
+                .add("bar")
+                .add(Json.createArrayBuilder()
+                        .add("abc")
+                        .add("def")).build(); // ["bar",["abc","def"]]
+
+        jsonPointer.replace(target, new JsonStringImpl("qux"));
+    }
+
+    @Test
+    public void testReplaceObjectMember() {
+        JsonPointer jsonPointer = new JsonPointer("/baz");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar")
+                .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
+
+        JsonStructure result = jsonPointer.replace(target, new JsonStringImpl("boo"));
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"boo\"}", result.toString()); // {"foo":"bar","baz":"boo"}
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceObjectMemberWithNonexistentTarget1() {
+        JsonPointer jsonPointer = new JsonPointer("/baz/a");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar")
+                .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
+
+        JsonStructure result = jsonPointer.replace(target, new JsonStringImpl("boo"));
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"boo\"}", result.toString()); // {"foo":"bar","baz":"boo"}
+    }
+
+    @Test(expected = JsonException.class)
+    public void testReplaceObjectMemberWithNonexistentTarget2() {
+        JsonPointer jsonPointer = new JsonPointer("/fo");
+        JsonStructure target = Json.createObjectBuilder()
+                .add("foo", "bar")
+                .add("baz", "qux").build(); // {"foo":"bar","baz":"qux"}
+
+        JsonStructure result = jsonPointer.replace(target, new JsonStringImpl("boo"));
+        assertEquals("{\"foo\":\"bar\",\"baz\":\"boo\"}", result.toString()); // {"foo":"bar","baz":"boo"}
+    }
+
+    @Test
+    public void testEqualsTrue() {
+        JsonPointer jsonPointer1 = new JsonPointer("/foo/1");
+        JsonPointer jsonPointer2 = new JsonPointer("/foo/1");
+        assertTrue(jsonPointer1.equals(jsonPointer2));
+    }
+
+    @Test
+    public void testEqualsFalse() {
+        JsonPointer jsonPointer1 = new JsonPointer("/foo/1");
+        JsonPointer jsonPointer2 = new JsonPointer("/foo/2");
+        assertFalse(jsonPointer1.equals(jsonPointer2));
+    }
+
     private JsonStructure getJsonDocument() {
         JsonReader reader = Json.createReaderFactory(Collections.<String, Object>emptyMap()).createReader(
                 Thread.currentThread().getContextClassLoader().getResourceAsStream("json/jsonPointerTest.json"));


[06/26] johnzon git commit: Implemented JsonPointer

Posted by st...@apache.org.
Implemented JsonPointer


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/45faea0e
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/45faea0e
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/45faea0e

Branch: refs/heads/master
Commit: 45faea0eb3e04f7adbe0724a448eb0cb62a4f258
Parents: d8a56d0
Author: Armin Hasler <ha...@gmail.com>
Authored: Wed Jul 6 17:06:26 2016 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:28:49 2016 +0100

----------------------------------------------------------------------
 .../org/apache/johnzon/core/JsonPointer.java    | 308 +++++++++++++++++++
 .../apache/johnzon/core/JsonPointerTest.java    | 197 ++++++++++++
 .../test/resources/json/jsonPointerTest.json    |  15 +
 3 files changed, 520 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/45faea0e/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
new file mode 100644
index 0000000..af228be
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointer.java
@@ -0,0 +1,308 @@
+/*
+ * 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 javax.json.JsonArray;
+import javax.json.JsonException;
+import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+/**
+ * <p>This class is an immutable representation of a JSON Pointer as specified in
+ * <a href="http://tools.ietf.org/html/rfc6901">RFC 6901</a>.
+ * </p>
+ * <p> A JSON Pointer, when applied to a target {@link JsonValue},
+ * defines a reference location in the target.</p>
+ * <p> An empty JSON Pointer string defines a reference to the target itself.</p>
+ * <p> If the JSON Pointer string is non-empty, it must be a sequence
+ * of '/' prefixed tokens, and the target must either be a {@link JsonArray}
+ * or {@link JsonObject}. If the target is a {@code JsonArray}, the pointer
+ * defines a reference to an array element, and the last token specifies the index.
+ * If the target is a {@link JsonObject}, the pointer defines a reference to a
+ * name/value pair, and the last token specifies the name.
+ * </p>
+ * <p> The method {@link JsonPointer#getValue getValue()} returns the referenced value.
+ * The methods {@link JsonPointer#add add()}, {@link JsonPointer#replace replace()},
+ * and {@link JsonPointer#remove remove()} executes the operations specified in
+ * <a href="http://tools.ietf.org/html/rfc6902">RFC 6902</a>. </p>
+ *
+ * @since 1.1
+ */
+
+public class JsonPointer {
+
+    private final String jsonPointer;
+    private final String[] referenceTokens;
+
+    /**
+     * Constructs and initializes a JsonPointer.
+     *
+     * @param jsonPointer the JSON Pointer string
+     * @throws NullPointerException if {@code jsonPointer} is {@code null}
+     * @throws JsonException        if {@code jsonPointer} is not a valid JSON Pointer
+     */
+    public JsonPointer(String jsonPointer) {
+        if (jsonPointer == null) {
+            throw new NullPointerException("jsonPointer must not be null");
+        }
+        if (!jsonPointer.equals("") && !jsonPointer.startsWith("/")) {
+            throw new JsonException("A non-empty JSON pointer must begin with a '/'");
+        }
+
+        this.jsonPointer = jsonPointer;
+        referenceTokens = jsonPointer.split("/", -1);
+    }
+
+    /**
+     * Compares this {@code JsonPointer} with another object.
+     *
+     * @param obj the object to compare this {@code JsonPointer} against
+     * @return true if the given object is a {@code JsonPointer} with the same
+     * reference tokens as this one, false otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        JsonPointer that = (JsonPointer) obj;
+        return jsonPointer.equals(that.jsonPointer);
+    }
+
+    /**
+     * Returns the hash code value for this {@code JsonPointer} object.
+     * The hash code of this object is defined by the hash codes of it's reference tokens.
+     *
+     * @return the hash code value for this {@code JsonPointer} object
+     */
+    @Override
+    public int hashCode() {
+        return jsonPointer.hashCode();
+    }
+
+    /**
+     * Returns the value at the referenced location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the referenced value in the target.
+     * @throws NullPointerException if {@code target} is null
+     * @throws JsonException        if the referenced value does not exist
+     */
+    public JsonValue getValue(JsonStructure target) {
+        if (target == null) {
+            throw new NullPointerException("target must not be null");
+        }
+
+        if (jsonPointer.equals("")) {
+            return target;
+        }
+
+        JsonValue jsonValue = target;
+
+        for (int i = 1; i < referenceTokens.length; i++) {
+            String decodedReferenceToken = JsonPointerUtil.decode(referenceTokens[i]);
+
+            if (jsonValue instanceof JsonObject) {
+                JsonObject jsonObject = (JsonObject) jsonValue;
+                jsonValue = jsonObject.get(decodedReferenceToken);
+
+                if (jsonValue == null) {
+                    throw new JsonException("The JsonObject " + jsonObject + " contains no value for token " + decodedReferenceToken);
+                }
+            } else if (jsonValue instanceof JsonArray) {
+                JsonArray jsonArray = (JsonArray) jsonValue;
+
+                try {
+                    int index = Integer.parseInt(decodedReferenceToken);
+                    if (index >= jsonArray.size()) {
+                        throw new JsonException("The JsonArray " + jsonArray + " contains no element for index " + index);
+                    }
+                    if (decodedReferenceToken.startsWith("0") && decodedReferenceToken.length() > 1) {
+                        throw new JsonException("The token " + decodedReferenceToken + " with leading zeros is not allowed to reference an element of a JsonArray");
+                    }
+
+                    jsonValue = jsonArray.get(index);
+                } catch (NumberFormatException e) {
+                    throw new JsonException("The token " + decodedReferenceToken + " for the JsonArray " + jsonArray + " is not a number", e);
+                }
+            }
+
+        }
+
+        return jsonValue;
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     * <ol>
+     * <li>If the reference is the target (empty JSON Pointer string),
+     * the specified {@code value}, which must be the same type as
+     * specified {@code target}, is returned.</li>
+     * <li>If the reference is an array element, the specified {@code value} is inserted
+     * into the array, at the referenced index. The value currently at that location, and
+     * any subsequent values, are shifted to the right (adds one to the indices).
+     * Index starts with 0. If the reference is specified with a "-", or if the
+     * index is equal to the size of the array, the value is appended to the array.</li>
+     * <li>If the reference is a name/value pair of a {@code JsonObject}, and the
+     * referenced value exists, the value is replaced by the specified {@code value}.
+     * If the value does not exist, a new name/value pair is added to the object.</li>
+     * </ol>
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     */
+    public JsonStructure add(JsonStructure target, JsonValue value) {
+        return null;
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure replace(JsonStructure target, JsonValue value) {
+        return null;
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     */
+    public JsonStructure remove(JsonStructure target) {
+        return null;
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     * @see #add(JsonStructure, JsonValue)
+     */
+    public JsonObject add(JsonObject target, JsonValue value) {
+        return (JsonObject) this.add((JsonStructure) target, value);
+    }
+
+    /**
+     * Adds or replaces a value at the referenced location in the specified
+     * {@code target} with the specified {@code value}.
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be added
+     * @return the transformed {@code target} after the value is added.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the reference is an array element and
+     *                              the index is out of range ({@code index < 0 || index > array size}),
+     *                              or if the pointer contains references to non-existing objects or arrays.
+     * @see #add(JsonStructure, JsonValue)
+     */
+    public JsonArray add(JsonArray target, JsonValue value) {
+        return (JsonArray) this.add((JsonStructure) target, value);
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     *                              {@code target} with the specified {@code value}.
+     * @see #replace(JsonStructure, JsonValue)
+     */
+    public JsonObject replace(JsonObject target, JsonValue value) {
+        return (JsonObject) this.replace((JsonStructure) target, value);
+    }
+
+    /**
+     * Replaces the value at the referenced location in the specified
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @param value  the value to be stored at the referenced location
+     * @return the transformed {@code target} after the value is replaced.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     *                              {@code target} with the specified {@code value}.
+     * @see #replace(JsonStructure, JsonValue)
+     */
+    public JsonArray replace(JsonArray target, JsonValue value) {
+        return (JsonArray) this.replace((JsonStructure) target, value);
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #remove(JsonStructure)
+     */
+    public JsonObject remove(JsonObject target) {
+        return (JsonObject) this.remove((JsonStructure) target);
+    }
+
+    /**
+     * Removes the value at the reference location in the specified {@code target}
+     *
+     * @param target the target referenced by this {@code JsonPointer}
+     * @return the transformed {@code target} after the value is removed.
+     * @throws NullPointerException if {@code target} is {@code null}
+     * @throws JsonException        if the referenced value does not exist,
+     *                              or if the reference is the target.
+     * @see #remove(JsonStructure)
+     */
+    public JsonArray remove(JsonArray target) {
+        return (JsonArray) this.remove((JsonStructure) target);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/45faea0e/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..7750ba6
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
@@ -0,0 +1,197 @@
+/*
+ * 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.junit.Test;
+
+import javax.json.Json;
+import javax.json.JsonException;
+import javax.json.JsonReader;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+
+public class JsonPointerTest {
+
+    @Test(expected = NullPointerException.class)
+    public void testConstructorWithNullShouldThrowNullPointerException() {
+        new JsonPointer(null);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testConstructorWithInvalidJsonPointerShouldThrowJsonException() {
+        new JsonPointer("a");
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void testGetValueWithNullShouldThrowNullPointerException() {
+        JsonPointer jsonPointer = new JsonPointer("");
+        jsonPointer.getValue(null);
+    }
+
+    @Test
+    public void testGetValueWholeDocument() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals(jsonDocument.toString(), result.toString());
+    }
+
+    @Test
+    public void testGetValue0() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("0", result.toString());
+    }
+
+    @Test
+    public void testGetValue1() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/a~1b");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("1", result.toString());
+    }
+
+    @Test
+    public void testGetValue2() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/c%d");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("2", result.toString());
+    }
+
+    @Test
+    public void testGetValue3() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/e^f");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("3", result.toString());
+    }
+
+    @Test
+    public void testGetValue4() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/g|h");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("4", result.toString());
+    }
+
+    @Test
+    public void testGetValue5() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/i\\j");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("5", result.toString());
+    }
+
+    @Test
+    public void testGetValue6() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/k\"l");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("6", result.toString());
+    }
+
+    @Test
+    public void testGetValue7() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/ ");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("7", result.toString());
+    }
+
+    @Test
+    public void testGetValue8() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/m~0n");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("8", result.toString());
+    }
+
+    @Test(expected = JsonException.class)
+    public void testGetValueElementNotExistentShouldThrowJsonException() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/fool");
+        jsonPointer.getValue(jsonDocument);
+    }
+
+    @Test
+    public void testGetValueWholeJsonArray() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("[\"bar\",\"baz\"]", result.toString());
+    }
+
+    @Test
+    public void testGetValueJsonArrayElement() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo/0");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("\"bar\"", result.toString());
+    }
+
+    @Test(expected = JsonException.class)
+    public void testGetValueJsonArrayElementNotExistentShouldThrowJsonException() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo/2");
+        jsonPointer.getValue(jsonDocument);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testGetValueJsonArrayElementNoNumberShouldThrowJsonException() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo/a");
+        jsonPointer.getValue(jsonDocument);
+    }
+
+    @Test(expected = JsonException.class)
+    public void testGetValueJsonArrayElementLeadingZeroShouldThrowJsonException() {
+        JsonStructure jsonDocument = getJsonDocument();
+
+        JsonPointer jsonPointer = new JsonPointer("/foo/001");
+        JsonValue result = jsonPointer.getValue(jsonDocument);
+        assertEquals("\"bar\"", result.toString());
+    }
+
+    private JsonStructure getJsonDocument() {
+        JsonReader reader = Json.createReaderFactory(Collections.<String, Object>emptyMap()).createReader(
+                Thread.currentThread().getContextClassLoader().getResourceAsStream("json/jsonPointerTest.json"));
+        return reader.read();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/45faea0e/johnzon-core/src/test/resources/json/jsonPointerTest.json
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/resources/json/jsonPointerTest.json b/johnzon-core/src/test/resources/json/jsonPointerTest.json
new file mode 100644
index 0000000..8cdc1c9
--- /dev/null
+++ b/johnzon-core/src/test/resources/json/jsonPointerTest.json
@@ -0,0 +1,15 @@
+{
+  "foo": [
+    "bar",
+    "baz"
+  ],
+  "": 0,
+  "a/b": 1,
+  "c%d": 2,
+  "e^f": 3,
+  "g|h": 4,
+  "i\\j": 5,
+  "k\"l": 6,
+  " ": 7,
+  "m~n": 8
+}
\ No newline at end of file


[12/26] johnzon git commit: JOHNZON-95 initial JsonPatchBuilder impl

Posted by st...@apache.org.
JOHNZON-95 initial JsonPatchBuilder impl


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/f34deb60
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/f34deb60
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/f34deb60

Branch: refs/heads/master
Commit: f34deb60920e08cbce6c969209c0ea2ab5714265
Parents: 4b3ddf5
Author: Mark Struberg <st...@apache.org>
Authored: Wed Nov 23 14:08:43 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Wed Nov 23 14:08:43 2016 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonPatchBuilderImpl.java      | 124 +++++++++++++++++++
 .../apache/johnzon/core/JsonPointerTest.java    |  40 ++++--
 2 files changed, 155 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/f34deb60/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
new file mode 100644
index 0000000..f2e6a0d
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
@@ -0,0 +1,124 @@
+/*
+ * 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 javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonPatchBuilder;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+
+public class JsonPatchBuilderImpl implements JsonPatchBuilder {
+    public JsonPatchBuilderImpl() {
+        super();
+    }
+
+    @Override
+    public JsonStructure apply(JsonStructure target) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonObject apply(JsonObject target) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonArray apply(JsonArray target) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder add(String path, JsonValue value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder add(String path, String value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder add(String path, int value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder add(String path, boolean value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder remove(String path) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder replace(String path, JsonValue value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder replace(String path, String value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder replace(String path, int value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder replace(String path, boolean value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder move(String path, String from) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder copy(String path, String from) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder test(String path, JsonValue value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder test(String path, String value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder test(String path, int value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonPatchBuilder test(String path, boolean value) {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+
+    @Override
+    public JsonArray build() {
+        throw new UnsupportedOperationException("JSON-P 1.1");
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/f34deb60/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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 7a3d32a..57d52b9 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
@@ -24,6 +24,7 @@ import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonException;
 import javax.json.JsonObject;
+import javax.json.JsonPointer;
 import javax.json.JsonReader;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
@@ -73,9 +74,16 @@ public class JsonPointerTest {
     public void testGetValue1() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointerImpl jsonPointer = new JsonPointerImpl("/a~1b");
-        JsonValue result = jsonPointer.getValue(jsonDocument);
-        assertEquals("1", result.toString());
+        {
+            JsonPointerImpl jsonPointer = new JsonPointerImpl("/a~1b");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("1", result.toString());
+        }
+        {
+            JsonPointer jsonPointer = Json.createJsonPointer("/a~1b");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("1", result.toString());
+        }
     }
 
     @Test
@@ -91,18 +99,32 @@ public class JsonPointerTest {
     public void testGetValue3() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointerImpl jsonPointer = new JsonPointerImpl("/e^f");
-        JsonValue result = jsonPointer.getValue(jsonDocument);
-        assertEquals("3", result.toString());
+        {
+            JsonPointerImpl jsonPointer = new JsonPointerImpl("/e^f");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("3", result.toString());
+        }
+        {
+            JsonPointer jsonPointer = Json.createJsonPointer("/e^f");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("3", result.toString());
+        }
     }
 
     @Test
     public void testGetValue4() {
         JsonStructure jsonDocument = getJsonDocument();
 
-        JsonPointerImpl jsonPointer = new JsonPointerImpl("/g|h");
-        JsonValue result = jsonPointer.getValue(jsonDocument);
-        assertEquals("4", result.toString());
+        {
+            JsonPointerImpl jsonPointer = new JsonPointerImpl("/g|h");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("4", result.toString());
+        }
+        {
+            JsonPointer jsonPointer = Json.createJsonPointer("/g|h");
+            JsonValue result = jsonPointer.getValue(jsonDocument);
+            assertEquals("4", result.toString());
+        }
     }
 
     @Test


[03/26] johnzon git commit: Update geronimo-json-spec from 1.0 to 1.1, add JsonPointer encode and decode methods

Posted by st...@apache.org.
Update geronimo-json-spec from 1.0 to 1.1, add JsonPointer encode and decode methods


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/28748ffb
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/28748ffb
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/28748ffb

Branch: refs/heads/master
Commit: 28748ffb18ff541c6d313c482024de255d60afd9
Parents: c378b9b
Author: Armin Hasler <ha...@gmail.com>
Authored: Fri Jun 24 14:49:29 2016 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:23:15 2016 +0100

----------------------------------------------------------------------
 .../apache/johnzon/core/JsonPointerUtil.java    | 37 ++++++++++++++++++++
 .../johnzon/core/JsonPointerUtilTest.java       |  7 ++++
 2 files changed, 44 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/28748ffb/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
new file mode 100644
index 0000000..276fb42
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+public class JsonPointerUtil {
+
+    /**
+     *
+     * @param s
+     * @return
+     */
+    public static String encode(String s) {
+        return null;
+    }
+
+    public static String decode(String s) {
+        return null;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/28748ffb/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
new file mode 100644
index 0000000..226d742
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
@@ -0,0 +1,7 @@
+package org.apache.johnzon.core;
+
+/**
+ * @author Armin Hasler (02eex458)
+ */
+public class JsonPointerUtilTest {
+}


[13/26] johnzon git commit: JOHNZON-95 fix PatchBuilder API and invocation

Posted by st...@apache.org.
JOHNZON-95 fix PatchBuilder API and invocation


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/d04e01ef
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/d04e01ef
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/d04e01ef

Branch: refs/heads/master
Commit: d04e01ef103e4198a9fce159151ece1e93cd80c0
Parents: f34deb6
Author: Mark Struberg <st...@apache.org>
Authored: Wed Nov 23 14:57:43 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Wed Nov 23 14:57:43 2016 +0100

----------------------------------------------------------------------
 .../java/org/apache/johnzon/core/JsonPatchBuilderImpl.java  | 9 ++++++++-
 .../main/java/org/apache/johnzon/core/JsonProviderImpl.java | 4 ++--
 2 files changed, 10 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/d04e01ef/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
index f2e6a0d..a6e7c8a 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
@@ -18,6 +18,7 @@ package org.apache.johnzon.core;
 
 import javax.json.JsonArray;
 import javax.json.JsonObject;
+import javax.json.JsonPatch;
 import javax.json.JsonPatchBuilder;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
@@ -27,6 +28,12 @@ public class JsonPatchBuilderImpl implements JsonPatchBuilder {
         super();
     }
 
+    public JsonPatchBuilderImpl(JsonArray initialData) {
+        super();
+    }
+
+
+
     @Override
     public JsonStructure apply(JsonStructure target) {
         throw new UnsupportedOperationException("JSON-P 1.1");
@@ -118,7 +125,7 @@ public class JsonPatchBuilderImpl implements JsonPatchBuilder {
     }
 
     @Override
-    public JsonArray build() {
+    public JsonPatch build() {
         throw new UnsupportedOperationException("JSON-P 1.1");
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d04e01ef/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 e9926f9..4b011a7 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
@@ -246,12 +246,12 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
 
         @Override
         public JsonPatchBuilder createPatchBuilder() {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+            return new JsonPatchBuilderImpl();
         }
 
         @Override
         public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
+            return new JsonPatchBuilderImpl(initialData);
         }
 
         @Override


[25/26] johnzon git commit: JOHNZON-96 add test + logic for ArrayBuilder ft of JSONP-1.1

Posted by st...@apache.org.
JOHNZON-96 add test + logic for ArrayBuilder ft of JSONP-1.1


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/a2a1a047
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/a2a1a047
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/a2a1a047

Branch: refs/heads/master
Commit: a2a1a047bd16b5976027ba2400ee0b925a1a0bb4
Parents: 525da3d
Author: Mark Struberg <st...@apache.org>
Authored: Fri Feb 24 00:21:06 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Fri Feb 24 00:21:06 2017 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonArrayBuilderImpl.java      | 35 +++++++++++++++++++-
 .../johnzon/core/JsonBuilderFactoryImpl.java    |  6 ++++
 .../apache/johnzon/core/JsonProviderImpl.java   |  9 +++++
 .../johnzon/core/JsonArrayBuilderImplTest.java  | 35 ++++++++++++++++++++
 4 files changed, 84 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2a1a047/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
index b8ff582..0936e22 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayBuilderImpl.java
@@ -20,12 +20,14 @@ package org.apache.johnzon.core;
 
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
+import javax.json.JsonException;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonValue;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -39,7 +41,38 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder, Serializable {
         tmpList = new ArrayList<>(initialData);
     }
 
-    @Override
+    public JsonArrayBuilderImpl(Collection<Object> initialData) {
+        tmpList = new ArrayList<>();
+        for (Object initialValue : initialData) {
+            add(initialValue);
+        }
+    }
+
+    public JsonArrayBuilder add(final Object value) {
+        if (value instanceof JsonValue) {
+            add((JsonValue) value);
+        } else if (value instanceof BigDecimal) {
+            add((BigDecimal) value);
+        } else if (value instanceof BigInteger) {
+            add((BigInteger) value);
+        } else if (value instanceof Boolean) {
+            add((boolean) value);
+        } else if (value instanceof Double) {
+            add((double) value);
+        } else if (value instanceof Integer) {
+            add((int) value);
+        } else if (value instanceof Long) {
+            add((long) value);
+        } else if (value instanceof String) {
+            add((String) value);
+        } else {
+            throw new JsonException("Illegal JSON type! type=" + value.getClass());
+        }
+
+        return this;
+    }
+
+        @Override
     public JsonArrayBuilder add(final JsonValue value) {
         addValue(value);
         return this;

http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2a1a047/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
index 6f1f9ba..c6062a7 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonBuilderFactoryImpl.java
@@ -19,6 +19,7 @@
 package org.apache.johnzon.core;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -73,6 +74,10 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory {
         return new JsonArrayBuilderImpl(initialData);
     }
 
+    public JsonArrayBuilder createArrayBuilder(Collection<Object> initialData) {
+        return new JsonArrayBuilderImpl(initialData);
+    }
+
     @Override
     public Map<String, ?> getConfigInUse() {
         return Collections.unmodifiableMap(internalConfig);
@@ -81,4 +86,5 @@ class JsonBuilderFactoryImpl implements JsonBuilderFactory {
     public JsonObjectBuilder createObjectBuilder(Map<String, Object> initialValues) {
         return new JsonObjectBuilderImpl(initialValues);
     }
+
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2a1a047/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 de18839..5fd5074 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
@@ -302,6 +302,15 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         }
 
         @Override
+        public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
+            return builderFactory.createArrayBuilder(initialData);
+        }
+
+        public JsonArrayBuilder createArrayBuilder(Collection<Object> initialData) {
+            return builderFactory.createArrayBuilder(initialData);
+        }
+
+        @Override
         public JsonBuilderFactory createBuilderFactory(final Map<String, ?> config) {
             return (config == null || config.isEmpty()) ? builderFactory : new JsonBuilderFactoryImpl(config);
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/a2a1a047/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
index df7a1af..85d14eb 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonArrayBuilderImplTest.java
@@ -22,12 +22,16 @@ import static org.junit.Assert.assertEquals;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import javax.json.Json;
+import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonValue;
 
+import org.junit.Assert;
 import org.junit.Test;
 
 public class JsonArrayBuilderImplTest {
@@ -167,4 +171,35 @@ public class JsonArrayBuilderImplTest {
         final JsonArrayBuilder builder = Json.createArrayBuilder();
         builder.add((double) Double.NEGATIVE_INFINITY);
     }
+
+
+    @Test
+    public void testCreateArrayBuilderWithJsonArrayInitialData() {
+        final JsonArrayBuilder builder = Json.createArrayBuilder();
+        builder.add("a");
+        builder.add("b");
+        builder.add("c");
+        JsonArray jsonArray = builder.build();
+
+        JsonArrayBuilder otherBuilder = Json.createArrayBuilder(jsonArray);
+        otherBuilder.add("d");
+
+        JsonArray jsonArray2 = otherBuilder.build();
+        Assert.assertEquals("[\"a\",\"b\",\"c\",\"d\"]", jsonArray2.toString());
+    }
+
+    @Test
+    public void testCreateArrayBuilderWithCollectionInitialData() {
+        //X TODO should be Collection<String>, but the current Json API is not nice enough...
+        Collection<Object> initialData = new ArrayList<>();
+        initialData.add("a");
+        initialData.add("b");
+        initialData.add("c");
+
+        JsonArrayBuilder otherBuilder = Json.createArrayBuilder(initialData);
+        otherBuilder.add("d");
+
+        JsonArray jsonArray2 = otherBuilder.build();
+        Assert.assertEquals("[\"a\",\"b\",\"c\",\"d\"]", jsonArray2.toString());
+    }
 }


[22/26] johnzon git commit: JOHNZON-95 fix missing JsonProviderDelegate method for creating JsonPointer

Posted by st...@apache.org.
JOHNZON-95 fix missing JsonProviderDelegate method for creating JsonPointer


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/c62932b8
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/c62932b8
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/c62932b8

Branch: refs/heads/master
Commit: c62932b816238d66309663c938534f0d8c419513
Parents: 184e477
Author: Mark Struberg <st...@apache.org>
Authored: Tue Feb 21 08:12:55 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Feb 21 08:12:55 2017 +0100

----------------------------------------------------------------------
 .../src/main/java/org/apache/johnzon/core/JsonProviderImpl.java | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/c62932b8/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 9d105fa..0eeef2c 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
@@ -306,6 +306,11 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
             return new JsonPatchBuilderImpl(initialData);
         }
 
+        @Override
+        public JsonPointer createPointer(String path) {
+            return new JsonPointerImpl(path);
+        }
+
         //X TODO add missing methods
 
     }


[26/26] johnzon git commit: Merge branch 'JSONP-1.1'

Posted by st...@apache.org.
Merge branch 'JSONP-1.1'


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/02993157
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/02993157
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/02993157

Branch: refs/heads/master
Commit: 02993157ee39c0c2c20ebd34215fccf869ab9c1c
Parents: d344cbc a2a1a04
Author: Mark Struberg <st...@apache.org>
Authored: Fri Feb 24 13:01:13 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Fri Feb 24 13:01:13 2017 +0100

----------------------------------------------------------------------
 johnzon-core/pom.xml                            |   2 +-
 .../johnzon/core/JsonArrayBuilderImpl.java      |  44 +-
 .../johnzon/core/JsonBuilderFactoryImpl.java    |  23 +
 .../apache/johnzon/core/JsonGeneratorImpl.java  |  36 +-
 .../johnzon/core/JsonMergePatchBuilder.java     |  74 ++
 .../johnzon/core/JsonObjectBuilderImpl.java     |  78 +-
 .../johnzon/core/JsonPatchBuilderImpl.java      | 185 ++++
 .../org/apache/johnzon/core/JsonPatchImpl.java  | 213 +++++
 .../apache/johnzon/core/JsonPatchOperation.java | 143 +++
 .../apache/johnzon/core/JsonPointerImpl.java    | 484 ++++++++++
 .../apache/johnzon/core/JsonPointerUtil.java    |  49 +
 .../apache/johnzon/core/JsonProviderImpl.java   | 137 ++-
 .../org/apache/johnzon/core/SimpleStack.java    |   4 +-
 .../johnzon/core/JsonArrayBuilderImplTest.java  |  35 +
 .../johnzon/core/JsonMergeBatchBuilderTest.java |  36 +
 .../johnzon/core/JsonObjectBuilderImplTest.java |  88 +-
 .../johnzon/core/JsonPatchBuilderTest.java      | 440 +++++++++
 .../org/apache/johnzon/core/JsonPatchTest.java  | 953 +++++++++++++++++++
 .../apache/johnzon/core/JsonPointerTest.java    | 667 +++++++++++++
 .../johnzon/core/JsonPointerUtilTest.java       |  98 ++
 .../apache/johnzon/core/JsonReaderImplTest.java |   4 +-
 .../test/resources/json/jsonPointerTest.json    |  15 +
 johnzon-distribution/pom.xml                    |  15 +-
 johnzon-jaxrs/pom.xml                           |   2 +-
 johnzon-jsonb/pom.xml                           |   4 +-
 johnzon-mapper/pom.xml                          |   2 +-
 .../johnzon/mapper/MappingParserImpl.java       |   2 +-
 .../org/apache/johnzon/mapper/MapperTest.java   |   5 +-
 johnzon-maven-plugin/pom.xml                    |   6 +-
 johnzon-websocket/pom.xml                       |  44 +-
 .../src/test/resources/arquillian.xml           |   6 +
 jsonb-api/pom.xml                               |   4 +-
 pom.xml                                         |  25 +-
 33 files changed, 3852 insertions(+), 71 deletions(-)
----------------------------------------------------------------------



[19/26] johnzon git commit: JOHNZON-99 JOHNZON-100 improve JSON-B private attribute support

Posted by st...@apache.org.
JOHNZON-99 JOHNZON-100 improve JSON-B private attribute support

* evaluate the JsonVisibility
* honor @JsonProperty fields


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/271a98e5
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/271a98e5
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/271a98e5

Branch: refs/heads/master
Commit: 271a98e5eea169c753bae877058491759e43c829
Parents: eb932c3
Author: Mark Struberg <st...@apache.org>
Authored: Mon Dec 5 21:32:36 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Dec 5 21:35:12 2016 +0100

----------------------------------------------------------------------
 .../apache/johnzon/jsonb/JohnzonBuilder.java    |  14 ++-
 .../johnzon/jsonb/JsonbVisitilityTest.java      | 106 +++++++++++++++++++
 2 files changed, 119 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/271a98e5/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index 673877a..137cf4c 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -38,6 +38,7 @@ import javax.json.bind.Jsonb;
 import javax.json.bind.JsonbBuilder;
 import javax.json.bind.JsonbConfig;
 import javax.json.bind.adapter.JsonbAdapter;
+import javax.json.bind.annotation.JsonbProperty;
 import javax.json.bind.annotation.JsonbVisibility;
 import javax.json.bind.config.BinaryDataStrategy;
 import javax.json.bind.config.PropertyNamingStrategy;
@@ -156,6 +157,9 @@ public class JohnzonBuilder implements JsonbBuilder {
 
                     @Override
                     public boolean isVisible(final Field field) {
+                        if (field.getAnnotation(JsonbProperty.class) != null) {
+                            return true;
+                        }
                         final PropertyVisibilityStrategy strategy = strategies.computeIfAbsent(field.getDeclaringClass(), this::visibilityStrategy);
                         return strategy == this ? Modifier.isPublic(field.getModifiers()) : strategy.isVisible(field);
                     }
@@ -167,9 +171,17 @@ public class JohnzonBuilder implements JsonbBuilder {
                     }
 
                     private PropertyVisibilityStrategy visibilityStrategy(final Class<?> type) { // can be cached
+                        JsonbVisibility visibility = type.getAnnotation(JsonbVisibility.class);
+                        if (visibility != null) {
+                            try {
+                                return visibility.value().newInstance();
+                            } catch (final InstantiationException | IllegalAccessException e) {
+                                throw new IllegalArgumentException(e);
+                            }
+                        }
                         Package p = type.getPackage();
                         while (p != null) {
-                            final JsonbVisibility visibility = p.getAnnotation(JsonbVisibility.class);
+                            visibility = p.getAnnotation(JsonbVisibility.class);
                             if (visibility != null) {
                                 try {
                                     return visibility.value().newInstance();

http://git-wip-us.apache.org/repos/asf/johnzon/blob/271a98e5/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbVisitilityTest.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbVisitilityTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbVisitilityTest.java
new file mode 100644
index 0000000..9fe45aa
--- /dev/null
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/JsonbVisitilityTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.jsonb;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.json.bind.Jsonb;
+import javax.json.bind.annotation.JsonbProperty;
+import javax.json.bind.annotation.JsonbVisibility;
+import javax.json.bind.config.PropertyVisibilityStrategy;
+import javax.json.bind.spi.JsonbProvider;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JsonbVisitilityTest {
+
+    @Test
+    public void testJsonVisibilityAllFields() {
+        MyDataVisibility data = new MyDataVisibility();
+        data.put("x", "a");
+        data.put("y", "b");
+
+        Jsonb jsonb = JsonbProvider.provider().create().build();
+        String json = jsonb.toJson(data);
+        Assert.assertEquals("{\"attribs\":{\"x\":\"a\",\"y\":\"b\"}}", json);
+
+        MyDataVisibility dataBack = jsonb.fromJson(json, MyDataVisibility.class);
+        Assert.assertEquals("a", dataBack.get("x"));
+        Assert.assertEquals("b", dataBack.get("y"));
+    }
+
+    @Test
+    public void testJsonPropertyInternalField() {
+        MyDataJsonField data = new MyDataJsonField();
+        data.put("x", "a");
+        data.put("y", "b");
+
+        Jsonb jsonb = JsonbProvider.provider().create().build();
+        String json = jsonb.toJson(data);
+        Assert.assertEquals("{\"attribs\":{\"x\":\"a\",\"y\":\"b\"}}", json);
+
+        MyDataJsonField dataBack = jsonb.fromJson(json, MyDataJsonField.class);
+        Assert.assertEquals("a", dataBack.get("x"));
+        Assert.assertEquals("b", dataBack.get("y"));
+    }
+
+
+    @JsonbVisibility(VisibleAllFields.class)
+    public static class MyDataVisibility {
+        private Map<String, String> attribs = new HashMap<>();
+
+        public void put(String key, String value) {
+            attribs.put(key, value);
+        }
+
+        public String get(String key) {
+            return attribs.get(key);
+        }
+    }
+
+    public static class MyDataJsonField {
+        @JsonbProperty
+        private Map<String, String> attribs = new HashMap<>();
+
+        public void put(String key, String value) {
+            attribs.put(key, value);
+        }
+
+        public String get(String key) {
+            return attribs.get(key);
+        }
+    }
+
+    /**
+     * All fields are visible. Even private, which by default won't get jsonified.
+     */
+    public static class VisibleAllFields implements PropertyVisibilityStrategy {
+        @Override
+        public boolean isVisible(Field field) {
+            return true;
+        }
+
+        @Override
+        public boolean isVisible(Method method) {
+            return false;
+        }
+    }
+}


[07/26] johnzon git commit: fix pom version

Posted by st...@apache.org.
fix pom version


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/bfdab106
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/bfdab106
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/bfdab106

Branch: refs/heads/master
Commit: bfdab106e4cdc63d131ecacca19559bca6ebae71
Parents: cc830c6
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 21:37:22 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:37:22 2016 +0100

----------------------------------------------------------------------
 johnzon-distribution/pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/bfdab106/johnzon-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-distribution/pom.xml b/johnzon-distribution/pom.xml
index f6f468e..1b0e3cd 100644
--- a/johnzon-distribution/pom.xml
+++ b/johnzon-distribution/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.4-SNAPSHOT</version>
+    <version>0.9.6-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 


[10/26] johnzon git commit: rename build property for geroniomo spec jar version

Posted by st...@apache.org.
rename build property for geroniomo spec jar version


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/cedcf0c6
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/cedcf0c6
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/cedcf0c6

Branch: refs/heads/master
Commit: cedcf0c646a69a431b4827195dd4ed44d4cc1760
Parents: 498aff8
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 22:28:04 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 22:28:04 2016 +0100

----------------------------------------------------------------------
 johnzon-distribution/pom.xml                        | 6 +++---
 johnzon-maven-plugin/pom.xml                        | 2 +-
 johnzon-websocket/src/test/resources/arquillian.xml | 2 +-
 pom.xml                                             | 4 ++--
 4 files changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/cedcf0c6/johnzon-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-distribution/pom.xml b/johnzon-distribution/pom.xml
index 1b0e3cd..420f8c9 100644
--- a/johnzon-distribution/pom.xml
+++ b/johnzon-distribution/pom.xml
@@ -32,20 +32,20 @@
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>${jsonspecversion}</version>
+      <version>${geronimo-jsonp.version}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>${jsonspecversion}</version>
+      <version>${geronimo-jsonp.version}</version>
       <scope>compile</scope>
       <classifier>sources</classifier>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>${jsonspecversion}</version>
+      <version>${geronimo-jsonp.version}</version>
       <scope>compile</scope>
       <classifier>javadoc</classifier>
     </dependency>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/cedcf0c6/johnzon-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-maven-plugin/pom.xml b/johnzon-maven-plugin/pom.xml
index 1feaee6..4e7f743 100644
--- a/johnzon-maven-plugin/pom.xml
+++ b/johnzon-maven-plugin/pom.xml
@@ -39,7 +39,7 @@
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>${jsonspecversion}</version>
+      <version>${geronimo-jsonp.version}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/cedcf0c6/johnzon-websocket/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/resources/arquillian.xml b/johnzon-websocket/src/test/resources/arquillian.xml
index db21eae..567fc50 100644
--- a/johnzon-websocket/src/test/resources/arquillian.xml
+++ b/johnzon-websocket/src/test/resources/arquillian.xml
@@ -35,7 +35,7 @@
       <!-- override jsonp api -->
       <property name="lib">${project.build.directory}/ee-api</property>
       <property name="additionalLibs">
-        mvn:org.apache.geronimo.specs:geronimo-json_1.1_spec:${jsonspecversion}
+        mvn:org.apache.geronimo.specs:geronimo-json_1.1_spec:${geronimo-jsonp.version}
       </property>
     </configuration>
   </container>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/cedcf0c6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1a442fe..964d31a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,7 +40,7 @@
   <url>http://johnzon.apache.org</url>
 
   <properties>
-    <jsonspecversion>1.0-SNAPSHOT</jsonspecversion>
+    <geronimo-jsonp.version>1.0-SNAPSHOT</geronimo-jsonp.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <johnzon.site.url>https://svn.apache.org/repos/asf/johnzon/site/publish/</johnzon.site.url>
     <pubsub.url>scm:svn:${johnzon.site.url}</pubsub.url>
@@ -67,7 +67,7 @@
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
       <artifactId>geronimo-json_1.1_spec</artifactId>
-      <version>${jsonspecversion}</version>
+      <version>${geronimo-jsonp.version}</version>
       <scope>provided</scope>
     </dependency>
 


[20/26] johnzon git commit: propagate JSON-P 1.1 work to version 1.1.0

Posted by st...@apache.org.
propagate JSON-P 1.1 work to version 1.1.0


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/6aea7acc
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/6aea7acc
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/6aea7acc

Branch: refs/heads/master
Commit: 6aea7acc3fd912a9d59439ad66c3cb2853fd591a
Parents: 271a98e
Author: Mark Struberg <st...@apache.org>
Authored: Mon Dec 5 22:23:55 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Dec 5 22:23:55 2016 +0100

----------------------------------------------------------------------
 johnzon-core/pom.xml         | 2 +-
 johnzon-distribution/pom.xml | 2 +-
 johnzon-jaxrs/pom.xml        | 2 +-
 johnzon-jsonb/pom.xml        | 4 ++--
 johnzon-mapper/pom.xml       | 2 +-
 johnzon-maven-plugin/pom.xml | 2 +-
 johnzon-websocket/pom.xml    | 2 +-
 jsonb-api/pom.xml            | 4 ++--
 pom.xml                      | 2 +-
 9 files changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-core/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-core/pom.xml b/johnzon-core/pom.xml
index 60de5ce..081840a 100644
--- a/johnzon-core/pom.xml
+++ b/johnzon-core/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-distribution/pom.xml b/johnzon-distribution/pom.xml
index 420f8c9..0ee6b85 100644
--- a/johnzon-distribution/pom.xml
+++ b/johnzon-distribution/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-jaxrs/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/pom.xml b/johnzon-jaxrs/pom.xml
index 752ead4..5a9dfa1 100644
--- a/johnzon-jaxrs/pom.xml
+++ b/johnzon-jaxrs/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-jsonb/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/pom.xml b/johnzon-jsonb/pom.xml
index 74dbfdb..1c225a9 100644
--- a/johnzon-jsonb/pom.xml
+++ b/johnzon-jsonb/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -50,7 +50,7 @@
     <dependency>
       <groupId>org.apache.johnzon</groupId>
       <artifactId>jsonb-api</artifactId>
-      <version>0.9.6-SNAPSHOT</version>
+      <version>1.1.0-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-mapper/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-mapper/pom.xml b/johnzon-mapper/pom.xml
index 1c74e39..b020fc3 100644
--- a/johnzon-mapper/pom.xml
+++ b/johnzon-mapper/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-maven-plugin/pom.xml b/johnzon-maven-plugin/pom.xml
index 4e7f743..60bd77b 100644
--- a/johnzon-maven-plugin/pom.xml
+++ b/johnzon-maven-plugin/pom.xml
@@ -23,7 +23,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>johnzon-maven-plugin</artifactId>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/johnzon-websocket/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/pom.xml b/johnzon-websocket/pom.xml
index 3420410..67a3917 100644
--- a/johnzon-websocket/pom.xml
+++ b/johnzon-websocket/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/jsonb-api/pom.xml
----------------------------------------------------------------------
diff --git a/jsonb-api/pom.xml b/jsonb-api/pom.xml
index 27244b2..6dcf095 100644
--- a/jsonb-api/pom.xml
+++ b/jsonb-api/pom.xml
@@ -21,12 +21,12 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
   <artifactId>jsonb-api</artifactId>
-  <version>0.9.6-SNAPSHOT</version>
+  <version>1.1.0-SNAPSHOT</version>
   <name>Johnzon :: JSON-B API</name>
 
   <properties>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/6aea7acc/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 964d31a..b9fa74a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -33,7 +33,7 @@
   <groupId>org.apache.johnzon</groupId>
   <artifactId>johnzon</artifactId>
   <packaging>pom</packaging>
-  <version>0.9.6-SNAPSHOT</version>
+  <version>1.1.0-SNAPSHOT</version>
   <name>Apache Johnzon</name>
   <description>Apache Johnzon is an implementation of JSR-353 (JavaTM API for JSON Processing).</description>
   <inceptionYear>2014</inceptionYear>


[18/26] johnzon git commit: JOHNZON-95 first bits of MergeBatch handling

Posted by st...@apache.org.
JOHNZON-95 first bits of MergeBatch handling


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/eb932c35
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/eb932c35
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/eb932c35

Branch: refs/heads/master
Commit: eb932c35e91c0a6762716570f1b452796a837d06
Parents: 0e4bd48
Author: Mark Struberg <st...@apache.org>
Authored: Wed Nov 23 22:51:37 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Dec 5 21:35:12 2016 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonMergePatchBuilder.java     | 74 ++++++++++++++++++++
 .../johnzon/core/JsonMergeBatchBuilderTest.java | 36 ++++++++++
 2 files changed, 110 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/eb932c35/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
new file mode 100644
index 0000000..831e82e
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
@@ -0,0 +1,74 @@
+/*
+ * 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 javax.json.JsonValue;
+
+/**
+ * Creates and applies a Json Merge Patch as defined in
+ * https://tools.ietf.org/html/rfc7396
+ */
+public class JsonMergePatchBuilder {
+
+    /**
+     * Create a merged patch by comparing the source to the target.
+     * Applying this JsonPatch to the source will give you the target.
+     * A mergePatch is a JsonValue as defined in http://tools.ietf.org/html/rfc7396
+     *
+     * If you have a JSON like
+     * <pre>
+     * {
+     *   "a": "b",
+     *   "c": {
+     *     "d": "e",
+     *     "f": "g"
+     *   }
+     * }
+     * </pre>
+     *
+     * Then you can change the value of "a" and removing "f" by sending:
+     * <pre>
+     * {
+     *   "a":"z",
+     *   "c": {
+     *     "f": null
+     *   }
+     * }
+     * </pre>
+     *
+     * @see #mergePatch(JsonValue, JsonValue)
+     *
+     * @since 1.1
+     */
+    public JsonValue createMergePatch(JsonValue source , JsonValue target) {
+        return null;
+    }
+
+    /**
+     * Merge the given patch to the existing source
+     * A mergePatch is a JsonValue as defined in http://tools.ietf.org/html/rfc7396
+     *
+     * @return the result of applying the patch to the source
+     *
+     * @see #createMergePatch(JsonValue, JsonValue)
+     * @since 1.1
+     */
+    public JsonValue mergePatch(JsonValue source, JsonValue patch) {
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/eb932c35/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchBuilderTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchBuilderTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchBuilderTest.java
new file mode 100644
index 0000000..141ed9d
--- /dev/null
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchBuilderTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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 javax.json.spi.JsonProvider;
+
+public class JsonMergeBatchBuilderTest {
+
+    private static final String[][] TEST_CASES = new String[][]{
+            {
+                "{\"a\":\"b\"}",
+                "{\"a\":\"c\"}",
+                "{\"a\":\"c\"}"
+            }
+    };
+
+    public void testSimpleMergePatch() {
+        JsonProvider provider = JsonProvider.provider();
+
+
+    }
+}


[09/26] johnzon git commit: upgrading the new jsonp api in tomee

Posted by st...@apache.org.
upgrading the new jsonp api in tomee


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/498aff8b
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/498aff8b
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/498aff8b

Branch: refs/heads/master
Commit: 498aff8bd36a7b733f3108be3bceeed508a60797
Parents: 24b01af
Author: rmannibucau <rm...@apache.org>
Authored: Tue Nov 22 22:17:15 2016 +0100
Committer: rmannibucau <rm...@apache.org>
Committed: Tue Nov 22 22:17:15 2016 +0100

----------------------------------------------------------------------
 johnzon-websocket/pom.xml                       | 42 ++++++++++++++++++++
 .../src/test/resources/arquillian.xml           |  5 +++
 2 files changed, 47 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/498aff8b/johnzon-websocket/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/pom.xml b/johnzon-websocket/pom.xml
index 8d5b4dd..3420410 100644
--- a/johnzon-websocket/pom.xml
+++ b/johnzon-websocket/pom.xml
@@ -109,6 +109,13 @@
   </dependencies>
 
   <build>
+    <testResources>
+      <testResource>
+        <directory>src/test/resources</directory>
+        <filtering>true</filtering>
+      </testResource>
+    </testResources>
+
     <plugins>
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
@@ -119,6 +126,41 @@
       </plugin>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.10</version>
+        <executions>
+          <execution> <!-- override some ee api -->
+            <id>unpack-ee-api</id>
+            <phase>generate-test-resources</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/ee-api</outputDirectory>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>org.apache.tomee</groupId>
+                  <artifactId>javaee-api</artifactId>
+                  <version>7.0-1</version>
+                  <type>zip</type>
+                  <excludes>
+                    LICENSE,NOTICE,README.txt,
+                    geronimo-jaspic_1.0_spec*jar,
+                    geronimo-jsp_2.2_spec*.jar,
+                    javaee-api*.jar,
+                    tomcat-el-api*.jar,
+                    tomcat-servlet-api*.jar,
+                    tomcat-websocket-api*.jar,
+                    geronimo-json_1.0_spec*.jar
+                  </excludes>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-enforcer-plugin</artifactId>
         <executions>
           <execution>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/498aff8b/johnzon-websocket/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/resources/arquillian.xml b/johnzon-websocket/src/test/resources/arquillian.xml
index 1f2d9d0..db21eae 100644
--- a/johnzon-websocket/src/test/resources/arquillian.xml
+++ b/johnzon-websocket/src/test/resources/arquillian.xml
@@ -32,6 +32,11 @@
       <property name="cleanOnStartUp">true</property>
       <property name="dir">target/apache-tomee-remote</property>
       <property name="appWorkingDir">target/arquillian-test-working-dir</property>
+      <!-- override jsonp api -->
+      <property name="lib">${project.build.directory}/ee-api</property>
+      <property name="additionalLibs">
+        mvn:org.apache.geronimo.specs:geronimo-json_1.1_spec:${jsonspecversion}
+      </property>
     </configuration>
   </container>
 </arquillian>


[11/26] johnzon git commit: dont forget to remove javaee-api

Posted by st...@apache.org.
dont forget to remove javaee-api


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/4b3ddf55
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/4b3ddf55
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/4b3ddf55

Branch: refs/heads/master
Commit: 4b3ddf55b4fb6f831244945648104eb4d6efa226
Parents: cedcf0c
Author: rmannibucau <rm...@apache.org>
Authored: Tue Nov 22 22:32:04 2016 +0100
Committer: rmannibucau <rm...@apache.org>
Committed: Tue Nov 22 22:32:04 2016 +0100

----------------------------------------------------------------------
 johnzon-websocket/src/test/resources/arquillian.xml | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/4b3ddf55/johnzon-websocket/src/test/resources/arquillian.xml
----------------------------------------------------------------------
diff --git a/johnzon-websocket/src/test/resources/arquillian.xml b/johnzon-websocket/src/test/resources/arquillian.xml
index 567fc50..8274edf 100644
--- a/johnzon-websocket/src/test/resources/arquillian.xml
+++ b/johnzon-websocket/src/test/resources/arquillian.xml
@@ -35,6 +35,7 @@
       <!-- override jsonp api -->
       <property name="lib">${project.build.directory}/ee-api</property>
       <property name="additionalLibs">
+        remove:javaee-api
         mvn:org.apache.geronimo.specs:geronimo-json_1.1_spec:${geronimo-jsonp.version}
       </property>
     </configuration>


[15/26] johnzon git commit: JOHNZON-95 fixed JsonPointer#add for complex objects

Posted by st...@apache.org.
JOHNZON-95 fixed JsonPointer#add for complex objects


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/24fe453b
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/24fe453b
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/24fe453b

Branch: refs/heads/master
Commit: 24fe453bd7bed2faa6a812040cbbdf5440a4bcf7
Parents: b0c1966
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Thu Nov 24 18:28:10 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Fri Nov 25 14:05:54 2016 +0100

----------------------------------------------------------------------
 .../apache/johnzon/core/JsonPointerImpl.java    | 40 ++++++++++-----
 .../apache/johnzon/core/JsonPointerTest.java    | 51 ++++++++++++++++++++
 2 files changed, 78 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/24fe453b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
----------------------------------------------------------------------
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 25e5ceb..8057f95 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
@@ -35,7 +35,7 @@ import java.util.Map;
 public class JsonPointerImpl implements JsonPointer {
 
     private final String jsonPointer;
-    private final List<String> referenceTokens = new ArrayList<String>();
+    private final List<String> referenceTokens = new ArrayList<>();
     private final String lastReferenceToken;
 
     /**
@@ -150,11 +150,7 @@ public class JsonPointerImpl implements JsonPointer {
             return (JsonStructure) value;
         }
 
-        if (target instanceof JsonObject) {
-            return add((JsonObject) target, value);
-        } else {
-            return add((JsonArray) target, value);
-        }
+        return addInternal(target, value);
     }
 
     /**
@@ -173,7 +169,7 @@ public class JsonPointerImpl implements JsonPointer {
     public JsonObject add(JsonObject target, JsonValue value) {
         validateAdd(target);
 
-        return (JsonObject) add(target, 1, referenceTokens.size() - 1, value);
+        return addInternal(target, value);
     }
 
     /**
@@ -192,7 +188,7 @@ public class JsonPointerImpl implements JsonPointer {
     public JsonArray add(JsonArray target, JsonValue value) {
         validateAdd(target);
 
-        return (JsonArray) add(target, 1, referenceTokens.size() - 1, value);
+        return addInternal(target, value);
     }
 
     /**
@@ -336,7 +332,14 @@ public class JsonPointerImpl implements JsonPointer {
         }
     }
 
-    private JsonValue add(JsonValue jsonValue, int currentPosition, int referencePosition, JsonValue newValue) {
+    private <T extends JsonStructure> T addInternal(T jsonValue, JsonValue newValue) {
+        List<String> currentPath = new ArrayList<>();
+        currentPath.add("");
+
+        return (T) addInternal(jsonValue, newValue, currentPath);
+    }
+
+    private JsonValue addInternal(JsonValue jsonValue, JsonValue newValue, List<String> currentPath) {
         if (jsonValue instanceof JsonObject) {
             JsonObject jsonObject = (JsonObject) jsonValue;
             JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
@@ -345,8 +348,13 @@ public class JsonPointerImpl implements JsonPointer {
                 objectBuilder.add(lastReferenceToken, newValue);
             } else {
                 for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
-                    objectBuilder.add(entry.getKey(), add(entry.getValue(), currentPosition + 1, referencePosition, newValue));
-                    if (currentPosition == referencePosition) {
+
+                    currentPath.add(entry.getKey());
+                    objectBuilder.add(entry.getKey(), addInternal(entry.getValue(), newValue, currentPath));
+                    currentPath.remove(entry.getKey());
+
+                    if (currentPath.size() == referenceTokens.size() - 1 &&
+                        currentPath.get(currentPath.size() - 1).equals(referenceTokens.get(referenceTokens.size() - 2))) {
                         objectBuilder.add(lastReferenceToken, newValue);
                     }
                 }
@@ -357,7 +365,9 @@ public class JsonPointerImpl implements JsonPointer {
             JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
 
             int arrayIndex = -1;
-            if (currentPosition == referencePosition) {
+            if (currentPath.size() == referenceTokens.size() - 1 &&
+                currentPath.get(currentPath.size() - 1).equals(referenceTokens.get(referenceTokens.size() - 2))) {
+
                 arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, true);
             }
 
@@ -369,7 +379,11 @@ public class JsonPointerImpl implements JsonPointer {
                 if (i == jsonArraySize) {
                     break;
                 }
-                arrayBuilder.add(add(jsonArray.get(i), currentPosition + 1, referencePosition, newValue));
+
+                String path = String.valueOf(i);
+                currentPath.add(path);
+                arrayBuilder.add(addInternal(jsonArray.get(i), newValue, currentPath));
+                currentPath.remove(path);
             }
             return arrayBuilder.build();
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/24fe453b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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 57d52b9..5c345e8 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
@@ -26,12 +26,15 @@ import javax.json.JsonException;
 import javax.json.JsonObject;
 import javax.json.JsonPointer;
 import javax.json.JsonReader;
+import javax.json.JsonString;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
 import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertTrue;
 
 public class JsonPointerTest {
@@ -607,6 +610,54 @@ public class JsonPointerTest {
         assertFalse(jsonPointer1.equals(jsonPointer2));
     }
 
+    @Test
+    public void testAddObjectMemberToNestedObject() {
+
+        JsonObject object = Json.createObjectBuilder()
+                                .add("object1", Json.createObjectBuilder()
+                                                    .add("key1", "value1"))
+                                .add("object2", Json.createObjectBuilder()
+                                                    .add("key2", "value2"))
+                                .build();
+
+        JsonPointerImpl pointer = new JsonPointerImpl("/object2/key3");
+
+        JsonObject pointered = pointer.add(object, new JsonStringImpl("value3"));
+        assertNotNull(pointered);
+        assertNotSame(object, pointered);
+
+        JsonObject object1 = pointered.getJsonObject("object1");
+        assertEquals(1, object1.size());
+        assertEquals("value1", object1.getString("key1"));
+
+        JsonObject object2 = pointered.getJsonObject("object2");
+        assertEquals(2, object2.size());
+        assertEquals("value2", object2.getString("key2"));
+        assertEquals("value3", object2.getString("key3"));
+    }
+
+    @Test
+    public void testGetValueFromNestedObject() {
+
+        JsonObject family = Json.createObjectBuilder()
+                                .add("family", Json.createObjectBuilder()
+                                                   .add("father", Json.createObjectBuilder()
+                                                                      .add("name", "Anakin Skywalker"))
+                                                   .add("mother", Json.createObjectBuilder()
+                                                                      .add("name", "Padme Amidala"))
+                                                   .add("children", Json.createArrayBuilder()
+                                                                        .add(Json.createObjectBuilder()
+                                                                                 .add("name", "Luke Skywalker"))
+                                                                        .add(Json.createObjectBuilder()
+                                                                                 .add("name", "Leia Skywalker"))))
+                                .build();
+
+        JsonValue padme = new JsonPointerImpl("/family/mother/name").getValue(family);
+        assertTrue("padme must be instanceOf JsonString", padme instanceof JsonString);
+        assertEquals("Padme Amidala", ((JsonString) padme).getString());
+    }
+
+
     private JsonStructure getJsonDocument() {
         JsonReader reader = Json.createReaderFactory(Collections.<String, Object>emptyMap()).createReader(
                 Thread.currentThread().getContextClassLoader().getResourceAsStream("json/jsonPointerTest.json"));


[04/26] johnzon git commit: Update geronimo-json-spec from 1.0 to 1.1, add JsonPointer encode and decode methods

Posted by st...@apache.org.
Update geronimo-json-spec from 1.0 to 1.1, add JsonPointer encode and decode methods


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/d8a56d05
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/d8a56d05
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/d8a56d05

Branch: refs/heads/master
Commit: d8a56d05cd1d22c85ecad781cdbef4f01f77697c
Parents: 28748ff
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 21:26:02 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:26:02 2016 +0100

----------------------------------------------------------------------
 .../apache/johnzon/core/JsonPointerUtil.java    | 24 +++--
 .../johnzon/core/JsonPointerUtilTest.java       | 97 +++++++++++++++++++-
 johnzon-distribution/pom.xml                    |  3 +-
 3 files changed, 113 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/d8a56d05/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
index 276fb42..91bc9c2 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerUtil.java
@@ -20,18 +20,30 @@ package org.apache.johnzon.core;
 
 public class JsonPointerUtil {
 
+    private JsonPointerUtil() {
+
+    }
+
     /**
-     *
-     * @param s
-     * @return
+     * Transforms "~" to "~0" and then "/" to "~1"
      */
     public static String encode(String s) {
-        return null;
+        if (s == null || s.length() == 0) {
+            return s;
+        }
+
+        return s.replace("~", "~0").replace("/", "~1");
     }
 
+    /**
+     * Transforms "~1" to "/" and then "~0" to "~",
+     */
     public static String decode(String s) {
-        return null;
-    }
+        if (s == null || s.length() == 0) {
+            return s;
+        }
 
+        return s.replace("~1", "/").replace("~0", "~");
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d8a56d05/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
index 226d742..73b0e01 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerUtilTest.java
@@ -1,7 +1,98 @@
+/*
+ * 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;
 
-/**
- * @author Armin Hasler (02eex458)
- */
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
 public class JsonPointerUtilTest {
+
+    @Test
+    public void testEncodeNull() {
+        assertNull(JsonPointerUtil.encode(null));
+    }
+
+    @Test
+    public void testEncodeEmptyString() {
+        String encodedString = JsonPointerUtil.encode("");
+        assertEquals("", encodedString);
+    }
+
+    @Test
+    public void testEncodeNoTransformation() {
+        String encodedString = JsonPointerUtil.encode("TestString");
+        assertEquals("TestString", encodedString);
+    }
+
+    @Test
+    public void testEncodeFirstTransformation() {
+        String encodedString = JsonPointerUtil.encode("~");
+        assertEquals("~0", encodedString);
+    }
+
+    @Test
+    public void testEncodeSecondTransformation() {
+        String encodedString = JsonPointerUtil.encode("/");
+        assertEquals("~1", encodedString);
+    }
+
+    @Test
+    public void testEncodeWholeTransformation() {
+        String decodedString = JsonPointerUtil.encode("~/");
+        assertEquals("~0~1", decodedString);
+    }
+
+    @Test
+    public void testDecodeNull() {
+        assertNull(JsonPointerUtil.decode(null));
+    }
+
+    @Test
+    public void testDecodeEmptyString() {
+        String decodedString = JsonPointerUtil.decode("");
+        assertEquals("", decodedString);
+    }
+
+    @Test
+    public void testDecodeNoTransformation() {
+        String decodedString = JsonPointerUtil.decode("TestString");
+        assertEquals("TestString", decodedString);
+    }
+
+    @Test
+    public void testDecodeFirstTransformation() {
+        String decodedString = JsonPointerUtil.decode("~1");
+        assertEquals("/", decodedString);
+    }
+
+    @Test
+    public void testDecodeSecondTransformation() {
+        String decodedString = JsonPointerUtil.decode("~0");
+        assertEquals("~", decodedString);
+    }
+
+    @Test
+    public void testDecodeWholeTransformation() {
+        String decodedString = JsonPointerUtil.decode("~01");
+        assertEquals("~1", decodedString);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/d8a56d05/johnzon-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-distribution/pom.xml b/johnzon-distribution/pom.xml
index c0e6e26..f6f468e 100644
--- a/johnzon-distribution/pom.xml
+++ b/johnzon-distribution/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <artifactId>johnzon</artifactId>
     <groupId>org.apache.johnzon</groupId>
-    <version>0.9.6-SNAPSHOT</version>
+    <version>0.9.4-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
@@ -49,7 +49,6 @@
       <scope>compile</scope>
       <classifier>javadoc</classifier>
     </dependency>
-
     <dependency>
       <groupId>org.apache.johnzon</groupId>
       <artifactId>johnzon-core</artifactId>


[02/26] johnzon git commit: JOHNZON-96 upgrade missing jsonp-spec dependencies

Posted by st...@apache.org.
JOHNZON-96 upgrade missing jsonp-spec dependencies


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/c378b9b0
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/c378b9b0
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/c378b9b0

Branch: refs/heads/master
Commit: c378b9b059d6e3035418edb33a1a446b8b9967c3
Parents: d396c5b
Author: Mark Struberg <st...@apache.org>
Authored: Tue Nov 22 21:02:17 2016 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Tue Nov 22 21:02:17 2016 +0100

----------------------------------------------------------------------
 johnzon-distribution/pom.xml |  6 +++---
 johnzon-maven-plugin/pom.xml |  2 +-
 pom.xml                      | 15 ++++++++++-----
 3 files changed, 14 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/c378b9b0/johnzon-distribution/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-distribution/pom.xml b/johnzon-distribution/pom.xml
index 2333fa5..c0e6e26 100644
--- a/johnzon-distribution/pom.xml
+++ b/johnzon-distribution/pom.xml
@@ -31,20 +31,20 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
       <version>${jsonspecversion}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
       <version>${jsonspecversion}</version>
       <scope>compile</scope>
       <classifier>sources</classifier>
     </dependency>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
       <version>${jsonspecversion}</version>
       <scope>compile</scope>
       <classifier>javadoc</classifier>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/c378b9b0/johnzon-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/johnzon-maven-plugin/pom.xml b/johnzon-maven-plugin/pom.xml
index 60e474d..1feaee6 100644
--- a/johnzon-maven-plugin/pom.xml
+++ b/johnzon-maven-plugin/pom.xml
@@ -38,7 +38,7 @@
   <dependencies>
     <dependency>
       <groupId>org.apache.geronimo.specs</groupId>
-      <artifactId>geronimo-json_1.0_spec</artifactId>
+      <artifactId>geronimo-json_1.1_spec</artifactId>
       <version>${jsonspecversion}</version>
       <scope>compile</scope>
     </dependency>

http://git-wip-us.apache.org/repos/asf/johnzon/blob/c378b9b0/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f8ca1f8..1a442fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -625,12 +625,14 @@
       <id>rmannibucau</id>
       <name>Romain Manni-Bucau</name>
       <email>rmannibucau AT apache.org</email>
+      <roles><role>PMC</role></roles>
     </developer>
 
     <developer>
       <id>jlmonteiro</id>
       <name>Jean-Louis Monteiro</name>
       <email>jlmonteiro AT apache.org</email>
+      <roles><role>PMC</role></roles>
     </developer>
 
     <developer>
@@ -638,20 +640,22 @@
       <name>Mark Struberg</name>
       <email>struberg AT apache.org</email>
       <roles>
-        <role>Champion</role>
+        <role>PMC</role>
       </roles>
     </developer>
 
     <developer>
-      <id>gpetracek</id>
-      <name>Gerhard Petracek</name>
-      <email>gpetracek AT apache.org</email>
+      <id>rsandtner</id>
+      <name>Reinhard Sandtner</name>
+      <email>rsandtner AT apache.org</email>
+      <roles><role>PMC</role></roles>
     </developer>
 
     <developer>
       <id>dblevins</id>
       <name>David Blevins</name>
       <email>dblevins AT apache.org</email>
+      <roles><role>PMC</role></roles>
     </developer>
 
     <developer>
@@ -667,13 +671,14 @@
       <properties>
         <picUrl>http://www.gravatar.com/avatar/af23e69dbed585db0ce6445d0adb4985.png</picUrl>
       </properties>
+      <roles><role>PMC</role></roles>
     </developer>
   </developers>
 
   <contributors>
     <contributor>
        <name>Thiago Veronezi</name>
-  </contributor>
+    </contributor>
      <contributor>
        <name>Karl Grosse</name>
     </contributor>


[21/26] johnzon git commit: JOHNZON-96 upgrade to last version of the JSON-P-1.1 spec

Posted by st...@apache.org.
JOHNZON-96 upgrade to last version of the JSON-P-1.1 spec

WIP.
Make it compile again.
Tests still broken.
Some methods still missing.


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/184e477c
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/184e477c
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/184e477c

Branch: refs/heads/master
Commit: 184e477c571604b0ff94454706ba6425b7808927
Parents: 6aea7ac
Author: Mark Struberg <st...@apache.org>
Authored: Mon Feb 20 22:05:11 2017 +0100
Committer: Mark Struberg <st...@apache.org>
Committed: Mon Feb 20 22:05:11 2017 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonPatchBuilderImpl.java      |  19 ----
 .../org/apache/johnzon/core/JsonPatchImpl.java  |   3 +-
 .../apache/johnzon/core/JsonPointerImpl.java    |  10 ++
 .../apache/johnzon/core/JsonProviderImpl.java   | 105 +++++++++++++------
 .../apache/johnzon/core/JsonPointerTest.java    |   6 +-
 5 files changed, 90 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/184e477c/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
index 1dc5ae4..0d8fe55 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchBuilderImpl.java
@@ -20,7 +20,6 @@ import javax.json.JsonArray;
 import javax.json.JsonObject;
 import javax.json.JsonPatch;
 import javax.json.JsonPatchBuilder;
-import javax.json.JsonStructure;
 import javax.json.JsonValue;
 import java.util.ArrayList;
 import java.util.List;
@@ -54,24 +53,6 @@ class JsonPatchBuilderImpl implements JsonPatchBuilder {
     }
 
 
-
-    //X TODO this should get simplified to only one method like JsonPatch
-    @Override
-    public JsonStructure apply(JsonStructure target) {
-        return build().apply(target);
-    }
-
-    @Override
-    public JsonObject apply(JsonObject target) {
-        return build().apply(target);
-    }
-
-    @Override
-    public JsonArray apply(JsonArray target) {
-        return build().apply(target);
-    }
-
-
     @Override
     public JsonPatchBuilder add(String path, JsonValue value) {
         return addOperation(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,

http://git-wip-us.apache.org/repos/asf/johnzon/blob/184e477c/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
----------------------------------------------------------------------
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 813dba0..ae45792 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
@@ -114,7 +114,8 @@ class JsonPatchImpl implements JsonPatch {
     }
 
 
-    JsonArray toJsonArray() {
+    @Override
+    public JsonArray toJsonArray() {
 
         JsonArrayBuilder builder = Json.createArrayBuilder();
         for (PatchValue patch : patches) {

http://git-wip-us.apache.org/repos/asf/johnzon/blob/184e477c/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
----------------------------------------------------------------------
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 0b01c3d..b674ad9 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
@@ -116,6 +116,16 @@ public class JsonPointerImpl implements JsonPointer {
         return jsonValue;
     }
 
+    @Override
+    public boolean containsValue(JsonStructure target) {
+        try {
+            getValue(target);
+            return true;
+        } catch (JsonException je) {
+            return false;
+        }
+    }
+
     /**
      * Adds or replaces a value at the referenced location in the specified
      * {@code target} with the specified {@code value}.

http://git-wip-us.apache.org/repos/asf/johnzon/blob/184e477c/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
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 4b011a7..9d105fa 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
@@ -23,17 +23,24 @@ import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Serializable;
 import java.io.Writer;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
 import java.util.Map;
 
 import javax.json.JsonArray;
 import javax.json.JsonArrayBuilder;
 import javax.json.JsonBuilderFactory;
+import javax.json.JsonMergePatch;
+import javax.json.JsonNumber;
+import javax.json.JsonObject;
 import javax.json.JsonObjectBuilder;
 import javax.json.JsonPatch;
 import javax.json.JsonPatchBuilder;
 import javax.json.JsonPointer;
 import javax.json.JsonReader;
 import javax.json.JsonReaderFactory;
+import javax.json.JsonString;
 import javax.json.JsonStructure;
 import javax.json.JsonValue;
 import javax.json.JsonWriter;
@@ -121,35 +128,90 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
     public JsonBuilderFactory createBuilderFactory(final Map<String, ?> stringMap) {
         return DELEGATE.createBuilderFactory(stringMap);
     }
+    
+    @Override
+    public JsonPatchBuilder createPatchBuilder() {
+        return DELEGATE.createPatchBuilder();
+    }
 
     @Override
-    public JsonPointer createJsonPointer(String path) {
-        return DELEGATE.createJsonPointer(path);
+    public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
+        return DELEGATE.createPatchBuilder(initialData);
     }
 
     @Override
-    public JsonPatch createPatch(JsonStructure source, JsonStructure target) {
-        return DELEGATE.createPatch(source, target);
+    public JsonObjectBuilder createObjectBuilder(JsonObject jsonObject) {
+        return DELEGATE.createObjectBuilder(jsonObject);
     }
 
     @Override
-    public JsonPatchBuilder createPatchBuilder() {
-        return DELEGATE.createPatchBuilder();
+    public JsonObjectBuilder createObjectBuilder(Map<String, Object> map) {
+        return DELEGATE.createObjectBuilder(map);
     }
 
     @Override
-    public JsonPatchBuilder createPatchBuilder(JsonArray initialData) {
-        return DELEGATE.createPatchBuilder(initialData);
+    public JsonArrayBuilder createArrayBuilder(JsonArray initialData) {
+        return DELEGATE.createArrayBuilder(initialData);
+    }
+
+    @Override
+    public JsonArrayBuilder createArrayBuilder(Collection<Object> initialData) {
+        return DELEGATE.createArrayBuilder(initialData);
+    }
+
+    @Override
+    public JsonPointer createPointer(String path) {
+        return DELEGATE.createPointer(path);
+    }
+
+    @Override
+    public JsonString createValue(String value) {
+        return DELEGATE.createValue(value);
+    }
+
+    @Override
+    public JsonNumber createValue(int value) {
+        return DELEGATE.createValue(value);
+    }
+
+    @Override
+    public JsonNumber createValue(long value) {
+        return DELEGATE.createValue(value);
     }
 
     @Override
-    public JsonValue createMergePatch(JsonValue source, JsonValue target) {
-        return DELEGATE.createMergePatch(source, target);
+    public JsonNumber createValue(double value) {
+        return DELEGATE.createValue(value);
     }
 
     @Override
-    public JsonValue mergePatch(JsonValue source, JsonValue patch) {
-        return DELEGATE.mergePatch(source, patch);
+    public JsonNumber createValue(BigDecimal value) {
+        return DELEGATE.createValue(value);
+    }
+
+    @Override
+    public JsonNumber createValue(BigInteger value) {
+        return DELEGATE.createValue(value);
+    }
+
+    @Override
+    public JsonPatch createPatch(JsonArray array) {
+        return DELEGATE.createPatch(array);
+    }
+
+    @Override
+    public JsonPatch createDiff(JsonStructure source, JsonStructure target) {
+        return DELEGATE.createDiff(source, target);
+    }
+
+    @Override
+    public JsonMergePatch createMergePatch(JsonValue patch) {
+        return DELEGATE.createMergePatch(patch);
+    }
+
+    @Override
+    public JsonMergePatch createMergeDiff(JsonValue source, JsonValue target) {
+        return DELEGATE.createMergeDiff(source, target);
     }
 
     static class JsonProviderDelegate extends JsonProvider {
@@ -235,16 +297,6 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
         }
 
         @Override
-        public JsonPointer createJsonPointer(String path) {
-            return new JsonPointerImpl(path);
-        }
-
-        @Override
-        public JsonPatch createPatch(JsonStructure source, JsonStructure target) {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
-        }
-
-        @Override
         public JsonPatchBuilder createPatchBuilder() {
             return new JsonPatchBuilderImpl();
         }
@@ -254,14 +306,7 @@ public class JsonProviderImpl extends JsonProvider implements Serializable {
             return new JsonPatchBuilderImpl(initialData);
         }
 
-        @Override
-        public JsonValue createMergePatch(JsonValue source, JsonValue target) {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
-        }
+        //X TODO add missing methods
 
-        @Override
-        public JsonValue mergePatch(JsonValue source, JsonValue patch) {
-            throw new UnsupportedOperationException("TODO JSON-P 1.1");
-        }
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/184e477c/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
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 5c345e8..acab1c9 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
@@ -83,7 +83,7 @@ public class JsonPointerTest {
             assertEquals("1", result.toString());
         }
         {
-            JsonPointer jsonPointer = Json.createJsonPointer("/a~1b");
+            JsonPointer jsonPointer = Json.createPointer("/a~1b");
             JsonValue result = jsonPointer.getValue(jsonDocument);
             assertEquals("1", result.toString());
         }
@@ -108,7 +108,7 @@ public class JsonPointerTest {
             assertEquals("3", result.toString());
         }
         {
-            JsonPointer jsonPointer = Json.createJsonPointer("/e^f");
+            JsonPointer jsonPointer = Json.createPointer("/e^f");
             JsonValue result = jsonPointer.getValue(jsonDocument);
             assertEquals("3", result.toString());
         }
@@ -124,7 +124,7 @@ public class JsonPointerTest {
             assertEquals("4", result.toString());
         }
         {
-            JsonPointer jsonPointer = Json.createJsonPointer("/g|h");
+            JsonPointer jsonPointer = Json.createPointer("/g|h");
             JsonValue result = jsonPointer.getValue(jsonDocument);
             assertEquals("4", result.toString());
         }