Repository: johnzon Updated Branches: refs/heads/master 7bbeb16fd -> 05effff6e
JOHNZON-139 implement getObject, getArray and getValue for JsonParser still missing: * skipObject * skipArray * getObjectStream * getArrayStream * getValueStream Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/05effff6 Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/05effff6 Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/05effff6 Branch: refs/heads/master Commit: 05effff6e0a555d1a2c62e65d1891745df028ea7 Parents: 7bbeb16 Author: Mark Struberg <[email protected]> Authored: Mon Oct 16 23:31:39 2017 +0200 Committer: Mark Struberg <[email protected]> Committed: Mon Oct 16 23:31:39 2017 +0200 ---------------------------------------------------------------------- .../apache/johnzon/core/JohnzonJsonParser.java | 8 ++ .../johnzon/core/JohnzonJsonParserImpl.java | 61 ++++++++++++++ .../apache/johnzon/core/JsonInMemoryParser.java | 7 +- .../org/apache/johnzon/core/JsonReaderImpl.java | 84 +++++++++++++------ .../johnzon/core/JsonStreamParserImpl.java | 10 ++- .../org/apache/johnzon/core/JsonParserTest.java | 30 ++++++- .../apache/johnzon/core/JsonReaderImplTest.java | 6 +- .../src/test/resources/json/simple.json | 6 +- .../src/test/resources/json/simple_utf16le.json | Bin 136 -> 232 bytes 9 files changed, 178 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java index b13852b..febff3d 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParser.java @@ -33,6 +33,14 @@ public interface JohnzonJsonParser extends JsonParser { boolean isNotTooLong(); + /** + * @return the _current_ Event. That's the one returned by the previous call to {@link #next()} + * but without propagating the Event pointer to the next entry. + */ + default Event current() { + throw new UnsupportedOperationException("getting the current JsonParser Event is not supported"); + } + public static class JohnzonJsonParserWrapper implements JohnzonJsonParser { private final JsonParser jsonParser; http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java new file mode 100644 index 0000000..5feb3d9 --- /dev/null +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JohnzonJsonParserImpl.java @@ -0,0 +1,61 @@ +/* + * 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.JsonValue; + +/** + * Base parser which handles higher level operations which are + * mixtures of Reader and Parsers like {@code getObject(), getValue(), getArray()} + */ +public abstract class JohnzonJsonParserImpl implements JohnzonJsonParser { + + @Override + public JsonObject getObject() { + Event current = current(); + if (current != Event.START_OBJECT) { + throw new IllegalStateException(current + " doesn't support getObject()"); + } + + JsonReaderImpl jsonReader = new JsonReaderImpl(this, true); + return jsonReader.readObject(); + } + + @Override + public JsonArray getArray() { + Event current = current(); + if (current != Event.START_ARRAY) { + throw new IllegalStateException(current + " doesn't support getArray()"); + } + + JsonReaderImpl jsonReader = new JsonReaderImpl(this, true); + return jsonReader.readArray(); + } + + @Override + public JsonValue getValue() { + Event current = current(); + if (current != Event.START_ARRAY && current != Event.START_OBJECT) { + throw new IllegalStateException(current + " doesn't support getArray()"); + } + + JsonReaderImpl jsonReader = new JsonReaderImpl(this, true); + return jsonReader.readValue(); + } +} http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java index 481ea23..7126e62 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonInMemoryParser.java @@ -31,7 +31,7 @@ import javax.json.JsonValue; import javax.json.JsonValue.ValueType; import javax.json.stream.JsonLocation; -class JsonInMemoryParser implements JohnzonJsonParser { +class JsonInMemoryParser extends JohnzonJsonParserImpl { private final SimpleStack<Iterator<Event>> stack = new SimpleStack<Iterator<Event>>(); @@ -170,6 +170,11 @@ class JsonInMemoryParser implements JohnzonJsonParser { } + @Override + public Event current() { + return currentEvent; + } + private static Event getEvent(final ValueType value) { switch (value) { http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java index e3af4af..02d1d39 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonReaderImpl.java @@ -34,12 +34,26 @@ public class JsonReaderImpl implements JsonReader { private final JohnzonJsonParser parser; private boolean closed = false; + private boolean subStreamReader; + public JsonReaderImpl(final JsonParser parser) { + this(parser, false); + } + + /** + * + * @param parser + * @param subStreamReader {@code true} if the Stream already got started and the first + * operation should not be next() but {@link JohnzonJsonParser#current()} instead. + */ + public JsonReaderImpl(final JsonParser parser, boolean subStreamReader) { if (parser instanceof JohnzonJsonParser) { this.parser = (JohnzonJsonParser) parser; } else { this.parser = new JohnzonJsonParser.JohnzonJsonParserWrapper(parser); } + + this.subStreamReader = subStreamReader; } @Override @@ -54,55 +68,77 @@ public class JsonReaderImpl implements JsonReader { if (!parser.hasNext()) { throw new IllegalStateException("Nothing to read"); } - final JsonParser.Event next = parser.next(); + + + JsonParser.Event next; + if (subStreamReader) { + next = parser.current(); + } else { + next = parser.next(); + } + switch (next) { case START_OBJECT: final JsonObjectBuilder objectBuilder = new JsonObjectBuilderImpl(); parseObject(objectBuilder); - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); } - close(); return objectBuilder.build(); case START_ARRAY: final JsonArrayBuilder arrayBuilder = new JsonArrayBuilderImpl(); parseArray(arrayBuilder); - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); } - close(); return arrayBuilder.build(); case VALUE_STRING: - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); - } final JsonStringImpl string = new JsonStringImpl(parser.getString()); - close(); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); + } return string; case VALUE_FALSE: - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); } - close(); return JsonValue.FALSE; case VALUE_TRUE: - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); } - close(); return JsonValue.TRUE; case VALUE_NULL: - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); } - close(); return JsonValue.NULL; case VALUE_NUMBER: - if (parser.hasNext()) { - throw new JsonParsingException("Expected end of file", parser.getLocation()); - } final JsonNumber number = new JsonNumberImpl(parser.getBigDecimal()); - close(); + if (!subStreamReader) { + if (parser.hasNext()) { + throw new JsonParsingException("Expected end of file", parser.getLocation()); + } + close(); + } return number; default: close(); http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java index 7011e01..6af101e 100644 --- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java +++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonStreamParserImpl.java @@ -30,7 +30,7 @@ import java.nio.charset.Charset; import java.util.NoSuchElementException; //This class represents either the Json tokenizer and the Json parser. -public class JsonStreamParserImpl implements JsonChars, JohnzonJsonParser { +public class JsonStreamParserImpl extends JohnzonJsonParserImpl implements JsonChars { private final boolean autoAdjust; //the main buffer where the stream will be buffered @@ -345,6 +345,13 @@ public class JsonStreamParserImpl implements JsonChars, JohnzonJsonParser { } @Override + public Event current() { + return previousEvent >= 0 && previousEvent < Event.values().length + ? Event.values()[previousEvent] + : null; + } + + @Override public final Event next() { //main entry, make decision how to handle the current character in the stream @@ -443,6 +450,7 @@ public class JsonStreamParserImpl implements JsonChars, JohnzonJsonParser { } } + protected Event defaultHandling(char c) { if (c == EOF) { throw uexc("End of file hit too early"); http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java ---------------------------------------------------------------------- diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java index e035789..6d57e26 100644 --- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java +++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonParserTest.java @@ -39,6 +39,7 @@ 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.JsonReader; import javax.json.stream.JsonParser; @@ -136,8 +137,24 @@ public class JsonParserTest { assertTrue(parser.hasNext()); final JsonParser.Event event = parser.next(); assertNotNull(event); + assertEquals(JsonParser.Event.KEY_NAME, event); + assertEquals("e", parser.getString()); + } + { + assertTrue(parser.hasNext()); + final JsonParser.Event event = parser.next(); + assertNotNull(event); + assertEquals(Event.START_OBJECT, event); + JsonObject jsonObject = parser.getObject(); + assertEquals("{\"x\":1,\"y\":2}", jsonObject.toString()); + } + { + assertTrue(parser.hasNext()); + final JsonParser.Event event = parser.next(); + assertNotNull(event); assertEquals(JsonParser.Event.END_OBJECT, event); } + { assertFalse(parser.hasNext()); } @@ -228,8 +245,12 @@ public class JsonParserTest { ab.add(new JsonNumberImpl(new BigDecimal(-2))); ob.add("d", ab); + ob.add ("e", Json.createObjectBuilder() + .add("x", 1) + .add("y", 2) + .build()); - final JsonParser parser = Json.createParserFactory(Collections.<String, Object>emptyMap()).createParser(ob.build()); + final JsonParser parser = Json.createParserFactory(Collections.emptyMap()).createParser(ob.build()); assertNotNull(parser); assertSimple(parser); } @@ -243,7 +264,7 @@ public class JsonParserTest { @Test public void simpleAttempting() { - final JsonParser parser = Json.createParser(new AttemptingInputStream("{\"a\": \"b\",\"c\": 4,\"d\": [1,-2]}".getBytes(UTF_8))); + final JsonParser parser = Json.createParser(new AttemptingInputStream("{\"a\": \"b\",\"c\": 4,\"d\": [1,-2], \"e\":{\"x\":1,\"y\":2}}".getBytes(UTF_8))); assertNotNull(parser); assertSimple(parser); } @@ -251,14 +272,15 @@ public class JsonParserTest { @Test public void simpleUTF16LE() { final JsonParser parser = Json.createParserFactory(null).createParser(Thread.currentThread() - .getContextClassLoader().getResourceAsStream("json/simple_utf16le.json"),UTF_16LE); + .getContextClassLoader().getResourceAsStream("json/simple_utf16le.json"), UTF_16LE); assertNotNull(parser); assertSimple(parser); } @Test public void simpleUTF16LEAutoDetect() { - final JsonParser parser = Json.createParserFactory(null).createParser(Thread.currentThread().getContextClassLoader().getResourceAsStream("json/simple_utf16le.json")); + final JsonParser parser = Json.createParserFactory(null).createParser(Thread.currentThread(). + getContextClassLoader().getResourceAsStream("json/simple_utf16le.json")); assertNotNull(parser); assertSimple(parser); } http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/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 eda5979..216610e 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 @@ -81,7 +81,7 @@ public class JsonReaderImplTest { assertNotNull(reader); final JsonObject object = reader.readObject(); assertNotNull(object); - assertEquals(3, object.size()); + assertEquals(4, object.size()); assertEquals("b", object.getString("a")); assertEquals(4, object.getInt("c")); assertThat(object.get("d"), instanceOf(JsonArray.class)); @@ -348,7 +348,7 @@ public class JsonReaderImplTest { assertNotNull(reader); final JsonObject object = reader.readObject(); assertNotNull(object); - assertEquals(3, object.size()); + assertEquals(4, object.size()); assertEquals("b", object.getString("a")); assertEquals(4, object.getInt("c")); assertThat(object.get("d"), instanceOf(JsonArray.class)); @@ -392,7 +392,7 @@ public class JsonReaderImplTest { assertNotNull(reader); final JsonObject object = reader.readObject(); assertNotNull(object); - assertEquals(3, object.size()); + assertEquals(4, object.size()); assertEquals("b", object.getString("a")); assertEquals(4, object.getInt("c")); assertThat(object.get("d"), instanceOf(JsonArray.class)); http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/test/resources/json/simple.json ---------------------------------------------------------------------- diff --git a/johnzon-core/src/test/resources/json/simple.json b/johnzon-core/src/test/resources/json/simple.json index 78be59e..22494f4 100644 --- a/johnzon-core/src/test/resources/json/simple.json +++ b/johnzon-core/src/test/resources/json/simple.json @@ -4,5 +4,9 @@ "d": [ 1, -2 - ] + ], + "e": { + "x": 1, + "y": 2 + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/johnzon/blob/05effff6/johnzon-core/src/test/resources/json/simple_utf16le.json ---------------------------------------------------------------------- diff --git a/johnzon-core/src/test/resources/json/simple_utf16le.json b/johnzon-core/src/test/resources/json/simple_utf16le.json index c2e2137..8c7960e 100644 Binary files a/johnzon-core/src/test/resources/json/simple_utf16le.json and b/johnzon-core/src/test/resources/json/simple_utf16le.json differ
