Skip to content

Commit 2cc36b7

Browse files
committed
[FasterXML#106] added code block to CsvGenerator writeNull method to process null values when processing nulls deeper than the root level.
[FasterXML#106] added unit test code to verify writeNull behavior for list elements.
1 parent e0e8bd7 commit 2cc36b7

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/main/java/com/fasterxml/jackson/dataformat/csv/CsvGenerator.java

+17-2
Original file line numberDiff line numberDiff line change
@@ -706,15 +706,30 @@ public void writeNull() throws IOException
706706
if (!_skipValue) {
707707
if (!_arraySeparator.isEmpty()) {
708708
_addToArray(_schema.getNullValueOrEmpty());
709-
} else if (!_writeContext.inObject()) { // as per [#69]
709+
} else if (!_writeContext.inObject()) {
710+
711+
// per issue 106:
712+
// this checks to see if this null item is at a level deeper
713+
// than the root level list of items.
714+
// Example Snippet:
715+
// List mainList = Arrays.asList(item1, item2, item3);
716+
// If one of the item1..3 are null, it will not be processed.
717+
// but if this null is part of a sub-list of item1..3,
718+
// then the null will be processed.
719+
if (_writeContext.getParent() != null
720+
&& _writeContext.getParent().getParent() != null) {
721+
_writer.writeNull(_columnIndex());
722+
}
723+
724+
// the initial 'inObject()' check is done as per [#69]
710725
// note: 'root' not enough, for case of wrap-as array, or serialize List
711726

712727
// or, to write 'empty Object' (for common case), would
713728
// write single null, then finish row, like so:
714729
/*
715730
_writer.writeNull(_columnIndex());
716731
finishRow();
717-
*/
732+
*/
718733
} else {
719734
_writer.writeNull(_columnIndex());
720735
}

src/test/java/com/fasterxml/jackson/dataformat/csv/ser/NullWritingTest.java

+41
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import java.io.ByteArrayOutputStream;
44
import java.io.StringWriter;
5+
import java.util.Arrays;
6+
import java.util.List;
57

68
import com.fasterxml.jackson.databind.*;
79
import com.fasterxml.jackson.dataformat.csv.*;
@@ -78,4 +80,43 @@ public void testCustomNullValue() throws Exception
7880
// MUST use doubling for quotes!
7981
assertEquals("id,n/a\n", result);
8082
}
83+
84+
public void testNullFieldsOfListsContainedByMainLevelListIssue106() throws Exception {
85+
CsvMapper mapper = mapperForCsv();
86+
87+
CsvSchema schema = CsvSchema.builder().build();
88+
89+
List row1 = Arrays.asList("d0", null, "d2");
90+
List row2 = Arrays.asList(null, "d1", "d2");
91+
List row3 = Arrays.asList("d0", "d1", null);
92+
93+
List dataList = Arrays.asList(row1, row2, row3);
94+
95+
String result = mapper.writer(schema).writeValueAsString(dataList);
96+
assertEquals("d0,,d2\n,d1,d2\nd0,d1,\n", result);
97+
98+
schema = schema.withNullValue("n/a");
99+
result = mapper.writer(schema).writeValueAsString(dataList);
100+
assertEquals("d0,n/a,d2\nn/a,d1,d2\nd0,d1,n/a\n", result);
101+
}
102+
103+
public void testNullElementsOfMainLevelListIssue106() throws Exception {
104+
CsvMapper mapper = mapperForCsv();
105+
CsvSchema schema = CsvSchema.builder().build();
106+
107+
List row1 = Arrays.asList("d0", null, "d2");
108+
List row2 = Arrays.asList(null, "d1", "d2");
109+
List row3 = Arrays.asList("d0", "d1", null);
110+
111+
// when serialized, the added root level nulls at index 1 and 3
112+
// should be absent from the output
113+
List dataList = Arrays.asList(row1, null, row2, null, row3);
114+
115+
String result = mapper.writer(schema).writeValueAsString(dataList);
116+
assertEquals("d0,,d2\n,d1,d2\nd0,d1,\n", result);
117+
118+
schema = schema.withNullValue("n/a");
119+
result = mapper.writer(schema).writeValueAsString(dataList);
120+
assertEquals("d0,n/a,d2\nn/a,d1,d2\nd0,d1,n/a\n", result);
121+
}
81122
}

0 commit comments

Comments
 (0)