Skip to main content

[jsonp~git:de09a346] [JSONP-11] Flusing the buffered contents after JsonWriter's write methods

  • From:
  • To:
  • Subject: [jsonp~git:de09a346] [JSONP-11] Flusing the buffered contents after JsonWriter's write methods
  • Date: Thu, 31 Oct 2013 22:42:27 +0000

Project:    jsonp
Repository: git
Revision:   de09a34647071859423e447382f524f136545f07
Author:     jitu
Date:       2013-10-31 22:41:18 UTC
Link:       

Log Message:
------------
[JSONP-11] Flusing the buffered contents after JsonWriter's write methods, but
it doesn't flush the underlying byte stream.



Revisions:
----------
de09a34647071859423e447382f524f136545f07


Modified Paths:
---------------
impl/src/main/java/org/glassfish/json/JsonWriterImpl.java
tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java


Diffs:
------
--- a/impl/src/main/java/org/glassfish/json/JsonWriterImpl.java
+++ b/impl/src/main/java/org/glassfish/json/JsonWriterImpl.java
@@ -43,6 +43,8 @@ package org.glassfish.json;
 import org.glassfish.json.api.BufferPool;
 
 import javax.json.*;
+import java.io.FilterOutputStream;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.io.Writer;
 import java.nio.charset.Charset;
@@ -58,6 +60,7 @@ class JsonWriterImpl implements JsonWriter {
 
     private final JsonGeneratorImpl generator;
     private boolean writeDone;
+    private final NoFlushOutputStream os;
 
     JsonWriterImpl(Writer writer, BufferPool bufferPool) {
         this(writer, false, bufferPool);
@@ -67,6 +70,7 @@ class JsonWriterImpl implements JsonWriter {
         generator = prettyPrinting
                 ? new JsonPrettyGeneratorImpl(writer, bufferPool)
                 : new JsonGeneratorImpl(writer, bufferPool);
+        os = null;
     }
 
     JsonWriterImpl(OutputStream out, BufferPool bufferPool) {
@@ -79,9 +83,12 @@ class JsonWriterImpl implements JsonWriter {
 
     JsonWriterImpl(OutputStream out, Charset charset,
                    boolean prettyPrinting, BufferPool bufferPool) {
+        // Decorating the given stream, so that buffered contents can be
+        // written without actually flushing the stream.
+        this.os = new NoFlushOutputStream(out);
         generator = prettyPrinting
-                ? new JsonPrettyGeneratorImpl(out, charset, bufferPool)
-                : new JsonGeneratorImpl(out, charset, bufferPool);
+                ? new JsonPrettyGeneratorImpl(os, charset, bufferPool)
+                : new JsonGeneratorImpl(os, charset, bufferPool);
     }
 
     @Override
@@ -95,9 +102,15 @@ class JsonWriterImpl implements JsonWriter {
             generator.write(value);
         }
         generator.writeEnd();
-        // may not flush the generated contents to output source, as an
-        // intermediary like OutputStreamWriter may buffer
+        // Flush the generator's buffered contents. This won't work for byte
+        // streams as intermediary OutputStreamWriter buffers.
         generator.flushBuffer();
+        // Flush buffered contents but not the byte stream. generator.flush()
+        // does OutputStreamWriter#flushBuffer (package private) and 
underlying
+        // byte stream#flush(). Here underlying stream's flush() is no-op.
+        if (os != null) {
+            generator.flush();
+        }
     }
 
     @Override
@@ -111,9 +124,15 @@ class JsonWriterImpl implements JsonWriter {
             generator.write(e.getKey(), e.getValue());
         }
         generator.writeEnd();
-        // may not flush the generated contents to output source, as an
-        // intermediary like OutputStreamWriter may buffer
+        // Flush the generator's buffered contents. This won't work for byte
+        // streams as intermediary OutputStreamWriter buffers.
         generator.flushBuffer();
+        // Flush buffered contents but not the byte stream. generator.flush()
+        // does OutputStreamWriter#flushBuffer (package private) and 
underlying
+        // byte stream#flush(). Here underlying stream's flush() is no-op.
+        if (os != null) {
+            generator.flush();
+        }
     }
 
     @Override
@@ -131,4 +150,20 @@ class JsonWriterImpl implements JsonWriter {
         generator.close();
     }
 
+    private static final class NoFlushOutputStream extends 
FilterOutputStream {
+        public NoFlushOutputStream(OutputStream out) {
+            super(out);
+        }
+
+        @Override
+        public void write(byte b[], int off, int len) throws IOException {
+            out.write(b, off ,len);
+        }
+
+        @Override
+        public void flush() {
+            // no-op
+        }
+    }
+
 }--- a/tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java
+++ b/tests/src/test/java/org/glassfish/json/tests/JsonWriterTest.java
@@ -41,6 +41,8 @@
 package org.glassfish.json.tests;
 
 import javax.json.*;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.StringWriter;
 
 import junit.framework.TestCase;
@@ -135,13 +137,57 @@ public class JsonWriterTest extends TestCase {
         writer.close();
     }
 
-// Doesn't work. We expect JsonWriter#close() to be called
-//
-//    public void testFlushBuffer() throws Exception {
-//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-//        JsonWriter writer = Json.createWriter(baos);
-//        writer.write(Json.createObjectBuilder().build());
-//        // not calling writer.close() intentionally
-//        assertEquals("{}", baos.toString("UTF-8"));
-//    }
+    public void testNoCloseWriteObjectToStream() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        JsonWriter writer = Json.createWriter(baos);
+        writer.write(Json.createObjectBuilder().build());
+        // not calling writer.close() intentionally
+        assertEquals("{}", baos.toString("UTF-8"));
+    }
+
+    public void testNoCloseWriteObjectToWriter() throws Exception {
+        StringWriter sw = new StringWriter();
+        JsonWriter writer = Json.createWriter(sw);
+        writer.write(Json.createObjectBuilder().build());
+        // not calling writer.close() intentionally
+        assertEquals("{}", sw.toString());
+    }
+
+    public void testNoCloseWriteArrayToStream() throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        JsonWriter writer = Json.createWriter(baos);
+        writer.write(Json.createArrayBuilder().build());
+        // not calling writer.close() intentionally
+        assertEquals("[]", baos.toString("UTF-8"));
+    }
+
+    public void testNoCloseWriteArrayToWriter() throws Exception {
+        StringWriter sw = new StringWriter();
+        JsonWriter writer = Json.createWriter(sw);
+        writer.write(Json.createArrayBuilder().build());
+        // not calling writer.close() intentionally
+        assertEquals("[]", sw.toString());
+    }
+
+    public void testClose() throws Exception {
+        MyByteStream baos = new MyByteStream();
+        JsonWriter writer = Json.createWriter(baos);
+        writer.write(Json.createObjectBuilder().build());
+        writer.close();
+        assertEquals("{}", baos.toString("UTF-8"));
+        assertTrue(baos.isClosed());
+    }
+
+    private static final class MyByteStream extends ByteArrayOutputStream {
+        boolean closed;
+
+        boolean isClosed() {
+            return closed;
+        }
+
+        public void close() throws IOException {
+            super.close();
+            closed = true;
+        }
+    }
 }





[jsonp~git:de09a346] [JSONP-11] Flusing the buffered contents after JsonWriter's write methods

jitu 10/31/2013
 
 
Close
loading
Please Confirm
Close