[CSV-97] Allow the String value for null to be customized for the CSV printer.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1465768 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gary D. Gregory 2013-04-08 20:34:49 +00:00
parent 60cc83af7f
commit 75b9a4ba4e
5 changed files with 51 additions and 13 deletions

View File

@ -63,6 +63,7 @@ public class CSVFormat implements Serializable {
private boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
private boolean ignoreEmptyLines;
private String recordSeparator; // for outputs
private String nullToString; // for outputs
private String[] header;
/**
@ -74,7 +75,7 @@ public class CSVFormat implements Serializable {
*/
// package protected to give access without needing a synthetic accessor
CSVFormatBuilder(final char delimiter){
this(delimiter, null, null, null, null, false, false, null, null);
this(delimiter, null, null, null, null, false, false, null, Constants.EMPTY, null);
}
/**
@ -94,10 +95,11 @@ public class CSVFormat implements Serializable {
* <tt>true</tt> when whitespaces enclosing values should be ignored
* @param ignoreEmptyLines
* <tt>true</tt> when the parser should skip empty lines
* @param recordSeparator
* the line separator to use for output
* @param nullToString TODO
* @param header
* the header
* @param recordSeparator
* the line separator to use for output
* @throws IllegalArgumentException if the delimiter is a line break character
*/
// package protected for use by test code
@ -105,7 +107,7 @@ public class CSVFormat implements Serializable {
final Quote quotePolicy, final Character commentStart,
final Character escape, final boolean ignoreSurroundingSpaces,
final boolean ignoreEmptyLines, final String lineSeparator,
final String[] header) {
String nullToString, final String[] header) {
if (isLineBreak(delimiter)) {
throw new IllegalArgumentException("The delimiter cannot be a line break");
}
@ -117,6 +119,7 @@ public class CSVFormat implements Serializable {
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
this.ignoreEmptyLines = ignoreEmptyLines;
this.recordSeparator = lineSeparator;
this.nullToString = nullToString;
this.header = header;
}
@ -132,7 +135,7 @@ public class CSVFormat implements Serializable {
this(format.delimiter, format.quoteChar, format.quotePolicy,
format.commentStart, format.escape,
format.ignoreSurroundingSpaces, format.ignoreEmptyLines,
format.recordSeparator, format.header);
format.recordSeparator, format.nullToString, format.header);
}
/**
@ -143,7 +146,7 @@ public class CSVFormat implements Serializable {
public CSVFormat build() {
validate();
return new CSVFormat(delimiter, quoteChar, quotePolicy, commentStart, escape,
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, header);
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullToString, header);
}
/**
@ -327,6 +330,19 @@ public class CSVFormat implements Serializable {
return this;
}
/**
* Sets the String to use for null values for output.
*
* @param nullToString
* the String to use for null values for output.
*
* @return This builder with the the specified output record separator
*/
public CSVFormatBuilder withNullToString(final String nullToString) {
this.nullToString = nullToString;
return this;
}
/**
* Sets the quoteChar of the format to the specified character.
*
@ -423,7 +439,8 @@ public class CSVFormat implements Serializable {
* @return a standard comma separated format builder, as for {@link #RFC4180} but allowing empty lines.
*/
public static CSVFormatBuilder newBuilder() {
return new CSVFormatBuilder(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF, null);
return new CSVFormatBuilder(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true, CRLF, Constants.EMPTY,
null);
}
private final char delimiter;
private final Character quoteChar;
@ -431,11 +448,12 @@ public class CSVFormat implements Serializable {
private final Character commentStart;
private final Character escape;
private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
private final boolean ignoreEmptyLines;
private final String recordSeparator; // for outputs
private final String nullToString; // for outputs
private final String[] header;
/**
@ -570,6 +588,7 @@ public class CSVFormat implements Serializable {
* <tt>true</tt> when the parser should skip empty lines
* @param recordSeparator
* the line separator to use for output
* @param nullToString TODO
* @param header
* the header
* @throws IllegalArgumentException if the delimiter is a line break character
@ -579,7 +598,7 @@ public class CSVFormat implements Serializable {
final Quote quotePolicy, final Character commentStart,
final Character escape, final boolean ignoreSurroundingSpaces,
final boolean ignoreEmptyLines, final String recordSeparator,
final String[] header) {
String nullToString, final String[] header) {
if (isLineBreak(delimiter)) {
throw new IllegalArgumentException("The delimiter cannot be a line break");
}
@ -591,6 +610,7 @@ public class CSVFormat implements Serializable {
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
this.ignoreEmptyLines = ignoreEmptyLines;
this.recordSeparator = recordSeparator;
this.nullToString = nullToString;
this.header = header == null ? null : header.clone();
}
@ -722,6 +742,15 @@ public class CSVFormat implements Serializable {
return ignoreSurroundingSpaces;
}
/**
* Returns the value to use for writing null values.
*
* @return the value to use for writing null values.
*/
public String getNullToString() {
return nullToString;
}
/**
* Returns the character used to encapsulate values containing special characters.
*

View File

@ -344,7 +344,7 @@ public class CSVPrinter implements Flushable, Closeable {
*/
public void print(final Object value) throws IOException {
// null values are considered empty
final String strValue = value == null ? EMPTY : value.toString();
final String strValue = value == null ? format.getNullToString() : value.toString();
print(value, strValue, 0, strValue.length());
}

View File

@ -41,7 +41,7 @@ public class CSVFormatBuilderTest {
@Before
public void setUp() throws Exception {
builder = new CSVFormatBuilder('+', Character.valueOf('!'), null, Character.valueOf('#'), Character.valueOf('!'), true, true, CRLF, null);
builder = new CSVFormatBuilder('+', Character.valueOf('!'), null, Character.valueOf('#'), Character.valueOf('!'), true, true, CRLF, Constants.EMPTY, null);
}
@Test

View File

@ -307,6 +307,15 @@ public class CSVPrinterTest {
printer.close();
}
@Test
public void testPrintCustomNullValues() throws IOException {
final StringWriter sw = new StringWriter();
final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.toBuilder().withNullToString("NULL").build());
printer.printRecord("a", null, "b");
assertEquals("a,NULL,b" + recordSeparator, sw.toString());
printer.close();
}
@Test
public void testQuoteAll() throws IOException {
final StringWriter sw = new StringWriter();