[CSV-217] Add autoFlush option for CsvPrinter. Applying modified patch
This closes #24.

Project: http://git-wip-us.apache.org/repos/asf/commons-csv/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-csv/commit/7e471527
Tree: http://git-wip-us.apache.org/repos/asf/commons-csv/tree/7e471527
Diff: http://git-wip-us.apache.org/repos/asf/commons-csv/diff/7e471527

Branch: refs/heads/CSV-216
Commit: 7e471527915cb0c73316c598fd02b71a56f2cf43
Parents: 10977ae
Author: Korolyov Alexei <alex270...@yandex.ru>
Authored: Mon Oct 9 13:22:53 2017 -0600
Committer: Gary Gregory <ggreg...@apache.org>
Committed: Mon Oct 9 13:22:53 2017 -0600

----------------------------------------------------------------------
 pom.xml                                         |  6 ++
 src/changes/changes.xml                         |  1 +
 .../java/org/apache/commons/csv/CSVFormat.java  | 75 ++++++++++++++------
 .../java/org/apache/commons/csv/CSVPrinter.java | 17 +++++
 .../org/apache/commons/csv/CSVPrinterTest.java  | 55 ++++++++++++++
 5 files changed, 131 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-csv/blob/7e471527/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 262bc17..8b13c17 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,12 @@ CSV files of various types.
       <scope>test</scope>
     </dependency>
     <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.9.5</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
       <version>2.5</version>

http://git-wip-us.apache.org/repos/asf/commons-csv/blob/7e471527/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bbfa930..b56b75f 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -39,6 +39,7 @@
   </properties>
   <body>
     <release version="1.6" date="2017-MM-DD" description="Feature and bug fix 
release">
+      <action issue="CSV-217" type="add" dev="ggregory" due-to="Korolyov 
Alexei">Add autoFlush option for CsvPrinter. PR #24.</action>
     </release>
     <release version="1.5" date="2017-09-03" description="Feature and bug fix 
release">
       <action issue="CSV-203" type="fix" dev="ggregory" due-to="Richard 
Wheeldon, Kai Paroth">withNullString value is printed without quotes when 
QuoteMode.ALL is specified; add QuoteMode.ALL_NON_NULL. PR #17.</action>

http://git-wip-us.apache.org/repos/asf/commons-csv/blob/7e471527/src/main/java/org/apache/commons/csv/CSVFormat.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/csv/CSVFormat.java 
b/src/main/java/org/apache/commons/csv/CSVFormat.java
index 410c8fb..29b7c36 100644
--- a/src/main/java/org/apache/commons/csv/CSVFormat.java
+++ b/src/main/java/org/apache/commons/csv/CSVFormat.java
@@ -242,7 +242,7 @@ public final class CSVFormat implements Serializable {
      * @see Predefined#Default
      */
     public static final CSVFormat DEFAULT = new CSVFormat(COMMA, 
DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
-            null, null, null, false, false, false, false, false);
+            null, null, null, false, false, false, false, false, false);
 
     /**
      * Excel file format (using a comma as the value delimiter). Note that the 
actual value delimiter used by Excel is
@@ -537,7 +537,7 @@ public final class CSVFormat implements Serializable {
      */
     public static CSVFormat newFormat(final char delimiter) {
         return new CSVFormat(delimiter, null, null, null, null, false, false, 
null, null, null, null, false, false,
-                false, false, false);
+                false, false, false, false);
     }
 
     /**
@@ -584,6 +584,8 @@ public final class CSVFormat implements Serializable {
 
     private final boolean trim;
 
+    private final boolean autoFlush;
+
     /**
      * Creates a customized CSV format.
      *
@@ -619,15 +621,16 @@ public final class CSVFormat implements Serializable {
      *            TODO
      * @param trailingDelimiter
      *            TODO
+     * @param autoFlush
      * @throws IllegalArgumentException
      *             if the delimiter is a line break character
      */
     private CSVFormat(final char delimiter, final Character quoteChar, final 
QuoteMode quoteMode,
-            final Character commentStart, final Character escape, final 
boolean ignoreSurroundingSpaces,
-            final boolean ignoreEmptyLines, final String recordSeparator, 
final String nullString,
-            final Object[] headerComments, final String[] header, final 
boolean skipHeaderRecord,
-            final boolean allowMissingColumnNames, final boolean 
ignoreHeaderCase, final boolean trim,
-            final boolean trailingDelimiter) {
+                      final Character commentStart, final Character escape, 
final boolean ignoreSurroundingSpaces,
+                      final boolean ignoreEmptyLines, final String 
recordSeparator, final String nullString,
+                      final Object[] headerComments, final String[] header, 
final boolean skipHeaderRecord,
+                      final boolean allowMissingColumnNames, final boolean 
ignoreHeaderCase, final boolean trim,
+                      final boolean trailingDelimiter, boolean autoFlush) {
         this.delimiter = delimiter;
         this.quoteCharacter = quoteChar;
         this.quoteMode = quoteMode;
@@ -644,6 +647,7 @@ public final class CSVFormat implements Serializable {
         this.ignoreHeaderCase = ignoreHeaderCase;
         this.trailingDelimiter = trailingDelimiter;
         this.trim = trim;
+        this.autoFlush = autoFlush;
         validate();
     }
 
@@ -887,6 +891,16 @@ public final class CSVFormat implements Serializable {
         return trim;
     }
 
+    /**
+     * Returns whether to flush on close.
+     *
+     * @return whether to flush on close.
+     * @since 1.6
+     */
+    public boolean getAutoFlush() {
+        return autoFlush;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -1431,7 +1445,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withAllowMissingColumnNames(final boolean 
allowMissingColumnNames) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1466,7 +1480,7 @@ public final class CSVFormat implements Serializable {
         }
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1484,7 +1498,7 @@ public final class CSVFormat implements Serializable {
         }
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1515,7 +1529,7 @@ public final class CSVFormat implements Serializable {
         }
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escape, ignoreSurroundingSpaces,
                 ignoreEmptyLines, recordSeparator, nullString, headerComments, 
header, skipHeaderRecord,
-                allowMissingColumnNames, ignoreHeaderCase, trim, 
trailingDelimiter);
+                allowMissingColumnNames, ignoreHeaderCase, trim, 
trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1670,7 +1684,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withHeader(final String... header) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1691,7 +1705,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withHeaderComments(final Object... headerComments) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1716,7 +1730,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1742,7 +1756,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1767,7 +1781,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withIgnoreSurroundingSpaces(final boolean 
ignoreSurroundingSpaces) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1786,7 +1800,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withNullString(final String nullString) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1817,7 +1831,7 @@ public final class CSVFormat implements Serializable {
         }
         return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, 
escapeCharacter, ignoreSurroundingSpaces,
                 ignoreEmptyLines, recordSeparator, nullString, headerComments, 
header, skipHeaderRecord,
-                allowMissingColumnNames, ignoreHeaderCase, trim, 
trailingDelimiter);
+                allowMissingColumnNames, ignoreHeaderCase, trim, 
trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1831,7 +1845,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
         return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1869,7 +1883,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withRecordSeparator(final String recordSeparator) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1896,7 +1910,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1921,7 +1935,7 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withTrailingDelimiter(final boolean trailingDelimiter) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
     }
 
     /**
@@ -1946,6 +1960,21 @@ public final class CSVFormat implements Serializable {
     public CSVFormat withTrim(final boolean trim) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
                 ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
-                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter);
+                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, 
trim, trailingDelimiter, autoFlush);
+    }
+
+    /**
+     * Returns a new {@code CSVFormat} with whether to flush on close.
+     *
+     * @param autoFlush
+     *            whether to flush on close.
+     *
+     * @return A new CSVFormat that is equal to this but with the specified 
autoFlush setting.
+     * @since 1.6
+     */
+    public CSVFormat withAutoFlush(final boolean autoFlush) {
+        return new CSVFormat(delimiter, quoteCharacter, quoteMode, 
commentMarker, escapeCharacter,
+            ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, 
nullString, headerComments, header,
+            skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, 
trailingDelimiter, autoFlush);
     }
 }

http://git-wip-us.apache.org/repos/asf/commons-csv/blob/7e471527/src/main/java/org/apache/commons/csv/CSVPrinter.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/csv/CSVPrinter.java 
b/src/main/java/org/apache/commons/csv/CSVPrinter.java
index 96b24a4..49d9022 100644
--- a/src/main/java/org/apache/commons/csv/CSVPrinter.java
+++ b/src/main/java/org/apache/commons/csv/CSVPrinter.java
@@ -81,6 +81,23 @@ public final class CSVPrinter implements Flushable, 
Closeable {
 
     @Override
     public void close() throws IOException {
+        close(false);
+    }
+
+    /**
+     * Closes the underlying stream with an optional flush first.
+     * @param flush whether to flush before the actual close.
+     * 
+     * @throws IOException
+     *             If an I/O error occurs
+     * @since 1.6
+     */
+    public void close(boolean flush) throws IOException {
+        if (flush || format.getAutoFlush()) {
+            if (out instanceof Flushable) {
+                ((Flushable) out).flush();
+            }
+        }
         if (out instanceof Closeable) {
             ((Closeable) out).close();
         }

http://git-wip-us.apache.org/repos/asf/commons-csv/blob/7e471527/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java 
b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
index 4a0ffbf..893675c 100644
--- a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
+++ b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
@@ -21,12 +21,17 @@ import static org.apache.commons.csv.Constants.CR;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
 
 import java.io.CharArrayWriter;
 import java.io.File;
 import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.io.Writer;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.sql.BatchUpdateException;
@@ -1311,4 +1316,54 @@ public class CSVPrinterTest {
         }
     }
 
+    @Test
+    public void testCloseWithFlushOn() throws IOException {
+        Writer writer = mock(Writer.class);
+        CSVFormat csvFormat = CSVFormat.DEFAULT;
+        CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat);
+        csvPrinter.close(true);
+        verify(writer, times(1)).flush();
+    }
+
+    @Test
+    public void testCloseWithFlushOff() throws IOException {
+        Writer writer = mock(Writer.class);
+        CSVFormat csvFormat = CSVFormat.DEFAULT;
+        CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat);
+        csvPrinter.close(false);
+        verify(writer, never()).flush();
+        verify(writer, times(1)).close();
+    }
+
+    @Test
+    public void testCloseBackwardCompatibility() throws IOException {
+        Writer writer = mock(Writer.class);
+        CSVFormat csvFormat = CSVFormat.DEFAULT;
+        try (CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat)) {
+        }
+        verify(writer, never()).flush();
+        verify(writer, times(1)).close();
+    }
+
+    @Test
+    public void testCloseWithCsvFormatAutoFlushOn() throws IOException {
+        System.out.println("start method");
+        Writer writer = mock(Writer.class);
+        CSVFormat csvFormat = CSVFormat.DEFAULT.withAutoFlush(true);
+        try (CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat)) {
+        }
+        verify(writer, times(1)).flush();
+        verify(writer, times(1)).close();
+    }
+
+    @Test
+    public void testCloseWithCsvFormatAutoFlushOff() throws IOException {
+        Writer writer = mock(Writer.class);
+        CSVFormat csvFormat = CSVFormat.DEFAULT.withAutoFlush(false);
+        try (CSVPrinter csvPrinter = new CSVPrinter(writer, csvFormat)) {
+        }
+        verify(writer, never()).flush();
+        verify(writer, times(1)).close();
+    }
+
 }

Reply via email to