Skip to content
This repository was archived by the owner on Jan 22, 2019. It is now read-only.

Commit 98d2f1a

Browse files
committed
One more fix wrt #72, to distinguish between empty String, null, when reading; only former will cause coercion of empty String into null, at streaming parser level (higher-level mapping may still occur).
1 parent b249d53 commit 98d2f1a

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

Diff for: src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ public void writeNull() throws IOException
643643
_verifyValueWrite("write null value");
644644
if (!_skipValue) {
645645
if (_arraySeparator >= 0) {
646-
_addToArray(_schema.getNullValue());
646+
_addToArray(_schema.getNullValueOrEmpty());
647647
} else if (_writeContext.inRoot()) { // as per [#69]
648648
// or, to write 'empty Object' (for common case), would
649649
// write single null, then finish row, like so:

Diff for: src/main/java/com/fasterxml/jackson/dataformat/csv/CsvSchema.java

+33-9
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public class CsvSchema
8484

8585
protected final static int DEFAULT_ENCODING_FEATURES = 0;
8686

87+
protected final static char[] NO_CHARS = new char[0];
88+
8789
/*
8890
/**********************************************************************
8991
/* Constants, default settings
@@ -100,13 +102,20 @@ public class CsvSchema
100102
* semicolon.
101103
*/
102104
public final static char DEFAULT_ARRAY_ELEMENT_SEPARATOR = ';';
103-
105+
104106
public final static char DEFAULT_QUOTE_CHAR = '"';
105107

106108
/**
107-
* By default, nulls are written as empty Strings ("")
109+
* By default, nulls are written as empty Strings (""); and no coercion
110+
* is performed from any String (higher level databind may, however,
111+
* coerce Strings into Java nulls).
112+
* To use automatic coercion on reading, null value must be set explicitly
113+
* to empty String ("").
114+
*<p>
115+
* NOTE: before 2.6, this value default to empty <code>char[]</code>; changed
116+
* to Java null in 2.6.
108117
*/
109-
public final static char[] DEFAULT_NULL_VALUE = new char[0];
118+
public final static char[] DEFAULT_NULL_VALUE = null;
110119

111120
/**
112121
* By default, no escape character is used -- this is denoted by
@@ -549,7 +558,7 @@ public Builder setNullValue(String nvl) {
549558
}
550559

551560
public Builder setNullValue(char[] nvl) {
552-
_nullValue = (nvl == null) ? DEFAULT_NULL_VALUE : nvl;
561+
_nullValue = nvl;
553562
return this;
554563
}
555564

@@ -888,7 +897,7 @@ public CsvSchema withNullValue(String nvl) {
888897
return new CsvSchema(_columns, _features,
889898
_columnSeparator, _quoteChar, _escapeChar, _lineSeparator,
890899
_arrayElementSeparator,
891-
(nvl == null) ? DEFAULT_NULL_VALUE : nvl.toCharArray(),
900+
(nvl == null) ? null : nvl.toCharArray(),
892901
_columnsByName);
893902
}
894903

@@ -982,21 +991,36 @@ public String getSchemaType() {
982991
public char[] getLineSeparator() { return _lineSeparator; }
983992

984993
/**
994+
* @return Null value defined, as char array, if one is defined to be recognized; Java null
995+
* if not.
996+
*
985997
* @since 2.5
986998
*/
987999
public char[] getNullValue() { return _nullValue; }
9881000

1001+
/**
1002+
* Same as {@link #getNullValue()} except that undefined null value (one that remains as <code>null</code>,
1003+
* or explicitly set as such) will be returned as empty <code>char[]</code>
1004+
*
1005+
* @since 2.6
1006+
*/
1007+
public char[] getNullValueOrEmpty() {
1008+
if (_nullValue == null) {
1009+
return NO_CHARS;
1010+
}
1011+
return _nullValue;
1012+
}
1013+
9891014
/**
9901015
* @since 2.6
9911016
*/
9921017
public String getNullValueString() {
9931018
String str = _nullValueAsString;
9941019
if (str == null) {
995-
if (_nullValue == null || _nullValue.length == 0) {
996-
str = "";
997-
} else {
998-
str = new String(_nullValue);
1020+
if (_nullValue == null) {
1021+
return null;
9991022
}
1023+
str = (_nullValue.length == 0) ? "" : new String(_nullValue);
10001024
_nullValueAsString = str;
10011025
}
10021026
return str;

Diff for: src/main/java/com/fasterxml/jackson/dataformat/csv/impl/CsvEncoder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema)
171171
_cfgQuoteCharacter = schema.getQuoteChar();
172172
_cfgLineSeparator = schema.getLineSeparator();
173173
_cfgLineSeparatorLength = (_cfgLineSeparator == null) ? 0 : _cfgLineSeparator.length;
174-
_cfgNullValue = schema.getNullValue();
174+
_cfgNullValue = schema.getNullValueOrEmpty();
175175

176176
_columnCount = schema.size();
177177

@@ -198,7 +198,7 @@ public CsvEncoder(CsvEncoder base, CsvSchema newSchema)
198198
_cfgQuoteCharacter = newSchema.getQuoteChar();
199199
_cfgLineSeparator = newSchema.getLineSeparator();
200200
_cfgLineSeparatorLength = _cfgLineSeparator.length;
201-
_cfgNullValue = newSchema.getNullValue();
201+
_cfgNullValue = newSchema.getNullValueOrEmpty();
202202
_cfgMinSafeChar = _calcSafeChar();
203203
_columnCount = newSchema.size();
204204
}

Diff for: src/test/java/com/fasterxml/jackson/dataformat/csv/deser/NullReadTest.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,19 @@ public void testReadNullValueFromEmptyString() throws Exception
5050
String csv = MAPPER.writer(schemaWithDefault).writeValueAsString(new IdDesc("id", null));
5151
assertEquals("id,\n", csv);
5252

53-
// but read back
53+
// but read back. Note: no null coercion unless explicitly defined
5454

5555
ObjectReader r = MAPPER.readerFor(IdDesc.class).with(schemaWithDefault);
5656

5757
IdDesc result = r.readValue(csv);
5858
assertNotNull(result);
5959
assertEquals("id", result.id);
60-
assertNull(result.desc);
60+
assertEquals("", result.desc);
6161

6262
// also try the other combination
6363
result = r.readValue(",Whatevs\n");
6464
assertNotNull(result);
65-
assertNull(result.id);
65+
assertEquals("", result.id);
6666
assertEquals("Whatevs", result.desc);
6767

6868
// And then with explicit Empty String
@@ -80,7 +80,7 @@ public void testReadNullValueFromEmptyString() throws Exception
8080
assertEquals("id", result.id);
8181
assertNull(result.desc);
8282

83-
// and finally with explicit `null`
83+
// and finally with explicit `null`, which once again disables coercion
8484
CsvSchema schemaWithExplicitNull = CsvSchema.builder()
8585
.setNullValue((String) null)
8686
.addColumn("id")
@@ -93,6 +93,6 @@ public void testReadNullValueFromEmptyString() throws Exception
9393
result = r.readValue(csv);
9494
assertNotNull(result);
9595
assertEquals("id", result.id);
96-
assertNull(result.desc);
96+
assertEquals("", result.desc);
9797
}
9898
}

0 commit comments

Comments
 (0)