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 <[email protected]> Authored: Wed Nov 23 21:50:45 2016 +0100 Committer: Reinhard Sandtner <[email protected]> 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()); + } + +}
