JSON.copy, JSON.buildObject
Project: http://git-wip-us.apache.org/repos/asf/jena/repo Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/e2f53c31 Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/e2f53c31 Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/e2f53c31 Branch: refs/heads/master Commit: e2f53c31174ec79461049a9b6830d22c94859be7 Parents: 9211180 Author: Andy Seaborne <[email protected]> Authored: Thu Feb 2 09:49:37 2017 +0000 Committer: Andy Seaborne <[email protected]> Committed: Thu Feb 2 14:18:32 2017 +0000 ---------------------------------------------------------------------- .../java/org/apache/jena/atlas/json/JSON.java | 31 +++++++++- .../org/apache/jena/atlas/json/JsonBuilder.java | 60 +++++++++++++++++++- .../org/apache/jena/atlas/json/TS_JSON.java | 1 + .../org/apache/jena/atlas/json/TestJson.java | 3 +- .../org/apache/jena/atlas/json/TestJsonAPI.java | 46 +++++++++++++++ .../apache/jena/atlas/json/TestJsonBuilder.java | 47 +++++++++++++-- .../org/apache/jena/atlas/json/TestJsonExt.java | 6 +- 7 files changed, 182 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/main/java/org/apache/jena/atlas/json/JSON.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/main/java/org/apache/jena/atlas/json/JSON.java b/jena-arq/src/main/java/org/apache/jena/atlas/json/JSON.java index 78fa7a4..2ddc912 100644 --- a/jena-arq/src/main/java/org/apache/jena/atlas/json/JSON.java +++ b/jena-arq/src/main/java/org/apache/jena/atlas/json/JSON.java @@ -19,6 +19,7 @@ package org.apache.jena.atlas.json; import java.io.* ; +import java.util.function.Consumer; import org.apache.jena.atlas.io.IO ; import org.apache.jena.atlas.io.IndentedLineBuffer ; @@ -84,9 +85,8 @@ public class JSON IO.exception("IOException: " + filename, ex) ; return null ; } - } - + // Hide the reader versions - not encouraged due to charset problems. private static JsonObject _parse(Reader r) { @@ -173,4 +173,31 @@ public class JSON public static void write(JsonValue jValue) { write(IndentedWriter.stdout, jValue) ; } + + // General functions for working with JSON + + /** Create a safe copy of a {@link JsonValue}. + * <p> + * If the JsonValue is a structure (object or array), copy the structure recursively. + * <p> + * If the JsonValue is a primitive (string, number, boolean or null), + * it is immutable so return the same object. + */ + public static JsonValue copy(JsonValue arg) { + return JsonBuilder.copy(arg); + } + + /** Build a JsonObject. The outer object is created and then the {@code setup} function called to fill in the contents. + * <pre> + * buildObject(builder->{ + * builder.pair("key", 1234); + * }); + * </pre> + * + * @param setup + * @return JsonObject + */ + public static JsonObject buildObject(Consumer<JsonBuilder> setup) { + return JsonBuilder.buildObject(setup); + } } http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonBuilder.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonBuilder.java b/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonBuilder.java index 7d2713f..8183a9c 100644 --- a/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonBuilder.java +++ b/jena-arq/src/main/java/org/apache/jena/atlas/json/JsonBuilder.java @@ -22,6 +22,7 @@ import java.math.BigDecimal ; import java.util.ArrayDeque ; import java.util.Deque ; import java.util.Objects; +import java.util.function.Consumer; import org.apache.jena.atlas.logging.Log ; @@ -47,8 +48,65 @@ public class JsonBuilder { public static JsonBuilder create() { return new JsonBuilder() ; } + /** Create a builder from a {@link JsonValue}. + * <p>If the argument is an object or array, use it to initailize the builder. + * <p>If the argument is a JSON primitive (string, number, boolean or null), + * <p>Otherwise thrown {@link IllegalArgumentException}. + */ + public static JsonBuilder createFrom(JsonValue arg) { + if ( arg.isObject() ) { + JsonObject obj = arg.getAsObject() ; + JsonBuilder builder = JsonBuilder.create() ; + builder.startObject() ; + obj.forEach((k,v) -> builder.key(k).value(copy(v))) ; + builder.finishObject() ; + return builder ; + } + if ( arg.isArray() ) { + JsonArray array = arg.getAsArray() ; + JsonBuilder builder = JsonBuilder.create() ; + builder.startArray() ; + array.forEach((a)->builder.value(copy(a))) ; + builder.finishArray() ; + return builder ; + } + throw new IllegalArgumentException("Not a JSON object or JSON array; "+arg); + } + + + /** Create a safe copy of a {@link JsonValue}. + * <p> + * If the JsonValue is a structure (object or array), copy the structure recursively. + * <p> + * If the JsonValue is a primitive (string, number, boolean or null), + * it is immutable so return the same object. + */ + public static JsonValue copy(JsonValue arg) { + if ( ! arg.isArray() && ! arg.isObject() ) + return arg; + return createFrom(arg).build(); + } + + // An unlikely-to-be-used label to help check object alignment + private static String LABEL = "%|%object%|%" ; + + /** Build a JsonObject. The outer object is created and then the {@code setup} function called to fill in the contents. + * <pre> + * buildObject(builder->{ + * builder.pair("key", 1234); + * }); + * </pre> + * + * @param setup + * @return JsonObject + */ + public static JsonObject buildObject(Consumer<JsonBuilder> setup) { + JsonBuilder b = JsonBuilder.create().startObject(LABEL) ; + setup.accept(b); + return b.finishObject(LABEL).build().getAsObject() ; + } + public JsonBuilder() { - } public JsonValue build() { http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/test/java/org/apache/jena/atlas/json/TS_JSON.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/json/TS_JSON.java b/jena-arq/src/test/java/org/apache/jena/atlas/json/TS_JSON.java index c2f2cb4..4338d37 100644 --- a/jena-arq/src/test/java/org/apache/jena/atlas/json/TS_JSON.java +++ b/jena-arq/src/test/java/org/apache/jena/atlas/json/TS_JSON.java @@ -27,6 +27,7 @@ import org.junit.runners.Suite ; , TestJsonExt.class , TestJsonWriter.class , TestJsonBuilder.class + , TestJsonAPI.class }) public class TS_JSON {} http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJson.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJson.java b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJson.java index 3b6398d..31169dd 100644 --- a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJson.java +++ b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJson.java @@ -19,10 +19,9 @@ package org.apache.jena.atlas.json; import static org.apache.jena.atlas.json.LibJsonTest.read ; -import org.apache.jena.atlas.junit.BaseTest ; import org.junit.Test ; -public class TestJson extends BaseTest +public class TestJson { @Test public void js_value_1() { http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonAPI.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonAPI.java b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonAPI.java new file mode 100644 index 0000000..36b70ac --- /dev/null +++ b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonAPI.java @@ -0,0 +1,46 @@ +/* + * 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.jena.atlas.json; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; + +import org.junit.Test ; + + +public class TestJsonAPI +{ + @Test public void jsonAPI_01() { + JsonObject obj = JSON.parse("{ key1: 'str1' , key2: [ 1 , 2 ] }") ; + assertEquals(2, obj.size()); + } + + @Test public void jsonAPI_02() { + JsonObject obj = JSON.parse("{ key1: 'str1' , key2: [ 1 , 2 ] }") ; + JsonObject obj2 = (JsonObject)JSON.copy(obj); + assertNotSame(obj, obj2); + assertEquals(obj, obj2); + } + + @Test public void jsonAPI_03() { + JsonValue jv1 = JSON.parseAny("2") ; + JsonValue jv2 = JSON.copy(jv1); + assertSame(jv1, jv2); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonBuilder.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonBuilder.java b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonBuilder.java index 505e0fa..a43fcf3 100644 --- a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonBuilder.java +++ b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonBuilder.java @@ -22,10 +22,6 @@ import org.apache.jena.atlas.junit.BaseTest ; import org.junit.Test ; public class TestJsonBuilder extends BaseTest{ - // The Jena JSON parser is more livberal than strict JSON to make embedding easier. - // * Keys do not need quotes - // * Strings can use '' - @Test public void jsonBuild01() { JsonValue x = JSON.parseAny("{ }") ; JsonBuilder builder = new JsonBuilder() ; @@ -79,8 +75,32 @@ public class TestJsonBuilder extends BaseTest{ JsonValue v = builder.build() ; assertEquals(x,v) ; } - + @Test public void jsonBuild06() { + JsonValue x = JSON.parseAny("{ a: 'B'}") ; + JsonBuilder builder = new JsonBuilder() ; + builder.startObject().pair("a", "B").finishObject() ; + JsonValue v = builder.build() ; + assertEquals(x,v) ; + } + + @Test public void jsonBuild07() { + JsonValue x = JSON.parseAny("{ a: 123}") ; + JsonBuilder builder = new JsonBuilder() ; + builder.startObject().pair("a", 123).finishObject() ; + JsonValue v = builder.build() ; + assertEquals(x,v) ; + } + + @Test public void jsonBuild08() { + JsonValue x = JSON.parseAny("{ a: true}") ; + JsonBuilder builder = new JsonBuilder() ; + JsonValue jv = new JsonBoolean(true); + builder.startObject().pair("a", jv).finishObject() ; + JsonValue v = builder.build() ; + assertEquals(x,v) ; + } + @Test(expected=JsonException.class) public void jsonBuildErr00() { JsonBuilder builder = new JsonBuilder() ; @@ -107,5 +127,20 @@ public class TestJsonBuilder extends BaseTest{ builder.startObject("A") ; builder.finishObject("B") ; } - + + @Test + public void jsonBuildObject_01() { + JsonObject obj = JsonBuilder.buildObject(b->{}); + assertTrue(obj.entrySet().isEmpty()); + } + + @Test + public void jsonBuildObject_02() { + JsonValue x = JSON.parseAny("{ key1: 'value1', key2: 'value2' }") ; + JsonObject obj = JsonBuilder.buildObject(b->{ + b.pair("key1", "value1") + .pair("key2", "value2"); + }); + assertEquals(x, obj); + } } http://git-wip-us.apache.org/repos/asf/jena/blob/e2f53c31/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonExt.java ---------------------------------------------------------------------- diff --git a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonExt.java b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonExt.java index 06b5adf..52f135c 100644 --- a/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonExt.java +++ b/jena-arq/src/test/java/org/apache/jena/atlas/json/TestJsonExt.java @@ -26,9 +26,13 @@ import org.apache.jena.atlas.json.JsonString ; import org.apache.jena.atlas.junit.BaseTest ; import org.junit.Test ; -/** Test that are of extension of JSON */ +/** Tests that are of extensions of JSON */ public class TestJsonExt extends BaseTest { + // The Jena JSON parser is more liberal than strict JSON to make embedding easier. + // * Keys do not need quotes + // * Strings can use '' + // -------- Non-standard things. @Test public void js_value_ext_1()
