Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 90E662004C8 for ; Mon, 9 May 2016 20:10:30 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 8F81016099C; Mon, 9 May 2016 18:10:30 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 4A0EF160A17 for ; Mon, 9 May 2016 20:10:28 +0200 (CEST) Received: (qmail 18073 invoked by uid 500); 9 May 2016 18:10:27 -0000 Mailing-List: contact notifications-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list notifications@commons.apache.org Received: (qmail 18063 invoked by uid 99); 9 May 2016 18:10:27 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 May 2016 18:10:27 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id F1DACC0B7C for ; Mon, 9 May 2016 18:10:26 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -1.079 X-Spam-Level: X-Spam-Status: No, score=-1.079 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-2.079] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id fYtlECEr3rGL for ; Mon, 9 May 2016 18:10:17 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTP id A78F15F24B for ; Mon, 9 May 2016 18:10:16 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 7E8CCE0E38 for ; Mon, 9 May 2016 18:10:14 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 7576A3A168F for ; Mon, 9 May 2016 18:10:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r987833 [8/47] - in /websites/production/commons/content/proper/commons-csv/archives/1.3: ./ apidocs/ apidocs/org/ apidocs/org/apache/ apidocs/org/apache/commons/ apidocs/org/apache/commons/csv/ apidocs/org/apache/commons/csv/class-use/ api... Date: Mon, 09 May 2016 18:10:11 -0000 To: notifications@commons.apache.org From: britter@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20160509181013.7576A3A168F@svn01-us-west.apache.org> archived-at: Mon, 09 May 2016 18:10:30 -0000 Added: websites/production/commons/content/proper/commons-csv/archives/1.3/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html ============================================================================== --- websites/production/commons/content/proper/commons-csv/archives/1.3/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html (added) +++ websites/production/commons/content/proper/commons-csv/archives/1.3/apidocs/src-html/org/apache/commons/csv/CSVFormat.Predefined.html Mon May 9 18:10:08 2016 @@ -0,0 +1,1578 @@ + + + +Source code + + + +
+
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.CR;
+023import static org.apache.commons.csv.Constants.CRLF;
+024import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
+025import static org.apache.commons.csv.Constants.LF;
+026import static org.apache.commons.csv.Constants.PIPE;
+027import static org.apache.commons.csv.Constants.TAB;
+028
+029import java.io.IOException;
+030import java.io.Reader;
+031import java.io.Serializable;
+032import java.io.StringWriter;
+033import java.sql.ResultSet;
+034import java.sql.ResultSetMetaData;
+035import java.sql.SQLException;
+036import java.util.Arrays;
+037import java.util.HashSet;
+038import java.util.Set;
+039
+040/**
+041 * Specifies the format of a CSV file and parses input.
+042 *
+043 * <h2>Using predefined formats</h2>
+044 *
+045 * <p>
+046 * You can use one of the predefined formats:
+047 * </p>
+048 *
+049 * <ul>
+050 * <li>{@link #DEFAULT}</li>
+051 * <li>{@link #EXCEL}</li>
+052 * <li>{@link #MYSQL}</li>
+053 * <li>{@link #RFC4180}</li>
+054 * <li>{@link #TDF}</li>
+055 * </ul>
+056 *
+057 * <p>
+058 * For example:
+059 * </p>
+060 *
+061 * <pre>
+062 * CSVParser parser = CSVFormat.EXCEL.parse(reader);
+063 * </pre>
+064 *
+065 * <p>
+066 * The {@link CSVParser} provides static methods to parse other input types, for example:
+067 * </p>
+068 *
+069 * <pre>
+070 * CSVParser parser = CSVParser.parse(file, StandardCharsets.US_ASCII, CSVFormat.EXCEL);
+071 * </pre>
+072 *
+073 * <h2>Defining formats</h2>
+074 *
+075 * <p>
+076 * You can extend a format by calling the {@code with} methods. For example:
+077 * </p>
+078 *
+079 * <pre>
+080 * CSVFormat.EXCEL.withNullString(&quot;N/A&quot;).withIgnoreSurroundingSpaces(true);
+081 * </pre>
+082 *
+083 * <h2>Defining column names</h2>
+084 *
+085 * <p>
+086 * To define the column names you want to use to access records, write:
+087 * </p>
+088 *
+089 * <pre>
+090 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;);
+091 * </pre>
+092 *
+093 * <p>
+094 * Calling {@link #withHeader(String...)} let's you use the given names to address values in a {@link CSVRecord}, and
+095 * assumes that your CSV source does not contain a first record that also defines column names.
+096 *
+097 * If it does, then you are overriding this metadata with your names and you should skip the first record by calling
+098 * {@link #withSkipHeaderRecord(boolean)} with {@code true}.
+099 * </p>
+100 *
+101 * <h2>Parsing</h2>
+102 *
+103 * <p>
+104 * You can use a format directly to parse a reader. For example, to parse an Excel file with columns header, write:
+105 * </p>
+106 *
+107 * <pre>
+108 * Reader in = ...;
+109 * CSVFormat.EXCEL.withHeader(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;).parse(in);
+110 * </pre>
+111 *
+112 * <p>
+113 * For other input types, like resources, files, and URLs, use the static methods on {@link CSVParser}.
+114 * </p>
+115 *
+116 * <h2>Referencing columns safely</h2>
+117 *
+118 * <p>
+119 * If your source contains a header record, you can simplify your code and safely reference columns, by using
+120 * {@link #withHeader(String...)} with no arguments:
+121 * </p>
+122 *
+123 * <pre>
+124 * CSVFormat.EXCEL.withHeader();
+125 * </pre>
+126 *
+127 * <p>
+128 * This causes the parser to read the first record and use its values as column names.
+129 *
+130 * Then, call one of the {@link CSVRecord} get method that takes a String column name argument:
+131 * </p>
+132 *
+133 * <pre>
+134 * String value = record.get(&quot;Col1&quot;);
+135 * </pre>
+136 *
+137 * <p>
+138 * This makes your code impervious to changes in column order in the CSV file.
+139 * </p>
+140 *
+141 * <h2>Notes</h2>
+142 *
+143 * <p>
+144 * This class is immutable.
+145 * </p>
+146 *
+147 * @version $Id: CSVFormat.java 1742506 2016-05-06 07:07:43Z britter $
+148 */
+149public final class CSVFormat implements Serializable {
+150
+151    /**
+152     * Predefines formats.
+153     *
+154     * @since 1.2
+155     */
+156    public enum Predefined {
+157
+158        /**
+159         * @see CSVFormat#DEFAULT
+160         */
+161        Default(CSVFormat.DEFAULT),
+162
+163        /**
+164         * @see CSVFormat#EXCEL
+165         */
+166        Excel(CSVFormat.EXCEL),
+167
+168        /**
+169         * @see CSVFormat#INFORMIX_UNLOAD
+170         * @since 1.3
+171         */
+172        InformixUnload(CSVFormat.INFORMIX_UNLOAD),
+173
+174        /**
+175         * @see CSVFormat#INFORMIX_UNLOAD_CSV
+176         * @since 1.3
+177         */
+178        InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),
+179
+180        /**
+181         * @see CSVFormat#MYSQL
+182         */
+183        MySQL(CSVFormat.MYSQL),
+184
+185        /**
+186         * @see CSVFormat#RFC4180
+187         */
+188        RFC4180(CSVFormat.RFC4180),
+189
+190        /**
+191         * @see CSVFormat#TDF
+192         */
+193        TDF(CSVFormat.TDF);
+194
+195        private final CSVFormat format;
+196
+197        Predefined(final CSVFormat format) {
+198            this.format = format;
+199        }
+200
+201        /**
+202         * Gets the format.
+203         *
+204         * @return the format.
+205         */
+206        public CSVFormat getFormat() {
+207            return format;
+208        }
+209    }
+210
+211    /**
+212     * Standard comma separated format, as for {@link #RFC4180} but allowing empty lines.
+213     *
+214     * <p>
+215     * Settings are:
+216     * </p>
+217     * <ul>
+218     * <li>withDelimiter(',')</li>
+219     * <li>withQuote('"')</li>
+220     * <li>withRecordSeparator("\r\n")</li>
+221     * <li>withIgnoreEmptyLines(true)</li>
+222     * </ul>
+223     *
+224     * @see Predefined#Default
+225     */
+226    public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
+227            null, null, null, false, false, false, false, false);
+228
+229    /**
+230     * Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
+231     * locale dependent, it might be necessary to customize this format to accommodate to your regional settings.
+232     *
+233     * <p>
+234     * For example for parsing or generating a CSV file on a French system the following format will be used:
+235     * </p>
+236     *
+237     * <pre>
+238     * CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');
+239     * </pre>
+240     *
+241     * <p>
+242     * Settings are:
+243     * </p>
+244     * <ul>
+245     * <li>{@link #withDelimiter(char) withDelimiter(',')}</li>
+246     * <li>{@link #withQuote(char) withQuote('"')}</li>
+247     * <li>{@link #withRecordSeparator(String) withRecordSeparator("\r\n")}</li>
+248     * <li>{@link #withIgnoreEmptyLines(boolean) withIgnoreEmptyLines(false)}</li>
+249     * <li>{@link #withAllowMissingColumnNames(boolean) withAllowMissingColumnNames(true)}</li>
+250     * </ul>
+251     * <p>
+252     * Note: this is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
+253     * withAllowMissingColumnNames(true)}.
+254     * </p>
+255     *
+256     * @see Predefined#Excel
+257     */
+258    public static final CSVFormat EXCEL = DEFAULT.withIgnoreEmptyLines(false).withAllowMissingColumnNames();
+259
+260    /**
+261     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
+262     *
+263     * <p>
+264     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
+265     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+266     * </p>
+267     *
+268     * <p>
+269     * Settings are:
+270     * </p>
+271     * <ul>
+272     * <li>withDelimiter(',')</li>
+273     * <li>withQuote("\"")</li>
+274     * <li>withRecordSeparator('\n')</li>
+275     * <li>withEscape('\\')</li>
+276     * </ul>
+277     *
+278     * @see Predefined#MySQL
+279     * @see <a href=
+280     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
+281     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
+282     * @since 1.3
+283     */
+284    public static final CSVFormat INFORMIX_UNLOAD = DEFAULT.withDelimiter(PIPE).withEscape(BACKSLASH)
+285            .withQuote(DOUBLE_QUOTE_CHAR).withRecordSeparator(LF);
+286
+287    /**
+288     * Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
+289     *
+290     * <p>
+291     * This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
+292     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+293     * </p>
+294     *
+295     * <p>
+296     * Settings are:
+297     * </p>
+298     * <ul>
+299     * <li>withDelimiter(',')</li>
+300     * <li>withQuote("\"")</li>
+301     * <li>withRecordSeparator('\n')</li>
+302     * </ul>
+303     *
+304     * @see Predefined#MySQL
+305     * @see <a href=
+306     *      "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
+307     *      http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
+308     * @since 1.3
+309     */
+310    public static final CSVFormat INFORMIX_UNLOAD_CSV = DEFAULT.withDelimiter(COMMA).withQuote(DOUBLE_QUOTE_CHAR)
+311            .withRecordSeparator(LF);
+312
+313    /**
+314     * Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
+315     *
+316     * <p>
+317     * This is a tab-delimited format with a LF character as the line separator. Values are not quoted and special
+318     * characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
+319     * </p>
+320     *
+321     * <p>
+322     * Settings are:
+323     * </p>
+324     * <ul>
+325     * <li>withDelimiter('\t')</li>
+326     * <li>withQuote(null)</li>
+327     * <li>withRecordSeparator('\n')</li>
+328     * <li>withIgnoreEmptyLines(false)</li>
+329     * <li>withEscape('\\')</li>
+330     * <li>withNullString("\\N")</li>
+331     * </ul>
+332     *
+333     * @see Predefined#MySQL
+334     * @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
+335     *      -data.html</a>
+336     */
+337    public static final CSVFormat MYSQL = DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
+338            .withQuote(null).withRecordSeparator(LF).withNullString("\\N");
+339
+340    /**
+341     * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
+342     *
+343     * <p>
+344     * Settings are:
+345     * </p>
+346     * <ul>
+347     * <li>withDelimiter(',')</li>
+348     * <li>withQuote('"')</li>
+349     * <li>withRecordSeparator("\r\n")</li>
+350     * <li>withIgnoreEmptyLines(false)</li>
+351     * </ul>
+352     *
+353     * @see Predefined#RFC4180
+354     */
+355    public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
+356
+357    private static final long serialVersionUID = 1L;
+358
+359    /**
+360     * Tab-delimited format.
+361     *
+362     * <p>
+363     * Settings are:
+364     * </p>
+365     * <ul>
+366     * <li>withDelimiter('\t')</li>
+367     * <li>withQuote('"')</li>
+368     * <li>withRecordSeparator("\r\n")</li>
+369     * <li>withIgnoreSurroundingSpaces(true)</li>
+370     * </ul>
+371     *
+372     * @see Predefined#TDF
+373     */
+374    public static final CSVFormat TDF = DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
+375
+376    /**
+377     * Returns true if the given character is a line break character.
+378     *
+379     * @param c
+380     *            the character to check
+381     *
+382     * @return true if <code>c</code> is a line break character
+383     */
+384    private static boolean isLineBreak(final char c) {
+385        return c == LF || c == CR;
+386    }
+387
+388    /**
+389     * Returns true if the given character is a line break character.
+390     *
+391     * @param c
+392     *            the character to check, may be null
+393     *
+394     * @return true if <code>c</code> is a line break character (and not null)
+395     */
+396    private static boolean isLineBreak(final Character c) {
+397        return c != null && isLineBreak(c.charValue());
+398    }
+399
+400    /**
+401     * Creates a new CSV format with the specified delimiter.
+402     *
+403     * <p>
+404     * Use this method if you want to create a CSVFormat from scratch. All fields but the delimiter will be initialized
+405     * with null/false.
+406     * </p>
+407     *
+408     * @param delimiter
+409     *            the char used for value separation, must not be a line break character
+410     * @return a new CSV format.
+411     * @throws IllegalArgumentException
+412     *             if the delimiter is a line break character
+413     *
+414     * @see #DEFAULT
+415     * @see #RFC4180
+416     * @see #MYSQL
+417     * @see #EXCEL
+418     * @see #TDF
+419     */
+420    public static CSVFormat newFormat(final char delimiter) {
+421        return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false,
+422                false, false, false);
+423    }
+424
+425    /**
+426     * Gets one of the predefined formats from {@link CSVFormat.Predefined}.
+427     *
+428     * @param format
+429     *            name
+430     * @return one of the predefined formats
+431     * @since 1.2
+432     */
+433    public static CSVFormat valueOf(final String format) {
+434        return CSVFormat.Predefined.valueOf(format).getFormat();
+435    }
+436
+437    private final boolean allowMissingColumnNames;
+438
+439    private final Character commentMarker; // null if commenting is disabled
+440
+441    private final char delimiter;
+442
+443    private final Character escapeCharacter; // null if escaping is disabled
+444
+445    private final String[] header; // array of header column names
+446
+447    private final String[] headerComments; // array of header comment lines
+448
+449    private final boolean ignoreEmptyLines;
+450
+451    private final boolean ignoreHeaderCase; // should ignore header names case
+452
+453    private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
+454
+455    private final String nullString; // the string to be used for null values
+456
+457    private final Character quoteCharacter; // null if quoting is disabled
+458
+459    private final QuoteMode quoteMode;
+460
+461    private final String recordSeparator; // for outputs
+462
+463    private final boolean skipHeaderRecord;
+464
+465    private final boolean trailingDelimiter;
+466
+467    private final boolean trim;
+468
+469    /**
+470     * Creates a customized CSV format.
+471     *
+472     * @param delimiter
+473     *            the char used for value separation, must not be a line break character
+474     * @param quoteChar
+475     *            the Character used as value encapsulation marker, may be {@code null} to disable
+476     * @param quoteMode
+477     *            the quote mode
+478     * @param commentStart
+479     *            the Character used for comment identification, may be {@code null} to disable
+480     * @param escape
+481     *            the Character used to escape special characters in values, may be {@code null} to disable
+482     * @param ignoreSurroundingSpaces
+483     *            {@code true} when whitespaces enclosing values should be ignored
+484     * @param ignoreEmptyLines
+485     *            {@code true} when the parser should skip empty lines
+486     * @param recordSeparator
+487     *            the line separator to use for output
+488     * @param nullString
+489     *            the line separator to use for output
+490     * @param headerComments
+491     *            the comments to be printed by the Printer before the actual CSV data
+492     * @param header
+493     *            the header
+494     * @param skipHeaderRecord
+495     *            TODO
+496     * @param allowMissingColumnNames
+497     *            TODO
+498     * @param ignoreHeaderCase
+499     *            TODO
+500     * @param trim
+501     *            TODO
+502     * @param trailingDelimiter TODO
+503     * @throws IllegalArgumentException
+504     *             if the delimiter is a line break character
+505     */
+506    private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMode quoteMode,
+507            final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
+508            final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
+509            final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
+510            final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, final boolean trim,
+511            final boolean trailingDelimiter) {
+512        this.delimiter = delimiter;
+513        this.quoteCharacter = quoteChar;
+514        this.quoteMode = quoteMode;
+515        this.commentMarker = commentStart;
+516        this.escapeCharacter = escape;
+517        this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
+518        this.allowMissingColumnNames = allowMissingColumnNames;
+519        this.ignoreEmptyLines = ignoreEmptyLines;
+520        this.recordSeparator = recordSeparator;
+521        this.nullString = nullString;
+522        this.headerComments = toStringArray(headerComments);
+523        this.header = header == null ? null : header.clone();
+524        this.skipHeaderRecord = skipHeaderRecord;
+525        this.ignoreHeaderCase = ignoreHeaderCase;
+526        this.trailingDelimiter = trailingDelimiter;
+527        this.trim = trim;
+528        validate();
+529    }
+530
+531    @Override
+532    public boolean equals(final Object obj) {
+533        if (this == obj) {
+534            return true;
+535        }
+536        if (obj == null) {
+537            return false;
+538        }
+539        if (getClass() != obj.getClass()) {
+540            return false;
+541        }
+542
+543        final CSVFormat other = (CSVFormat) obj;
+544        if (delimiter != other.delimiter) {
+545            return false;
+546        }
+547        if (quoteMode != other.quoteMode) {
+548            return false;
+549        }
+550        if (quoteCharacter == null) {
+551            if (other.quoteCharacter != null) {
+552                return false;
+553            }
+554        } else if (!quoteCharacter.equals(other.quoteCharacter)) {
+555            return false;
+556        }
+557        if (commentMarker == null) {
+558            if (other.commentMarker != null) {
+559                return false;
+560            }
+561        } else if (!commentMarker.equals(other.commentMarker)) {
+562            return false;
+563        }
+564        if (escapeCharacter == null) {
+565            if (other.escapeCharacter != null) {
+566                return false;
+567            }
+568        } else if (!escapeCharacter.equals(other.escapeCharacter)) {
+569            return false;
+570        }
+571        if (nullString == null) {
+572            if (other.nullString != null) {
+573                return false;
+574            }
+575        } else if (!nullString.equals(other.nullString)) {
+576            return false;
+577        }
+578        if (!Arrays.equals(header, other.header)) {
+579            return false;
+580        }
+581        if (ignoreSurroundingSpaces != other.ignoreSurroundingSpaces) {
+582            return false;
+583        }
+584        if (ignoreEmptyLines != other.ignoreEmptyLines) {
+585            return false;
+586        }
+587        if (skipHeaderRecord != other.skipHeaderRecord) {
+588            return false;
+589        }
+590        if (recordSeparator == null) {
+591            if (other.recordSeparator != null) {
+592                return false;
+593            }
+594        } else if (!recordSeparator.equals(other.recordSeparator)) {
+595            return false;
+596        }
+597        return true;
+598    }
+599
+600    /**
+601     * Formats the specified values.
+602     *
+603     * @param values
+604     *            the values to format
+605     * @return the formatted values
+606     */
+607    public String format(final Object... values) {
+608        final StringWriter out = new StringWriter();
+609        try {
+610            new CSVPrinter(out, this).printRecord(values);
+611            return out.toString().trim();
+612        } catch (final IOException e) {
+613            // should not happen because a StringWriter does not do IO.
+614            throw new IllegalStateException(e);
+615        }
+616    }
+617
+618    /**
+619     * Specifies whether missing column names are allowed when parsing the header line.
+620     *
+621     * @return {@code true} if missing column names are allowed when parsing the header line, {@code false} to throw an
+622     *         {@link IllegalArgumentException}.
+623     */
+624    public boolean getAllowMissingColumnNames() {
+625        return allowMissingColumnNames;
+626    }
+627
+628    /**
+629     * Returns the character marking the start of a line comment.
+630     *
+631     * @return the comment start marker, may be {@code null}
+632     */
+633    public Character getCommentMarker() {
+634        return commentMarker;
+635    }
+636
+637    /**
+638     * Returns the character delimiting the values (typically ';', ',' or '\t').
+639     *
+640     * @return the delimiter character
+641     */
+642    public char getDelimiter() {
+643        return delimiter;
+644    }
+645
+646    /**
+647     * Returns the escape character.
+648     *
+649     * @return the escape character, may be {@code null}
+650     */
+651    public Character getEscapeCharacter() {
+652        return escapeCharacter;
+653    }
+654
+655    /**
+656     * Returns a copy of the header array.
+657     *
+658     * @return a copy of the header array; {@code null} if disabled, the empty array if to be read from the file
+659     */
+660    public String[] getHeader() {
+661        return header != null ? header.clone() : null;
+662    }
+663
+664    /**
+665     * Returns a copy of the header comment array.
+666     *
+667     * @return a copy of the header comment array; {@code null} if disabled.
+668     */
+669    public String[] getHeaderComments() {
+670        return headerComments != null ? headerComments.clone() : null;
+671    }
+672
+673    /**
+674     * Specifies whether empty lines between records are ignored when parsing input.
+675     *
+676     * @return {@code true} if empty lines between records are ignored, {@code false} if they are turned into empty
+677     *         records.
+678     */
+679    public boolean getIgnoreEmptyLines() {
+680        return ignoreEmptyLines;
+681    }
+682
+683    /**
+684     * Specifies whether header names will be accessed ignoring case.
+685     *
+686     * @return {@code true} if header names cases are ignored, {@code false} if they are case sensitive.
+687     * @since 1.3
+688     */
+689    public boolean getIgnoreHeaderCase() {
+690        return ignoreHeaderCase;
+691    }
+692
+693    /**
+694     * Specifies whether spaces around values are ignored when parsing input.
+695     *
+696     * @return {@code true} if spaces around values are ignored, {@code false} if they are treated as part of the value.
+697     */
+698    public boolean getIgnoreSurroundingSpaces() {
+699        return ignoreSurroundingSpaces;
+700    }
+701
+702    /**
+703     * Gets the String to convert to and from {@code null}.
+704     * <ul>
+705     * <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
+706     * records.</li>
+707     * <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
+708     * </ul>
+709     *
+710     * @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
+711     */
+712    public String getNullString() {
+713        return nullString;
+714    }
+715
+716    /**
+717     * Returns the character used to encapsulate values containing special characters.
+718     *
+719     * @return the quoteChar character, may be {@code null}
+720     */
+721    public Character getQuoteCharacter() {
+722        return quoteCharacter;
+723    }
+724
+725    /**
+726     * Returns the quote policy output fields.
+727     *
+728     * @return the quote policy
+729     */
+730    public QuoteMode getQuoteMode() {
+731        return quoteMode;
+732    }
+733
+734    /**
+735     * Returns the record separator delimiting output records.
+736     *
+737     * @return the record separator
+738     */
+739    public String getRecordSeparator() {
+740        return recordSeparator;
+741    }
+742
+743    /**
+744     * Returns whether to skip the header record.
+745     *
+746     * @return whether to skip the header record.
+747     */
+748    public boolean getSkipHeaderRecord() {
+749        return skipHeaderRecord;
+750    }
+751
+752    /**
+753     * Returns whether to add a trailing delimiter.
+754     *
+755     * @return whether to add a trailing delimiter.
+756     * @since 1.3
+757     */
+758    public boolean getTrailingDelimiter() {
+759        return trailingDelimiter;
+760    }
+761
+762    /**
+763     * Returns whether to trim leading and trailing blanks.
+764     *
+765     * @return whether to trim leading and trailing blanks.
+766     */
+767    public boolean getTrim() {
+768        return trim;
+769    }
+770
+771    @Override
+772    public int hashCode() {
+773        final int prime = 31;
+774        int result = 1;
+775
+776        result = prime * result + delimiter;
+777        result = prime * result + ((quoteMode == null) ? 0 : quoteMode.hashCode());
+778        result = prime * result + ((quoteCharacter == null) ? 0 : quoteCharacter.hashCode());
+779        result = prime * result + ((commentMarker == null) ? 0 : commentMarker.hashCode());
+780        result = prime * result + ((escapeCharacter == null) ? 0 : escapeCharacter.hashCode());
+781        result = prime * result + ((nullString == null) ? 0 : nullString.hashCode());
+782        result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
+783        result = prime * result + (ignoreHeaderCase ? 1231 : 1237);
+784        result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
+785        result = prime * result + (skipHeaderRecord ? 1231 : 1237);
+786        result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
+787        result = prime * result + Arrays.hashCode(header);
+788        return result;
+789    }
+790
+791    /**
+792     * Specifies whether comments are supported by this format.
+793     *
+794     * Note that the comment introducer character is only recognized at the start of a line.
+795     *
+796     * @return {@code true} is comments are supported, {@code false} otherwise
+797     */
+798    public boolean isCommentMarkerSet() {
+799        return commentMarker != null;
+800    }
+801
+802    /**
+803     * Returns whether escape are being processed.
+804     *
+805     * @return {@code true} if escapes are processed
+806     */
+807    public boolean isEscapeCharacterSet() {
+808        return escapeCharacter != null;
+809    }
+810
+811    /**
+812     * Returns whether a nullString has been defined.
+813     *
+814     * @return {@code true} if a nullString is defined
+815     */
+816    public boolean isNullStringSet() {
+817        return nullString != null;
+818    }
+819
+820    /**
+821     * Returns whether a quoteChar has been defined.
+822     *
+823     * @return {@code true} if a quoteChar is defined
+824     */
+825    public boolean isQuoteCharacterSet() {
+826        return quoteCharacter != null;
+827    }
+828
+829    /**
+830     * Parses the specified content.
+831     *
+832     * <p>
+833     * See also the various static parse methods on {@link CSVParser}.
+834     * </p>
+835     *
+836     * @param in
+837     *            the input stream
+838     * @return a parser over a stream of {@link CSVRecord}s.
+839     * @throws IOException
+840     *             If an I/O error occurs
+841     */
+842    public CSVParser parse(final Reader in) throws IOException {
+843        return new CSVParser(in, this);
+844    }
+845
+846    /**
+847     * Prints to the specified output.
+848     *
+849     * <p>
+850     * See also {@link CSVPrinter}.
+851     * </p>
+852     *
+853     * @param out
+854     *            the output
+855     * @return a printer to an output
+856     * @throws IOException
+857     *             thrown if the optional header cannot be printed.
+858     */
+859    public CSVPrinter print(final Appendable out) throws IOException {
+860        return new CSVPrinter(out, this);
+861    }
+862
+863    @Override
+864    public String toString() {
+865        final StringBuilder sb = new StringBuilder();
+866        sb.append("Delimiter=<").append(delimiter).append('>');
+867        if (isEscapeCharacterSet()) {
+868            sb.append(' ');
+869            sb.append("Escape=<").append(escapeCharacter).append('>');
+870        }
+871        if (isQuoteCharacterSet()) {
+872            sb.append(' ');
+873            sb.append("QuoteChar=<").append(quoteCharacter).append('>');
+874        }
+875        if (isCommentMarkerSet()) {
+876            sb.append(' ');
+877            sb.append("CommentStart=<").append(commentMarker).append('>');
+878        }
+879        if (isNullStringSet()) {
+880            sb.append(' ');
+881            sb.append("NullString=<").append(nullString).append('>');
+882        }
+883        if (recordSeparator != null) {
+884            sb.append(' ');
+885            sb.append("RecordSeparator=<").append(recordSeparator).append('>');
+886        }
+887        if (getIgnoreEmptyLines()) {
+888            sb.append(" EmptyLines:ignored");
+889        }
+890        if (getIgnoreSurroundingSpaces()) {
+891            sb.append(" SurroundingSpaces:ignored");
+892        }
+893        if (getIgnoreHeaderCase()) {
+894            sb.append(" IgnoreHeaderCase:ignored");
+895        }
+896        sb.append(" SkipHeaderRecord:").append(skipHeaderRecord);
+897        if (headerComments != null) {
+898            sb.append(' ');
+899            sb.append("HeaderComments:").append(Arrays.toString(headerComments));
+900        }
+901        if (header != null) {
+902            sb.append(' ');
+903            sb.append("Header:").append(Arrays.toString(header));
+904        }
+905        return sb.toString();
+906    }
+907
+908    private String[] toStringArray(final Object[] values) {
+909        if (values == null) {
+910            return null;
+911        }
+912        final String[] strings = new String[values.length];
+913        for (int i = 0; i < values.length; i++) {
+914            final Object value = values[i];
+915            strings[i] = value == null ? null : value.toString();
+916        }
+917        return strings;
+918    }
+919
+920    /**
+921     * Verifies the consistency of the parameters and throws an IllegalArgumentException if necessary.
+922     *
+923     * @throws IllegalArgumentException
+924     */
+925    private void validate() throws IllegalArgumentException {
+926        if (isLineBreak(delimiter)) {
+927            throw new IllegalArgumentException("The delimiter cannot be a line break");
+928        }
+929
+930        if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
+931            throw new IllegalArgumentException(
+932                    "The quoteChar character and the delimiter cannot be the same ('" + quoteCharacter + "')");
+933        }
+934
+935        if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
+936            throw new IllegalArgumentException(
+937                    "The escape character and the delimiter cannot be the same ('" + escapeCharacter + "')");
+938        }
+939
+940        if (commentMarker != null && delimiter == commentMarker.charValue()) {
+941            throw new IllegalArgumentException(
+942                    "The comment start character and the delimiter cannot be the same ('" + commentMarker + "')");
+943        }
+944
+945        if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
+946            throw new IllegalArgumentException(

[... 625 lines stripped ...]