001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.csv;
019
020import static org.apache.commons.csv.Constants.BACKSLASH;
021import static org.apache.commons.csv.Constants.COMMA;
022import static org.apache.commons.csv.Constants.COMMENT;
023import static org.apache.commons.csv.Constants.EMPTY;
024import static org.apache.commons.csv.Constants.CR;
025import static org.apache.commons.csv.Constants.CRLF;
026import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
027import static org.apache.commons.csv.Constants.LF;
028import static org.apache.commons.csv.Constants.PIPE;
029import static org.apache.commons.csv.Constants.SP;
030import static org.apache.commons.csv.Constants.TAB;
031
032import java.io.File;
033import java.io.FileOutputStream;
034import java.io.IOException;
035import java.io.OutputStreamWriter;
036import java.io.Reader;
037import java.io.Serializable;
038import java.io.StringWriter;
039import java.nio.charset.Charset;
040import java.nio.file.Files;
041import java.nio.file.Path;
042import java.sql.ResultSet;
043import java.sql.ResultSetMetaData;
044import java.sql.SQLException;
045import java.util.Arrays;
046import java.util.HashSet;
047import java.util.Set;
048
049/**
050 * Specifies the format of a CSV file and parses input.
051 *
052 * <h2>Using predefined formats</h2>
053 *
054 * <p>
055 * You can use one of the predefined formats:
056 * </p>
057 *
058 * <ul>
059 * <li>{@link #DEFAULT}</li>
060 * <li>{@link #EXCEL}</li>
061 * <li>{@link #INFORMIX_UNLOAD}</li>
062 * <li>{@link #INFORMIX_UNLOAD_CSV}</li>
063 * <li>{@link #MYSQL}</li>
064 * <li>{@link #RFC4180}</li>
065 * <li>{@link #ORACLE}</li>
066 * <li>{@link #POSTGRESQL_CSV}</li>
067 * <li>{@link #POSTGRESQL_TEXT}</li>
068 * <li>{@link #TDF}</li>
069 * </ul>
070 *
071 * <p>
072 * For example:
073 * </p>
074 *
075 * <pre>
076 * CSVParser parser = CSVFormat.EXCEL.parse(reader);
077 * </pre>
078 *
079 * <p>
080 * The {@link CSVParser} provides static methods to parse other input types, for example:
081 * </p>
082 *
083 * <pre>
084 * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);
085 * </pre>
086 *
087 * <h2>Defining formats</h2>
088 *
089 * <p>
090 * You can extend a format by calling the {@code with} methods. For example:
091 * </p>
092 *
093 * <pre>
094 * CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
095 * </pre>
096 *
097 * <h2>Defining column names</h2>
098 *
099 * <p>
100 * To define the column names you want to use to access records, write:
101 * </p>
102 *
103 * <pre>
104 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;);
105 * </pre>
106 *
107 * <p>
108 * Calling {@link #withHeader(String...)} let's you use the given names to address values in a {@link CSVRecord}, and
109 * assumes that your CSV source does not contain a first record that also defines column names.
110 *
111 * If it does, then you are overriding this metadata with your names and you should skip the first record by calling
112 * {@link #withSkipHeaderRecord(boolean)} with {@code true}.
113 * </p>
114 *
115 * <h2>Parsing</h2>
116 *
117 * <p>
118 * You can use a format directly to parse a reader. For example, to parse an Excel file with columns header, write:
119 * </p>
120 *
121 * <pre>
122 * Reader in = ...;
123 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;).parse(in);
124 * </pre>
125 *
126 * <p>
127 * For other input types, like resources, files, and URLs, use the static methods on {@link CSVParser}.
128 * </p>
129 *
130 * <h2>Referencing columns safely</h2>
131 *
132 * <p>
133 * If your source contains a header record, you can simplify your code and safely reference columns, by using
134 * {@link #withHeader(String...)} with no arguments:
135 * </p>
136 *
137 * <pre>
138 * CSVFormat.EXCEL.withHeader();
139 * </pre>
140 *
141 * <p>
142 * This causes the parser to read the first record and use its values as column names.
143 *
144 * Then, call one of the {@link CSVRecord} get method that takes a String column name argument:
145 * </p>
146 *
147 * <pre>
148 * String value = record.get(&quot;Col1&quot;);
149 * </pre>
150 *
151 * <p>
152 * This makes your code impervious to changes in column order in the CSV file.
153 * </p>
154 *
155 * <h2>Notes</h2>
156 *
157 * <p>
158 * This class is immutable.
159 * </p>
160 */
161public final class CSVFormat implements Serializable {
162
163    /**
164     * Predefines formats.
165     *
166     * @since 1.2
167     */
168    public enum Predefined {
169
170        /**
171         * @see CSVFormat#DEFAULT
172         */
173        Default(CSVFormat.DEFAULT),
174
175        /**
176         * @see CSVFormat#EXCEL
177         */
178        Excel(CSVFormat.EXCEL),
179
180        /**
181         * @see CSVFormat#INFORMIX_UNLOAD
182         * @since 1.3
183         */
184        InformixUnload(CSVFormat.INFORMIX_UNLOAD),
185
186        /**
187         * @see CSVFormat#INFORMIX_UNLOAD_CSV
188         * @since 1.3
189         */
190        InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),
191
192        /**
193         * @see CSVFormat#MYSQL
194         */
195        MySQL(CSVFormat.MYSQL),
196
197        /**
198         * @see CSVFormat#ORACLE
199         */
200        Oracle(CSVFormat.ORACLE),
201
202        /**
203         * @see CSVFormat#POSTGRESQL_CSV
204         * @since 1.5
205         */
206        PostgreSQLCsv(CSVFormat.POSTGRESQL_CSV),
207
208        /**
209         * @see CSVFormat#POSTGRESQL_CSV
210         */
211        PostgreSQLText(CSVFormat.POSTGRESQL_TEXT),
212
213        /**
214         * @see CSVFormat#RFC4180
215         */
216        RFC4180(CSVFormat.RFC4180),
217
218        /**
219         * @see CSVFormat#TDF
220         */
221        TDF(CSVFormat.TDF);
222
223        private final CSVFormat format;
224
225        Predefined(final CSVFormat format) {
226            this.format = format;
227        }
228
229        /**
230         * Gets the format.
231         *
232         * @return the format.
233         */
234        public CSVFormat getFormat() {
235            return format;
236        }
237    }
238
239    /**
240     * Standard Comma Separated Value format, as for {@link #RFC4180} but allowing empty lines.
241     *
242     * <p>
243     * Settings are:
244     * </p>
245     * <ul>
246     * <li>withDelimiter(',')</li>
247     * <li>withQuote('"')</li>
248     * <li>withRecordSeparator("\r\n")</li>
249     * <li>withIgnoreEmptyLines(true)</li>
250     * </ul>
251     *
252     * @see Predefined#Default
253     */
254    public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
255            null, null, null, false, false, false, false, false, false);
256
257    /**
258     * Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
259     * locale dependent, it might be necessary to customize this format to accommodate to your regional settings.
260     *
261     * <p>
262     * For example for parsing or generating a CSV file on a French system the following format will be used:
263     * </p>
264     *
265     * <pre>
266     * CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');
267     * </pre>
268     *
269     * <p>
270     * Settings are:
271     * </p>
272     * <ul>
273     * <li>{@link #withDelimiter(char) withDelimiter(',')}</li>
274     * <li>{@link #withQuote(char) withQuote('"')}</li>
275     * <li>{@link #withRecordSeparator(String) withRecordSeparator("\r\n")}</li>
276     * <li>{@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}</li>
277     * <li>{@link #withAllowMissingColumnNames(boolean) withAllowMissingColumnNames(true)}</li>
278     * </ul>
279     * <p>
280     * Note: This is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
281     * withAllowMissingColumnNames(true)} and {@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}.
282     * </p>
283     *
284     * @see Predefined#Excel
285     */
286    // @formatter:off
287    public static final CSVFormat EXCEL = DEFAULT
288            .withIgnoreEmptyLines(false)
289            .withAllowMissingColumnNames();
290    // @formatter:on
291
292    /**
293     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
294     *
295     * <p>
296     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
297     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
298     * </p>
299     *
300     * <p>
301     * Settings are:
302     * </p>
303     * <ul>
304     * <li>withDelimiter(',')</li>
305     * <li>withQuote("\"")</li>
306     * <li>withRecordSeparator('\n')</li>
307     * <li>withEscape('\\')</li>
308     * </ul>
309     *
310     * @see Predefined#MySQL
311     * @see <a href=
312     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
313     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
314     * @since 1.3
315     */
316    // @formatter:off
317    public static final CSVFormat INFORMIX_UNLOAD = DEFAULT
318            .withDelimiter(PIPE)
319            .withEscape(BACKSLASH)
320            .withQuote(DOUBLE_QUOTE_CHAR)
321            .withRecordSeparator(LF);
322    // @formatter:on
323
324    /**
325     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation (escaping is disabled.)
326     *
327     * <p>
328     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
329     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
330     * </p>
331     *
332     * <p>
333     * Settings are:
334     * </p>
335     * <ul>
336     * <li>withDelimiter(',')</li>
337     * <li>withQuote("\"")</li>
338     * <li>withRecordSeparator('\n')</li>
339     * </ul>
340     *
341     * @see Predefined#MySQL
342     * @see <a href=
343     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
344     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
345     * @since 1.3
346     */
347    // @formatter:off
348    public static final CSVFormat INFORMIX_UNLOAD_CSV = DEFAULT
349            .withDelimiter(COMMA)
350            .withQuote(DOUBLE_QUOTE_CHAR)
351            .withRecordSeparator(LF);
352    // @formatter:on
353
354    /**
355     * Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
356     *
357     * <p>
358     * This is a tab-delimited format with a LF character as the line separator. Values are not quoted and special
359     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
360     * </p>
361     *
362     * <p>
363     * Settings are:
364     * </p>
365     * <ul>
366     * <li>withDelimiter('\t')</li>
367     * <li>withQuote(null)</li>
368     * <li>withRecordSeparator('\n')</li>
369     * <li>withIgnoreEmptyLines(false)</li>
370     * <li>withEscape('\\')</li>
371     * <li>withNullString("\\N")</li>
372     * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
373     * </ul>
374     *
375     * @see Predefined#MySQL
376     * @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
377     *      -data.html</a>
378     */
379    // @formatter:off
380    public static final CSVFormat MYSQL = DEFAULT
381            .withDelimiter(TAB)
382            .withEscape(BACKSLASH)
383            .withIgnoreEmptyLines(false)
384            .withQuote(null)
385            .withRecordSeparator(LF)
386            .withNullString("\\N")
387            .withQuoteMode(QuoteMode.ALL_NON_NULL);
388    // @formatter:off
389
390    /**
391     * Default Oracle format used by the SQL*Loader utility.
392     *
393     * <p>
394     * This is a comma-delimited format with the system line separator character as the record separator.Values are
395     * double quoted when needed and special characters are escaped with {@code '"'}. The default NULL string is
396     * {@code ""}. Values are trimmed.
397     * </p>
398     *
399     * <p>
400     * Settings are:
401     * </p>
402     * <ul>
403     * <li>withDelimiter(',') // default is {@code FIELDS TERMINATED BY ','}</li>
404     * <li>withQuote('"')  // default is {@code OPTIONALLY ENCLOSED BY '"'}</li>
405     * <li>withSystemRecordSeparator()</li>
406     * <li>withTrim()</li>
407     * <li>withIgnoreEmptyLines(false)</li>
408     * <li>withEscape('\\')</li>
409     * <li>withNullString("\\N")</li>
410     * <li>withQuoteMode(QuoteMode.MINIMAL)</li>
411     * </ul>
412     *
413     * @see Predefined#Oracle
414     * @see <a href="https://s.apache.org/CGXG">Oracle CSV Format Specification</a>
415     * @since 1.6
416     */
417    // @formatter:off
418    public static final CSVFormat ORACLE = DEFAULT
419            .withDelimiter(COMMA)
420            .withEscape(BACKSLASH)
421            .withIgnoreEmptyLines(false)
422            .withQuote(DOUBLE_QUOTE_CHAR)
423            .withNullString("\\N")
424            .withTrim()
425            .withSystemRecordSeparator()
426            .withQuoteMode(QuoteMode.MINIMAL);
427    // @formatter:off
428
429    /**
430     * Default PostgreSQL CSV format used by the {@code COPY} operation.
431     *
432     * <p>
433     * This is a comma-delimited format with a LF character as the line separator. Values are double quoted and special
434     * characters are escaped with {@code '"'}. The default NULL string is {@code ""}.
435     * </p>
436     *
437     * <p>
438     * Settings are:
439     * </p>
440     * <ul>
441     * <li>withDelimiter(',')</li>
442     * <li>withQuote('"')</li>
443     * <li>withRecordSeparator('\n')</li>
444     * <li>withIgnoreEmptyLines(false)</li>
445     * <li>withEscape('\\')</li>
446     * <li>withNullString("")</li>
447     * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
448     * </ul>
449     *
450     * @see Predefined#MySQL
451     * @see <a href="https://www.postgresql.org/docs/current/static/sql-copy.html">PostgreSQL COPY command
452     *          documentation</a>
453     * @since 1.5
454     */
455    // @formatter:off
456    public static final CSVFormat POSTGRESQL_CSV = DEFAULT
457            .withDelimiter(COMMA)
458            .withEscape(DOUBLE_QUOTE_CHAR)
459            .withIgnoreEmptyLines(false)
460            .withQuote(DOUBLE_QUOTE_CHAR)
461            .withRecordSeparator(LF)
462            .withNullString(EMPTY)
463            .withQuoteMode(QuoteMode.ALL_NON_NULL);
464    // @formatter:off
465
466    /**
467     * Default PostgreSQL text format used by the {@code COPY} operation.
468     *
469     * <p>
470     * This is a tab-delimited format with a LF character as the line separator. Values are double quoted and special
471     * characters are escaped with {@code '"'}. The default NULL string is {@code "\\N"}.
472     * </p>
473     *
474     * <p>
475     * Settings are:
476     * </p>
477     * <ul>
478     * <li>withDelimiter('\t')</li>
479     * <li>withQuote('"')</li>
480     * <li>withRecordSeparator('\n')</li>
481     * <li>withIgnoreEmptyLines(false)</li>
482     * <li>withEscape('\\')</li>
483     * <li>withNullString("\\N")</li>
484     * <li>withQuoteMode(QuoteMode.ALL_NON_NULL)</li>
485     * </ul>
486     *
487     * @see Predefined#MySQL
488     * @see <a href="https://www.postgresql.org/docs/current/static/sql-copy.html">PostgreSQL COPY command
489     *          documentation</a>
490     * @since 1.5
491     */
492    // @formatter:off
493    public static final CSVFormat POSTGRESQL_TEXT = DEFAULT
494            .withDelimiter(TAB)
495            .withEscape(DOUBLE_QUOTE_CHAR)
496            .withIgnoreEmptyLines(false)
497            .withQuote(DOUBLE_QUOTE_CHAR)
498            .withRecordSeparator(LF)
499            .withNullString("\\N")
500            .withQuoteMode(QuoteMode.ALL_NON_NULL);
501    // @formatter:off
502
503    /**
504     * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
505     *
506     * <p>
507     * Settings are:
508     * </p>
509     * <ul>
510     * <li>withDelimiter(',')</li>
511     * <li>withQuote('"')</li>
512     * <li>withRecordSeparator("\r\n")</li>
513     * <li>withIgnoreEmptyLines(false)</li>
514     * </ul>
515     *
516     * @see Predefined#RFC4180
517     */
518    public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
519
520    private static final long serialVersionUID = 1L;
521
522    /**
523     * Tab-delimited format.
524     *
525     * <p>
526     * Settings are:
527     * </p>
528     * <ul>
529     * <li>withDelimiter('\t')</li>
530     * <li>withQuote('"')</li>
531     * <li>withRecordSeparator("\r\n")</li>
532     * <li>withIgnoreSurroundingSpaces(true)</li>
533     * </ul>
534     *
535     * @see Predefined#TDF
536     */
537    // @formatter:off
538    public static final CSVFormat TDF = DEFAULT
539            .withDelimiter(TAB)
540            .withIgnoreSurroundingSpaces();
541    // @formatter:on
542
543    /**
544     * Returns true if the given character is a line break character.
545     *
546     * @param c
547     *            the character to check
548     *
549     * @return true if <code>c</code> is a line break character
550     */
551    private static boolean isLineBreak(final char c) {
552        return c == LF || c == CR;
553    }
554
555    /**
556     * Returns true if the given character is a line break character.
557     *
558     * @param c
559     *            the character to check, may be null
560     *
561     * @return true if <code>c</code> is a line break character (and not null)
562     */
563    private static boolean isLineBreak(final Character c) {
564        return c != null && isLineBreak(c.charValue());
565    }
566
567    /**
568     * Creates a new CSV format with the specified delimiter.
569     *
570     * <p>
571     * Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be initialized
572     * with null/false.
573     * </p>
574     *
575     * @param delimiter
576     *            the char used for value separation, must not be a line break character
577     * @return a new CSV format.
578     * @throws IllegalArgumentException
579     *             if the delimiter is a line break character
580     *
581     * @see #DEFAULT
582     * @see #RFC4180
583     * @see #MYSQL
584     * @see #EXCEL
585     * @see #TDF
586     */
587    public static CSVFormat newFormat(final char delimiter) {
588        return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false,
589                false, false, false, false);
590    }
591
592    /**
593     * Gets one of the predefined formats from {@link CSVFormat.Predefined}.
594     *
595     * @param format
596     *            name
597     * @return one of the predefined formats
598     * @since 1.2
599     */
600    public static CSVFormat valueOf(final String format) {
601        return CSVFormat.Predefined.valueOf(format).getFormat();
602    }
603
604    private final boolean allowMissingColumnNames;
605
606    private final Character commentMarker; // null if commenting is disabled
607
608    private final char delimiter;
609
610    private final Character escapeCharacter; // null if escaping is disabled
611
612    private final String[] header; // array of header column names
613
614    private final String[] headerComments; // array of header comment lines
615
616    private final boolean ignoreEmptyLines;
617
618    private final boolean ignoreHeaderCase; // should ignore header names case
619
620    private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
621
622    private final String nullString; // the string to be used for null values
623
624    private final Character quoteCharacter; // null if quoting is disabled
625
626    private final QuoteMode quoteMode;
627
628    private final String recordSeparator; // for outputs
629
630    private final boolean skipHeaderRecord;
631
632    private final boolean trailingDelimiter;
633
634    private final boolean trim;
635
636    private final boolean autoFlush;
637
638    /**
639     * Creates a customized CSV format.
640     *
641     * @param delimiter
642     *            the char used for value separation, must not be a line break character
643     * @param quoteChar
644     *            the Character used as value encapsulation marker, may be {@code null} to disable
645     * @param quoteMode
646     *            the quote mode
647     * @param commentStart
648     *            the Character used for comment identification, may be {@code null} to disable
649     * @param escape
650     *            the Character used to escape special characters in values, may be {@code null} to disable
651     * @param ignoreSurroundingSpaces
652     *            {@code true} when whitespaces enclosing values should be ignored
653     * @param ignoreEmptyLines
654     *            {@code true} when the parser should skip empty lines
655     * @param recordSeparator
656     *            the line separator to use for output
657     * @param nullString
658     *            the line separator to use for output
659     * @param headerComments
660     *            the comments to be printed by the Printer before the actual CSV data
661     * @param header
662     *            the header
663     * @param skipHeaderRecord
664     *            TODO
665     * @param allowMissingColumnNames
666     *            TODO
667     * @param ignoreHeaderCase
668     *            TODO
669     * @param trim
670     *            TODO
671     * @param trailingDelimiter
672     *            TODO
673     * @param autoFlush
674     * @throws IllegalArgumentException
675     *             if the delimiter is a line break character
676     */
677    private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMode quoteMode,
678                      final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
679                      final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
680                      final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
681                      final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, final boolean trim,
682                      final boolean trailingDelimiter, final boolean autoFlush) {
683        this.delimiter = delimiter;
684        this.quoteCharacter = quoteChar;
685        this.quoteMode = quoteMode;
686        this.commentMarker = commentStart;
687        this.escapeCharacter = escape;
688        this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
689        this.allowMissingColumnNames = allowMissingColumnNames;
690        this.ignoreEmptyLines = ignoreEmptyLines;
691        this.recordSeparator = recordSeparator;
692        this.nullString = nullString;
693        this.headerComments = toStringArray(headerComments);
694        this.header = header == null ? null : header.clone();
695        this.skipHeaderRecord = skipHeaderRecord;
696        this.ignoreHeaderCase = ignoreHeaderCase;
697        this.trailingDelimiter = trailingDelimiter;
698        this.trim = trim;
699        this.autoFlush = autoFlush;
700        validate();
701    }
702
703    @Override
704    public boolean equals(final Object obj) {
705        if (this == obj) {
706            return true;
707        }
708        if (obj == null) {
709            return false;
710        }
711        if (getClass() != obj.getClass()) {
712            return false;
713        }
714
715        final CSVFormat other = (CSVFormat) obj;
716        if (delimiter != other.delimiter) {
717            return false;
718        }
719        if (quoteMode != other.quoteMode) {
720            return false;
721        }
722        if (quoteCharacter == null) {
723            if (other.quoteCharacter != null) {
724                return false;
725            }
726        } else if (!quoteCharacter.equals(other.quoteCharacter)) {
727            return false;
728        }
729        if (commentMarker == null) {
730            if (other.commentMarker != null) {
731                return false;
732            }
733        } else if (!commentMarker.equals(other.commentMarker)) {
734            return false;
735        }
736        if (escapeCharacter == null) {
737            if (other.escapeCharacter != null) {
738                return false;
739            }
740        } else if (!escapeCharacter.equals(other.escapeCharacter)) {
741            return false;
742        }
743        if (nullString == null) {
744            if (other.nullString != null) {
745                return false;
746            }
747        } else if (!nullString.equals(other.nullString)) {
748            return false;
749        }
750        if (!Arrays.equals(header, other.header)) {
751            return false;
752        }
753        if (ignoreSurroundingSpaces != other.ignoreSurroundingSpaces) {
754            return false;
755        }
756        if (ignoreEmptyLines != other.ignoreEmptyLines) {
757            return false;
758        }
759        if (skipHeaderRecord != other.skipHeaderRecord) {
760            return false;
761        }
762        if (recordSeparator == null) {
763            if (other.recordSeparator != null) {
764                return false;
765            }
766        } else if (!recordSeparator.equals(other.recordSeparator)) {
767            return false;
768        }
769        return true;
770    }
771
772    /**
773     * Formats the specified values.
774     *
775     * @param values
776     *            the values to format
777     * @return the formatted values
778     */
779    public String format(final Object... values) {
780        final StringWriter out = new StringWriter();
781        try (final CSVPrinter csvPrinter = new CSVPrinter(out, this)) {
782            csvPrinter.printRecord(values);
783            return out.toString().trim();
784        } catch (final IOException e) {
785            // should not happen because a StringWriter does not do IO.
786            throw new IllegalStateException(e);
787        }
788    }
789
790    /**
791     * Specifies whether missing column names are allowed when parsing the header line.
792     *
793     * @return {@code true} if missing column names are allowed when parsing the header line, {@code false} to throw an
794     *         {@link IllegalArgumentException}.
795     */
796    public boolean getAllowMissingColumnNames() {
797        return allowMissingColumnNames;
798    }
799
800    /**
801     * Returns whether to flush on close.
802     *
803     * @return whether to flush on close.
804     * @since 1.6
805     */
806    public boolean getAutoFlush() {
807        return autoFlush;
808    }
809
810    /**
811     * Returns the character marking the start of a line comment.
812     *
813     * @return the comment start marker, may be {@code null}
814     */
815    public Character getCommentMarker() {
816        return commentMarker;
817    }
818
819    /**
820     * Returns the character delimiting the values (typically ';', ',' or '\t').
821     *
822     * @return the delimiter character
823     */
824    public char getDelimiter() {
825        return delimiter;
826    }
827
828    /**
829     * Returns the escape character.
830     *
831     * @return the escape character, may be {@code null}
832     */
833    public Character getEscapeCharacter() {
834        return escapeCharacter;
835    }
836
837    /**
838     * Returns a copy of the header array.
839     *
840     * @return a copy of the header array; {@code null} if disabled, the empty array if to be read from the file
841     */
842    public String[] getHeader() {
843        return header != null ? header.clone() : null;
844    }
845
846    /**
847     * Returns a copy of the header comment array.
848     *
849     * @return a copy of the header comment array; {@code null} if disabled.
850     */
851    public String[] getHeaderComments() {
852        return headerComments != null ? headerComments.clone() : null;
853    }
854
855    /**
856     * Specifies whether empty lines between records are ignored when parsing input.
857     *
858     * @return {@code true} if empty lines between records are ignored, {@code false} if they are turned into empty
859     *         records.
860     */
861    public boolean getIgnoreEmptyLines() {
862        return ignoreEmptyLines;
863    }
864
865    /**
866     * Specifies whether header names will be accessed ignoring case.
867     *
868     * @return {@code true} if header names cases are ignored, {@code false} if they are case sensitive.
869     * @since 1.3
870     */
871    public boolean getIgnoreHeaderCase() {
872        return ignoreHeaderCase;
873    }
874
875    /**
876     * Specifies whether spaces around values are ignored when parsing input.
877     *
878     * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the value.
879     */
880    public boolean getIgnoreSurroundingSpaces() {
881        return ignoreSurroundingSpaces;
882    }
883
884    /**
885     * Gets the String to convert to and from {@code null}.
886     * <ul>
887     * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
888     * records.</li>
889     * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
890     * </ul>
891     *
892     * @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
893     */
894    public String getNullString() {
895        return nullString;
896    }
897
898    /**
899     * Returns the character used to encapsulate values containing special characters.
900     *
901     * @return the quoteChar character, may be {@code null}
902     */
903    public Character getQuoteCharacter() {
904        return quoteCharacter;
905    }
906
907    /**
908     * Returns the quote policy output fields.
909     *
910     * @return the quote policy
911     */
912    public QuoteMode getQuoteMode() {
913        return quoteMode;
914    }
915
916    /**
917     * Returns the record separator delimiting output records.
918     *
919     * @return the record separator
920     */
921    public String getRecordSeparator() {
922        return recordSeparator;
923    }
924
925    /**
926     * Returns whether to skip the header record.
927     *
928     * @return whether to skip the header record.
929     */
930    public boolean getSkipHeaderRecord() {
931        return skipHeaderRecord;
932    }
933
934    /**
935     * Returns whether to add a trailing delimiter.
936     *
937     * @return whether to add a trailing delimiter.
938     * @since 1.3
939     */
940    public boolean getTrailingDelimiter() {
941        return trailingDelimiter;
942    }
943
944    /**
945     * Returns whether to trim leading and trailing blanks.
946     *
947     * @return whether to trim leading and trailing blanks.
948     */
949    public boolean getTrim() {
950        return trim;
951    }
952
953    @Override
954    public int hashCode() {
955        final int prime = 31;
956        int result = 1;
957
958        result = prime * result + delimiter;
959        result = prime * result + ((quoteMode == null) ? 0 : quoteMode.hashCode());
960        result = prime * result + ((quoteCharacter == null) ? 0 : quoteCharacter.hashCode());
961        result = prime * result + ((commentMarker == null) ? 0 : commentMarker.hashCode());
962        result = prime * result + ((escapeCharacter == null) ? 0 : escapeCharacter.hashCode());
963        result = prime * result + ((nullString == null) ? 0 : nullString.hashCode());
964        result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
965        result = prime * result + (ignoreHeaderCase ? 1231 : 1237);
966        result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
967        result = prime * result + (skipHeaderRecord ? 1231 : 1237);
968        result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
969        result = prime * result + Arrays.hashCode(header);
970        return result;
971    }
972
973    /**
974     * Specifies whether comments are supported by this format.
975     *
976     * Note that the comment introducer character is only recognized at the start of a line.
977     *
978     * @return {@code true} is comments are supported, {@code false} otherwise
979     */
980    public boolean isCommentMarkerSet() {
981        return commentMarker != null;
982    }
983
984    /**
985     * Returns whether escape are being processed.
986     *
987     * @return {@code true} if escapes are processed
988     */
989    public boolean isEscapeCharacterSet() {
990        return escapeCharacter != null;
991    }
992
993    /**
994     * Returns whether a nullString has been defined.
995     *
996     * @return {@code true} if a nullString is defined
997     */
998    public boolean isNullStringSet() {
999        return nullString != null;
1000    }
1001
1002    /**
1003     * Returns whether a quoteChar has been defined.
1004     *
1005     * @return {@code true} if a quoteChar is defined
1006     */
1007    public boolean isQuoteCharacterSet() {
1008        return quoteCharacter != null;
1009    }
1010
1011    /**
1012     * Parses the specified content.
1013     *
1014     * <p>
1015     * See also the various static parse methods on {@link CSVParser}.
1016     * </p>
1017     *
1018     * @param in
1019     *            the input stream
1020     * @return a parser over a stream of {@link CSVRecord}s.
1021     * @throws IOException
1022     *             If an I/O error occurs
1023     */
1024    public CSVParser parse(final Reader in) throws IOException {
1025        return new CSVParser(in, this);
1026    }
1027
1028    /**
1029     * Prints to the specified output.
1030     *
1031     * <p>
1032     * See also {@link CSVPrinter}.
1033     * </p>
1034     *
1035     * @param out
1036     *            the output.
1037     * @return a printer to an output.
1038     * @throws IOException
1039     *             thrown if the optional header cannot be printed.
1040     */
1041    public CSVPrinter print(final Appendable out) throws IOException {
1042        return new CSVPrinter(out, this);
1043    }
1044
1045    /**
1046     * Prints to the specified output.
1047     *
1048     * <p>
1049     * See also {@link CSVPrinter}.
1050     * </p>
1051     *
1052     * @param out
1053     *            the output.
1054     * @param charset
1055     *            A charset.
1056     * @return a printer to an output.
1057     * @throws IOException
1058     *             thrown if the optional header cannot be printed.
1059     * @since 1.5
1060     */
1061    @SuppressWarnings("resource")
1062    public CSVPrinter print(final File out, final Charset charset) throws IOException {
1063        // The writer will be closed when close() is called.
1064        return new CSVPrinter(new OutputStreamWriter(new FileOutputStream(out), charset), this);
1065    }
1066
1067    /**
1068     * Prints the {@code value} as the next value on the line to {@code out}. The value will be escaped or encapsulated
1069     * as needed. Useful when one wants to avoid creating CSVPrinters.
1070     *
1071     * @param value
1072     *            value to output.
1073     * @param out
1074     *            where to print the value.
1075     * @param newRecord
1076     *            if this a new record.
1077     * @throws IOException
1078     *             If an I/O error occurs.
1079     * @since 1.4
1080     */
1081    public void print(final Object value, final Appendable out, final boolean newRecord) throws IOException {
1082        // null values are considered empty
1083        // Only call CharSequence.toString() if you have to, helps GC-free use cases.
1084        CharSequence charSequence;
1085        if (value == null) {
1086            // https://issues.apache.org/jira/browse/CSV-203
1087            if (null == nullString) {
1088                charSequence = EMPTY;
1089            } else {
1090                if (QuoteMode.ALL == quoteMode) {
1091                    charSequence = quoteCharacter + nullString + quoteCharacter;
1092                } else {
1093                    charSequence = nullString;
1094                }
1095            }
1096        } else {
1097            charSequence = value instanceof CharSequence ? (CharSequence) value : value.toString();
1098        }
1099        charSequence = getTrim() ? trim(charSequence) : charSequence;
1100        this.print(value, charSequence, 0, charSequence.length(), out, newRecord);
1101    }
1102
1103    private void print(final Object object, final CharSequence value, final int offset, final int len,
1104            final Appendable out, final boolean newRecord) throws IOException {
1105        if (!newRecord) {
1106            out.append(getDelimiter());
1107        }
1108        if (object == null) {
1109            out.append(value);
1110        } else if (isQuoteCharacterSet()) {
1111            // the original object is needed so can check for Number
1112            printAndQuote(object, value, offset, len, out, newRecord);
1113        } else if (isEscapeCharacterSet()) {
1114            printAndEscape(value, offset, len, out);
1115        } else {
1116            out.append(value, offset, offset + len);
1117        }
1118    }
1119
1120    /**
1121     * Prints to the specified output.
1122     *
1123     * <p>
1124     * See also {@link CSVPrinter}.
1125     * </p>
1126     *
1127     * @param out
1128     *            the output.
1129     * @param charset
1130     *            A charset.
1131     * @return a printer to an output.
1132     * @throws IOException
1133     *             thrown if the optional header cannot be printed.
1134     * @since 1.5
1135     */
1136    public CSVPrinter print(final Path out, final Charset charset) throws IOException {
1137        return print(Files.newBufferedWriter(out, charset));
1138    }
1139
1140    /*
1141     * Note: must only be called if escaping is enabled, otherwise will generate NPE
1142     */
1143    private void printAndEscape(final CharSequence value, final int offset, final int len, final Appendable out)
1144            throws IOException {
1145        int start = offset;
1146        int pos = offset;
1147        final int end = offset + len;
1148
1149        final char delim = getDelimiter();
1150        final char escape = getEscapeCharacter().charValue();
1151
1152        while (pos < end) {
1153            char c = value.charAt(pos);
1154            if (c == CR || c == LF || c == delim || c == escape) {
1155                // write out segment up until this char
1156                if (pos > start) {
1157                    out.append(value, start, pos);
1158                }
1159                if (c == LF) {
1160                    c = 'n';
1161                } else if (c == CR) {
1162                    c = 'r';
1163                }
1164
1165                out.append(escape);
1166                out.append(c);
1167
1168                start = pos + 1; // start on the current char after this one
1169            }
1170
1171            pos++;
1172        }
1173
1174        // write last segment
1175        if (pos > start) {
1176            out.append(value, start, pos);
1177        }
1178    }
1179
1180    /*
1181     * Note: must only be called if quoting is enabled, otherwise will generate NPE
1182     */
1183    // the original object is needed so can check for Number
1184    private void printAndQuote(final Object object, final CharSequence value, final int offset, final int len,
1185            final Appendable out, final boolean newRecord) throws IOException {
1186        boolean quote = false;
1187        int start = offset;
1188        int pos = offset;
1189        final int end = offset + len;
1190
1191        final char delimChar = getDelimiter();
1192        final char quoteChar = getQuoteCharacter().charValue();
1193
1194        QuoteMode quoteModePolicy = getQuoteMode();
1195        if (quoteModePolicy == null) {
1196            quoteModePolicy = QuoteMode.MINIMAL;
1197        }
1198        switch (quoteModePolicy) {
1199        case ALL:
1200        case ALL_NON_NULL:
1201            quote = true;
1202            break;
1203        case NON_NUMERIC:
1204            quote = !(object instanceof Number);
1205            break;
1206        case NONE:
1207            // Use the existing escaping code
1208            printAndEscape(value, offset, len, out);
1209            return;
1210        case MINIMAL:
1211            if (len <= 0) {
1212                // always quote an empty token that is the first
1213                // on the line, as it may be the only thing on the
1214                // line. If it were not quoted in that case,
1215                // an empty line has no tokens.
1216                if (newRecord) {
1217                    quote = true;
1218                }
1219            } else {
1220                char c = value.charAt(pos);
1221
1222                if (c <= COMMENT) {
1223                    // Some other chars at the start of a value caused the parser to fail, so for now
1224                    // encapsulate if we start in anything less than '#'. We are being conservative
1225                    // by including the default comment char too.
1226                    quote = true;
1227                } else {
1228                    while (pos < end) {
1229                        c = value.charAt(pos);
1230                        if (c == LF || c == CR || c == quoteChar || c == delimChar) {
1231                            quote = true;
1232                            break;
1233                        }
1234                        pos++;
1235                    }
1236
1237                    if (!quote) {
1238                        pos = end - 1;
1239                        c = value.charAt(pos);
1240                        // Some other chars at the end caused the parser to fail, so for now
1241                        // encapsulate if we end in anything less than ' '
1242                        if (c <= SP) {
1243                            quote = true;
1244                        }
1245                    }
1246                }
1247            }
1248
1249            if (!quote) {
1250                // no encapsulation needed - write out the original value
1251                out.append(value, start, end);
1252                return;
1253            }
1254            break;
1255        default:
1256            throw new IllegalStateException("Unexpected Quote value: " + quoteModePolicy);
1257        }
1258
1259        if (!quote) {
1260            // no encapsulation needed - write out the original value
1261            out.append(value, start, end);
1262            return;
1263        }
1264
1265        // we hit something that needed encapsulation
1266        out.append(quoteChar);
1267
1268        // Pick up where we left off: pos should be positioned on the first character that caused
1269        // the need for encapsulation.
1270        while (pos < end) {
1271            final char c = value.charAt(pos);
1272            if (c == quoteChar) {
1273                // write out the chunk up until this point
1274
1275                // add 1 to the length to write out the encapsulator also
1276                out.append(value, start, pos + 1);
1277                // put the next starting position on the encapsulator so we will
1278                // write it out again with the next string (effectively doubling it)
1279                start = pos;
1280            }
1281            pos++;
1282        }
1283
1284        // write the last segment
1285        out.append(value, start, pos);
1286        out.append(quoteChar);
1287    }
1288
1289    /**
1290     * Prints to the {@link System#out}.
1291     *
1292     * <p>
1293     * See also {@link CSVPrinter}.
1294     * </p>
1295     *
1296     * @return a printer to {@link System#out}.
1297     * @throws IOException
1298     *             thrown if the optional header cannot be printed.
1299     * @since 1.5
1300     */
1301    public CSVPrinter printer() throws IOException {
1302        return new CSVPrinter(System.out, this);
1303    }
1304
1305    /**
1306     * Outputs the trailing delimiter (if set) followed by the record separator (if set).
1307     *
1308     * @param out
1309     *            where to write
1310     * @throws IOException
1311     *             If an I/O error occurs
1312     * @since 1.4
1313     */
1314    public void println(final Appendable out) throws IOException {
1315        if (getTrailingDelimiter()) {
1316            out.append(getDelimiter());
1317        }
1318        if (recordSeparator != null) {
1319            out.append(recordSeparator);
1320        }
1321    }
1322
1323    /**
1324     * Prints the given {@code values} to {@code out} as a single record of delimiter separated values followed by the
1325     * record separator.
1326     *
1327     * <p>
1328     * The values will be quoted if needed. Quotes and new-line characters will be escaped. This method adds the record
1329     * separator to the output after printing the record, so there is no need to call {@link #println(Appendable)}.
1330     * </p>
1331     *
1332     * @param out
1333     *            where to write.
1334     * @param values
1335     *            values to output.
1336     * @throws IOException
1337     *             If an I/O error occurs.
1338     * @since 1.4
1339     */
1340    public void printRecord(final Appendable out, final Object... values) throws IOException {
1341        for (int i = 0; i < values.length; i++) {
1342            print(values[i], out, i == 0);
1343        }
1344        println(out);
1345    }
1346
1347    @Override
1348    public String toString() {
1349        final StringBuilder sb = new StringBuilder();
1350        sb.append("Delimiter=<").append(delimiter).append('>');
1351        if (isEscapeCharacterSet()) {
1352            sb.append(' ');
1353            sb.append("Escape=<").append(escapeCharacter).append('>');
1354        }
1355        if (isQuoteCharacterSet()) {
1356            sb.append(' ');
1357            sb.append("QuoteChar=<").append(quoteCharacter).append('>');
1358        }
1359        if (isCommentMarkerSet()) {
1360            sb.append(' ');
1361            sb.append("CommentStart=<").append(commentMarker).append('>');
1362        }
1363        if (isNullStringSet()) {
1364            sb.append(' ');
1365            sb.append("NullString=<").append(nullString).append('>');
1366        }
1367        if (recordSeparator != null) {
1368            sb.append(' ');
1369            sb.append("RecordSeparator=<").append(recordSeparator).append('>');
1370        }
1371        if (getIgnoreEmptyLines()) {
1372            sb.append(" EmptyLines:ignored");
1373        }
1374        if (getIgnoreSurroundingSpaces()) {
1375            sb.append(" SurroundingSpaces:ignored");
1376        }
1377        if (getIgnoreHeaderCase()) {
1378            sb.append(" IgnoreHeaderCase:ignored");
1379        }
1380        sb.append(" SkipHeaderRecord:").append(skipHeaderRecord);
1381        if (headerComments != null) {
1382            sb.append(' ');
1383            sb.append("HeaderComments:").append(Arrays.toString(headerComments));
1384        }
1385        if (header != null) {
1386            sb.append(' ');
1387            sb.append("Header:").append(Arrays.toString(header));
1388        }
1389        return sb.toString();
1390    }
1391
1392    private String[] toStringArray(final Object[] values) {
1393        if (values == null) {
1394            return null;
1395        }
1396        final String[] strings = new String[values.length];
1397        for (int i = 0; i < values.length; i++) {
1398            final Object value = values[i];
1399            strings[i] = value == null ? null : value.toString();
1400        }
1401        return strings;
1402    }
1403
1404    private CharSequence trim(final CharSequence charSequence) {
1405        if (charSequence instanceof String) {
1406            return ((String) charSequence).trim();
1407        }
1408        final int count = charSequence.length();
1409        int len = count;
1410        int pos = 0;
1411
1412        while (pos < len && charSequence.charAt(pos) <= SP) {
1413            pos++;
1414        }
1415        while (pos < len && charSequence.charAt(len - 1) <= SP) {
1416            len--;
1417        }
1418        return pos > 0 || len < count ? charSequence.subSequence(pos, len) : charSequence;
1419    }
1420
1421    /**
1422     * Verifies the consistency of the parameters and throws an IllegalArgumentException if necessary.
1423     *
1424     * @throws IllegalArgumentException
1425     */
1426    private void validate() throws IllegalArgumentException {
1427        if (isLineBreak(delimiter)) {
1428            throw new IllegalArgumentException("The delimiter cannot be a line break");
1429        }
1430
1431        if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
1432            throw new IllegalArgumentException(
1433                    "The quoteChar character and the delimiter cannot be the same ('" + quoteCharacter + "')");
1434        }
1435
1436        if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
1437            throw new IllegalArgumentException(
1438                    "The escape character and the delimiter cannot be the same ('" + escapeCharacter + "')");
1439        }
1440
1441        if (commentMarker != null && delimiter == commentMarker.charValue()) {
1442            throw new IllegalArgumentException(
1443                    "The comment start character and the delimiter cannot be the same ('" + commentMarker + "')");
1444        }
1445
1446        if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
1447            throw new IllegalArgumentException(
1448                    "The comment start character and the quoteChar cannot be the same ('" + commentMarker + "')");
1449        }
1450
1451        if (escapeCharacter != null && escapeCharacter.equals(commentMarker)) {
1452            throw new IllegalArgumentException(
1453                    "The comment start and the escape character cannot be the same ('" + commentMarker + "')");
1454        }
1455
1456        if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
1457            throw new IllegalArgumentException("No quotes mode set but no escape character is set");
1458        }
1459
1460        // validate header
1461        if (header != null) {
1462            final Set<String> dupCheck = new HashSet<>();
1463            for (final String hdr : header) {
1464                if (!dupCheck.add(hdr)) {
1465                    throw new IllegalArgumentException(
1466                            "The header contains a duplicate entry: '" + hdr + "' in " + Arrays.toString(header));
1467                }
1468            }
1469        }
1470    }
1471
1472    /**
1473     * Returns a new {@code CSVFormat} with the missing column names behavior of the format set to {@code true}
1474     *
1475     * @return A new CSVFormat that is equal to this but with the specified missing column names behavior.
1476     * @see #withAllowMissingColumnNames(boolean)
1477     * @since 1.1
1478     */
1479    public CSVFormat withAllowMissingColumnNames() {
1480        return this.withAllowMissingColumnNames(true);
1481    }
1482
1483    /**
1484     * Returns a new {@code CSVFormat} with the missing column names behavior of the format set to the given value.
1485     *
1486     * @param allowMissingColumnNames
1487     *            the missing column names behavior, {@code true} to allow missing column names in the header line,
1488     *            {@code false} to cause an {@link IllegalArgumentException} to be thrown.
1489     * @return A new CSVFormat that is equal to this but with the specified missing column names behavior.
1490     */
1491    public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
1492        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1493                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1494                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1495    }
1496
1497    /**
1498     * Returns a new {@code CSVFormat} with whether to flush on close.
1499     *
1500     * @param autoFlush
1501     *            whether to flush on close.
1502     *
1503     * @return A new CSVFormat that is equal to this but with the specified autoFlush setting.
1504     * @since 1.6
1505     */
1506    public CSVFormat withAutoFlush(final boolean autoFlush) {
1507        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1508            ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1509            skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1510    }
1511
1512    /**
1513     * Returns a new {@code CSVFormat} with the comment start marker of the format set to the specified character.
1514     *
1515     * Note that the comment start character is only recognized at the start of a line.
1516     *
1517     * @param commentMarker
1518     *            the comment start marker
1519     * @return A new CSVFormat that is equal to this one but with the specified character as the comment start marker
1520     * @throws IllegalArgumentException
1521     *             thrown if the specified character is a line break
1522     */
1523    public CSVFormat withCommentMarker(final char commentMarker) {
1524        return withCommentMarker(Character.valueOf(commentMarker));
1525    }
1526
1527    /**
1528     * Returns a new {@code CSVFormat} with the comment start marker of the format set to the specified character.
1529     *
1530     * Note that the comment start character is only recognized at the start of a line.
1531     *
1532     * @param commentMarker
1533     *            the comment start marker, use {@code null} to disable
1534     * @return A new CSVFormat that is equal to this one but with the specified character as the comment start marker
1535     * @throws IllegalArgumentException
1536     *             thrown if the specified character is a line break
1537     */
1538    public CSVFormat withCommentMarker(final Character commentMarker) {
1539        if (isLineBreak(commentMarker)) {
1540            throw new IllegalArgumentException("The comment start marker character cannot be a line break");
1541        }
1542        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1543                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1544                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1545    }
1546
1547    /**
1548     * Returns a new {@code CSVFormat} with the delimiter of the format set to the specified character.
1549     *
1550     * @param delimiter
1551     *            the delimiter character
1552     * @return A new CSVFormat that is equal to this with the specified character as delimiter
1553     * @throws IllegalArgumentException
1554     *             thrown if the specified character is a line break
1555     */
1556    public CSVFormat withDelimiter(final char delimiter) {
1557        if (isLineBreak(delimiter)) {
1558            throw new IllegalArgumentException("The delimiter cannot be a line break");
1559        }
1560        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1561                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1562                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1563    }
1564
1565    /**
1566     * Returns a new {@code CSVFormat} with the escape character of the format set to the specified character.
1567     *
1568     * @param escape
1569     *            the escape character
1570     * @return A new CSVFormat that is equal to his but with the specified character as the escape character
1571     * @throws IllegalArgumentException
1572     *             thrown if the specified character is a line break
1573     */
1574    public CSVFormat withEscape(final char escape) {
1575        return withEscape(Character.valueOf(escape));
1576    }
1577
1578    /**
1579     * Returns a new {@code CSVFormat} with the escape character of the format set to the specified character.
1580     *
1581     * @param escape
1582     *            the escape character, use {@code null} to disable
1583     * @return A new CSVFormat that is equal to this but with the specified character as the escape character
1584     * @throws IllegalArgumentException
1585     *             thrown if the specified character is a line break
1586     */
1587    public CSVFormat withEscape(final Character escape) {
1588        if (isLineBreak(escape)) {
1589            throw new IllegalArgumentException("The escape character cannot be a line break");
1590        }
1591        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
1592                ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
1593                allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1594    }
1595
1596    /**
1597     * Returns a new {@code CSVFormat} using the first record as header.
1598     *
1599     * <p>
1600     * Calling this method is equivalent to calling:
1601     * </p>
1602     *
1603     * <pre>
1604     * CSVFormat format = aFormat.withHeader().withSkipHeaderRecord();
1605     * </pre>
1606     *
1607     * @return A new CSVFormat that is equal to this but using the first record as header.
1608     * @see #withSkipHeaderRecord(boolean)
1609     * @see #withHeader(String...)
1610     * @since 1.3
1611     */
1612    public CSVFormat withFirstRecordAsHeader() {
1613        return withHeader().withSkipHeaderRecord();
1614    }
1615
1616    /**
1617     * Returns a new {@code CSVFormat} with the header of the format defined by the enum class.
1618     *
1619     * <p>
1620     * Example:
1621     * </p>
1622     * <pre>
1623     * public enum Header {
1624     *     Name, Email, Phone
1625     * }
1626     *
1627     * CSVFormat format = aformat.withHeader(Header.class);
1628     * </pre>
1629     * <p>
1630     * The header is also used by the {@link CSVPrinter}.
1631     * </p>
1632     *
1633     * @param headerEnum
1634     *            the enum defining the header, {@code null} if disabled, empty if parsed automatically, user specified
1635     *            otherwise.
1636     *
1637     * @return A new CSVFormat that is equal to this but with the specified header
1638     * @see #withHeader(String...)
1639     * @see #withSkipHeaderRecord(boolean)
1640     * @since 1.3
1641     */
1642    public CSVFormat withHeader(final Class<? extends Enum<?>> headerEnum) {
1643        String[] header = null;
1644        if (headerEnum != null) {
1645            final Enum<?>[] enumValues = headerEnum.getEnumConstants();
1646            header = new String[enumValues.length];
1647            for (int i = 0; i < enumValues.length; i++) {
1648                header[i] = enumValues[i].name();
1649            }
1650        }
1651        return withHeader(header);
1652    }
1653
1654    /**
1655     * Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
1656     * either be parsed automatically from the input file with:
1657     *
1658     * <pre>
1659     * CSVFormat format = aformat.withHeader();
1660     * </pre>
1661     *
1662     * or specified manually with:
1663     *
1664     * <pre>
1665     * CSVFormat format = aformat.withHeader(resultSet);
1666     * </pre>
1667     * <p>
1668     * The header is also used by the {@link CSVPrinter}.
1669     * </p>
1670     *
1671     * @param resultSet
1672     *            the resultSet for the header, {@code null} if disabled, empty if parsed automatically, user specified
1673     *            otherwise.
1674     *
1675     * @return A new CSVFormat that is equal to this but with the specified header
1676     * @throws SQLException
1677     *             SQLException if a database access error occurs or this method is called on a closed result set.
1678     * @since 1.1
1679     */
1680    public CSVFormat withHeader(final ResultSet resultSet) throws SQLException {
1681        return withHeader(resultSet != null ? resultSet.getMetaData() : null);
1682    }
1683
1684    /**
1685     * Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
1686     * either be parsed automatically from the input file with:
1687     *
1688     * <pre>
1689     * CSVFormat format = aformat.withHeader();
1690     * </pre>
1691     *
1692     * or specified manually with:
1693     *
1694     * <pre>
1695     * CSVFormat format = aformat.withHeader(metaData);
1696     * </pre>
1697     * <p>
1698     * The header is also used by the {@link CSVPrinter}.
1699     * </p>
1700     *
1701     * @param metaData
1702     *            the metaData for the header, {@code null} if disabled, empty if parsed automatically, user specified
1703     *            otherwise.
1704     *
1705     * @return A new CSVFormat that is equal to this but with the specified header
1706     * @throws SQLException
1707     *             SQLException if a database access error occurs or this method is called on a closed result set.
1708     * @since 1.1
1709     */
1710    public CSVFormat withHeader(final ResultSetMetaData metaData) throws SQLException {
1711        String[] labels = null;
1712        if (metaData != null) {
1713            final int columnCount = metaData.getColumnCount();
1714            labels = new String[columnCount];
1715            for (int i = 0; i < columnCount; i++) {
1716                labels[i] = metaData.getColumnLabel(i + 1);
1717            }
1718        }
1719        return withHeader(labels);
1720    }
1721
1722    /**
1723     * Returns a new {@code CSVFormat} with the header of the format set to the given values. The header can either be
1724     * parsed automatically from the input file with:
1725     *
1726     * <pre>
1727     * CSVFormat format = aformat.withHeader();
1728     * </pre>
1729     *
1730     * or specified manually with:
1731     *
1732     * <pre>
1733     * CSVFormat format = aformat.withHeader(&quot;name&quot;, &quot;email&quot;, &quot;phone&quot;);
1734     * </pre>
1735     * <p>
1736     * The header is also used by the {@link CSVPrinter}.
1737     * </p>
1738     *
1739     * @param header
1740     *            the header, {@code null} if disabled, empty if parsed automatically, user specified otherwise.
1741     *
1742     * @return A new CSVFormat that is equal to this but with the specified header
1743     * @see #withSkipHeaderRecord(boolean)
1744     */
1745    public CSVFormat withHeader(final String... header) {
1746        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1747                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1748                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1749    }
1750
1751    /**
1752     * Returns a new {@code CSVFormat} with the header comments of the format set to the given values. The comments will
1753     * be printed first, before the headers. This setting is ignored by the parser.
1754     *
1755     * <pre>
1756     * CSVFormat format = aformat.withHeaderComments(&quot;Generated by Apache Commons CSV 1.1.&quot;, new Date());
1757     * </pre>
1758     *
1759     * @param headerComments
1760     *            the headerComments which will be printed by the Printer before the actual CSV data.
1761     *
1762     * @return A new CSVFormat that is equal to this but with the specified header
1763     * @see #withSkipHeaderRecord(boolean)
1764     * @since 1.1
1765     */
1766    public CSVFormat withHeaderComments(final Object... headerComments) {
1767        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1768                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1769                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1770    }
1771
1772    /**
1773     * Returns a new {@code CSVFormat} with the empty line skipping behavior of the format set to {@code true}.
1774     *
1775     * @return A new CSVFormat that is equal to this but with the specified empty line skipping behavior.
1776     * @since {@link #withIgnoreEmptyLines(boolean)}
1777     * @since 1.1
1778     */
1779    public CSVFormat withIgnoreEmptyLines() {
1780        return this.withIgnoreEmptyLines(true);
1781    }
1782
1783    /**
1784     * Returns a new {@code CSVFormat} with the empty line skipping behavior of the format set to the given value.
1785     *
1786     * @param ignoreEmptyLines
1787     *            the empty line skipping behavior, {@code true} to ignore the empty lines between the records,
1788     *            {@code false} to translate empty lines to empty records.
1789     * @return A new CSVFormat that is equal to this but with the specified empty line skipping behavior.
1790     */
1791    public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
1792        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1793                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1794                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1795    }
1796
1797    /**
1798     * Returns a new {@code CSVFormat} with the header ignore case behavior set to {@code true}.
1799     *
1800     * @return A new CSVFormat that will ignore case header name.
1801     * @see #withIgnoreHeaderCase(boolean)
1802     * @since 1.3
1803     */
1804    public CSVFormat withIgnoreHeaderCase() {
1805        return this.withIgnoreHeaderCase(true);
1806    }
1807
1808    /**
1809     * Returns a new {@code CSVFormat} with whether header names should be accessed ignoring case.
1810     *
1811     * @param ignoreHeaderCase
1812     *            the case mapping behavior, {@code true} to access name/values, {@code false} to leave the mapping as
1813     *            is.
1814     * @return A new CSVFormat that will ignore case header name if specified as {@code true}
1815     * @since 1.3
1816     */
1817    public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
1818        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1819                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1820                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1821    }
1822
1823    /**
1824     * Returns a new {@code CSVFormat} with the trimming behavior of the format set to {@code true}.
1825     *
1826     * @return A new CSVFormat that is equal to this but with the specified trimming behavior.
1827     * @see #withIgnoreSurroundingSpaces(boolean)
1828     * @since 1.1
1829     */
1830    public CSVFormat withIgnoreSurroundingSpaces() {
1831        return this.withIgnoreSurroundingSpaces(true);
1832    }
1833
1834    /**
1835     * Returns a new {@code CSVFormat} with the trimming behavior of the format set to the given value.
1836     *
1837     * @param ignoreSurroundingSpaces
1838     *            the trimming behavior, {@code true} to remove the surrounding spaces, {@code false} to leave the
1839     *            spaces as is.
1840     * @return A new CSVFormat that is equal to this but with the specified trimming behavior.
1841     */
1842    public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
1843        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1844                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1845                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1846    }
1847
1848    /**
1849     * Returns a new {@code CSVFormat} with conversions to and from null for strings on input and output.
1850     * <ul>
1851     * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
1852     * records.</li>
1853     * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
1854     * </ul>
1855     *
1856     * @param nullString
1857     *            the String to convert to and from {@code null}. No substitution occurs if {@code null}
1858     *
1859     * @return A new CSVFormat that is equal to this but with the specified null conversion string.
1860     */
1861    public CSVFormat withNullString(final String nullString) {
1862        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1863                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1864                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1865    }
1866
1867    /**
1868     * Returns a new {@code CSVFormat} with the quoteChar of the format set to the specified character.
1869     *
1870     * @param quoteChar
1871     *            the quoteChar character
1872     * @return A new CSVFormat that is equal to this but with the specified character as quoteChar
1873     * @throws IllegalArgumentException
1874     *             thrown if the specified character is a line break
1875     */
1876    public CSVFormat withQuote(final char quoteChar) {
1877        return withQuote(Character.valueOf(quoteChar));
1878    }
1879
1880    /**
1881     * Returns a new {@code CSVFormat} with the quoteChar of the format set to the specified character.
1882     *
1883     * @param quoteChar
1884     *            the quoteChar character, use {@code null} to disable
1885     * @return A new CSVFormat that is equal to this but with the specified character as quoteChar
1886     * @throws IllegalArgumentException
1887     *             thrown if the specified character is a line break
1888     */
1889    public CSVFormat withQuote(final Character quoteChar) {
1890        if (isLineBreak(quoteChar)) {
1891            throw new IllegalArgumentException("The quoteChar cannot be a line break");
1892        }
1893        return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
1894                ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
1895                allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1896    }
1897
1898    /**
1899     * Returns a new {@code CSVFormat} with the output quote policy of the format set to the specified value.
1900     *
1901     * @param quoteModePolicy
1902     *            the quote policy to use for output.
1903     *
1904     * @return A new CSVFormat that is equal to this but with the specified quote policy
1905     */
1906    public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
1907        return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
1908                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1909                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1910    }
1911
1912    /**
1913     * Returns a new {@code CSVFormat} with the record separator of the format set to the specified character.
1914     *
1915     * <p>
1916     * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1917     * only works for inputs with '\n', '\r' and "\r\n"
1918     * </p>
1919     *
1920     * @param recordSeparator
1921     *            the record separator to use for output.
1922     *
1923     * @return A new CSVFormat that is equal to this but with the specified output record separator
1924     */
1925    public CSVFormat withRecordSeparator(final char recordSeparator) {
1926        return withRecordSeparator(String.valueOf(recordSeparator));
1927    }
1928
1929    /**
1930     * Returns a new {@code CSVFormat} with the record separator of the format set to the specified String.
1931     *
1932     * <p>
1933     * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1934     * only works for inputs with '\n', '\r' and "\r\n"
1935     * </p>
1936     *
1937     * @param recordSeparator
1938     *            the record separator to use for output.
1939     *
1940     * @return A new CSVFormat that is equal to this but with the specified output record separator
1941     * @throws IllegalArgumentException
1942     *             if recordSeparator is none of CR, LF or CRLF
1943     */
1944    public CSVFormat withRecordSeparator(final String recordSeparator) {
1945        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1946                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1947                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1948    }
1949
1950    /**
1951     * Returns a new {@code CSVFormat} with skipping the header record set to {@code true}.
1952     *
1953     * @return A new CSVFormat that is equal to this but with the specified skipHeaderRecord setting.
1954     * @see #withSkipHeaderRecord(boolean)
1955     * @see #withHeader(String...)
1956     * @since 1.1
1957     */
1958    public CSVFormat withSkipHeaderRecord() {
1959        return this.withSkipHeaderRecord(true);
1960    }
1961
1962    /**
1963     * Returns a new {@code CSVFormat} with whether to skip the header record.
1964     *
1965     * @param skipHeaderRecord
1966     *            whether to skip the header record.
1967     *
1968     * @return A new CSVFormat that is equal to this but with the specified skipHeaderRecord setting.
1969     * @see #withHeader(String...)
1970     */
1971    public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
1972        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1973                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1974                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
1975    }
1976
1977    /**
1978     * Returns a new {@code CSVFormat} with the record separator of the format set to the operating system's line
1979     * separator string, typically CR+LF on Windows and LF on Linux.
1980     *
1981     * <p>
1982     * <strong>Note:</strong> This setting is only used during printing and does not affect parsing. Parsing currently
1983     * only works for inputs with '\n', '\r' and "\r\n"
1984     * </p>
1985     *
1986     * @return A new CSVFormat that is equal to this but with the operating system's line separator string.
1987     * @since 1.6
1988     */
1989    public CSVFormat withSystemRecordSeparator() {
1990        return withRecordSeparator(System.getProperty("line.separator"));
1991    }
1992
1993    /**
1994     * Returns a new {@code CSVFormat} to add a trailing delimiter.
1995     *
1996     * @return A new CSVFormat that is equal to this but with the trailing delimiter setting.
1997     * @since 1.3
1998     */
1999    public CSVFormat withTrailingDelimiter() {
2000        return withTrailingDelimiter(true);
2001    }
2002
2003    /**
2004     * Returns a new {@code CSVFormat} with whether to add a trailing delimiter.
2005     *
2006     * @param trailingDelimiter
2007     *            whether to add a trailing delimiter.
2008     *
2009     * @return A new CSVFormat that is equal to this but with the specified trailing delimiter setting.
2010     * @since 1.3
2011     */
2012    public CSVFormat withTrailingDelimiter(final boolean trailingDelimiter) {
2013        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
2014                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
2015                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
2016    }
2017
2018    /**
2019     * Returns a new {@code CSVFormat} to trim leading and trailing blanks.
2020     *
2021     * @return A new CSVFormat that is equal to this but with the trim setting on.
2022     * @since 1.3
2023     */
2024    public CSVFormat withTrim() {
2025        return withTrim(true);
2026    }
2027
2028    /**
2029     * Returns a new {@code CSVFormat} with whether to trim leading and trailing blanks.
2030     *
2031     * @param trim
2032     *            whether to trim leading and trailing blanks.
2033     *
2034     * @return A new CSVFormat that is equal to this but with the specified trim setting.
2035     * @since 1.3
2036     */
2037    public CSVFormat withTrim(final boolean trim) {
2038        return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
2039                ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
2040                skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter, autoFlush);
2041    }
2042}