[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:
parent
60cc83af7f
commit
75b9a4ba4e
|
@ -63,6 +63,7 @@ public class CSVFormat implements Serializable {
|
||||||
private boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
|
private boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
|
||||||
private boolean ignoreEmptyLines;
|
private boolean ignoreEmptyLines;
|
||||||
private String recordSeparator; // for outputs
|
private String recordSeparator; // for outputs
|
||||||
|
private String nullToString; // for outputs
|
||||||
private String[] header;
|
private String[] header;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +75,7 @@ public class CSVFormat implements Serializable {
|
||||||
*/
|
*/
|
||||||
// package protected to give access without needing a synthetic accessor
|
// package protected to give access without needing a synthetic accessor
|
||||||
CSVFormatBuilder(final char delimiter){
|
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
|
* <tt>true</tt> when whitespaces enclosing values should be ignored
|
||||||
* @param ignoreEmptyLines
|
* @param ignoreEmptyLines
|
||||||
* <tt>true</tt> when the parser should skip empty lines
|
* <tt>true</tt> when the parser should skip empty lines
|
||||||
* @param recordSeparator
|
* @param nullToString TODO
|
||||||
* the line separator to use for output
|
|
||||||
* @param header
|
* @param header
|
||||||
* the header
|
* the header
|
||||||
|
* @param recordSeparator
|
||||||
|
* the line separator to use for output
|
||||||
* @throws IllegalArgumentException if the delimiter is a line break character
|
* @throws IllegalArgumentException if the delimiter is a line break character
|
||||||
*/
|
*/
|
||||||
// package protected for use by test code
|
// package protected for use by test code
|
||||||
|
@ -105,7 +107,7 @@ public class CSVFormat implements Serializable {
|
||||||
final Quote quotePolicy, final Character commentStart,
|
final Quote quotePolicy, final Character commentStart,
|
||||||
final Character escape, final boolean ignoreSurroundingSpaces,
|
final Character escape, final boolean ignoreSurroundingSpaces,
|
||||||
final boolean ignoreEmptyLines, final String lineSeparator,
|
final boolean ignoreEmptyLines, final String lineSeparator,
|
||||||
final String[] header) {
|
String nullToString, final String[] header) {
|
||||||
if (isLineBreak(delimiter)) {
|
if (isLineBreak(delimiter)) {
|
||||||
throw new IllegalArgumentException("The delimiter cannot be a line break");
|
throw new IllegalArgumentException("The delimiter cannot be a line break");
|
||||||
}
|
}
|
||||||
|
@ -117,6 +119,7 @@ public class CSVFormat implements Serializable {
|
||||||
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
|
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
|
||||||
this.ignoreEmptyLines = ignoreEmptyLines;
|
this.ignoreEmptyLines = ignoreEmptyLines;
|
||||||
this.recordSeparator = lineSeparator;
|
this.recordSeparator = lineSeparator;
|
||||||
|
this.nullToString = nullToString;
|
||||||
this.header = header;
|
this.header = header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +135,7 @@ public class CSVFormat implements Serializable {
|
||||||
this(format.delimiter, format.quoteChar, format.quotePolicy,
|
this(format.delimiter, format.quoteChar, format.quotePolicy,
|
||||||
format.commentStart, format.escape,
|
format.commentStart, format.escape,
|
||||||
format.ignoreSurroundingSpaces, format.ignoreEmptyLines,
|
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() {
|
public CSVFormat build() {
|
||||||
validate();
|
validate();
|
||||||
return new CSVFormat(delimiter, quoteChar, quotePolicy, commentStart, escape,
|
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;
|
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.
|
* 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.
|
* @return a standard comma separated format builder, as for {@link #RFC4180} but allowing empty lines.
|
||||||
*/
|
*/
|
||||||
public static CSVFormatBuilder newBuilder() {
|
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 char delimiter;
|
||||||
private final Character quoteChar;
|
private final Character quoteChar;
|
||||||
|
@ -431,11 +448,12 @@ public class CSVFormat implements Serializable {
|
||||||
private final Character commentStart;
|
private final Character commentStart;
|
||||||
private final Character escape;
|
private final Character escape;
|
||||||
private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
|
private final boolean ignoreSurroundingSpaces; // Should leading/trailing spaces be ignored around values?
|
||||||
|
|
||||||
private final boolean ignoreEmptyLines;
|
private final boolean ignoreEmptyLines;
|
||||||
|
|
||||||
private final String recordSeparator; // for outputs
|
private final String recordSeparator; // for outputs
|
||||||
|
|
||||||
|
private final String nullToString; // for outputs
|
||||||
|
|
||||||
private final String[] header;
|
private final String[] header;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -570,6 +588,7 @@ public class CSVFormat implements Serializable {
|
||||||
* <tt>true</tt> when the parser should skip empty lines
|
* <tt>true</tt> when the parser should skip empty lines
|
||||||
* @param recordSeparator
|
* @param recordSeparator
|
||||||
* the line separator to use for output
|
* the line separator to use for output
|
||||||
|
* @param nullToString TODO
|
||||||
* @param header
|
* @param header
|
||||||
* the header
|
* the header
|
||||||
* @throws IllegalArgumentException if the delimiter is a line break character
|
* @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 Quote quotePolicy, final Character commentStart,
|
||||||
final Character escape, final boolean ignoreSurroundingSpaces,
|
final Character escape, final boolean ignoreSurroundingSpaces,
|
||||||
final boolean ignoreEmptyLines, final String recordSeparator,
|
final boolean ignoreEmptyLines, final String recordSeparator,
|
||||||
final String[] header) {
|
String nullToString, final String[] header) {
|
||||||
if (isLineBreak(delimiter)) {
|
if (isLineBreak(delimiter)) {
|
||||||
throw new IllegalArgumentException("The delimiter cannot be a line break");
|
throw new IllegalArgumentException("The delimiter cannot be a line break");
|
||||||
}
|
}
|
||||||
|
@ -591,6 +610,7 @@ public class CSVFormat implements Serializable {
|
||||||
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
|
this.ignoreSurroundingSpaces = ignoreSurroundingSpaces;
|
||||||
this.ignoreEmptyLines = ignoreEmptyLines;
|
this.ignoreEmptyLines = ignoreEmptyLines;
|
||||||
this.recordSeparator = recordSeparator;
|
this.recordSeparator = recordSeparator;
|
||||||
|
this.nullToString = nullToString;
|
||||||
this.header = header == null ? null : header.clone();
|
this.header = header == null ? null : header.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,6 +742,15 @@ public class CSVFormat implements Serializable {
|
||||||
return ignoreSurroundingSpaces;
|
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.
|
* Returns the character used to encapsulate values containing special characters.
|
||||||
*
|
*
|
||||||
|
|
|
@ -36,7 +36,7 @@ import java.util.NoSuchElementException;
|
||||||
* specification of a {@link CSVFormat}.
|
* specification of a {@link CSVFormat}.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* To parse a CSV input with tabs as separators, '"' (double-quote) as an optional value encapsulator,
|
* To parse a CSV input with tabs as separators, '"' (double-quote) as an optional value encapsulator,
|
||||||
* and comments starting with '#', you write:
|
* and comments starting with '#', you write:
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class CSVPrinter implements Flushable, Closeable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outputs the line separator.
|
* Outputs the line separator.
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* If an I/O error occurs
|
* If an I/O error occurs
|
||||||
*/
|
*/
|
||||||
|
@ -344,7 +344,7 @@ public class CSVPrinter implements Flushable, Closeable {
|
||||||
*/
|
*/
|
||||||
public void print(final Object value) throws IOException {
|
public void print(final Object value) throws IOException {
|
||||||
// null values are considered empty
|
// 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());
|
print(value, strValue, 0, strValue.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class CSVFormatBuilderTest {
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
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
|
@Test
|
||||||
|
|
|
@ -307,6 +307,15 @@ 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.toBuilder().withNullToString("NULL").build());
|
||||||
|
printer.printRecord("a", null, "b");
|
||||||
|
assertEquals("a,NULL,b" + recordSeparator, sw.toString());
|
||||||
|
printer.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testQuoteAll() throws IOException {
|
public void testQuoteAll() throws IOException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
|
|
Loading…
Reference in New Issue