You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2014/11/11 15:00:48 UTC

svn commit: r1638101 - in /commons/proper/csv/trunk/src: changes/changes.xml main/java/org/apache/commons/csv/CSVFormat.java main/java/org/apache/commons/csv/CSVPrinter.java test/java/org/apache/commons/csv/CSVPrinterTest.java

Author: ggregory
Date: Tue Nov 11 14:00:47 2014
New Revision: 1638101

URL: http://svn.apache.org/r1638101
Log:
[CSV-139] CSVPrinter.printRecord(ResultSet) with metadata.

Modified:
    commons/proper/csv/trunk/src/changes/changes.xml
    commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
    commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
    commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java

Modified: commons/proper/csv/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/changes/changes.xml?rev=1638101&r1=1638100&r2=1638101&view=diff
==============================================================================
--- commons/proper/csv/trunk/src/changes/changes.xml (original)
+++ commons/proper/csv/trunk/src/changes/changes.xml Tue Nov 11 14:00:47 2014
@@ -46,6 +46,7 @@
       <action issue="CSV-124" type="update" dev="brentworden" due-to="Kalyan">Improve toString() implementation of CSVRecord</action>
       <action issue="CSV-129" type="add" dev="ggregory">Add CSVFormat#with 0-arg methods matching boolean arg methods</action>
       <action issue="CSV-131" type="add" dev="ggregory" due-to="Holger Stratmann">Save positions of records to enable random access</action>
+      <action issue="CSV-139" type="add" dev="ggregory">CSVPrinter.printRecord(ResultSet) with metadata</action>
     </release>
     <release version="1.0" date="2014-08-14" description="First release">
       <action issue="CSV-125" type="fix" dev="britter">No longer works with Java 6</action>

Modified: commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java?rev=1638101&r1=1638100&r2=1638101&view=diff
==============================================================================
--- commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java (original)
+++ commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java Tue Nov 11 14:00:47 2014
@@ -29,6 +29,9 @@ import java.io.IOException;
 import java.io.Reader;
 import java.io.Serializable;
 import java.io.StringWriter;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
@@ -43,11 +46,11 @@ import java.util.Set;
  * </p>
  *
  * <ul>
- *      <li>{@link #DEFAULT}</li>
- *      <li>{@link #EXCEL}</li>
- *      <li>{@link #MYSQL}</li>
- *      <li>{@link #RFC4180}</li>
- *      <li>{@link #TDF}</li>
+ * <li>{@link #DEFAULT}</li>
+ * <li>{@link #EXCEL}</li>
+ * <li>{@link #MYSQL}</li>
+ * <li>{@link #RFC4180}</li>
+ * <li>{@link #TDF}</li>
  * </ul>
  *
  * <p>
@@ -62,7 +65,9 @@ import java.util.Set;
  * The {@link CSVParser} provides static methods to parse other input types, for example:
  * </p>
  *
- * <pre>CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);</pre>
+ * <pre>
+ * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);
+ * </pre>
  *
  * <h2>Defining formats</h2>
  *
@@ -71,9 +76,7 @@ import java.util.Set;
  * </p>
  *
  * <pre>
- * CSVFormat.EXCEL
- *   .withNullString(&quot;N/A&quot;)
- *   .withIgnoreSurroundingSpaces(true);
+ * CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
  * </pre>
  *
  * <h2>Defining column names</h2>
@@ -112,8 +115,8 @@ import java.util.Set;
  * <h2>Referencing columns safely</h2>
  *
  * <p>
- * If your source contains a header record, you can simplify your code and safely reference columns,
- * by using {@link #withHeader(String...)} with no arguments:
+ * If your source contains a header record, you can simplify your code and safely reference columns, by using
+ * {@link #withHeader(String...)} with no arguments:
  * </p>
  *
  * <pre>
@@ -167,14 +170,14 @@ public final class CSVFormat implements 
      * Settings are:
      * </p>
      * <ul>
-     *   <li>withDelimiter(',')</li>
-     *   <li>withQuote('"')</li>
-     *   <li>withRecordSeparator("\r\n")</li>
-     *   <li>withIgnoreEmptyLines(true)</li>
+     * <li>withDelimiter(',')</li>
+     * <li>withQuote('"')</li>
+     * <li>withRecordSeparator("\r\n")</li>
+     * <li>withIgnoreEmptyLines(true)</li>
      * </ul>
      */
-    public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null,
-                                                            false, true, CRLF, null, null, null, false, false);
+    public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true,
+            CRLF, null, null, null, false, false);
 
     /**
      * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
@@ -183,10 +186,10 @@ public final class CSVFormat implements 
      * Settings are:
      * </p>
      * <ul>
-     *   <li>withDelimiter(',')</li>
-     *   <li>withQuote('"')</li>
-     *   <li>withRecordSeparator("\r\n")</li>
-     *   <li>withIgnoreEmptyLines(false)</li>
+     * <li>withDelimiter(',')</li>
+     * <li>withQuote('"')</li>
+     * <li>withRecordSeparator("\r\n")</li>
+     * <li>withIgnoreEmptyLines(false)</li>
      * </ul>
      */
     public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
@@ -227,16 +230,13 @@ public final class CSVFormat implements 
      * Settings are:
      * </p>
      * <ul>
-     *   <li>withDelimiter('\t')</li>
-     *   <li>withQuote('"')</li>
-     *   <li>withRecordSeparator("\r\n")</li>
-     *   <li>withIgnoreSurroundingSpaces(true)</li>
+     * <li>withDelimiter('\t')</li>
+     * <li>withQuote('"')</li>
+     * <li>withRecordSeparator("\r\n")</li>
+     * <li>withIgnoreSurroundingSpaces(true)</li>
      * </ul>
      */
-    public static final CSVFormat TDF =
-            DEFAULT
-            .withDelimiter(TAB)
-            .withIgnoreSurroundingSpaces();
+    public static final CSVFormat TDF = DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
 
     /**
      * Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
@@ -250,22 +250,18 @@ public final class CSVFormat implements 
      * Settings are:
      * </p>
      * <ul>
-     *   <li>withDelimiter('\t')</li>
-     *   <li>withQuote(null)</li>
-     *   <li>withRecordSeparator('\n')</li>
-     *   <li>withIgnoreEmptyLines(false)</li>
-     *   <li>withEscape('\\')</li>
+     * <li>withDelimiter('\t')</li>
+     * <li>withQuote(null)</li>
+     * <li>withRecordSeparator('\n')</li>
+     * <li>withIgnoreEmptyLines(false)</li>
+     * <li>withEscape('\\')</li>
      * </ul>
+     *
      * @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">
      *      http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
      */
-    public static final CSVFormat MYSQL =
-            DEFAULT
-            .withDelimiter(TAB)
-            .withEscape(BACKSLASH)
-            .withIgnoreEmptyLines(false)
-            .withQuote(null)
-            .withRecordSeparator(LF);
+    public static final CSVFormat MYSQL = DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
+            .withQuote(null).withRecordSeparator(LF);
 
     /**
      * Returns true if the given character is a line break character.
@@ -294,13 +290,16 @@ public final class CSVFormat implements 
     /**
      * Creates a new CSV format with the specified delimiter.
      *
-     * <p>Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be
-     * initialized with null/false.</p>
+     * <p>
+     * Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be initialized
+     * with null/false.
+     * </p>
      *
      * @param delimiter
      *            the char used for value separation, must not be a line break character
      * @return a new CSV format.
-     * @throws IllegalArgumentException if the delimiter is a line break character
+     * @throws IllegalArgumentException
+     *             if the delimiter is a line break character
      *
      * @see #DEFAULT
      * @see #RFC4180
@@ -337,16 +336,18 @@ public final class CSVFormat implements 
      *            the comments to be printed by the Printer before the actual CSV data
      * @param header
      *            the header
-     * @param skipHeaderRecord TODO
-     * @param allowMissingColumnNames TODO
-     * @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) {
+     * @param skipHeaderRecord
+     *            TODO
+     * @param allowMissingColumnNames
+     *            TODO
+     * @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) {
         if (isLineBreak(delimiter)) {
             throw new IllegalArgumentException("The delimiter cannot be a line break");
         }
@@ -377,13 +378,13 @@ public final class CSVFormat implements 
         validate();
     }
 
-    private String[] toStringArray(Object[] values) {
+    private String[] toStringArray(final Object[] values) {
         if (values == null) {
             return null;
         }
-        String[] strings = new String[values.length];
+        final String[] strings = new String[values.length];
         for (int i = 0; i < values.length; i++) {
-            Object value = values[i];
+            final Object value = values[i];
             strings[i] = value == null ? null : value.toString();
         }
         return strings;
@@ -544,8 +545,7 @@ public final class CSVFormat implements 
     /**
      * Specifies whether spaces around values are ignored when parsing input.
      *
-     * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the
-     *         value.
+     * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the value.
      */
     public boolean getIgnoreSurroundingSpaces() {
         return ignoreSurroundingSpaces;
@@ -556,8 +556,7 @@ public final class CSVFormat implements 
      * <ul>
      * <li>
      * <strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
-     * records.
-     * </li>
+     * records.</li>
      * <li>
      * <strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
      * </ul>
@@ -605,8 +604,7 @@ public final class CSVFormat implements 
     }
 
     @Override
-    public int hashCode()
-    {
+    public int hashCode() {
         final int prime = 31;
         int result = 1;
 
@@ -687,10 +685,10 @@ public final class CSVFormat implements 
      * </p>
      *
      * @param out
-     *        the output
+     *            the output
      * @return a printer to an output
      * @throws IOException
-     *         thrown if the optional header cannot be printed.
+     *             thrown if the optional header cannot be printed.
      */
     public CSVPrinter print(final Appendable out) throws IOException {
         return new CSVPrinter(out, this);
@@ -716,7 +714,7 @@ public final class CSVFormat implements 
             sb.append(' ');
             sb.append("NullString=<").append(nullString).append('>');
         }
-        if(recordSeparator != null) {
+        if (recordSeparator != null) {
             sb.append(' ');
             sb.append("RecordSeparator=<").append(recordSeparator).append('>');
         }
@@ -745,28 +743,28 @@ public final class CSVFormat implements 
      */
     private void validate() throws IllegalArgumentException {
         if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
-            throw new IllegalArgumentException(
-                    "The quoteChar character and the delimiter cannot be the same ('" + quoteCharacter + "')");
+            throw new IllegalArgumentException("The quoteChar character and the delimiter cannot be the same ('" +
+                    quoteCharacter + "')");
         }
 
         if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
-            throw new IllegalArgumentException(
-                    "The escape character and the delimiter cannot be the same ('" + escapeCharacter + "')");
+            throw new IllegalArgumentException("The escape character and the delimiter cannot be the same ('" +
+                    escapeCharacter + "')");
         }
 
         if (commentMarker != null && delimiter == commentMarker.charValue()) {
-            throw new IllegalArgumentException(
-                    "The comment start character and the delimiter cannot be the same ('" + commentMarker + "')");
+            throw new IllegalArgumentException("The comment start character and the delimiter cannot be the same ('" +
+                    commentMarker + "')");
         }
 
         if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
-            throw new IllegalArgumentException(
-                    "The comment start character and the quoteChar cannot be the same ('" + commentMarker + "')");
+            throw new IllegalArgumentException("The comment start character and the quoteChar cannot be the same ('" +
+                    commentMarker + "')");
         }
 
         if (escapeCharacter != null && escapeCharacter.equals(commentMarker)) {
-            throw new IllegalArgumentException(
-                    "The comment start and the escape character cannot be the same ('" + commentMarker + "')");
+            throw new IllegalArgumentException("The comment start and the escape character cannot be the same ('" +
+                    commentMarker + "')");
         }
 
         if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
@@ -805,8 +803,8 @@ public final class CSVFormat implements 
             throw new IllegalArgumentException("The comment start marker character cannot be a line break");
         }
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -823,8 +821,8 @@ public final class CSVFormat implements 
             throw new IllegalArgumentException("The delimiter cannot be a line break");
         }
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -853,21 +851,25 @@ public final class CSVFormat implements 
         if (isLineBreak(escape)) {
             throw new IllegalArgumentException("The escape character cannot be a line break");
         }
-        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
+                ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord, allowMissingColumnNames);
     }
 
     /**
      * Sets the header of the format. The header can either be parsed automatically from the input file with:
      *
      * <pre>
-     * CSVFormat format = aformat.withHeader();</pre>
+     * CSVFormat format = aformat.withHeader();
+     * </pre>
      *
      * or specified manually with:
      *
      * <pre>
-     * CSVFormat format = aformat.withHeader(&quot;name&quot;, &quot;email&quot;, &quot;phone&quot;);</pre>
+     * CSVFormat format = aformat.withHeader(&quot;name&quot;, &quot;email&quot;, &quot;phone&quot;);
+     * </pre>
+     * <p>
+     * The header is also used by the {@link CSVPrinter}..
+     * </p>
      *
      * @param header
      *            the header, {@code null} if disabled, empty if parsed automatically, user specified otherwise.
@@ -877,8 +879,76 @@ public final class CSVFormat implements 
      */
     public CSVFormat withHeader(final String... header) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
+    }
+
+    /**
+     * Sets the header of the format. The header can either be parsed automatically from the input file with:
+     *
+     * <pre>
+     * CSVFormat format = aformat.withHeader();
+     * </pre>
+     *
+     * or specified manually with:
+     *
+     * <pre>
+     * CSVFormat format = aformat.withHeader(resultSet);
+     * </pre>
+     * <p>
+     * The header is also used by the {@link CSVPrinter}..
+     * </p>
+     *
+     * @param resultSet
+     *            the resultSet for the header, {@code null} if disabled, empty if parsed automatically, user specified
+     *            otherwise.
+     *
+     * @return A new CSVFormat that is equal to this but with the specified header
+     * @throws SQLException
+     *             SQLException if a database access error occurs or this method is called on a closed result set.
+     * @since 1.1
+     */
+    public CSVFormat withHeader(final ResultSet resultSet) throws SQLException {
+        return withHeader(resultSet != null ? resultSet.getMetaData() : null);
+    }
+
+    /**
+     * Sets the header of the format. The header can either be parsed automatically from the input file with:
+     *
+     * <pre>
+     * CSVFormat format = aformat.withHeader();
+     * </pre>
+     *
+     * or specified manually with:
+     *
+     * <pre>
+     * CSVFormat format = aformat.withHeader(metaData);
+     * </pre>
+     * <p>
+     * The header is also used by the {@link CSVPrinter}..
+     * </p>
+     *
+     * @param metaData
+     *            the metaData for the header, {@code null} if disabled, empty if parsed automatically, user specified
+     *            otherwise.
+     *
+     * @return A new CSVFormat that is equal to this but with the specified header
+     * @throws SQLException
+     *             SQLException if a database access error occurs or this method is called on a closed result set.
+     * @since 1.1
+     */
+    public CSVFormat withHeader(final ResultSetMetaData metaData) throws SQLException {
+        String[] labels = null;
+        if (metaData != null) {
+            final int columnCount = metaData.getColumnCount();
+            labels = new String[columnCount];
+            for (int i = 0; i < columnCount; i++) {
+                labels[i] = metaData.getColumnLabel(i + 1);
+            }
+        }
+        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, labels, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -923,8 +993,8 @@ public final class CSVFormat implements 
      */
     public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -948,8 +1018,8 @@ public final class CSVFormat implements 
      */
     public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -973,8 +1043,8 @@ public final class CSVFormat implements 
      */
     public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -994,8 +1064,8 @@ public final class CSVFormat implements 
      */
     public CSVFormat withNullString(final String nullString) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -1024,9 +1094,8 @@ public final class CSVFormat implements 
         if (isLineBreak(quoteChar)) {
             throw new IllegalArgumentException("The quoteChar cannot be a line break");
         }
-        return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+        return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
+                ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord, allowMissingColumnNames);
     }
 
     /**
@@ -1039,15 +1108,17 @@ public final class CSVFormat implements 
      */
     public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
         return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
      * Sets the record separator of the format to the specified character.
      *
-     * <p><strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing
-     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
+     * <p>
+     * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
+     * only works for inputs with '\n', '\r' and "\r\n"
+     * </p>
      *
      * @param recordSeparator
      *            the record separator to use for output.
@@ -1061,20 +1132,22 @@ public final class CSVFormat implements 
     /**
      * Sets the record separator of the format to the specified String.
      *
-     * <p><strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing
-     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
+     * <p>
+     * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
+     * only works for inputs with '\n', '\r' and "\r\n"
+     * </p>
      *
      * @param recordSeparator
      *            the record separator to use for output.
      *
      * @return A new CSVFormat that is equal to this but with the the specified output record separator
      * @throws IllegalArgumentException
-     *              if recordSeparator is none of CR, LF or CRLF
+     *             if recordSeparator is none of CR, LF or CRLF
      */
     public CSVFormat withRecordSeparator(final String recordSeparator) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 
     /**
@@ -1100,7 +1173,7 @@ public final class CSVFormat implements 
      */
     public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
         return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
-                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header,
-                skipHeaderRecord, allowMissingColumnNames);
+                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, null, header, skipHeaderRecord,
+                allowMissingColumnNames);
     }
 }

Modified: commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java?rev=1638101&r1=1638100&r2=1638101&view=diff
==============================================================================
--- commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java (original)
+++ commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java Tue Nov 11 14:00:47 2014
@@ -501,17 +501,7 @@ public final class CSVPrinter implements
      *             if a database access error occurs
      */
     public void printRecords(final ResultSet resultSet) throws SQLException, IOException {
-        ResultSetMetaData metaData = resultSet.getMetaData();
-        final int columnCount = metaData.getColumnCount();
-        // TODO should printing the header be a parameter to this function or an existing CSVFormat option or a new
-        // CSVFormat option.
-        boolean printHeader = false;
-        if (printHeader) {
-            for (int i = 1; i <= columnCount; i++) {
-                print(metaData.getColumnLabel(i));
-            }
-            println();
-        }
+        final int columnCount = resultSet.getMetaData().getColumnCount();
         while (resultSet.next()) {
             for (int i = 1; i <= columnCount; i++) {
                 print(resultSet.getObject(i));

Modified: commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java?rev=1638101&r1=1638100&r2=1638101&view=diff
==============================================================================
--- commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java (original)
+++ commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java Tue Nov 11 14:00:47 2014
@@ -26,6 +26,7 @@ import java.io.StringReader;
 import java.io.StringWriter;
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Arrays;
@@ -34,7 +35,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
@@ -213,11 +213,15 @@ public class CSVPrinterTest {
         printer.close();
     }
 
+    private Connection geH2Connection() throws SQLException, ClassNotFoundException {
+        Class.forName("org.h2.Driver");
+        return DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
+    }
+
     @Test
     public void testJdbcPrinter() throws IOException, ClassNotFoundException, SQLException {
         final StringWriter sw = new StringWriter();
-        Class.forName("org.h2.Driver");
-        final Connection connection = DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
+        final Connection connection = geH2Connection();
         try {
             final Statement stmt = connection.createStatement();
             setUpTable(stmt);
@@ -230,30 +234,58 @@ public class CSVPrinterTest {
         }
     }
 
-    private void setUpTable(final Statement stmt) throws SQLException {
-        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
-        stmt.execute("insert into TEST values(1, 'r1')");
-        stmt.execute("insert into TEST values(2, 'r2')");
+    @Test
+    public void testJdbcPrinterWithResultSet() throws IOException, ClassNotFoundException, SQLException {
+        final StringWriter sw = new StringWriter();
+        Class.forName("org.h2.Driver");
+        final Connection connection = geH2Connection();
+        try {
+            @SuppressWarnings("resource")
+            // Closed when the connection is closed.
+            final Statement stmt = connection.createStatement();
+            setUpTable(stmt);
+            @SuppressWarnings("resource")
+            // Closed when the connection is closed.
+            final ResultSet resultSet = stmt.executeQuery("select ID, NAME from TEST");
+            final CSVPrinter printer = CSVFormat.DEFAULT.withHeader(resultSet).print(sw);
+            printer.printRecords(resultSet);
+            assertEquals("ID,NAME" + recordSeparator + "1,r1" + recordSeparator + "2,r2" + recordSeparator,
+                    sw.toString());
+            printer.close();
+        } finally {
+            connection.close();
+        }
     }
 
     @Test
-    @Ignore
-    public void testJdbcPrinterWithHeaders() throws IOException, ClassNotFoundException, SQLException {
+    public void testJdbcPrinterWithResultSetMetaData() throws IOException, ClassNotFoundException, SQLException {
         final StringWriter sw = new StringWriter();
         Class.forName("org.h2.Driver");
-        final Connection connection = DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
+        final Connection connection = geH2Connection();
         try {
+            @SuppressWarnings("resource")
+            // Closed when the connection is closed.
             final Statement stmt = connection.createStatement();
             setUpTable(stmt);
-            final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT);
-            printer.printRecords(stmt.executeQuery("select ID, NAME from TEST"));
-            assertEquals("ID,NAME" + recordSeparator + "1,r1" + recordSeparator + "2,r2" + recordSeparator, sw.toString());
+            @SuppressWarnings("resource")
+            // Closed when the connection is closed.
+            final ResultSet resultSet = stmt.executeQuery("select ID, NAME from TEST");
+            final CSVPrinter printer = CSVFormat.DEFAULT.withHeader(resultSet.getMetaData()).print(sw);
+            printer.printRecords(resultSet);
+            assertEquals("ID,NAME" + recordSeparator + "1,r1" + recordSeparator + "2,r2" + recordSeparator,
+                    sw.toString());
             printer.close();
         } finally {
             connection.close();
         }
     }
 
+    private void setUpTable(final Statement stmt) throws SQLException {
+        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
+        stmt.execute("insert into TEST values(1, 'r1')");
+        stmt.execute("insert into TEST values(2, 'r2')");
+    }
+
     @Test
     public void testMultiLineComment() throws IOException {
         final StringWriter sw = new StringWriter();
@@ -523,8 +555,8 @@ public class CSVPrinterTest {
     @Test
     public void testHeaderCommentExcel() throws IOException {
         final StringWriter sw = new StringWriter();
-        Date now = new Date();
-        CSVFormat format = CSVFormat.EXCEL;
+        final Date now = new Date();
+        final CSVFormat format = CSVFormat.EXCEL;
         final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
         assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1,Col2\r\nA,B\r\nC,D\r\n", sw.toString());
         csvPrinter.close();
@@ -533,14 +565,14 @@ public class CSVPrinterTest {
     @Test
     public void testHeaderCommentTdf() throws IOException {
         final StringWriter sw = new StringWriter();
-        Date now = new Date();
-        CSVFormat format = CSVFormat.TDF;
+        final Date now = new Date();
+        final CSVFormat format = CSVFormat.TDF;
         final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
         assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1\tCol2\r\nA\tB\r\nC\tD\r\n", sw.toString());
         csvPrinter.close();
     }
 
-    private CSVPrinter printWithHeaderComments(final StringWriter sw, Date now, CSVFormat baseFormat)
+    private CSVPrinter printWithHeaderComments(final StringWriter sw, final Date now, final CSVFormat baseFormat)
             throws IOException {
         CSVFormat format = baseFormat.withCommentMarker('#').withHeader("Col1", "Col2");
         format = format.withHeaderComments("Generated by Apache Commons CSV 1.1", now);



Re: svn commit: r1638101 - in /commons/proper/csv/trunk/src: changes/changes.xml main/java/org/apache/commons/csv/CSVFormat.java main/java/org/apache/commons/csv/CSVPrinter.java test/java/org/apache/commons/csv/CSVPrinterTest.java

Posted by Gary Gregory <ga...@gmail.com>.
On Tue, Nov 11, 2014 at 9:18 AM, Benedikt Ritter <br...@apache.org> wrote:

> Hello Gary,
>
> it looks like you've also reformatted the source code, which makes it
> harder to review the actual changes for CSV-139. I'd rather do reformatting
> in a seperate commit. WDYT?
>

I agree, that was an unintentional mistake on my part. Please accept my
apologies for the noise.

Gary

>
> Benedikt
>
> 2014-11-11 15:00 GMT+01:00 <gg...@apache.org>:
>
> > Author: ggregory
> > Date: Tue Nov 11 14:00:47 2014
> > New Revision: 1638101
> >
> > URL: http://svn.apache.org/r1638101
> > Log:
> > [CSV-139] CSVPrinter.printRecord(ResultSet) with metadata.
> >
> > Modified:
> >     commons/proper/csv/trunk/src/changes/changes.xml
> >
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> >
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> >
> >
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> >
> > Modified: commons/proper/csv/trunk/src/changes/changes.xml
> > URL:
> >
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/changes/changes.xml?rev=1638101&r1=1638100&r2=1638101&view=diff
> >
> >
> ==============================================================================
> > --- commons/proper/csv/trunk/src/changes/changes.xml (original)
> > +++ commons/proper/csv/trunk/src/changes/changes.xml Tue Nov 11 14:00:47
> > 2014
> > @@ -46,6 +46,7 @@
> >        <action issue="CSV-124" type="update" dev="brentworden"
> > due-to="Kalyan">Improve toString() implementation of CSVRecord</action>
> >        <action issue="CSV-129" type="add" dev="ggregory">Add
> > CSVFormat#with 0-arg methods matching boolean arg methods</action>
> >        <action issue="CSV-131" type="add" dev="ggregory" due-to="Holger
> > Stratmann">Save positions of records to enable random access</action>
> > +      <action issue="CSV-139" type="add"
> > dev="ggregory">CSVPrinter.printRecord(ResultSet) with metadata</action>
> >      </release>
> >      <release version="1.0" date="2014-08-14" description="First
> release">
> >        <action issue="CSV-125" type="fix" dev="britter">No longer works
> > with Java 6</action>
> >
> > Modified:
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> > URL:
> >
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java?rev=1638101&r1=1638100&r2=1638101&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> > (original)
> > +++
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> > Tue Nov 11 14:00:47 2014
> > @@ -29,6 +29,9 @@ import java.io.IOException;
> >  import java.io.Reader;
> >  import java.io.Serializable;
> >  import java.io.StringWriter;
> > +import java.sql.ResultSet;
> > +import java.sql.ResultSetMetaData;
> > +import java.sql.SQLException;
> >  import java.util.Arrays;
> >  import java.util.HashSet;
> >  import java.util.Set;
> > @@ -43,11 +46,11 @@ import java.util.Set;
> >   * </p>
> >   *
> >   * <ul>
> > - *      <li>{@link #DEFAULT}</li>
> > - *      <li>{@link #EXCEL}</li>
> > - *      <li>{@link #MYSQL}</li>
> > - *      <li>{@link #RFC4180}</li>
> > - *      <li>{@link #TDF}</li>
> > + * <li>{@link #DEFAULT}</li>
> > + * <li>{@link #EXCEL}</li>
> > + * <li>{@link #MYSQL}</li>
> > + * <li>{@link #RFC4180}</li>
> > + * <li>{@link #TDF}</li>
> >   * </ul>
> >   *
> >   * <p>
> > @@ -62,7 +65,9 @@ import java.util.Set;
> >   * The {@link CSVParser} provides static methods to parse other input
> > types, for example:
> >   * </p>
> >   *
> > - * <pre>CSVParser parser = CSVParser.parse(file,
> > StandardCharsets.US_ASCII, CSVFormat.EXCEL);</pre>
> > + * <pre>
> > + * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII,
> > CSVFormat.EXCEL);
> > + * </pre>
> >   *
> >   * <h2>Defining formats</h2>
> >   *
> > @@ -71,9 +76,7 @@ import java.util.Set;
> >   * </p>
> >   *
> >   * <pre>
> > - * CSVFormat.EXCEL
> > - *   .withNullString(&quot;N/A&quot;)
> > - *   .withIgnoreSurroundingSpaces(true);
> > + *
> >
> CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
> >   * </pre>
> >   *
> >   * <h2>Defining column names</h2>
> > @@ -112,8 +115,8 @@ import java.util.Set;
> >   * <h2>Referencing columns safely</h2>
> >   *
> >   * <p>
> > - * If your source contains a header record, you can simplify your code
> > and safely reference columns,
> > - * by using {@link #withHeader(String...)} with no arguments:
> > + * If your source contains a header record, you can simplify your code
> > and safely reference columns, by using
> > + * {@link #withHeader(String...)} with no arguments:
> >   * </p>
> >   *
> >   * <pre>
> > @@ -167,14 +170,14 @@ public final class CSVFormat implements
> >       * Settings are:
> >       * </p>
> >       * <ul>
> > -     *   <li>withDelimiter(',')</li>
> > -     *   <li>withQuote('"')</li>
> > -     *   <li>withRecordSeparator("\r\n")</li>
> > -     *   <li>withIgnoreEmptyLines(true)</li>
> > +     * <li>withDelimiter(',')</li>
> > +     * <li>withQuote('"')</li>
> > +     * <li>withRecordSeparator("\r\n")</li>
> > +     * <li>withIgnoreEmptyLines(true)</li>
> >       * </ul>
> >       */
> > -    public static final CSVFormat DEFAULT = new CSVFormat(COMMA,
> > DOUBLE_QUOTE_CHAR, null, null, null,
> > -                                                            false, true,
> > CRLF, null, null, null, false, false);
> > +    public static final CSVFormat DEFAULT = new CSVFormat(COMMA,
> > DOUBLE_QUOTE_CHAR, null, null, null, false, true,
> > +            CRLF, null, null, null, false, false);
> >
> >      /**
> >       * Comma separated format as defined by <a href="
> > http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
> > @@ -183,10 +186,10 @@ public final class CSVFormat implements
> >       * Settings are:
> >       * </p>
> >       * <ul>
> > -     *   <li>withDelimiter(',')</li>
> > -     *   <li>withQuote('"')</li>
> > -     *   <li>withRecordSeparator("\r\n")</li>
> > -     *   <li>withIgnoreEmptyLines(false)</li>
> > +     * <li>withDelimiter(',')</li>
> > +     * <li>withQuote('"')</li>
> > +     * <li>withRecordSeparator("\r\n")</li>
> > +     * <li>withIgnoreEmptyLines(false)</li>
> >       * </ul>
> >       */
> >      public static final CSVFormat RFC4180 =
> > DEFAULT.withIgnoreEmptyLines(false);
> > @@ -227,16 +230,13 @@ public final class CSVFormat implements
> >       * Settings are:
> >       * </p>
> >       * <ul>
> > -     *   <li>withDelimiter('\t')</li>
> > -     *   <li>withQuote('"')</li>
> > -     *   <li>withRecordSeparator("\r\n")</li>
> > -     *   <li>withIgnoreSurroundingSpaces(true)</li>
> > +     * <li>withDelimiter('\t')</li>
> > +     * <li>withQuote('"')</li>
> > +     * <li>withRecordSeparator("\r\n")</li>
> > +     * <li>withIgnoreSurroundingSpaces(true)</li>
> >       * </ul>
> >       */
> > -    public static final CSVFormat TDF =
> > -            DEFAULT
> > -            .withDelimiter(TAB)
> > -            .withIgnoreSurroundingSpaces();
> > +    public static final CSVFormat TDF =
> > DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
> >
> >      /**
> >       * Default MySQL format used by the {@code SELECT INTO OUTFILE} and
> > {@code LOAD DATA INFILE} operations.
> > @@ -250,22 +250,18 @@ public final class CSVFormat implements
> >       * Settings are:
> >       * </p>
> >       * <ul>
> > -     *   <li>withDelimiter('\t')</li>
> > -     *   <li>withQuote(null)</li>
> > -     *   <li>withRecordSeparator('\n')</li>
> > -     *   <li>withIgnoreEmptyLines(false)</li>
> > -     *   <li>withEscape('\\')</li>
> > +     * <li>withDelimiter('\t')</li>
> > +     * <li>withQuote(null)</li>
> > +     * <li>withRecordSeparator('\n')</li>
> > +     * <li>withIgnoreEmptyLines(false)</li>
> > +     * <li>withEscape('\\')</li>
> >       * </ul>
> > +     *
> >       * @see <a href="
> > http://dev.mysql.com/doc/refman/5.1/en/load-data.html">
> >       *      http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
> >       */
> > -    public static final CSVFormat MYSQL =
> > -            DEFAULT
> > -            .withDelimiter(TAB)
> > -            .withEscape(BACKSLASH)
> > -            .withIgnoreEmptyLines(false)
> > -            .withQuote(null)
> > -            .withRecordSeparator(LF);
> > +    public static final CSVFormat MYSQL =
> >
> DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
> > +            .withQuote(null).withRecordSeparator(LF);
> >
> >      /**
> >       * Returns true if the given character is a line break character.
> > @@ -294,13 +290,16 @@ public final class CSVFormat implements
> >      /**
> >       * Creates a new CSV format with the specified delimiter.
> >       *
> > -     * <p>Use this method if you want to create a CSVFormat from
> scratch.
> > All fields but the delimiter will be
> > -     * initialized with null/false.</p>
> > +     * <p>
> > +     * Use this method if you want to create a CSVFormat from scratch.
> > All fields but the delimiter will be initialized
> > +     * with null/false.
> > +     * </p>
> >       *
> >       * @param delimiter
> >       *            the char used for value separation, must not be a line
> > break character
> >       * @return a new CSV format.
> > -     * @throws IllegalArgumentException if the delimiter is a line break
> > character
> > +     * @throws IllegalArgumentException
> > +     *             if the delimiter is a line break character
> >       *
> >       * @see #DEFAULT
> >       * @see #RFC4180
> > @@ -337,16 +336,18 @@ public final class CSVFormat implements
> >       *            the comments to be printed by the Printer before the
> > actual CSV data
> >       * @param header
> >       *            the header
> > -     * @param skipHeaderRecord TODO
> > -     * @param allowMissingColumnNames TODO
> > -     * @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) {
> > +     * @param skipHeaderRecord
> > +     *            TODO
> > +     * @param allowMissingColumnNames
> > +     *            TODO
> > +     * @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) {
> >          if (isLineBreak(delimiter)) {
> >              throw new IllegalArgumentException("The delimiter cannot be
> a
> > line break");
> >          }
> > @@ -377,13 +378,13 @@ public final class CSVFormat implements
> >          validate();
> >      }
> >
> > -    private String[] toStringArray(Object[] values) {
> > +    private String[] toStringArray(final Object[] values) {
> >          if (values == null) {
> >              return null;
> >          }
> > -        String[] strings = new String[values.length];
> > +        final String[] strings = new String[values.length];
> >          for (int i = 0; i < values.length; i++) {
> > -            Object value = values[i];
> > +            final Object value = values[i];
> >              strings[i] = value == null ? null : value.toString();
> >          }
> >          return strings;
> > @@ -544,8 +545,7 @@ public final class CSVFormat implements
> >      /**
> >       * Specifies whether spaces around values are ignored when parsing
> > input.
> >       *
> > -     * @return {@code true} if spaces around values are ignored, {@code
> > false} if they are treated as part of the
> > -     *         value.
> > +     * @return {@code true} if spaces around values are ignored, {@code
> > false} if they are treated as part of the value.
> >       */
> >      public boolean getIgnoreSurroundingSpaces() {
> >          return ignoreSurroundingSpaces;
> > @@ -556,8 +556,7 @@ public final class CSVFormat implements
> >       * <ul>
> >       * <li>
> >       * <strong>Reading:</strong> Converts strings equal to the given
> > {@code nullString} to {@code null} when reading
> > -     * records.
> > -     * </li>
> > +     * records.</li>
> >       * <li>
> >       * <strong>Writing:</strong> Writes {@code null} as the given {@code
> > nullString} when writing records.</li>
> >       * </ul>
> > @@ -605,8 +604,7 @@ public final class CSVFormat implements
> >      }
> >
> >      @Override
> > -    public int hashCode()
> > -    {
> > +    public int hashCode() {
> >          final int prime = 31;
> >          int result = 1;
> >
> > @@ -687,10 +685,10 @@ public final class CSVFormat implements
> >       * </p>
> >       *
> >       * @param out
> > -     *        the output
> > +     *            the output
> >       * @return a printer to an output
> >       * @throws IOException
> > -     *         thrown if the optional header cannot be printed.
> > +     *             thrown if the optional header cannot be printed.
> >       */
> >      public CSVPrinter print(final Appendable out) throws IOException {
> >          return new CSVPrinter(out, this);
> > @@ -716,7 +714,7 @@ public final class CSVFormat implements
> >              sb.append(' ');
> >              sb.append("NullString=<").append(nullString).append('>');
> >          }
> > -        if(recordSeparator != null) {
> > +        if (recordSeparator != null) {
> >              sb.append(' ');
> >
> >  sb.append("RecordSeparator=<").append(recordSeparator).append('>');
> >          }
> > @@ -745,28 +743,28 @@ public final class CSVFormat implements
> >       */
> >      private void validate() throws IllegalArgumentException {
> >          if (quoteCharacter != null && delimiter ==
> > quoteCharacter.charValue()) {
> > -            throw new IllegalArgumentException(
> > -                    "The quoteChar character and the delimiter cannot be
> > the same ('" + quoteCharacter + "')");
> > +            throw new IllegalArgumentException("The quoteChar character
> > and the delimiter cannot be the same ('" +
> > +                    quoteCharacter + "')");
> >          }
> >
> >          if (escapeCharacter != null && delimiter ==
> > escapeCharacter.charValue()) {
> > -            throw new IllegalArgumentException(
> > -                    "The escape character and the delimiter cannot be
> the
> > same ('" + escapeCharacter + "')");
> > +            throw new IllegalArgumentException("The escape character and
> > the delimiter cannot be the same ('" +
> > +                    escapeCharacter + "')");
> >          }
> >
> >          if (commentMarker != null && delimiter ==
> > commentMarker.charValue()) {
> > -            throw new IllegalArgumentException(
> > -                    "The comment start character and the delimiter
> cannot
> > be the same ('" + commentMarker + "')");
> > +            throw new IllegalArgumentException("The comment start
> > character and the delimiter cannot be the same ('" +
> > +                    commentMarker + "')");
> >          }
> >
> >          if (quoteCharacter != null &&
> > quoteCharacter.equals(commentMarker)) {
> > -            throw new IllegalArgumentException(
> > -                    "The comment start character and the quoteChar
> cannot
> > be the same ('" + commentMarker + "')");
> > +            throw new IllegalArgumentException("The comment start
> > character and the quoteChar cannot be the same ('" +
> > +                    commentMarker + "')");
> >          }
> >
> >          if (escapeCharacter != null &&
> > escapeCharacter.equals(commentMarker)) {
> > -            throw new IllegalArgumentException(
> > -                    "The comment start and the escape character cannot
> be
> > the same ('" + commentMarker + "')");
> > +            throw new IllegalArgumentException("The comment start and
> the
> > escape character cannot be the same ('" +
> > +                    commentMarker + "')");
> >          }
> >
> >          if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
> > @@ -805,8 +803,8 @@ public final class CSVFormat implements
> >              throw new IllegalArgumentException("The comment start marker
> > character cannot be a line break");
> >          }
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -823,8 +821,8 @@ public final class CSVFormat implements
> >              throw new IllegalArgumentException("The delimiter cannot be
> a
> > line break");
> >          }
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -853,21 +851,25 @@ public final class CSVFormat implements
> >          if (isLineBreak(escape)) {
> >              throw new IllegalArgumentException("The escape character
> > cannot be a line break");
> >          }
> > -        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escape,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escape, ignoreSurroundingSpaces,
> > +                ignoreEmptyLines, recordSeparator, nullString, null,
> > header, skipHeaderRecord, allowMissingColumnNames);
> >      }
> >
> >      /**
> >       * Sets the header of the format. The header can either be parsed
> > automatically from the input file with:
> >       *
> >       * <pre>
> > -     * CSVFormat format = aformat.withHeader();</pre>
> > +     * CSVFormat format = aformat.withHeader();
> > +     * </pre>
> >       *
> >       * or specified manually with:
> >       *
> >       * <pre>
> > -     * CSVFormat format = aformat.withHeader(&quot;name&quot;,
> > &quot;email&quot;, &quot;phone&quot;);</pre>
> > +     * CSVFormat format = aformat.withHeader(&quot;name&quot;,
> > &quot;email&quot;, &quot;phone&quot;);
> > +     * </pre>
> > +     * <p>
> > +     * The header is also used by the {@link CSVPrinter}..
> > +     * </p>
> >       *
> >       * @param header
> >       *            the header, {@code null} if disabled, empty if parsed
> > automatically, user specified otherwise.
> > @@ -877,8 +879,76 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withHeader(final String... header) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> > +    }
> > +
> > +    /**
> > +     * Sets the header of the format. The header can either be parsed
> > automatically from the input file with:
> > +     *
> > +     * <pre>
> > +     * CSVFormat format = aformat.withHeader();
> > +     * </pre>
> > +     *
> > +     * or specified manually with:
> > +     *
> > +     * <pre>
> > +     * CSVFormat format = aformat.withHeader(resultSet);
> > +     * </pre>
> > +     * <p>
> > +     * The header is also used by the {@link CSVPrinter}..
> > +     * </p>
> > +     *
> > +     * @param resultSet
> > +     *            the resultSet for the header, {@code null} if
> disabled,
> > empty if parsed automatically, user specified
> > +     *            otherwise.
> > +     *
> > +     * @return A new CSVFormat that is equal to this but with the
> > specified header
> > +     * @throws SQLException
> > +     *             SQLException if a database access error occurs or
> this
> > method is called on a closed result set.
> > +     * @since 1.1
> > +     */
> > +    public CSVFormat withHeader(final ResultSet resultSet) throws
> > SQLException {
> > +        return withHeader(resultSet != null ? resultSet.getMetaData() :
> > null);
> > +    }
> > +
> > +    /**
> > +     * Sets the header of the format. The header can either be parsed
> > automatically from the input file with:
> > +     *
> > +     * <pre>
> > +     * CSVFormat format = aformat.withHeader();
> > +     * </pre>
> > +     *
> > +     * or specified manually with:
> > +     *
> > +     * <pre>
> > +     * CSVFormat format = aformat.withHeader(metaData);
> > +     * </pre>
> > +     * <p>
> > +     * The header is also used by the {@link CSVPrinter}..
> > +     * </p>
> > +     *
> > +     * @param metaData
> > +     *            the metaData for the header, {@code null} if disabled,
> > empty if parsed automatically, user specified
> > +     *            otherwise.
> > +     *
> > +     * @return A new CSVFormat that is equal to this but with the
> > specified header
> > +     * @throws SQLException
> > +     *             SQLException if a database access error occurs or
> this
> > method is called on a closed result set.
> > +     * @since 1.1
> > +     */
> > +    public CSVFormat withHeader(final ResultSetMetaData metaData) throws
> > SQLException {
> > +        String[] labels = null;
> > +        if (metaData != null) {
> > +            final int columnCount = metaData.getColumnCount();
> > +            labels = new String[columnCount];
> > +            for (int i = 0; i < columnCount; i++) {
> > +                labels[i] = metaData.getColumnLabel(i + 1);
> > +            }
> > +        }
> > +        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, labels, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -923,8 +993,8 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withAllowMissingColumnNames(final boolean
> > allowMissingColumnNames) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -948,8 +1018,8 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withIgnoreEmptyLines(final boolean
> ignoreEmptyLines)
> > {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -973,8 +1043,8 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withIgnoreSurroundingSpaces(final boolean
> > ignoreSurroundingSpaces) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -994,8 +1064,8 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withNullString(final String nullString) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -1024,9 +1094,8 @@ public final class CSVFormat implements
> >          if (isLineBreak(quoteChar)) {
> >              throw new IllegalArgumentException("The quoteChar cannot be
> a
> > line break");
> >          }
> > -        return new CSVFormat(delimiter, quoteChar, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +        return new CSVFormat(delimiter, quoteChar, quoteMode,
> > commentMarker, escapeCharacter, ignoreSurroundingSpaces,
> > +                ignoreEmptyLines, recordSeparator, nullString, null,
> > header, skipHeaderRecord, allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -1039,15 +1108,17 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> >       * Sets the record separator of the format to the specified
> character.
> >       *
> > -     * <p><strong>Note:</strong> This setting is only used during
> > printing and does not affect parsing. Parsing
> > -     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
> > +     * <p>
> > +     * <strong>Note:</strong> This setting is only used during printing
> > and does not affect parsing. Parsing currently
> > +     * only works for inputs with '\n', '\r' and "\r\n"
> > +     * </p>
> >       *
> >       * @param recordSeparator
> >       *            the record separator to use for output.
> > @@ -1061,20 +1132,22 @@ public final class CSVFormat implements
> >      /**
> >       * Sets the record separator of the format to the specified String.
> >       *
> > -     * <p><strong>Note:</strong> This setting is only used during
> > printing and does not affect parsing. Parsing
> > -     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
> > +     * <p>
> > +     * <strong>Note:</strong> This setting is only used during printing
> > and does not affect parsing. Parsing currently
> > +     * only works for inputs with '\n', '\r' and "\r\n"
> > +     * </p>
> >       *
> >       * @param recordSeparator
> >       *            the record separator to use for output.
> >       *
> >       * @return A new CSVFormat that is equal to this but with the the
> > specified output record separator
> >       * @throws IllegalArgumentException
> > -     *              if recordSeparator is none of CR, LF or CRLF
> > +     *             if recordSeparator is none of CR, LF or CRLF
> >       */
> >      public CSVFormat withRecordSeparator(final String recordSeparator) {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >
> >      /**
> > @@ -1100,7 +1173,7 @@ public final class CSVFormat implements
> >       */
> >      public CSVFormat withSkipHeaderRecord(final boolean
> skipHeaderRecord)
> > {
> >          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> > commentMarker, escapeCharacter,
> > -                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header,
> > -                skipHeaderRecord, allowMissingColumnNames);
> > +                ignoreSurroundingSpaces, ignoreEmptyLines,
> > recordSeparator, nullString, null, header, skipHeaderRecord,
> > +                allowMissingColumnNames);
> >      }
> >  }
> >
> > Modified:
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> > URL:
> >
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java?rev=1638101&r1=1638100&r2=1638101&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> > (original)
> > +++
> >
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> > Tue Nov 11 14:00:47 2014
> > @@ -501,17 +501,7 @@ public final class CSVPrinter implements
> >       *             if a database access error occurs
> >       */
> >      public void printRecords(final ResultSet resultSet) throws
> > SQLException, IOException {
> > -        ResultSetMetaData metaData = resultSet.getMetaData();
> > -        final int columnCount = metaData.getColumnCount();
> > -        // TODO should printing the header be a parameter to this
> > function or an existing CSVFormat option or a new
> > -        // CSVFormat option.
> > -        boolean printHeader = false;
> > -        if (printHeader) {
> > -            for (int i = 1; i <= columnCount; i++) {
> > -                print(metaData.getColumnLabel(i));
> > -            }
> > -            println();
> > -        }
> > +        final int columnCount =
> resultSet.getMetaData().getColumnCount();
> >          while (resultSet.next()) {
> >              for (int i = 1; i <= columnCount; i++) {
> >                  print(resultSet.getObject(i));
> >
> > Modified:
> >
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> > URL:
> >
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java?rev=1638101&r1=1638100&r2=1638101&view=diff
> >
> >
> ==============================================================================
> > ---
> >
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> > (original)
> > +++
> >
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> > Tue Nov 11 14:00:47 2014
> > @@ -26,6 +26,7 @@ import java.io.StringReader;
> >  import java.io.StringWriter;
> >  import java.sql.Connection;
> >  import java.sql.DriverManager;
> > +import java.sql.ResultSet;
> >  import java.sql.SQLException;
> >  import java.sql.Statement;
> >  import java.util.Arrays;
> > @@ -34,7 +35,6 @@ import java.util.Iterator;
> >  import java.util.List;
> >  import java.util.Random;
> >
> > -import org.junit.Ignore;
> >  import org.junit.Test;
> >
> >  /**
> > @@ -213,11 +213,15 @@ public class CSVPrinterTest {
> >          printer.close();
> >      }
> >
> > +    private Connection geH2Connection() throws SQLException,
> > ClassNotFoundException {
> > +        Class.forName("org.h2.Driver");
> > +        return DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa",
> > "");
> > +    }
> > +
> >      @Test
> >      public void testJdbcPrinter() throws IOException,
> > ClassNotFoundException, SQLException {
> >          final StringWriter sw = new StringWriter();
> > -        Class.forName("org.h2.Driver");
> > -        final Connection connection =
> > DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
> > +        final Connection connection = geH2Connection();
> >          try {
> >              final Statement stmt = connection.createStatement();
> >              setUpTable(stmt);
> > @@ -230,30 +234,58 @@ public class CSVPrinterTest {
> >          }
> >      }
> >
> > -    private void setUpTable(final Statement stmt) throws SQLException {
> > -        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME
> > VARCHAR(255))");
> > -        stmt.execute("insert into TEST values(1, 'r1')");
> > -        stmt.execute("insert into TEST values(2, 'r2')");
> > +    @Test
> > +    public void testJdbcPrinterWithResultSet() throws IOException,
> > ClassNotFoundException, SQLException {
> > +        final StringWriter sw = new StringWriter();
> > +        Class.forName("org.h2.Driver");
> > +        final Connection connection = geH2Connection();
> > +        try {
> > +            @SuppressWarnings("resource")
> > +            // Closed when the connection is closed.
> > +            final Statement stmt = connection.createStatement();
> > +            setUpTable(stmt);
> > +            @SuppressWarnings("resource")
> > +            // Closed when the connection is closed.
> > +            final ResultSet resultSet = stmt.executeQuery("select ID,
> > NAME from TEST");
> > +            final CSVPrinter printer =
> > CSVFormat.DEFAULT.withHeader(resultSet).print(sw);
> > +            printer.printRecords(resultSet);
> > +            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> > recordSeparator + "2,r2" + recordSeparator,
> > +                    sw.toString());
> > +            printer.close();
> > +        } finally {
> > +            connection.close();
> > +        }
> >      }
> >
> >      @Test
> > -    @Ignore
> > -    public void testJdbcPrinterWithHeaders() throws IOException,
> > ClassNotFoundException, SQLException {
> > +    public void testJdbcPrinterWithResultSetMetaData() throws
> > IOException, ClassNotFoundException, SQLException {
> >          final StringWriter sw = new StringWriter();
> >          Class.forName("org.h2.Driver");
> > -        final Connection connection =
> > DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
> > +        final Connection connection = geH2Connection();
> >          try {
> > +            @SuppressWarnings("resource")
> > +            // Closed when the connection is closed.
> >              final Statement stmt = connection.createStatement();
> >              setUpTable(stmt);
> > -            final CSVPrinter printer = new CSVPrinter(sw,
> > CSVFormat.DEFAULT);
> > -            printer.printRecords(stmt.executeQuery("select ID, NAME from
> > TEST"));
> > -            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> > recordSeparator + "2,r2" + recordSeparator, sw.toString());
> > +            @SuppressWarnings("resource")
> > +            // Closed when the connection is closed.
> > +            final ResultSet resultSet = stmt.executeQuery("select ID,
> > NAME from TEST");
> > +            final CSVPrinter printer =
> > CSVFormat.DEFAULT.withHeader(resultSet.getMetaData()).print(sw);
> > +            printer.printRecords(resultSet);
> > +            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> > recordSeparator + "2,r2" + recordSeparator,
> > +                    sw.toString());
> >              printer.close();
> >          } finally {
> >              connection.close();
> >          }
> >      }
> >
> > +    private void setUpTable(final Statement stmt) throws SQLException {
> > +        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME
> > VARCHAR(255))");
> > +        stmt.execute("insert into TEST values(1, 'r1')");
> > +        stmt.execute("insert into TEST values(2, 'r2')");
> > +    }
> > +
> >      @Test
> >      public void testMultiLineComment() throws IOException {
> >          final StringWriter sw = new StringWriter();
> > @@ -523,8 +555,8 @@ public class CSVPrinterTest {
> >      @Test
> >      public void testHeaderCommentExcel() throws IOException {
> >          final StringWriter sw = new StringWriter();
> > -        Date now = new Date();
> > -        CSVFormat format = CSVFormat.EXCEL;
> > +        final Date now = new Date();
> > +        final CSVFormat format = CSVFormat.EXCEL;
> >          final CSVPrinter csvPrinter = printWithHeaderComments(sw, now,
> > format);
> >          assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now
> > + "\r\nCol1,Col2\r\nA,B\r\nC,D\r\n", sw.toString());
> >          csvPrinter.close();
> > @@ -533,14 +565,14 @@ public class CSVPrinterTest {
> >      @Test
> >      public void testHeaderCommentTdf() throws IOException {
> >          final StringWriter sw = new StringWriter();
> > -        Date now = new Date();
> > -        CSVFormat format = CSVFormat.TDF;
> > +        final Date now = new Date();
> > +        final CSVFormat format = CSVFormat.TDF;
> >          final CSVPrinter csvPrinter = printWithHeaderComments(sw, now,
> > format);
> >          assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now
> > + "\r\nCol1\tCol2\r\nA\tB\r\nC\tD\r\n", sw.toString());
> >          csvPrinter.close();
> >      }
> >
> > -    private CSVPrinter printWithHeaderComments(final StringWriter sw,
> > Date now, CSVFormat baseFormat)
> > +    private CSVPrinter printWithHeaderComments(final StringWriter sw,
> > final Date now, final CSVFormat baseFormat)
> >              throws IOException {
> >          CSVFormat format =
> > baseFormat.withCommentMarker('#').withHeader("Col1", "Col2");
> >          format = format.withHeaderComments("Generated by Apache Commons
> > CSV 1.1", now);
> >
> >
> >
>
>
> --
> http://people.apache.org/~britter/
> http://www.systemoutprintln.de/
> http://twitter.com/BenediktRitter
> http://github.com/britter
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Re: svn commit: r1638101 - in /commons/proper/csv/trunk/src: changes/changes.xml main/java/org/apache/commons/csv/CSVFormat.java main/java/org/apache/commons/csv/CSVPrinter.java test/java/org/apache/commons/csv/CSVPrinterTest.java

Posted by Benedikt Ritter <br...@apache.org>.
Hello Gary,

it looks like you've also reformatted the source code, which makes it
harder to review the actual changes for CSV-139. I'd rather do reformatting
in a seperate commit. WDYT?

Benedikt

2014-11-11 15:00 GMT+01:00 <gg...@apache.org>:

> Author: ggregory
> Date: Tue Nov 11 14:00:47 2014
> New Revision: 1638101
>
> URL: http://svn.apache.org/r1638101
> Log:
> [CSV-139] CSVPrinter.printRecord(ResultSet) with metadata.
>
> Modified:
>     commons/proper/csv/trunk/src/changes/changes.xml
>
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
>
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
>
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
>
> Modified: commons/proper/csv/trunk/src/changes/changes.xml
> URL:
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/changes/changes.xml?rev=1638101&r1=1638100&r2=1638101&view=diff
>
> ==============================================================================
> --- commons/proper/csv/trunk/src/changes/changes.xml (original)
> +++ commons/proper/csv/trunk/src/changes/changes.xml Tue Nov 11 14:00:47
> 2014
> @@ -46,6 +46,7 @@
>        <action issue="CSV-124" type="update" dev="brentworden"
> due-to="Kalyan">Improve toString() implementation of CSVRecord</action>
>        <action issue="CSV-129" type="add" dev="ggregory">Add
> CSVFormat#with 0-arg methods matching boolean arg methods</action>
>        <action issue="CSV-131" type="add" dev="ggregory" due-to="Holger
> Stratmann">Save positions of records to enable random access</action>
> +      <action issue="CSV-139" type="add"
> dev="ggregory">CSVPrinter.printRecord(ResultSet) with metadata</action>
>      </release>
>      <release version="1.0" date="2014-08-14" description="First release">
>        <action issue="CSV-125" type="fix" dev="britter">No longer works
> with Java 6</action>
>
> Modified:
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java?rev=1638101&r1=1638100&r2=1638101&view=diff
>
> ==============================================================================
> ---
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> (original)
> +++
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVFormat.java
> Tue Nov 11 14:00:47 2014
> @@ -29,6 +29,9 @@ import java.io.IOException;
>  import java.io.Reader;
>  import java.io.Serializable;
>  import java.io.StringWriter;
> +import java.sql.ResultSet;
> +import java.sql.ResultSetMetaData;
> +import java.sql.SQLException;
>  import java.util.Arrays;
>  import java.util.HashSet;
>  import java.util.Set;
> @@ -43,11 +46,11 @@ import java.util.Set;
>   * </p>
>   *
>   * <ul>
> - *      <li>{@link #DEFAULT}</li>
> - *      <li>{@link #EXCEL}</li>
> - *      <li>{@link #MYSQL}</li>
> - *      <li>{@link #RFC4180}</li>
> - *      <li>{@link #TDF}</li>
> + * <li>{@link #DEFAULT}</li>
> + * <li>{@link #EXCEL}</li>
> + * <li>{@link #MYSQL}</li>
> + * <li>{@link #RFC4180}</li>
> + * <li>{@link #TDF}</li>
>   * </ul>
>   *
>   * <p>
> @@ -62,7 +65,9 @@ import java.util.Set;
>   * The {@link CSVParser} provides static methods to parse other input
> types, for example:
>   * </p>
>   *
> - * <pre>CSVParser parser = CSVParser.parse(file,
> StandardCharsets.US_ASCII, CSVFormat.EXCEL);</pre>
> + * <pre>
> + * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII,
> CSVFormat.EXCEL);
> + * </pre>
>   *
>   * <h2>Defining formats</h2>
>   *
> @@ -71,9 +76,7 @@ import java.util.Set;
>   * </p>
>   *
>   * <pre>
> - * CSVFormat.EXCEL
> - *   .withNullString(&quot;N/A&quot;)
> - *   .withIgnoreSurroundingSpaces(true);
> + *
> CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
>   * </pre>
>   *
>   * <h2>Defining column names</h2>
> @@ -112,8 +115,8 @@ import java.util.Set;
>   * <h2>Referencing columns safely</h2>
>   *
>   * <p>
> - * If your source contains a header record, you can simplify your code
> and safely reference columns,
> - * by using {@link #withHeader(String...)} with no arguments:
> + * If your source contains a header record, you can simplify your code
> and safely reference columns, by using
> + * {@link #withHeader(String...)} with no arguments:
>   * </p>
>   *
>   * <pre>
> @@ -167,14 +170,14 @@ public final class CSVFormat implements
>       * Settings are:
>       * </p>
>       * <ul>
> -     *   <li>withDelimiter(',')</li>
> -     *   <li>withQuote('"')</li>
> -     *   <li>withRecordSeparator("\r\n")</li>
> -     *   <li>withIgnoreEmptyLines(true)</li>
> +     * <li>withDelimiter(',')</li>
> +     * <li>withQuote('"')</li>
> +     * <li>withRecordSeparator("\r\n")</li>
> +     * <li>withIgnoreEmptyLines(true)</li>
>       * </ul>
>       */
> -    public static final CSVFormat DEFAULT = new CSVFormat(COMMA,
> DOUBLE_QUOTE_CHAR, null, null, null,
> -                                                            false, true,
> CRLF, null, null, null, false, false);
> +    public static final CSVFormat DEFAULT = new CSVFormat(COMMA,
> DOUBLE_QUOTE_CHAR, null, null, null, false, true,
> +            CRLF, null, null, null, false, false);
>
>      /**
>       * Comma separated format as defined by <a href="
> http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
> @@ -183,10 +186,10 @@ public final class CSVFormat implements
>       * Settings are:
>       * </p>
>       * <ul>
> -     *   <li>withDelimiter(',')</li>
> -     *   <li>withQuote('"')</li>
> -     *   <li>withRecordSeparator("\r\n")</li>
> -     *   <li>withIgnoreEmptyLines(false)</li>
> +     * <li>withDelimiter(',')</li>
> +     * <li>withQuote('"')</li>
> +     * <li>withRecordSeparator("\r\n")</li>
> +     * <li>withIgnoreEmptyLines(false)</li>
>       * </ul>
>       */
>      public static final CSVFormat RFC4180 =
> DEFAULT.withIgnoreEmptyLines(false);
> @@ -227,16 +230,13 @@ public final class CSVFormat implements
>       * Settings are:
>       * </p>
>       * <ul>
> -     *   <li>withDelimiter('\t')</li>
> -     *   <li>withQuote('"')</li>
> -     *   <li>withRecordSeparator("\r\n")</li>
> -     *   <li>withIgnoreSurroundingSpaces(true)</li>
> +     * <li>withDelimiter('\t')</li>
> +     * <li>withQuote('"')</li>
> +     * <li>withRecordSeparator("\r\n")</li>
> +     * <li>withIgnoreSurroundingSpaces(true)</li>
>       * </ul>
>       */
> -    public static final CSVFormat TDF =
> -            DEFAULT
> -            .withDelimiter(TAB)
> -            .withIgnoreSurroundingSpaces();
> +    public static final CSVFormat TDF =
> DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
>
>      /**
>       * Default MySQL format used by the {@code SELECT INTO OUTFILE} and
> {@code LOAD DATA INFILE} operations.
> @@ -250,22 +250,18 @@ public final class CSVFormat implements
>       * Settings are:
>       * </p>
>       * <ul>
> -     *   <li>withDelimiter('\t')</li>
> -     *   <li>withQuote(null)</li>
> -     *   <li>withRecordSeparator('\n')</li>
> -     *   <li>withIgnoreEmptyLines(false)</li>
> -     *   <li>withEscape('\\')</li>
> +     * <li>withDelimiter('\t')</li>
> +     * <li>withQuote(null)</li>
> +     * <li>withRecordSeparator('\n')</li>
> +     * <li>withIgnoreEmptyLines(false)</li>
> +     * <li>withEscape('\\')</li>
>       * </ul>
> +     *
>       * @see <a href="
> http://dev.mysql.com/doc/refman/5.1/en/load-data.html">
>       *      http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
>       */
> -    public static final CSVFormat MYSQL =
> -            DEFAULT
> -            .withDelimiter(TAB)
> -            .withEscape(BACKSLASH)
> -            .withIgnoreEmptyLines(false)
> -            .withQuote(null)
> -            .withRecordSeparator(LF);
> +    public static final CSVFormat MYSQL =
> DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
> +            .withQuote(null).withRecordSeparator(LF);
>
>      /**
>       * Returns true if the given character is a line break character.
> @@ -294,13 +290,16 @@ public final class CSVFormat implements
>      /**
>       * Creates a new CSV format with the specified delimiter.
>       *
> -     * <p>Use this method if you want to create a CSVFormat from scratch.
> All fields but the delimiter will be
> -     * initialized with null/false.</p>
> +     * <p>
> +     * Use this method if you want to create a CSVFormat from scratch.
> All fields but the delimiter will be initialized
> +     * with null/false.
> +     * </p>
>       *
>       * @param delimiter
>       *            the char used for value separation, must not be a line
> break character
>       * @return a new CSV format.
> -     * @throws IllegalArgumentException if the delimiter is a line break
> character
> +     * @throws IllegalArgumentException
> +     *             if the delimiter is a line break character
>       *
>       * @see #DEFAULT
>       * @see #RFC4180
> @@ -337,16 +336,18 @@ public final class CSVFormat implements
>       *            the comments to be printed by the Printer before the
> actual CSV data
>       * @param header
>       *            the header
> -     * @param skipHeaderRecord TODO
> -     * @param allowMissingColumnNames TODO
> -     * @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) {
> +     * @param skipHeaderRecord
> +     *            TODO
> +     * @param allowMissingColumnNames
> +     *            TODO
> +     * @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) {
>          if (isLineBreak(delimiter)) {
>              throw new IllegalArgumentException("The delimiter cannot be a
> line break");
>          }
> @@ -377,13 +378,13 @@ public final class CSVFormat implements
>          validate();
>      }
>
> -    private String[] toStringArray(Object[] values) {
> +    private String[] toStringArray(final Object[] values) {
>          if (values == null) {
>              return null;
>          }
> -        String[] strings = new String[values.length];
> +        final String[] strings = new String[values.length];
>          for (int i = 0; i < values.length; i++) {
> -            Object value = values[i];
> +            final Object value = values[i];
>              strings[i] = value == null ? null : value.toString();
>          }
>          return strings;
> @@ -544,8 +545,7 @@ public final class CSVFormat implements
>      /**
>       * Specifies whether spaces around values are ignored when parsing
> input.
>       *
> -     * @return {@code true} if spaces around values are ignored, {@code
> false} if they are treated as part of the
> -     *         value.
> +     * @return {@code true} if spaces around values are ignored, {@code
> false} if they are treated as part of the value.
>       */
>      public boolean getIgnoreSurroundingSpaces() {
>          return ignoreSurroundingSpaces;
> @@ -556,8 +556,7 @@ public final class CSVFormat implements
>       * <ul>
>       * <li>
>       * <strong>Reading:</strong> Converts strings equal to the given
> {@code nullString} to {@code null} when reading
> -     * records.
> -     * </li>
> +     * records.</li>
>       * <li>
>       * <strong>Writing:</strong> Writes {@code null} as the given {@code
> nullString} when writing records.</li>
>       * </ul>
> @@ -605,8 +604,7 @@ public final class CSVFormat implements
>      }
>
>      @Override
> -    public int hashCode()
> -    {
> +    public int hashCode() {
>          final int prime = 31;
>          int result = 1;
>
> @@ -687,10 +685,10 @@ public final class CSVFormat implements
>       * </p>
>       *
>       * @param out
> -     *        the output
> +     *            the output
>       * @return a printer to an output
>       * @throws IOException
> -     *         thrown if the optional header cannot be printed.
> +     *             thrown if the optional header cannot be printed.
>       */
>      public CSVPrinter print(final Appendable out) throws IOException {
>          return new CSVPrinter(out, this);
> @@ -716,7 +714,7 @@ public final class CSVFormat implements
>              sb.append(' ');
>              sb.append("NullString=<").append(nullString).append('>');
>          }
> -        if(recordSeparator != null) {
> +        if (recordSeparator != null) {
>              sb.append(' ');
>
>  sb.append("RecordSeparator=<").append(recordSeparator).append('>');
>          }
> @@ -745,28 +743,28 @@ public final class CSVFormat implements
>       */
>      private void validate() throws IllegalArgumentException {
>          if (quoteCharacter != null && delimiter ==
> quoteCharacter.charValue()) {
> -            throw new IllegalArgumentException(
> -                    "The quoteChar character and the delimiter cannot be
> the same ('" + quoteCharacter + "')");
> +            throw new IllegalArgumentException("The quoteChar character
> and the delimiter cannot be the same ('" +
> +                    quoteCharacter + "')");
>          }
>
>          if (escapeCharacter != null && delimiter ==
> escapeCharacter.charValue()) {
> -            throw new IllegalArgumentException(
> -                    "The escape character and the delimiter cannot be the
> same ('" + escapeCharacter + "')");
> +            throw new IllegalArgumentException("The escape character and
> the delimiter cannot be the same ('" +
> +                    escapeCharacter + "')");
>          }
>
>          if (commentMarker != null && delimiter ==
> commentMarker.charValue()) {
> -            throw new IllegalArgumentException(
> -                    "The comment start character and the delimiter cannot
> be the same ('" + commentMarker + "')");
> +            throw new IllegalArgumentException("The comment start
> character and the delimiter cannot be the same ('" +
> +                    commentMarker + "')");
>          }
>
>          if (quoteCharacter != null &&
> quoteCharacter.equals(commentMarker)) {
> -            throw new IllegalArgumentException(
> -                    "The comment start character and the quoteChar cannot
> be the same ('" + commentMarker + "')");
> +            throw new IllegalArgumentException("The comment start
> character and the quoteChar cannot be the same ('" +
> +                    commentMarker + "')");
>          }
>
>          if (escapeCharacter != null &&
> escapeCharacter.equals(commentMarker)) {
> -            throw new IllegalArgumentException(
> -                    "The comment start and the escape character cannot be
> the same ('" + commentMarker + "')");
> +            throw new IllegalArgumentException("The comment start and the
> escape character cannot be the same ('" +
> +                    commentMarker + "')");
>          }
>
>          if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
> @@ -805,8 +803,8 @@ public final class CSVFormat implements
>              throw new IllegalArgumentException("The comment start marker
> character cannot be a line break");
>          }
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -823,8 +821,8 @@ public final class CSVFormat implements
>              throw new IllegalArgumentException("The delimiter cannot be a
> line break");
>          }
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -853,21 +851,25 @@ public final class CSVFormat implements
>          if (isLineBreak(escape)) {
>              throw new IllegalArgumentException("The escape character
> cannot be a line break");
>          }
> -        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escape,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escape, ignoreSurroundingSpaces,
> +                ignoreEmptyLines, recordSeparator, nullString, null,
> header, skipHeaderRecord, allowMissingColumnNames);
>      }
>
>      /**
>       * Sets the header of the format. The header can either be parsed
> automatically from the input file with:
>       *
>       * <pre>
> -     * CSVFormat format = aformat.withHeader();</pre>
> +     * CSVFormat format = aformat.withHeader();
> +     * </pre>
>       *
>       * or specified manually with:
>       *
>       * <pre>
> -     * CSVFormat format = aformat.withHeader(&quot;name&quot;,
> &quot;email&quot;, &quot;phone&quot;);</pre>
> +     * CSVFormat format = aformat.withHeader(&quot;name&quot;,
> &quot;email&quot;, &quot;phone&quot;);
> +     * </pre>
> +     * <p>
> +     * The header is also used by the {@link CSVPrinter}..
> +     * </p>
>       *
>       * @param header
>       *            the header, {@code null} if disabled, empty if parsed
> automatically, user specified otherwise.
> @@ -877,8 +879,76 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withHeader(final String... header) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
> +    }
> +
> +    /**
> +     * Sets the header of the format. The header can either be parsed
> automatically from the input file with:
> +     *
> +     * <pre>
> +     * CSVFormat format = aformat.withHeader();
> +     * </pre>
> +     *
> +     * or specified manually with:
> +     *
> +     * <pre>
> +     * CSVFormat format = aformat.withHeader(resultSet);
> +     * </pre>
> +     * <p>
> +     * The header is also used by the {@link CSVPrinter}..
> +     * </p>
> +     *
> +     * @param resultSet
> +     *            the resultSet for the header, {@code null} if disabled,
> empty if parsed automatically, user specified
> +     *            otherwise.
> +     *
> +     * @return A new CSVFormat that is equal to this but with the
> specified header
> +     * @throws SQLException
> +     *             SQLException if a database access error occurs or this
> method is called on a closed result set.
> +     * @since 1.1
> +     */
> +    public CSVFormat withHeader(final ResultSet resultSet) throws
> SQLException {
> +        return withHeader(resultSet != null ? resultSet.getMetaData() :
> null);
> +    }
> +
> +    /**
> +     * Sets the header of the format. The header can either be parsed
> automatically from the input file with:
> +     *
> +     * <pre>
> +     * CSVFormat format = aformat.withHeader();
> +     * </pre>
> +     *
> +     * or specified manually with:
> +     *
> +     * <pre>
> +     * CSVFormat format = aformat.withHeader(metaData);
> +     * </pre>
> +     * <p>
> +     * The header is also used by the {@link CSVPrinter}..
> +     * </p>
> +     *
> +     * @param metaData
> +     *            the metaData for the header, {@code null} if disabled,
> empty if parsed automatically, user specified
> +     *            otherwise.
> +     *
> +     * @return A new CSVFormat that is equal to this but with the
> specified header
> +     * @throws SQLException
> +     *             SQLException if a database access error occurs or this
> method is called on a closed result set.
> +     * @since 1.1
> +     */
> +    public CSVFormat withHeader(final ResultSetMetaData metaData) throws
> SQLException {
> +        String[] labels = null;
> +        if (metaData != null) {
> +            final int columnCount = metaData.getColumnCount();
> +            labels = new String[columnCount];
> +            for (int i = 0; i < columnCount; i++) {
> +                labels[i] = metaData.getColumnLabel(i + 1);
> +            }
> +        }
> +        return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, labels, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -923,8 +993,8 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withAllowMissingColumnNames(final boolean
> allowMissingColumnNames) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -948,8 +1018,8 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines)
> {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -973,8 +1043,8 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withIgnoreSurroundingSpaces(final boolean
> ignoreSurroundingSpaces) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -994,8 +1064,8 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withNullString(final String nullString) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -1024,9 +1094,8 @@ public final class CSVFormat implements
>          if (isLineBreak(quoteChar)) {
>              throw new IllegalArgumentException("The quoteChar cannot be a
> line break");
>          }
> -        return new CSVFormat(delimiter, quoteChar, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +        return new CSVFormat(delimiter, quoteChar, quoteMode,
> commentMarker, escapeCharacter, ignoreSurroundingSpaces,
> +                ignoreEmptyLines, recordSeparator, nullString, null,
> header, skipHeaderRecord, allowMissingColumnNames);
>      }
>
>      /**
> @@ -1039,15 +1108,17 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
>       * Sets the record separator of the format to the specified character.
>       *
> -     * <p><strong>Note:</strong> This setting is only used during
> printing and does not affect parsing. Parsing
> -     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
> +     * <p>
> +     * <strong>Note:</strong> This setting is only used during printing
> and does not affect parsing. Parsing currently
> +     * only works for inputs with '\n', '\r' and "\r\n"
> +     * </p>
>       *
>       * @param recordSeparator
>       *            the record separator to use for output.
> @@ -1061,20 +1132,22 @@ public final class CSVFormat implements
>      /**
>       * Sets the record separator of the format to the specified String.
>       *
> -     * <p><strong>Note:</strong> This setting is only used during
> printing and does not affect parsing. Parsing
> -     * currently only works for inputs with '\n', '\r' and "\r\n"</p>
> +     * <p>
> +     * <strong>Note:</strong> This setting is only used during printing
> and does not affect parsing. Parsing currently
> +     * only works for inputs with '\n', '\r' and "\r\n"
> +     * </p>
>       *
>       * @param recordSeparator
>       *            the record separator to use for output.
>       *
>       * @return A new CSVFormat that is equal to this but with the the
> specified output record separator
>       * @throws IllegalArgumentException
> -     *              if recordSeparator is none of CR, LF or CRLF
> +     *             if recordSeparator is none of CR, LF or CRLF
>       */
>      public CSVFormat withRecordSeparator(final String recordSeparator) {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>
>      /**
> @@ -1100,7 +1173,7 @@ public final class CSVFormat implements
>       */
>      public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord)
> {
>          return new CSVFormat(delimiter, quoteCharacter, quoteMode,
> commentMarker, escapeCharacter,
> -                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header,
> -                skipHeaderRecord, allowMissingColumnNames);
> +                ignoreSurroundingSpaces, ignoreEmptyLines,
> recordSeparator, nullString, null, header, skipHeaderRecord,
> +                allowMissingColumnNames);
>      }
>  }
>
> Modified:
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java?rev=1638101&r1=1638100&r2=1638101&view=diff
>
> ==============================================================================
> ---
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> (original)
> +++
> commons/proper/csv/trunk/src/main/java/org/apache/commons/csv/CSVPrinter.java
> Tue Nov 11 14:00:47 2014
> @@ -501,17 +501,7 @@ public final class CSVPrinter implements
>       *             if a database access error occurs
>       */
>      public void printRecords(final ResultSet resultSet) throws
> SQLException, IOException {
> -        ResultSetMetaData metaData = resultSet.getMetaData();
> -        final int columnCount = metaData.getColumnCount();
> -        // TODO should printing the header be a parameter to this
> function or an existing CSVFormat option or a new
> -        // CSVFormat option.
> -        boolean printHeader = false;
> -        if (printHeader) {
> -            for (int i = 1; i <= columnCount; i++) {
> -                print(metaData.getColumnLabel(i));
> -            }
> -            println();
> -        }
> +        final int columnCount = resultSet.getMetaData().getColumnCount();
>          while (resultSet.next()) {
>              for (int i = 1; i <= columnCount; i++) {
>                  print(resultSet.getObject(i));
>
> Modified:
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> URL:
> http://svn.apache.org/viewvc/commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java?rev=1638101&r1=1638100&r2=1638101&view=diff
>
> ==============================================================================
> ---
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> (original)
> +++
> commons/proper/csv/trunk/src/test/java/org/apache/commons/csv/CSVPrinterTest.java
> Tue Nov 11 14:00:47 2014
> @@ -26,6 +26,7 @@ import java.io.StringReader;
>  import java.io.StringWriter;
>  import java.sql.Connection;
>  import java.sql.DriverManager;
> +import java.sql.ResultSet;
>  import java.sql.SQLException;
>  import java.sql.Statement;
>  import java.util.Arrays;
> @@ -34,7 +35,6 @@ import java.util.Iterator;
>  import java.util.List;
>  import java.util.Random;
>
> -import org.junit.Ignore;
>  import org.junit.Test;
>
>  /**
> @@ -213,11 +213,15 @@ public class CSVPrinterTest {
>          printer.close();
>      }
>
> +    private Connection geH2Connection() throws SQLException,
> ClassNotFoundException {
> +        Class.forName("org.h2.Driver");
> +        return DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa",
> "");
> +    }
> +
>      @Test
>      public void testJdbcPrinter() throws IOException,
> ClassNotFoundException, SQLException {
>          final StringWriter sw = new StringWriter();
> -        Class.forName("org.h2.Driver");
> -        final Connection connection =
> DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
> +        final Connection connection = geH2Connection();
>          try {
>              final Statement stmt = connection.createStatement();
>              setUpTable(stmt);
> @@ -230,30 +234,58 @@ public class CSVPrinterTest {
>          }
>      }
>
> -    private void setUpTable(final Statement stmt) throws SQLException {
> -        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME
> VARCHAR(255))");
> -        stmt.execute("insert into TEST values(1, 'r1')");
> -        stmt.execute("insert into TEST values(2, 'r2')");
> +    @Test
> +    public void testJdbcPrinterWithResultSet() throws IOException,
> ClassNotFoundException, SQLException {
> +        final StringWriter sw = new StringWriter();
> +        Class.forName("org.h2.Driver");
> +        final Connection connection = geH2Connection();
> +        try {
> +            @SuppressWarnings("resource")
> +            // Closed when the connection is closed.
> +            final Statement stmt = connection.createStatement();
> +            setUpTable(stmt);
> +            @SuppressWarnings("resource")
> +            // Closed when the connection is closed.
> +            final ResultSet resultSet = stmt.executeQuery("select ID,
> NAME from TEST");
> +            final CSVPrinter printer =
> CSVFormat.DEFAULT.withHeader(resultSet).print(sw);
> +            printer.printRecords(resultSet);
> +            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> recordSeparator + "2,r2" + recordSeparator,
> +                    sw.toString());
> +            printer.close();
> +        } finally {
> +            connection.close();
> +        }
>      }
>
>      @Test
> -    @Ignore
> -    public void testJdbcPrinterWithHeaders() throws IOException,
> ClassNotFoundException, SQLException {
> +    public void testJdbcPrinterWithResultSetMetaData() throws
> IOException, ClassNotFoundException, SQLException {
>          final StringWriter sw = new StringWriter();
>          Class.forName("org.h2.Driver");
> -        final Connection connection =
> DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
> +        final Connection connection = geH2Connection();
>          try {
> +            @SuppressWarnings("resource")
> +            // Closed when the connection is closed.
>              final Statement stmt = connection.createStatement();
>              setUpTable(stmt);
> -            final CSVPrinter printer = new CSVPrinter(sw,
> CSVFormat.DEFAULT);
> -            printer.printRecords(stmt.executeQuery("select ID, NAME from
> TEST"));
> -            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> recordSeparator + "2,r2" + recordSeparator, sw.toString());
> +            @SuppressWarnings("resource")
> +            // Closed when the connection is closed.
> +            final ResultSet resultSet = stmt.executeQuery("select ID,
> NAME from TEST");
> +            final CSVPrinter printer =
> CSVFormat.DEFAULT.withHeader(resultSet.getMetaData()).print(sw);
> +            printer.printRecords(resultSet);
> +            assertEquals("ID,NAME" + recordSeparator + "1,r1" +
> recordSeparator + "2,r2" + recordSeparator,
> +                    sw.toString());
>              printer.close();
>          } finally {
>              connection.close();
>          }
>      }
>
> +    private void setUpTable(final Statement stmt) throws SQLException {
> +        stmt.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME
> VARCHAR(255))");
> +        stmt.execute("insert into TEST values(1, 'r1')");
> +        stmt.execute("insert into TEST values(2, 'r2')");
> +    }
> +
>      @Test
>      public void testMultiLineComment() throws IOException {
>          final StringWriter sw = new StringWriter();
> @@ -523,8 +555,8 @@ public class CSVPrinterTest {
>      @Test
>      public void testHeaderCommentExcel() throws IOException {
>          final StringWriter sw = new StringWriter();
> -        Date now = new Date();
> -        CSVFormat format = CSVFormat.EXCEL;
> +        final Date now = new Date();
> +        final CSVFormat format = CSVFormat.EXCEL;
>          final CSVPrinter csvPrinter = printWithHeaderComments(sw, now,
> format);
>          assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now
> + "\r\nCol1,Col2\r\nA,B\r\nC,D\r\n", sw.toString());
>          csvPrinter.close();
> @@ -533,14 +565,14 @@ public class CSVPrinterTest {
>      @Test
>      public void testHeaderCommentTdf() throws IOException {
>          final StringWriter sw = new StringWriter();
> -        Date now = new Date();
> -        CSVFormat format = CSVFormat.TDF;
> +        final Date now = new Date();
> +        final CSVFormat format = CSVFormat.TDF;
>          final CSVPrinter csvPrinter = printWithHeaderComments(sw, now,
> format);
>          assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now
> + "\r\nCol1\tCol2\r\nA\tB\r\nC\tD\r\n", sw.toString());
>          csvPrinter.close();
>      }
>
> -    private CSVPrinter printWithHeaderComments(final StringWriter sw,
> Date now, CSVFormat baseFormat)
> +    private CSVPrinter printWithHeaderComments(final StringWriter sw,
> final Date now, final CSVFormat baseFormat)
>              throws IOException {
>          CSVFormat format =
> baseFormat.withCommentMarker('#').withHeader("Col1", "Col2");
>          format = format.withHeaderComments("Generated by Apache Commons
> CSV 1.1", now);
>
>
>


-- 
http://people.apache.org/~britter/
http://www.systemoutprintln.de/
http://twitter.com/BenediktRitter
http://github.com/britter