[CSV-175] Support for ignoring trailing delimiter.
[CSV-177] Support trimming leading and trailing blanks. [CSV-178] Create default formats for Informix UNLOAD and UNLOAD CSV. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1739694 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
103995083c
commit
16b9e2c791
|
@ -43,9 +43,12 @@
|
||||||
<action issue="CSV-153" type="update" dev="britter" due-to="Wren">CSVPrinter doesn't skip creation of header record if skipHeaderRecord is set to true</action>
|
<action issue="CSV-153" type="update" dev="britter" due-to="Wren">CSVPrinter doesn't skip creation of header record if skipHeaderRecord is set to true</action>
|
||||||
<action issue="CSV-159" type="add" dev="ggregory" due-to="Yamil Medina">Add IgnoreCase option for accessing header names</action>
|
<action issue="CSV-159" type="add" dev="ggregory" due-to="Yamil Medina">Add IgnoreCase option for accessing header names</action>
|
||||||
<action issue="CSV-169" type="add" dev="ggregory" due-to="Gary Gregory">The null string should be case-sensitive when reading records</action>
|
<action issue="CSV-169" type="add" dev="ggregory" due-to="Gary Gregory">The null string should be case-sensitive when reading records</action>
|
||||||
<action issue="CSV-168" type="fix" dev="ggregory" due-to="Gary Gregory, cornel creanga">CsvFormat.nullString should not be escaped</action>
|
<action issue="CSV-168" type="fix" dev="ggregory" due-to="Gary Gregory, cornel creanga">CSVFormat.nullString should not be escaped</action>
|
||||||
<action issue="CSV-170" type="fix" dev="ggregory" due-to="Gary Gregory, cornel creanga">CSVFormat.MYSQL nullString should be "\N"</action>
|
<action issue="CSV-170" type="fix" dev="ggregory" due-to="Gary Gregory, cornel creanga">CSVFormat.MYSQL nullString should be "\N"</action>
|
||||||
<action issue="CSV-161" type="fix" dev="ggregory" due-to="Gary Gregory, Kristof Meixner, Emmanuel Bourg">Fix Javadoc to say CSVFormat with() methods return a new CSVFormat</action>
|
<action issue="CSV-161" type="fix" dev="ggregory" due-to="Gary Gregory, Kristof Meixner, Emmanuel Bourg">Fix Javadoc to say CSVFormat with() methods return a new CSVFormat</action>
|
||||||
|
<action issue="CSV-175" type="add" dev="ggregory" due-to="Gary Gregory, Chris Jones">Support for ignoring trailing delimiter.</action>
|
||||||
|
<action issue="CSV-177" type="add" dev="ggregory" due-to="Gary Gregory">Support trimming leading and trailing blanks.</action>
|
||||||
|
<action issue="CSV-178" type="add" dev="ggregory" due-to="Gary Gregory">Create default formats for Informix UNLOAD and UNLOAD CSV.</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="1.2" date="2015-08-24" description="Feature and bug fix release">
|
<release version="1.2" date="2015-08-24" description="Feature and bug fix release">
|
||||||
<action issue="CSV-145" type="fix" dev="ggregory" due-to="Frank Ulbricht">CSVFormat.with* methods clear the header comments</action>
|
<action issue="CSV-145" type="fix" dev="ggregory" due-to="Frank Ulbricht">CSVFormat.with* methods clear the header comments</action>
|
||||||
|
|
|
@ -23,6 +23,7 @@ import static org.apache.commons.csv.Constants.CR;
|
||||||
import static org.apache.commons.csv.Constants.CRLF;
|
import static org.apache.commons.csv.Constants.CRLF;
|
||||||
import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
|
import static org.apache.commons.csv.Constants.DOUBLE_QUOTE_CHAR;
|
||||||
import static org.apache.commons.csv.Constants.LF;
|
import static org.apache.commons.csv.Constants.LF;
|
||||||
|
import static org.apache.commons.csv.Constants.PIPE;
|
||||||
import static org.apache.commons.csv.Constants.TAB;
|
import static org.apache.commons.csv.Constants.TAB;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -164,6 +165,18 @@ public final class CSVFormat implements Serializable {
|
||||||
*/
|
*/
|
||||||
Excel(CSVFormat.EXCEL),
|
Excel(CSVFormat.EXCEL),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CSVFormat#INFORMIX_UNLOAD
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
InformixUnload(CSVFormat.INFORMIX_UNLOAD),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CSVFormat#INFORMIX_UNLOAD_CSV
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
InformixUnloadCsv(CSVFormat.INFORMIX_UNLOAD_CSV),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see CSVFormat#MYSQL
|
* @see CSVFormat#MYSQL
|
||||||
*/
|
*/
|
||||||
|
@ -207,10 +220,11 @@ public final class CSVFormat implements Serializable {
|
||||||
* <li>withRecordSeparator("\r\n")</li>
|
* <li>withRecordSeparator("\r\n")</li>
|
||||||
* <li>withIgnoreEmptyLines(true)</li>
|
* <li>withIgnoreEmptyLines(true)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
* @see Predefined#Default
|
* @see Predefined#Default
|
||||||
*/
|
*/
|
||||||
public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true,
|
public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF,
|
||||||
CRLF, null, null, null, false, false, false);
|
null, null, null, false, false, false, false, false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
|
* Excel file format (using a comma as the value delimiter). Note that the actual value delimiter used by Excel is
|
||||||
|
@ -238,10 +252,64 @@ public final class CSVFormat implements Serializable {
|
||||||
* Note: this is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
|
* Note: this is currently like {@link #RFC4180} plus {@link #withAllowMissingColumnNames(boolean)
|
||||||
* withAllowMissingColumnNames(true)}.
|
* withAllowMissingColumnNames(true)}.
|
||||||
* </p>
|
* </p>
|
||||||
|
*
|
||||||
* @see Predefined#Excel
|
* @see Predefined#Excel
|
||||||
*/
|
*/
|
||||||
public static final CSVFormat EXCEL = DEFAULT.withIgnoreEmptyLines(false).withAllowMissingColumnNames();
|
public static final CSVFormat EXCEL = DEFAULT.withIgnoreEmptyLines(false).withAllowMissingColumnNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
|
||||||
|
* characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Settings are:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>withDelimiter(',')</li>
|
||||||
|
* <li>withQuote("\"")</li>
|
||||||
|
* <li>withRecordSeparator('\n')</li>
|
||||||
|
* <li>withEscape('\\')</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see Predefined#MySQL
|
||||||
|
* @see <a href=
|
||||||
|
* "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
|
||||||
|
* http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public static final CSVFormat INFORMIX_UNLOAD = DEFAULT.withDelimiter(PIPE).withEscape(BACKSLASH)
|
||||||
|
.withQuote(DOUBLE_QUOTE_CHAR).withRecordSeparator(LF);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default Informix CSV UNLOAD format used by the {@code UNLOAD TO file_name} operation.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This is a comma-delimited format with a LF character as the line separator. Values are not quoted and special
|
||||||
|
* characters are escaped with {@code '\'}. The default NULL string is {@code "\\N"}.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Settings are:
|
||||||
|
* </p>
|
||||||
|
* <ul>
|
||||||
|
* <li>withDelimiter(',')</li>
|
||||||
|
* <li>withQuote("\"")</li>
|
||||||
|
* <li>withRecordSeparator('\n')</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see Predefined#MySQL
|
||||||
|
* @see <a href=
|
||||||
|
* "http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm">
|
||||||
|
* http://www.ibm.com/support/knowledgecenter/SSBJG3_2.5.0/com.ibm.gen_busug.doc/c_fgl_InOutSql_UNLOAD.htm</a>
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public static final CSVFormat INFORMIX_UNLOAD_CSV = DEFAULT.withDelimiter(COMMA).withQuote(DOUBLE_QUOTE_CHAR)
|
||||||
|
.withRecordSeparator(LF);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
|
* Default MySQL format used by the {@code SELECT INTO OUTFILE} and {@code LOAD DATA INFILE} operations.
|
||||||
*
|
*
|
||||||
|
@ -263,8 +331,8 @@ public final class CSVFormat implements Serializable {
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see Predefined#MySQL
|
* @see Predefined#MySQL
|
||||||
* @see <a href="http://dev.mysql.com/doc/refman/5.1/en/load-data.html">
|
* @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
|
||||||
* http://dev.mysql.com/doc/refman/5.1/en/load-data.html</a>
|
* -data.html</a>
|
||||||
*/
|
*/
|
||||||
public static final CSVFormat MYSQL = DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
|
public static final CSVFormat MYSQL = DEFAULT.withDelimiter(TAB).withEscape(BACKSLASH).withIgnoreEmptyLines(false)
|
||||||
.withQuote(null).withRecordSeparator(LF).withNullString("\\N");
|
.withQuote(null).withRecordSeparator(LF).withNullString("\\N");
|
||||||
|
@ -281,6 +349,7 @@ public final class CSVFormat implements Serializable {
|
||||||
* <li>withRecordSeparator("\r\n")</li>
|
* <li>withRecordSeparator("\r\n")</li>
|
||||||
* <li>withIgnoreEmptyLines(false)</li>
|
* <li>withIgnoreEmptyLines(false)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
* @see Predefined#RFC4180
|
* @see Predefined#RFC4180
|
||||||
*/
|
*/
|
||||||
public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
|
public static final CSVFormat RFC4180 = DEFAULT.withIgnoreEmptyLines(false);
|
||||||
|
@ -299,6 +368,7 @@ public final class CSVFormat implements Serializable {
|
||||||
* <li>withRecordSeparator("\r\n")</li>
|
* <li>withRecordSeparator("\r\n")</li>
|
||||||
* <li>withIgnoreSurroundingSpaces(true)</li>
|
* <li>withIgnoreSurroundingSpaces(true)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
*
|
||||||
* @see Predefined#TDF
|
* @see Predefined#TDF
|
||||||
*/
|
*/
|
||||||
public static final CSVFormat TDF = DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
|
public static final CSVFormat TDF = DEFAULT.withDelimiter(TAB).withIgnoreSurroundingSpaces();
|
||||||
|
@ -348,7 +418,8 @@ public final class CSVFormat implements Serializable {
|
||||||
* @see #TDF
|
* @see #TDF
|
||||||
*/
|
*/
|
||||||
public static CSVFormat newFormat(final char delimiter) {
|
public static CSVFormat newFormat(final char delimiter) {
|
||||||
return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false, false);
|
return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false,
|
||||||
|
false, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -391,6 +462,10 @@ public final class CSVFormat implements Serializable {
|
||||||
|
|
||||||
private final boolean skipHeaderRecord;
|
private final boolean skipHeaderRecord;
|
||||||
|
|
||||||
|
private final boolean trailingDelimiter;
|
||||||
|
|
||||||
|
private final boolean trim;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a customized CSV format.
|
* Creates a customized CSV format.
|
||||||
*
|
*
|
||||||
|
@ -422,6 +497,9 @@ public final class CSVFormat implements Serializable {
|
||||||
* TODO
|
* TODO
|
||||||
* @param ignoreHeaderCase
|
* @param ignoreHeaderCase
|
||||||
* TODO
|
* TODO
|
||||||
|
* @param trim
|
||||||
|
* TODO
|
||||||
|
* @param trailingDelimiter TODO
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* if the delimiter is a line break character
|
* if the delimiter is a line break character
|
||||||
*/
|
*/
|
||||||
|
@ -429,7 +507,7 @@ public final class CSVFormat implements Serializable {
|
||||||
final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
|
final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
|
||||||
final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
|
final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
|
||||||
final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
|
final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
|
||||||
final boolean allowMissingColumnNames, final boolean ignoreHeaderCase) {
|
final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, boolean trim, boolean trailingDelimiter) {
|
||||||
this.delimiter = delimiter;
|
this.delimiter = delimiter;
|
||||||
this.quoteCharacter = quoteChar;
|
this.quoteCharacter = quoteChar;
|
||||||
this.quoteMode = quoteMode;
|
this.quoteMode = quoteMode;
|
||||||
|
@ -444,6 +522,8 @@ public final class CSVFormat implements Serializable {
|
||||||
this.header = header == null ? null : header.clone();
|
this.header = header == null ? null : header.clone();
|
||||||
this.skipHeaderRecord = skipHeaderRecord;
|
this.skipHeaderRecord = skipHeaderRecord;
|
||||||
this.ignoreHeaderCase = ignoreHeaderCase;
|
this.ignoreHeaderCase = ignoreHeaderCase;
|
||||||
|
this.trailingDelimiter = trailingDelimiter;
|
||||||
|
this.trim = trim;
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,11 +700,9 @@ public final class CSVFormat implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Gets the String to convert to and from {@code null}.
|
* Gets the String to convert to and from {@code null}.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>
|
* <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
|
||||||
* <strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
|
|
||||||
* records.</li>
|
* records.</li>
|
||||||
* <li>
|
* <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
|
||||||
* <strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
|
* @return the String to convert to and from {@code null}. No substitution occurs if {@code null}
|
||||||
|
@ -669,6 +747,24 @@ public final class CSVFormat implements Serializable {
|
||||||
return skipHeaderRecord;
|
return skipHeaderRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether to add a trailing delimiter.
|
||||||
|
*
|
||||||
|
* @return whether to add a trailing delimiter.
|
||||||
|
*/
|
||||||
|
public boolean getTrailingDelimiter() {
|
||||||
|
return trailingDelimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether to trim leading and trailing blanks.
|
||||||
|
*
|
||||||
|
* @return whether to trim leading and trailing blanks.
|
||||||
|
*/
|
||||||
|
public boolean getTrim() {
|
||||||
|
return trim;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
|
@ -829,28 +925,28 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
|
if (quoteCharacter != null && delimiter == quoteCharacter.charValue()) {
|
||||||
throw new IllegalArgumentException("The quoteChar character and the delimiter cannot be the same ('" +
|
throw new IllegalArgumentException(
|
||||||
quoteCharacter + "')");
|
"The quoteChar character and the delimiter cannot be the same ('" + quoteCharacter + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
|
if (escapeCharacter != null && delimiter == escapeCharacter.charValue()) {
|
||||||
throw new IllegalArgumentException("The escape character and the delimiter cannot be the same ('" +
|
throw new IllegalArgumentException(
|
||||||
escapeCharacter + "')");
|
"The escape character and the delimiter cannot be the same ('" + escapeCharacter + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commentMarker != null && delimiter == commentMarker.charValue()) {
|
if (commentMarker != null && delimiter == commentMarker.charValue()) {
|
||||||
throw new IllegalArgumentException("The comment start character and the delimiter cannot be the same ('" +
|
throw new IllegalArgumentException(
|
||||||
commentMarker + "')");
|
"The comment start character and the delimiter cannot be the same ('" + commentMarker + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
|
if (quoteCharacter != null && quoteCharacter.equals(commentMarker)) {
|
||||||
throw new IllegalArgumentException("The comment start character and the quoteChar cannot be the same ('" +
|
throw new IllegalArgumentException(
|
||||||
commentMarker + "')");
|
"The comment start character and the quoteChar cannot be the same ('" + commentMarker + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escapeCharacter != null && escapeCharacter.equals(commentMarker)) {
|
if (escapeCharacter != null && escapeCharacter.equals(commentMarker)) {
|
||||||
throw new IllegalArgumentException("The comment start and the escape character cannot be the same ('" +
|
throw new IllegalArgumentException(
|
||||||
commentMarker + "')");
|
"The comment start and the escape character cannot be the same ('" + commentMarker + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
|
if (escapeCharacter == null && quoteMode == QuoteMode.NONE) {
|
||||||
|
@ -862,8 +958,8 @@ public final class CSVFormat implements Serializable {
|
||||||
final Set<String> dupCheck = new HashSet<String>();
|
final Set<String> dupCheck = new HashSet<String>();
|
||||||
for (final String hdr : header) {
|
for (final String hdr : header) {
|
||||||
if (!dupCheck.add(hdr)) {
|
if (!dupCheck.add(hdr)) {
|
||||||
throw new IllegalArgumentException("The header contains a duplicate entry: '" + hdr + "' in " +
|
throw new IllegalArgumentException(
|
||||||
Arrays.toString(header));
|
"The header contains a duplicate entry: '" + hdr + "' in " + Arrays.toString(header));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -891,7 +987,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
|
public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -926,7 +1022,7 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -944,7 +1040,7 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -975,12 +1071,12 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
|
||||||
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
|
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
|
||||||
allowMissingColumnNames, ignoreHeaderCase);
|
allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code CSVFormat} with the header of the format set from the result set metadata.
|
* Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
|
||||||
* The header can either be parsed automatically from the input file with:
|
* either be parsed automatically from the input file with:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* CSVFormat format = aformat.withHeader();
|
* CSVFormat format = aformat.withHeader();
|
||||||
|
@ -1009,8 +1105,8 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code CSVFormat} with the header of the format set from the result set metadata.
|
* Returns a new {@code CSVFormat} with the header of the format set from the result set metadata. The header can
|
||||||
* The header can either be parsed automatically from the input file with:
|
* either be parsed automatically from the input file with:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* CSVFormat format = aformat.withHeader();
|
* CSVFormat format = aformat.withHeader();
|
||||||
|
@ -1045,12 +1141,12 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, labels,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, labels,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code CSVFormat} with the header of the format set to the given values.
|
* Returns a new {@code CSVFormat} with the header of the format set to the given values. The header can either be
|
||||||
* The header can either be parsed automatically from the input file with:
|
* parsed automatically from the input file with:
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* CSVFormat format = aformat.withHeader();
|
* CSVFormat format = aformat.withHeader();
|
||||||
|
@ -1074,12 +1170,12 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withHeader(final String... header) {
|
public CSVFormat withHeader(final String... header) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code CSVFormat} with the header comments of the format set to the given values.
|
* Returns a new {@code CSVFormat} with the header comments of the format set to the given values. The comments will
|
||||||
* The comments will be printed first, before the headers. This setting is ignored by the parser.
|
* be printed first, before the headers. This setting is ignored by the parser.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* CSVFormat format = aformat.withHeaderComments("Generated by Apache Commons CSV 1.1.", new Date());
|
* CSVFormat format = aformat.withHeaderComments("Generated by Apache Commons CSV 1.1.", new Date());
|
||||||
|
@ -1095,7 +1191,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withHeaderComments(final Object... headerComments) {
|
public CSVFormat withHeaderComments(final Object... headerComments) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1120,7 +1216,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
|
public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1138,14 +1234,14 @@ public final class CSVFormat implements Serializable {
|
||||||
* Returns a new {@code CSVFormat} with whether header names should be accessed ignoring case.
|
* Returns a new {@code CSVFormat} with whether header names should be accessed ignoring case.
|
||||||
*
|
*
|
||||||
* @param ignoreHeaderCase
|
* @param ignoreHeaderCase
|
||||||
* the case mapping behavior, {@code true} to access name/values, {@code false} to leave the
|
* the case mapping behavior, {@code true} to access name/values, {@code false} to leave the mapping as
|
||||||
* mapping as is.
|
* is.
|
||||||
* @return A new CSVFormat that will ignore case header name if specified as {@code true}
|
* @return A new CSVFormat that will ignore case header name if specified as {@code true}
|
||||||
*/
|
*/
|
||||||
public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
|
public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1170,17 +1266,15 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
|
public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new {@code CSVFormat} with conversions to and from null for strings on input and output.
|
* Returns a new {@code CSVFormat} with conversions to and from null for strings on input and output.
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>
|
* <li><strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
|
||||||
* <strong>Reading:</strong> Converts strings equal to the given {@code nullString} to {@code null} when reading
|
|
||||||
* records.</li>
|
* records.</li>
|
||||||
* <li>
|
* <li><strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
|
||||||
* <strong>Writing:</strong> Writes {@code null} as the given {@code nullString} when writing records.</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param nullString
|
* @param nullString
|
||||||
|
@ -1191,7 +1285,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withNullString(final String nullString) {
|
public CSVFormat withNullString(final String nullString) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1222,7 +1316,7 @@ public final class CSVFormat implements Serializable {
|
||||||
}
|
}
|
||||||
return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
|
return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
|
||||||
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
|
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
|
||||||
allowMissingColumnNames, ignoreHeaderCase);
|
allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1236,7 +1330,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
|
public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1274,7 +1368,7 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withRecordSeparator(final String recordSeparator) {
|
public CSVFormat withRecordSeparator(final String recordSeparator) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1301,6 +1395,52 @@ public final class CSVFormat implements Serializable {
|
||||||
public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
|
public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
|
||||||
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code CSVFormat} with whether to trim leading and trailing blanks.
|
||||||
|
*
|
||||||
|
* @param trim
|
||||||
|
* whether to trim leading and trailing blanks.
|
||||||
|
*
|
||||||
|
* @return A new CSVFormat that is equal to this but with the specified trim setting.
|
||||||
|
*/
|
||||||
|
public CSVFormat withTrim(final boolean trim) {
|
||||||
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code CSVFormat} to add a trailing delimiter.
|
||||||
|
* *
|
||||||
|
* @return A new CSVFormat that is equal to this but with the trailing delimiter setting.
|
||||||
|
*/
|
||||||
|
public CSVFormat withTrailingDelimiter() {
|
||||||
|
return withTrailingDelimiter(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code CSVFormat} with whether to add a trailing delimiter.
|
||||||
|
*
|
||||||
|
* @param trim
|
||||||
|
* whether to add a trailing delimiter.
|
||||||
|
*
|
||||||
|
* @return A new CSVFormat that is equal to this but with the specified trailing delimiter setting.
|
||||||
|
*/
|
||||||
|
public CSVFormat withTrailingDelimiter(final boolean trailingDelimiter) {
|
||||||
|
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
|
||||||
|
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
|
||||||
|
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase, trim, trailingDelimiter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a new {@code CSVFormat} to trim leading and trailing blanks.
|
||||||
|
*
|
||||||
|
* @return A new CSVFormat that is equal to this but with the trim setting on.
|
||||||
|
*/
|
||||||
|
public CSVFormat withTrim() {
|
||||||
|
return withTrim(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,10 +286,14 @@ public final class CSVParser implements Iterable<CSVRecord>, Closeable {
|
||||||
this.recordNumber = recordNumber - 1;
|
this.recordNumber = recordNumber - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addRecordValue() {
|
private void addRecordValue(boolean lastRecord) {
|
||||||
final String input = this.reusableToken.content.toString();
|
final String input = this.reusableToken.content.toString();
|
||||||
|
final String inputClean = this.format.getTrim() ? input.trim() : input;
|
||||||
|
if (lastRecord && inputClean.isEmpty() && this.format.getTrailingDelimiter()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
final String nullString = this.format.getNullString();
|
final String nullString = this.format.getNullString();
|
||||||
this.record.add(input.equals(nullString) ? null : input);
|
this.record.add(inputClean.equals(nullString) ? null : inputClean);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -497,14 +501,14 @@ public final class CSVParser implements Iterable<CSVRecord>, Closeable {
|
||||||
this.lexer.nextToken(this.reusableToken);
|
this.lexer.nextToken(this.reusableToken);
|
||||||
switch (this.reusableToken.type) {
|
switch (this.reusableToken.type) {
|
||||||
case TOKEN:
|
case TOKEN:
|
||||||
this.addRecordValue();
|
this.addRecordValue(false);
|
||||||
break;
|
break;
|
||||||
case EORECORD:
|
case EORECORD:
|
||||||
this.addRecordValue();
|
this.addRecordValue(true);
|
||||||
break;
|
break;
|
||||||
case EOF:
|
case EOF:
|
||||||
if (this.reusableToken.isReady) {
|
if (this.reusableToken.isReady) {
|
||||||
this.addRecordValue();
|
this.addRecordValue(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INVALID:
|
case INVALID:
|
||||||
|
|
|
@ -128,6 +128,7 @@ public final class CSVPrinter implements Flushable, Closeable {
|
||||||
} else {
|
} else {
|
||||||
strValue = value.toString();
|
strValue = value.toString();
|
||||||
}
|
}
|
||||||
|
strValue = format.getTrim() ? strValue.trim() : strValue;
|
||||||
this.print(value, strValue, 0, strValue.length());
|
this.print(value, strValue, 0, strValue.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +352,9 @@ public final class CSVPrinter implements Flushable, Closeable {
|
||||||
* If an I/O error occurs
|
* If an I/O error occurs
|
||||||
*/
|
*/
|
||||||
public void println() throws IOException {
|
public void println() throws IOException {
|
||||||
|
if (format.getTrailingDelimiter()) {
|
||||||
|
out.append(format.getDelimiter());
|
||||||
|
}
|
||||||
final String recordSeparator = format.getRecordSeparator();
|
final String recordSeparator = format.getRecordSeparator();
|
||||||
if (recordSeparator != null) {
|
if (recordSeparator != null) {
|
||||||
out.append(recordSeparator);
|
out.append(recordSeparator);
|
||||||
|
|
|
@ -911,6 +911,30 @@ public class CSVParserTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTrailingDelimiter() throws Exception {
|
||||||
|
final Reader in = new StringReader("a,a,a,\n\"1\",\"2\",\"3\",\nx,y,z,");
|
||||||
|
final Iterator<CSVRecord> records = CSVFormat.DEFAULT.withHeader("X", "Y", "Z").withSkipHeaderRecord().withTrailingDelimiter()
|
||||||
|
.parse(in).iterator();
|
||||||
|
final CSVRecord record = records.next();
|
||||||
|
assertEquals("1", record.get("X"));
|
||||||
|
assertEquals("2", record.get("Y"));
|
||||||
|
assertEquals("3", record.get("Z"));
|
||||||
|
Assert.assertEquals(3, record.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTrim() throws Exception {
|
||||||
|
final Reader in = new StringReader("a,a,a\n\" 1 \",\" 2 \",\" 3 \"\nx,y,z");
|
||||||
|
final Iterator<CSVRecord> records = CSVFormat.DEFAULT.withHeader("X", "Y", "Z").withSkipHeaderRecord().withTrim()
|
||||||
|
.parse(in).iterator();
|
||||||
|
final CSVRecord record = records.next();
|
||||||
|
assertEquals("1", record.get("X"));
|
||||||
|
assertEquals("2", record.get("Y"));
|
||||||
|
assertEquals("3", record.get("Z"));
|
||||||
|
Assert.assertEquals(3, record.size());
|
||||||
|
}
|
||||||
|
|
||||||
private void validateLineNumbers(final String lineSeparator) throws IOException {
|
private void validateLineNumbers(final String lineSeparator) throws IOException {
|
||||||
final CSVParser parser = CSVParser.parse("a" + lineSeparator + "b" + lineSeparator + "c",
|
final CSVParser parser = CSVParser.parse("a" + lineSeparator + "b" + lineSeparator + "c",
|
||||||
CSVFormat.DEFAULT.withRecordSeparator(lineSeparator));
|
CSVFormat.DEFAULT.withRecordSeparator(lineSeparator));
|
||||||
|
|
|
@ -50,8 +50,6 @@ public class CSVPrinterTest {
|
||||||
|
|
||||||
private static final int ITERATIONS_FOR_RANDOM_TEST = 50000;
|
private static final int ITERATIONS_FOR_RANDOM_TEST = 50000;
|
||||||
|
|
||||||
private final String recordSeparator = CSVFormat.DEFAULT.getRecordSeparator();
|
|
||||||
|
|
||||||
private static String printable(final String s) {
|
private static String printable(final String s) {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < s.length(); i++) {
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
@ -65,6 +63,8 @@ public class CSVPrinterTest {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final String recordSeparator = CSVFormat.DEFAULT.getRecordSeparator();
|
||||||
|
|
||||||
private void doOneRandom(final CSVFormat format) throws Exception {
|
private void doOneRandom(final CSVFormat format) throws Exception {
|
||||||
final Random r = new Random();
|
final Random r = new Random();
|
||||||
|
|
||||||
|
@ -97,6 +97,31 @@ public class CSVPrinterTest {
|
||||||
parser.close();
|
parser.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doRandom(final CSVFormat format, final int iter) throws Exception {
|
||||||
|
for (int i = 0; i < iter; i++) {
|
||||||
|
doOneRandom(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an input CSV array into expected output values WRT NULLs. NULL strings are converted to null values
|
||||||
|
* because the parser will convert these strings to null.
|
||||||
|
*/
|
||||||
|
private <T> T[] expectNulls(final T[] original, final CSVFormat csvFormat) {
|
||||||
|
final T[] fixed = original.clone();
|
||||||
|
for (int i = 0; i < fixed.length; i++) {
|
||||||
|
if (ObjectUtils.equals(csvFormat.getNullString(), fixed[i])) {
|
||||||
|
fixed[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Connection geH2Connection() throws SQLException, ClassNotFoundException {
|
||||||
|
Class.forName("org.h2.Driver");
|
||||||
|
return DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
|
||||||
|
}
|
||||||
|
|
||||||
private String[][] generateLines(final int nLines, final int nCol) {
|
private String[][] generateLines(final int nLines, final int nCol) {
|
||||||
final String[][] lines = new String[nLines][];
|
final String[][] lines = new String[nLines][];
|
||||||
for (int i = 0; i < nLines; i++) {
|
for (int i = 0; i < nLines; i++) {
|
||||||
|
@ -109,10 +134,18 @@ public class CSVPrinterTest {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doRandom(final CSVFormat format, final int iter) throws Exception {
|
private CSVPrinter printWithHeaderComments(final StringWriter sw, final Date now, final CSVFormat baseFormat)
|
||||||
for (int i = 0; i < iter; i++) {
|
throws IOException {
|
||||||
doOneRandom(format);
|
CSVFormat format = baseFormat;
|
||||||
}
|
// Use withHeaderComments first to test CSV-145
|
||||||
|
format = format.withHeaderComments("Generated by Apache Commons CSV 1.1", now);
|
||||||
|
format = format.withCommentMarker('#');
|
||||||
|
format = format.withHeader("Col1", "Col2");
|
||||||
|
final CSVPrinter csvPrinter = format.print(sw);
|
||||||
|
csvPrinter.printRecord("A", "B");
|
||||||
|
csvPrinter.printRecord("C", "D");
|
||||||
|
csvPrinter.close();
|
||||||
|
return csvPrinter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String randStr() {
|
private String randStr() {
|
||||||
|
@ -163,6 +196,58 @@ public class CSVPrinterTest {
|
||||||
return new String(buf);
|
return new String(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setUpTable(final Connection connection) throws SQLException {
|
||||||
|
final Statement statement = connection.createStatement();
|
||||||
|
try {
|
||||||
|
statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
|
||||||
|
statement.execute("insert into TEST values(1, 'r1')");
|
||||||
|
statement.execute("insert into TEST values(2, 'r2')");
|
||||||
|
} finally {
|
||||||
|
statement.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelimeterQuoted() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
||||||
|
printer.print("a,b,c");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("'a,b,c',xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelimeterQuoteNONE() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVFormat format = CSVFormat.DEFAULT.withEscape('!').withQuoteMode(QuoteMode.NONE);
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
|
printer.print("a,b,c");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("a!,b!,c,xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelimiterEscaped() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withEscape('!').withQuote(null));
|
||||||
|
printer.print("a,b,c");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("a!,b!,c,xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDelimiterPlain() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
||||||
|
printer.print("a,b,c");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("a,b,c,xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisabledComment() throws IOException {
|
public void testDisabledComment() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
@ -173,6 +258,72 @@ public class CSVPrinterTest {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEOLEscaped() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withEscape('!'));
|
||||||
|
printer.print("a\rb\nc");
|
||||||
|
printer.print("x\fy\bz");
|
||||||
|
assertEquals("a!rb!nc,x\fy\bz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEOLPlain() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
||||||
|
printer.print("a\rb\nc");
|
||||||
|
printer.print("x\fy\bz");
|
||||||
|
assertEquals("a\rb\nc,x\fy\bz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEOLQuoted() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
||||||
|
printer.print("a\rb\nc");
|
||||||
|
printer.print("x\by\fz");
|
||||||
|
assertEquals("'a\rb\nc',x\by\fz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEscapeBackslash() throws IOException {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
final char quoteChar = '\'';
|
||||||
|
final String eol = "\r\n";
|
||||||
|
CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
||||||
|
printer.print("\\");
|
||||||
|
printer.close();
|
||||||
|
assertEquals("'\\'", sw.toString());
|
||||||
|
|
||||||
|
sw = new StringWriter();
|
||||||
|
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
||||||
|
printer.print("\\\r");
|
||||||
|
printer.close();
|
||||||
|
assertEquals("'\\\r'", sw.toString());
|
||||||
|
|
||||||
|
sw = new StringWriter();
|
||||||
|
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
||||||
|
printer.print("X\\\r");
|
||||||
|
printer.close();
|
||||||
|
assertEquals("'X\\\r'", sw.toString());
|
||||||
|
|
||||||
|
sw = new StringWriter();
|
||||||
|
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
||||||
|
printer.printRecord(new Object[] { "\\\r" });
|
||||||
|
printer.close();
|
||||||
|
assertEquals("'\\\r'" + eol, sw.toString());
|
||||||
|
|
||||||
|
sw = new StringWriter();
|
||||||
|
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
||||||
|
printer.print("\\\\");
|
||||||
|
printer.close();
|
||||||
|
assertEquals("'\\\\'", sw.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExcelPrintAllArrayOfArrays() throws IOException {
|
public void testExcelPrintAllArrayOfArrays() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
@ -228,75 +379,52 @@ public class CSVPrinterTest {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Connection geH2Connection() throws SQLException, ClassNotFoundException {
|
@Test
|
||||||
Class.forName("org.h2.Driver");
|
public void testHeader() throws IOException {
|
||||||
return DriverManager.getConnection("jdbc:h2:mem:my_test;", "sa", "");
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withHeader("C1", "C2", "C3"));
|
||||||
|
printer.printRecord("a", "b", "c");
|
||||||
|
printer.printRecord("x", "y", "z");
|
||||||
|
assertEquals("C1,C2,C3\r\na,b,c\r\nx,y,z\r\n", sw.toString());
|
||||||
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
public void testHeaderCommentExcel() throws IOException {
|
||||||
public void testJira135All() throws IOException {
|
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
final Date now = new Date();
|
||||||
final List<String> list = new LinkedList<String>();
|
final CSVFormat format = CSVFormat.EXCEL;
|
||||||
list.add("\"");
|
final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
|
||||||
list.add("\n");
|
assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1,Col2\r\nA,B\r\nC,D\r\n",
|
||||||
list.add("\\");
|
sw.toString());
|
||||||
printer.printRecord(list);
|
csvPrinter.close();
|
||||||
printer.close();
|
|
||||||
final String expected = "\"\\\"\",\"\\n\",\"\\\"" + format.getRecordSeparator();
|
|
||||||
assertEquals(expected, sw.toString());
|
|
||||||
final String[] record0 = toFirstRecordValues(expected, format);
|
|
||||||
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
public void testHeaderCommentTdf() throws IOException {
|
||||||
public void testJira135_part3() throws IOException {
|
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
final Date now = new Date();
|
||||||
final List<String> list = new LinkedList<String>();
|
final CSVFormat format = CSVFormat.TDF;
|
||||||
list.add("\\");
|
final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
|
||||||
printer.printRecord(list);
|
assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1\tCol2\r\nA\tB\r\nC\tD\r\n",
|
||||||
printer.close();
|
sw.toString());
|
||||||
final String expected = "\"\\\\\"" + format.getRecordSeparator();
|
csvPrinter.close();
|
||||||
assertEquals(expected, sw.toString());
|
|
||||||
final String[] record0 = toFirstRecordValues(expected, format);
|
|
||||||
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
public void testHeaderNotSet() throws IOException {
|
||||||
public void testJira135_part2() throws IOException {
|
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
||||||
final List<String> list = new LinkedList<String>();
|
printer.printRecord("a", "b", "c");
|
||||||
list.add("\n");
|
printer.printRecord("x", "y", "z");
|
||||||
printer.printRecord(list);
|
assertEquals("a,b,c\r\nx,y,z\r\n", sw.toString());
|
||||||
printer.close();
|
printer.close();
|
||||||
final String expected = "\"\\n\"" + format.getRecordSeparator();
|
|
||||||
assertEquals(expected, sw.toString());
|
|
||||||
final String[] record0 = toFirstRecordValues(expected, format);
|
|
||||||
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test(expected = IllegalArgumentException.class)
|
||||||
@Ignore
|
public void testInvalidFormat() throws Exception {
|
||||||
public void testJira135_part1() throws IOException {
|
final CSVFormat invalidFormat = CSVFormat.DEFAULT.withDelimiter(CR);
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
new CSVPrinter(new StringWriter(), invalidFormat).close();
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
|
||||||
final List<String> list = new LinkedList<String>();
|
|
||||||
list.add("\"");
|
|
||||||
printer.printRecord(list);
|
|
||||||
printer.close();
|
|
||||||
final String expected = "\"\\\"\"" + format.getRecordSeparator();
|
|
||||||
assertEquals(expected, sw.toString());
|
|
||||||
final String[] record0 = toFirstRecordValues(expected, format);
|
|
||||||
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -361,15 +489,70 @@ public class CSVPrinterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpTable(final Connection connection) throws SQLException {
|
@Test
|
||||||
final Statement statement = connection.createStatement();
|
@Ignore
|
||||||
try {
|
public void testJira135_part1() throws IOException {
|
||||||
statement.execute("CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
|
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
||||||
statement.execute("insert into TEST values(1, 'r1')");
|
final StringWriter sw = new StringWriter();
|
||||||
statement.execute("insert into TEST values(2, 'r2')");
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
} finally {
|
final List<String> list = new LinkedList<String>();
|
||||||
statement.close();
|
list.add("\"");
|
||||||
|
printer.printRecord(list);
|
||||||
|
printer.close();
|
||||||
|
final String expected = "\"\\\"\"" + format.getRecordSeparator();
|
||||||
|
assertEquals(expected, sw.toString());
|
||||||
|
final String[] record0 = toFirstRecordValues(expected, format);
|
||||||
|
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testJira135_part2() throws IOException {
|
||||||
|
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
|
final List<String> list = new LinkedList<String>();
|
||||||
|
list.add("\n");
|
||||||
|
printer.printRecord(list);
|
||||||
|
printer.close();
|
||||||
|
final String expected = "\"\\n\"" + format.getRecordSeparator();
|
||||||
|
assertEquals(expected, sw.toString());
|
||||||
|
final String[] record0 = toFirstRecordValues(expected, format);
|
||||||
|
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testJira135_part3() throws IOException {
|
||||||
|
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
|
final List<String> list = new LinkedList<String>();
|
||||||
|
list.add("\\");
|
||||||
|
printer.printRecord(list);
|
||||||
|
printer.close();
|
||||||
|
final String expected = "\"\\\\\"" + format.getRecordSeparator();
|
||||||
|
assertEquals(expected, sw.toString());
|
||||||
|
final String[] record0 = toFirstRecordValues(expected, format);
|
||||||
|
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testJira135All() throws IOException {
|
||||||
|
final CSVFormat format = CSVFormat.DEFAULT.withRecordSeparator('\n').withQuote('"').withEscape('\\');
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
|
final List<String> list = new LinkedList<String>();
|
||||||
|
list.add("\"");
|
||||||
|
list.add("\n");
|
||||||
|
list.add("\\");
|
||||||
|
printer.printRecord(list);
|
||||||
|
printer.close();
|
||||||
|
final String expected = "\"\\\"\",\"\\n\",\"\\\"" + format.getRecordSeparator();
|
||||||
|
assertEquals(expected, sw.toString());
|
||||||
|
final String[] record0 = toFirstRecordValues(expected, format);
|
||||||
|
assertArrayEquals(expectNulls(list.toArray(), format), record0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -382,11 +565,6 @@ public class CSVPrinterTest {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMySqlNullStringDefault() throws IOException {
|
|
||||||
assertEquals("\\N", CSVFormat.MYSQL.getNullString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMySqlNullOutput() throws IOException {
|
public void testMySqlNullOutput() throws IOException {
|
||||||
Object[] s = new String[] { "NULL", null };
|
Object[] s = new String[] { "NULL", null };
|
||||||
|
@ -489,22 +667,85 @@ public class CSVPrinterTest {
|
||||||
assertArrayEquals(expectNulls(s, format), record0);
|
assertArrayEquals(expectNulls(s, format), record0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Test
|
||||||
* Converts an input CSV array into expected output values WRT NULLs. NULL strings are converted to null values
|
public void testMySqlNullStringDefault() throws IOException {
|
||||||
* because the parser will convert these strings to null.
|
assertEquals("\\N", CSVFormat.MYSQL.getNullString());
|
||||||
*/
|
|
||||||
private <T> T[] expectNulls(final T[] original, final CSVFormat csvFormat) {
|
|
||||||
final T[] fixed = original.clone();
|
|
||||||
for (int i = 0; i < fixed.length; i++) {
|
|
||||||
if (ObjectUtils.equals(csvFormat.getNullString(), fixed[i])) {
|
|
||||||
fixed[i] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fixed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] toFirstRecordValues(final String expected, final CSVFormat format) throws IOException {
|
@Test(expected = IllegalArgumentException.class)
|
||||||
return CSVParser.parse(expected, format).getRecords().get(0).values();
|
public void testNewCsvPrinterAppendableNullFormat() throws Exception {
|
||||||
|
new CSVPrinter(new StringWriter(), null).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testNewCSVPrinterNullAppendableFormat() throws Exception {
|
||||||
|
new CSVPrinter(null, CSVFormat.DEFAULT).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseCustomNullValues() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVFormat format = CSVFormat.DEFAULT.withNullString("NULL");
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, format);
|
||||||
|
printer.printRecord("a", null, "b");
|
||||||
|
printer.close();
|
||||||
|
final String csvString = sw.toString();
|
||||||
|
assertEquals("a,NULL,b" + recordSeparator, csvString);
|
||||||
|
final Iterable<CSVRecord> iterable = format.parse(new StringReader(csvString));
|
||||||
|
final Iterator<CSVRecord> iterator = iterable.iterator();
|
||||||
|
final CSVRecord record = iterator.next();
|
||||||
|
assertEquals("a", record.get(0));
|
||||||
|
assertEquals(null, record.get(1));
|
||||||
|
assertEquals("b", record.get(2));
|
||||||
|
assertFalse(iterator.hasNext());
|
||||||
|
((CSVParser) iterable).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlainEscaped() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withEscape('!'));
|
||||||
|
printer.print("abc");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("abc,xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlainPlain() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
||||||
|
printer.print("abc");
|
||||||
|
printer.print("xyz");
|
||||||
|
assertEquals("abc,xyz", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPlainQuoted() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
||||||
|
printer.print("abc");
|
||||||
|
assertEquals("abc", sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrint() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = CSVFormat.DEFAULT.print(sw);
|
||||||
|
printer.printRecord("a", "b\\c");
|
||||||
|
assertEquals("a,b\\c" + recordSeparator, sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPrintCustomNullValues() throws IOException {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withNullString("NULL"));
|
||||||
|
printer.printRecord("a", null, "b");
|
||||||
|
assertEquals("a,NULL,b" + recordSeparator, sw.toString());
|
||||||
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -570,15 +811,6 @@ public class CSVPrinterTest {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPrint() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = CSVFormat.DEFAULT.print(sw);
|
|
||||||
printer.printRecord("a", "b\\c");
|
|
||||||
assertEquals("a,b\\c" + recordSeparator, sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPrintNullValues() throws IOException {
|
public void testPrintNullValues() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
@ -588,34 +820,6 @@ public class CSVPrinterTest {
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPrintCustomNullValues() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withNullString("NULL"));
|
|
||||||
printer.printRecord("a", null, "b");
|
|
||||||
assertEquals("a,NULL,b" + recordSeparator, sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testParseCustomNullValues() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withNullString("NULL");
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
|
||||||
printer.printRecord("a", null, "b");
|
|
||||||
printer.close();
|
|
||||||
final String csvString = sw.toString();
|
|
||||||
assertEquals("a,NULL,b" + recordSeparator, csvString);
|
|
||||||
final Iterable<CSVRecord> iterable = format.parse(new StringReader(csvString));
|
|
||||||
final Iterator<CSVRecord> iterator = iterable.iterator();
|
|
||||||
final CSVRecord record = iterator.next();
|
|
||||||
assertEquals("a", record.get(0));
|
|
||||||
assertEquals(null, record.get(1));
|
|
||||||
assertEquals("b", record.get(2));
|
|
||||||
assertFalse(iterator.hasNext());
|
|
||||||
((CSVParser) iterable).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuoteAll() throws IOException {
|
public void testQuoteAll() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
@ -649,23 +853,14 @@ public class CSVPrinterTest {
|
||||||
doRandom(CSVFormat.MYSQL, ITERATIONS_FOR_RANDOM_TEST);
|
doRandom(CSVFormat.MYSQL, ITERATIONS_FOR_RANDOM_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRandomTdf() throws Exception {
|
|
||||||
doRandom(CSVFormat.TDF, ITERATIONS_FOR_RANDOM_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRandomRfc4180() throws Exception {
|
public void testRandomRfc4180() throws Exception {
|
||||||
doRandom(CSVFormat.RFC4180, ITERATIONS_FOR_RANDOM_TEST);
|
doRandom(CSVFormat.RFC4180, ITERATIONS_FOR_RANDOM_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPlainQuoted() throws IOException {
|
public void testRandomTdf() throws Exception {
|
||||||
final StringWriter sw = new StringWriter();
|
doRandom(CSVFormat.TDF, ITERATIONS_FOR_RANDOM_TEST);
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
|
||||||
printer.print("abc");
|
|
||||||
assertEquals("abc", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -689,142 +884,17 @@ public class CSVPrinterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDelimeterQuoted() throws IOException {
|
public void testSkipHeaderRecordFalse() throws IOException {
|
||||||
|
// functionally identical to testHeader, used to test CSV-153
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
final CSVPrinter printer = new CSVPrinter(sw,
|
||||||
printer.print("a,b,c");
|
CSVFormat.DEFAULT.withQuote(null).withHeader("C1", "C2", "C3").withSkipHeaderRecord(false));
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("'a,b,c',xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelimeterQuoteNONE() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVFormat format = CSVFormat.DEFAULT.withEscape('!').withQuoteMode(QuoteMode.NONE);
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, format);
|
|
||||||
printer.print("a,b,c");
|
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("a!,b!,c,xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEOLQuoted() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote('\''));
|
|
||||||
printer.print("a\rb\nc");
|
|
||||||
printer.print("x\by\fz");
|
|
||||||
assertEquals("'a\rb\nc',x\by\fz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEscapeBackslash() throws IOException {
|
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
final char quoteChar = '\'';
|
|
||||||
final String eol = "\r\n";
|
|
||||||
CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
|
||||||
printer.print("\\");
|
|
||||||
printer.close();
|
|
||||||
assertEquals("'\\'", sw.toString());
|
|
||||||
|
|
||||||
sw = new StringWriter();
|
|
||||||
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
|
||||||
printer.print("\\\r");
|
|
||||||
printer.close();
|
|
||||||
assertEquals("'\\\r'", sw.toString());
|
|
||||||
|
|
||||||
sw = new StringWriter();
|
|
||||||
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
|
||||||
printer.print("X\\\r");
|
|
||||||
printer.close();
|
|
||||||
assertEquals("'X\\\r'", sw.toString());
|
|
||||||
|
|
||||||
sw = new StringWriter();
|
|
||||||
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
|
||||||
printer.printRecord(new Object[] { "\\\r" });
|
|
||||||
printer.close();
|
|
||||||
assertEquals("'\\\r'" + eol, sw.toString());
|
|
||||||
|
|
||||||
sw = new StringWriter();
|
|
||||||
printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(quoteChar));
|
|
||||||
printer.print("\\\\");
|
|
||||||
printer.close();
|
|
||||||
assertEquals("'\\\\'", sw.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPlainEscaped() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withEscape('!'));
|
|
||||||
printer.print("abc");
|
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("abc,xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelimiterEscaped() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withEscape('!').withQuote(null));
|
|
||||||
printer.print("a,b,c");
|
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("a!,b!,c,xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEOLEscaped() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withEscape('!'));
|
|
||||||
printer.print("a\rb\nc");
|
|
||||||
printer.print("x\fy\bz");
|
|
||||||
assertEquals("a!rb!nc,x\fy\bz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPlainPlain() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
|
||||||
printer.print("abc");
|
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("abc,xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDelimiterPlain() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
|
||||||
printer.print("a,b,c");
|
|
||||||
printer.print("xyz");
|
|
||||||
assertEquals("a,b,c,xyz", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHeader() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null).withHeader("C1", "C2", "C3"));
|
|
||||||
printer.printRecord("a", "b", "c");
|
printer.printRecord("a", "b", "c");
|
||||||
printer.printRecord("x", "y", "z");
|
printer.printRecord("x", "y", "z");
|
||||||
assertEquals("C1,C2,C3\r\na,b,c\r\nx,y,z\r\n", sw.toString());
|
assertEquals("C1,C2,C3\r\na,b,c\r\nx,y,z\r\n", sw.toString());
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHeaderNotSet() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
|
||||||
printer.printRecord("a", "b", "c");
|
|
||||||
printer.printRecord("x", "y", "z");
|
|
||||||
assertEquals("a,b,c\r\nx,y,z\r\n", sw.toString());
|
|
||||||
printer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipHeaderRecordTrue() throws IOException {
|
public void testSkipHeaderRecordTrue() throws IOException {
|
||||||
// functionally identical to testHeaderNotSet, used to test CSV-153
|
// functionally identical to testHeaderNotSet, used to test CSV-153
|
||||||
|
@ -838,76 +908,43 @@ public class CSVPrinterTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipHeaderRecordFalse() throws IOException {
|
public void testTrimOnOneColumn() throws IOException {
|
||||||
// functionally identical to testHeader, used to test CSV-153
|
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final CSVPrinter printer = new CSVPrinter(sw,
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withTrim());
|
||||||
CSVFormat.DEFAULT.withQuote(null).withHeader("C1", "C2", "C3").withSkipHeaderRecord(false));
|
printer.print(" A ");
|
||||||
printer.printRecord("a", "b", "c");
|
assertEquals("A", sw.toString());
|
||||||
printer.printRecord("x", "y", "z");
|
|
||||||
assertEquals("C1,C2,C3\r\na,b,c\r\nx,y,z\r\n", sw.toString());
|
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHeaderCommentExcel() throws IOException {
|
public void testTrimOnTwoColumns() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
final Date now = new Date();
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withTrim());
|
||||||
final CSVFormat format = CSVFormat.EXCEL;
|
printer.print(" A ");
|
||||||
final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
|
printer.print(" B ");
|
||||||
assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1,Col2\r\nA,B\r\nC,D\r\n",
|
assertEquals("A,B", sw.toString());
|
||||||
sw.toString());
|
|
||||||
csvPrinter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testHeaderCommentTdf() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final Date now = new Date();
|
|
||||||
final CSVFormat format = CSVFormat.TDF;
|
|
||||||
final CSVPrinter csvPrinter = printWithHeaderComments(sw, now, format);
|
|
||||||
assertEquals("# Generated by Apache Commons CSV 1.1\r\n# " + now + "\r\nCol1\tCol2\r\nA\tB\r\nC\tD\r\n",
|
|
||||||
sw.toString());
|
|
||||||
csvPrinter.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private CSVPrinter printWithHeaderComments(final StringWriter sw, final Date now, final CSVFormat baseFormat)
|
|
||||||
throws IOException {
|
|
||||||
CSVFormat format = baseFormat;
|
|
||||||
// Use withHeaderComments first to test CSV-145
|
|
||||||
format = format.withHeaderComments("Generated by Apache Commons CSV 1.1", now);
|
|
||||||
format = format.withCommentMarker('#');
|
|
||||||
format = format.withHeader("Col1", "Col2");
|
|
||||||
final CSVPrinter csvPrinter = format.print(sw);
|
|
||||||
csvPrinter.printRecord("A", "B");
|
|
||||||
csvPrinter.printRecord("C", "D");
|
|
||||||
csvPrinter.close();
|
|
||||||
return csvPrinter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testEOLPlain() throws IOException {
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withQuote(null));
|
|
||||||
printer.print("a\rb\nc");
|
|
||||||
printer.print("x\fy\bz");
|
|
||||||
assertEquals("a\rb\nc,x\fy\bz", sw.toString());
|
|
||||||
printer.close();
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testInvalidFormat() throws Exception {
|
public void testTrailingDelimiterOnTwoColumns() throws IOException {
|
||||||
final CSVFormat invalidFormat = CSVFormat.DEFAULT.withDelimiter(CR);
|
final StringWriter sw = new StringWriter();
|
||||||
new CSVPrinter(new StringWriter(), invalidFormat).close();
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withTrailingDelimiter());
|
||||||
|
printer.printRecord("A", "B");
|
||||||
|
assertEquals("A,B,\r\n", sw.toString());
|
||||||
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test
|
||||||
public void testNewCSVPrinterNullAppendableFormat() throws Exception {
|
public void testTrimOffOneColumn() throws IOException {
|
||||||
new CSVPrinter(null, CSVFormat.DEFAULT).close();
|
final StringWriter sw = new StringWriter();
|
||||||
|
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withTrim(false));
|
||||||
|
printer.print(" A ");
|
||||||
|
assertEquals("\" A \"", sw.toString());
|
||||||
|
printer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
private String[] toFirstRecordValues(final String expected, final CSVFormat format) throws IOException {
|
||||||
public void testNewCsvPrinterAppendableNullFormat() throws Exception {
|
return CSVParser.parse(expected, format).getRecords().get(0).values();
|
||||||
new CSVPrinter(new StringWriter(), null).close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue