From 9b7b49bf0fa0e33e993ef75ca75c5fe5920976cc Mon Sep 17 00:00:00 2001 From: Jesse Wilson Date: Sat, 1 Oct 2011 00:12:36 +0000 Subject: [PATCH] Implement JsonElementWriter.close() --- .../gson/internal/bind/JsonElementWriter.java | 23 +++++++++++----- .../internal/bind/JsonElementWriterTest.java | 26 ++++++++++++++++++- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/gson/src/main/java/com/google/gson/internal/bind/JsonElementWriter.java b/gson/src/main/java/com/google/gson/internal/bind/JsonElementWriter.java index 0a815617..3328cdc2 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/JsonElementWriter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/JsonElementWriter.java @@ -28,7 +28,7 @@ import java.util.ArrayList; import java.util.List; /** - * This writer writes a JsonElement. + * This writer creates a JsonElement. */ public final class JsonElementWriter extends JsonWriter { private static final Writer UNWRITABLE_WRITER = new Writer() { @@ -42,22 +42,27 @@ public final class JsonElementWriter extends JsonWriter { throw new AssertionError(); } }; + /** Added to the top of the stack when this writer is closed to cause following ops to fail. */ + private static final JsonPrimitive SENTINEL_CLOSED = new JsonPrimitive("closed"); + /** The JsonElements and JsonArrays under modification, outermost to innermost. */ private final List stack = new ArrayList(); + + /** The name for the next JSON object value. If non-null, the top of the stack is a JsonObject. */ private String pendingName; + /** the JSON element constructed by this writer. */ + private JsonElement product = JsonNull.INSTANCE; // TODO: is this really what we want?; + public JsonElementWriter() { super(UNWRITABLE_WRITER); } public JsonElement get() { - if (stack.isEmpty()) { - return JsonNull.INSTANCE; // TODO: is this really what we want? - } - if (stack.size() != 1) { + if (!stack.isEmpty()) { throw new IllegalStateException("Expected one JSON element but was " + stack); } - return stack.get(0); + return product; } private JsonElement peek() { @@ -70,7 +75,7 @@ public final class JsonElementWriter extends JsonWriter { object.add(pendingName, value); pendingName = null; } else if (stack.isEmpty()) { - stack.add(value); + product = value; } else { JsonElement element = peek(); if (element instanceof JsonArray) { @@ -171,5 +176,9 @@ public final class JsonElementWriter extends JsonWriter { } @Override public void close() throws IOException { + if (!stack.isEmpty()) { + throw new IOException("Incomplete document"); + } + stack.add(SENTINEL_CLOSED); } } diff --git a/gson/src/test/java/com/google/gson/internal/bind/JsonElementWriterTest.java b/gson/src/test/java/com/google/gson/internal/bind/JsonElementWriterTest.java index 4f37552a..dfe4fb25 100644 --- a/gson/src/test/java/com/google/gson/internal/bind/JsonElementWriterTest.java +++ b/gson/src/test/java/com/google/gson/internal/bind/JsonElementWriterTest.java @@ -22,7 +22,6 @@ import junit.framework.TestCase; public final class JsonElementWriterTest extends TestCase { // TODO: more tests - // TODO: close support // TODO: figure out what should be returned by an empty writer // TODO: test when serialize nulls is false @@ -73,4 +72,29 @@ public final class JsonElementWriterTest extends TestCase { writer.endObject(); assertEquals("{\"A\":{\"B\":{}},\"C\":{}}", writer.get().toString()); } + + public void testWriteAfterClose() throws Exception { + JsonElementWriter writer = new JsonElementWriter(); + writer.setLenient(true); + writer.beginArray(); + writer.value("A"); + writer.endArray(); + writer.close(); + try { + writer.beginArray(); + fail(); + } catch (IllegalStateException expected) { + } + } + + public void testPrematureClose() throws Exception { + JsonElementWriter writer = new JsonElementWriter(); + writer.setLenient(true); + writer.beginArray(); + try { + writer.close(); + fail(); + } catch (IOException expected) { + } + } }