You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2018/11/22 08:55:17 UTC

[2/2] johnzon git commit: JOHNZON-195 ensure jsongenerator can write pritmitives directly (jsonp 1.1) and it still fails when it writes array items in an object

JOHNZON-195 ensure jsongenerator can write pritmitives directly (jsonp 1.1) and it still fails when it writes array items in an object


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

Branch: refs/heads/master
Commit: 2893743f2846e0e5983d4efb593492e6525ae058
Parents: 54c0b11
Author: Romain Manni-Bucau <rm...@gmail.com>
Authored: Thu Nov 22 09:55:02 2018 +0100
Committer: Romain Manni-Bucau <rm...@gmail.com>
Committed: Thu Nov 22 09:55:02 2018 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonGeneratorFactoryImpl.java  |  8 +-
 .../apache/johnzon/core/JsonGeneratorImpl.java  | 98 +++++++++-----------
 .../johnzon/core/JsonGeneratorImplTest.java     | 33 +++++++
 .../johnzon/core/TestJsonGeneratorFactory.java  |  5 +-
 4 files changed, 84 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/2893743f/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorFactoryImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorFactoryImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorFactoryImpl.java
index 92abbcd..8d1f6ec 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorFactoryImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorFactoryImpl.java
@@ -26,7 +26,6 @@ import java.nio.charset.Charset;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
 
 import javax.json.stream.JsonGenerator;
 import javax.json.stream.JsonGeneratorFactory;
@@ -39,7 +38,6 @@ public class JsonGeneratorFactoryImpl extends AbstractJsonFactory implements Jso
         JsonGenerator.PRETTY_PRINTING, GENERATOR_BUFFER_LENGTH, BUFFER_STRATEGY
     );
     //key caching currently disabled
-    private final ConcurrentMap<String, String> cache = null;//new ConcurrentHashMap<String, String>();
     private final boolean pretty;
     private final BufferStrategy.BufferProvider<char[]> bufferProvider;
 
@@ -59,17 +57,17 @@ public class JsonGeneratorFactoryImpl extends AbstractJsonFactory implements Jso
 
     @Override
     public JsonGenerator createGenerator(final Writer writer) {
-        return new JsonGeneratorImpl(writer, bufferProvider, cache, pretty);
+        return new JsonGeneratorImpl(writer, bufferProvider, pretty);
     }
 
     @Override
     public JsonGenerator createGenerator(final OutputStream out) {
-        return new JsonGeneratorImpl(out, bufferProvider, cache, pretty);
+        return new JsonGeneratorImpl(out, bufferProvider, pretty);
     }
 
     @Override
     public JsonGenerator createGenerator(final OutputStream out, final Charset charset) {
-        return new JsonGeneratorImpl(out,charset, bufferProvider, cache, pretty);
+        return new JsonGeneratorImpl(out,charset, bufferProvider, pretty);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/johnzon/blob/2893743f/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 49f52e1..ce5e8b7 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
@@ -36,7 +36,6 @@ import java.math.BigInteger;
 import java.nio.charset.Charset;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.concurrent.ConcurrentMap;
 
 class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     private static final Charset UTF8_CHARSET = Charset.forName("UTF-8");
@@ -47,27 +46,31 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     private int bufferPos = 0;
     private final boolean prettyPrint;
     private static final String INDENT = "  ";
-    //private final ConcurrentMap<String, String> cache;
     private int depth = 0;
     private boolean closed;
 
     private final HStack<GeneratorState> state = new HStack<GeneratorState>();
 
     private enum GeneratorState {
-        INITIAL(false, true), START_OBJECT(true, false), IN_OBJECT(true, false), AFTER_KEY(false, true), START_ARRAY(false, true), IN_ARRAY(
-                false, true), END(false, false);
+        INITIAL(false, true, false), // nothing created yet
+        START_OBJECT(true, false, true), IN_OBJECT(true, false, true), AFTER_KEY(false, true, false), // object
+        START_ARRAY(false, true, true), IN_ARRAY(false, true, true), // array
+        END(false, false, false), // end of context
+        ROOT_VALUE(false, false, true); // direct primitive (added in jsonp 1.1, was not supported in 1.0)
 
         private final boolean acceptsKey;
         private final boolean acceptsValue;
+        private final boolean endable;
 
-        GeneratorState(final boolean acceptsKey, final boolean acceptsValue) {
+        GeneratorState(final boolean acceptsKey, final boolean acceptsValue, final boolean endable) {
             this.acceptsKey = acceptsKey;
             this.acceptsValue = acceptsValue;
+            this.endable = endable;
         }
     }
 
     JsonGeneratorImpl(final Writer writer, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-            final ConcurrentMap<String, String> cache, final boolean prettyPrint) {
+                      final boolean prettyPrint) {
         this.writer = writer;
         //this.cache = cache;
         this.buffer = bufferProvider.newBuffer();
@@ -77,13 +80,13 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     }
 
     JsonGeneratorImpl(final OutputStream out, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-            final ConcurrentMap<String, String> cache, final boolean prettyPrint) {
-        this(new OutputStreamWriter(out, UTF8_CHARSET), bufferProvider, cache, prettyPrint);
+                      final boolean prettyPrint) {
+        this(new OutputStreamWriter(out, UTF8_CHARSET), bufferProvider, prettyPrint);
     }
 
     JsonGeneratorImpl(final OutputStream out, final Charset encoding, final BufferStrategy.BufferProvider<char[]> bufferProvider,
-            final ConcurrentMap<String, String> cache, final boolean prettyPrint) {
-        this(new OutputStreamWriter(out, encoding), bufferProvider, cache, prettyPrint);
+                      final boolean prettyPrint) {
+        this(new OutputStreamWriter(out, encoding), bufferProvider, prettyPrint);
     }
 
     private void writeEol() {
@@ -144,7 +147,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator writeStartObject(final String name) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         justWrite(START_OBJECT_CHAR);
         writeEol();
@@ -166,7 +169,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator writeStartArray(final String name) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         justWrite(START_ARRAY_CHAR);
         writeEol();
@@ -176,7 +179,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     }
 
     private void writeJsonValue(final String name, final JsonValue value) {
-        checkObject(false);
+        checkObject();
         //TODO check null handling
         switch (value.getValueType()) {
             case ARRAY:
@@ -227,7 +230,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
     }
 
     private void writeJsonValue(final JsonValue value) {
-        checkArray(true);
+        checkArray();
         //TODO check null handling
         switch (value.getValueType()) {
             case ARRAY:
@@ -279,14 +282,14 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final JsonValue value) {
-        checkObject(false);
+        checkObject();
         writeJsonValue(name, value);
         return this;
     }
 
     @Override
     public JsonGenerator write(final String name, final String value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValueAsJsonString(value);
         return this;
@@ -294,7 +297,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final BigInteger value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(String.valueOf(value));
         return this;
@@ -302,7 +305,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final BigDecimal value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(String.valueOf(value));
         return this;
@@ -310,7 +313,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final int value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(value);
         return this;
@@ -318,7 +321,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final long value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(value);
         return this;
@@ -326,7 +329,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final double value) {
-        checkObject(false);
+        checkObject();
         checkDoubleRange(value);
         writeKey(name);
         writeValue(String.valueOf(value));
@@ -335,7 +338,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final String name, final boolean value) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(String.valueOf(value));
         return this;
@@ -343,7 +346,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator writeNull(final String name) {
-        checkObject(false);
+        checkObject();
         writeKey(name);
         writeValue(NULL);
         return this;
@@ -351,8 +354,10 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator writeEnd() {
-        checkArrayOrObject(false);
         final GeneratorState last = state.pop();
+        if (last == null || !last.endable) {
+            throw new JsonGenerationException("Can't end current context: " + last);
+        }
         depth--;
         if (last != GeneratorState.START_ARRAY) {
             writeEol();
@@ -360,7 +365,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
         writeIndent();
         if (last == GeneratorState.IN_ARRAY || last == GeneratorState.START_ARRAY) {
             justWrite(END_ARRAY_CHAR);
-        } else {
+        } else if (last != GeneratorState.ROOT_VALUE) {
             justWrite(END_OBJECT_CHAR);
         }
         alignState();
@@ -369,49 +374,49 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final JsonValue value) {
-        checkArray(true);
+        checkArray();
         writeJsonValue(value);
         return this;
     }
 
     @Override
     public JsonGenerator write(final String value) {
-        checkArray(true);
+        checkArray();
         writeValueAsJsonString(value);
         return this;
     }
 
     @Override
     public JsonGenerator write(final BigDecimal value) {
-        checkArray(true);
+        checkArray();
         writeValue(String.valueOf(value));
         return this;
     }
 
     @Override
     public JsonGenerator write(final BigInteger value) {
-        checkArray(true);
+        checkArray();
         writeValue(String.valueOf(value));
         return this;
     }
 
     @Override
     public JsonGenerator write(final int value) {
-        checkArray(true);
+        checkArray();
         writeValue(value);
         return this;
     }
 
     @Override
     public JsonGenerator write(final long value) {
-        checkArray(true);
+        checkArray();
         writeValue(value);
         return this;
     }
 
     @Override
     public JsonGenerator write(final double value) {
-        checkArray(true);
+        checkArray();
         checkDoubleRange(value);
         writeValue(String.valueOf(value));
         return this;
@@ -419,14 +424,14 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
 
     @Override
     public JsonGenerator write(final boolean value) {
-        checkArray(true);
+        checkArray();
         writeValue(String.valueOf(value));
         return this;
     }
 
     @Override
     public JsonGenerator writeNull() {
-        checkArray(true);
+        checkArray();
         writeValue(NULL);
         return this;
     }
@@ -457,7 +462,8 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
             return;
         }
         try {
-            if (currentState() != GeneratorState.END) {
+            final GeneratorState state = currentState();
+            if (state != GeneratorState.END && state != GeneratorState.ROOT_VALUE) {
                 throw new JsonGenerationException("Invalid json");
             }
         } finally {
@@ -603,34 +609,22 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
         buffer[bufferPos++] = value;
     }
 
-    private void checkObject(final boolean allowInitial) {
+    private void checkObject() {
         final GeneratorState currentState = currentState();
         if (currentState != GeneratorState.IN_OBJECT && currentState != GeneratorState.START_OBJECT) {
-            if (!allowInitial || currentState != GeneratorState.INITIAL) {
-                throw new JsonGenerationException("write(name, param) is only valid in objects");
-            }
+            throw new JsonGenerationException("write(name, param) is only valid in objects");
         }
     }
 
-    private void checkArray(final boolean allowInitial) {
+    private void checkArray() {
         final GeneratorState currentState = currentState();
         if (currentState != GeneratorState.IN_ARRAY && currentState != GeneratorState.START_ARRAY) {
-            if (!allowInitial || currentState != GeneratorState.INITIAL) {
+            if (currentState != GeneratorState.INITIAL) {
                 throw new JsonGenerationException("write(param) is only valid in arrays");
             }
         }
     }
 
-    private void checkArrayOrObject(final boolean allowInitial) {
-        final GeneratorState currentState = currentState();
-        if (currentState != GeneratorState.IN_ARRAY && currentState != GeneratorState.START_ARRAY
-                && currentState != GeneratorState.IN_OBJECT && currentState != GeneratorState.START_OBJECT) {
-            if (!allowInitial || currentState != GeneratorState.INITIAL) {
-                throw new JsonGenerationException("only valid within array or object");
-            }
-        }
-    }
-
     private static void checkDoubleRange(final double value) {
         if (Double.isInfinite(value) || Double.isNaN(value)) {
             throw new NumberFormatException("double can't be infinite or NaN");
@@ -661,7 +655,7 @@ class JsonGeneratorImpl implements JsonGenerator, JsonChars, Serializable {
                 swapState(GeneratorState.IN_OBJECT);
                 break;
             case INITIAL:
-                swapState(GeneratorState.END);
+                state.push(GeneratorState.ROOT_VALUE);
                 break;
             default:
         }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/2893743f/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
index e373f41..b359e20 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonGeneratorImplTest.java
@@ -441,4 +441,37 @@ public class JsonGeneratorImplTest {
 
         assertEquals("{\n" + "  \"firstName\":\"John\"\n" + "}", buffer.toString());
     }
+
+    @Test(expected = JsonGenerationException.class)
+    public void errorWhenWritingValueInObject() {
+        Json.createGenerator(new StringWriter()).writeStartObject().write(1);
+    }
+
+    @Test
+    public void writeNumber() {
+        {
+            final StringWriter writer = new StringWriter();
+            Json.createGenerator(writer).write(1).writeEnd().close();
+            assertEquals("1", writer.toString());
+        }
+        {
+            final StringWriter writer = new StringWriter();
+            Json.createGenerator(writer).write(1).close();
+            assertEquals("1", writer.toString());
+        }
+    }
+
+    @Test
+    public void writeBoolean() {
+        {
+            final StringWriter writer = new StringWriter();
+            Json.createGenerator(writer).write(true).writeEnd().close();
+            assertEquals("true", writer.toString());
+        }
+        {
+            final StringWriter writer = new StringWriter();
+            Json.createGenerator(writer).write(true).close();
+            assertEquals("true", writer.toString());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/2893743f/johnzon-mapper/src/test/java/org/apache/johnzon/core/TestJsonGeneratorFactory.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/core/TestJsonGeneratorFactory.java b/johnzon-mapper/src/test/java/org/apache/johnzon/core/TestJsonGeneratorFactory.java
index 363a86d..3380b82 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/core/TestJsonGeneratorFactory.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/core/TestJsonGeneratorFactory.java
@@ -21,7 +21,6 @@ package org.apache.johnzon.core;
 import javax.json.stream.JsonGenerator;
 import java.io.Writer;
 import java.util.Collections;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * This class is only used for {@link org.apache.johnzon.mapper.JsonGeneratorCloseTest}.
@@ -36,13 +35,13 @@ import java.util.concurrent.ConcurrentHashMap;
 public class TestJsonGeneratorFactory extends JsonGeneratorFactoryImpl {
 
     public TestJsonGeneratorFactory() {
-        super(Collections.<String, Object>emptyMap());
+        super(Collections.emptyMap());
     }
 
 
     @Override
     public JsonGenerator createGenerator(Writer writer) {
-        return new JsonGeneratorImpl(writer, TestBufferProvider.INSTANCE, new ConcurrentHashMap<String, String>(0), false);
+        return new JsonGeneratorImpl(writer, TestBufferProvider.INSTANCE, false);
     }
 
 }