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/10/16 21:35:21 UTC

johnzon git commit: JOHNZON-139 implement getObject, getArray and getValue for JsonParser

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 <st...@apache.org>
Authored: Mon Oct 16 23:31:39 2017 +0200
Committer: Mark Struberg <st...@apache.org>
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