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

Commit 93dfe48

Browse files
committed
Fix #93
1 parent c0b2d33 commit 93dfe48

File tree

5 files changed

+133
-11
lines changed

5 files changed

+133
-11
lines changed

release-notes/CREDITS

+6
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,9 @@ Oliver Röss (cloudyday@github)
5555

5656
* Reported #98: Escape char is not being escaped during serialization
5757
(2.6.4)
58+
59+
Rob Baily (rob-baily@github)
60+
61+
* Contributed fix for #93: CSV mapper does not support Views or filtering correctly
62+
for serialization
63+
(2.6.5)

release-notes/VERSION

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ Project: jackson-dataformat-csv
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.6.5 (not yet released)
8+
9+
#93: CSV mapper does not support Views or filtering correctly for serialization
10+
(reported by triviski@github; fix contributed by Rob B)
11+
712
2.6.4 (07-Dec-2015)
813

914
#90: Unexpected output with arrays starting with a null/empty element

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -793,16 +793,16 @@ public void writeNumber(String encodedValue) throws IOException
793793
@Override
794794
public void writeOmittedField(String fieldName) throws IOException
795795
{
796-
// basically combination of "writeFieldName()" and "writeNull()"
797-
if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) {
798-
_reportError("Can not skip a field, expecting a value");
799-
}
800796
// Hmmh. Should we require a match? Actually, let's use logic: if field found,
801797
// assumption is we must add a placeholder; if not, we can merely ignore
802798
CsvSchema.Column col = _schema.column(fieldName);
803799
if (col == null) {
804800
// assumed to have been removed from schema too
805801
} else {
802+
// basically combination of "writeFieldName()" and "writeNull()"
803+
if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) {
804+
_reportError("Can not skip a field, expecting a value");
805+
}
806806
// and all we do is just note index to use for following value write
807807
_nextColumnByName = col.getIndex();
808808
// We can basically copy what 'writeNull()' does...

src/test/java/com/fasterxml/jackson/dataformat/csv/deser/TestFiltering.java

+32-7
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ public static class Company {
5555
/**********************************************************
5656
*/
5757

58+
private final CsvMapper MAPPER = mapperForCsv();
59+
5860
public void testWithJsonView() throws Exception
5961
{
60-
CsvMapper mapper = mapperForCsv();
61-
CsvSchema schema = mapper.schemaFor(Bean.class).withLineSeparator("\n").withHeader();
62-
String actual = mapper.writer(schema).withView(ViewB.class).writeValueAsString(new Bean());
62+
CsvSchema schema = MAPPER.schemaFor(Bean.class).withLineSeparator("\n").withHeader();
63+
String actual = MAPPER.writer(schema).withView(ViewB.class).writeValueAsString(new Bean());
6364
// System.out.println(actual);
6465

6566
BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
@@ -69,7 +70,7 @@ public void testWithJsonView() throws Exception
6970

7071
// plus read back?
7172
final String INPUT = "a,aa,b\n5,6,7\n";
72-
Bean result = mapper.readerFor(Bean.class).with(schema).withView(ViewB.class).readValue(INPUT);
73+
Bean result = MAPPER.readerFor(Bean.class).with(schema).withView(ViewB.class).readValue(INPUT);
7374
assertEquals("5", result.a);
7475
// due to filtering, ought to use default
7576
assertEquals("2", result.aa);
@@ -78,8 +79,7 @@ public void testWithJsonView() throws Exception
7879

7980
public void testWithJsonFilter() throws Exception
8081
{
81-
CsvMapper mapper = mapperForCsv();
82-
CsvSchema schema = mapper.schemaFor(Company.class).withLineSeparator("\n").withHeader();
82+
CsvSchema schema = MAPPER.schemaFor(Company.class).withLineSeparator("\n").withHeader();
8383

8484
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
8585
.addFilter(COMPANY_FILTER, FilterExceptFilter.filterOutAllExcept("name", "ticker"));
@@ -88,7 +88,7 @@ public void testWithJsonFilter() throws Exception
8888
new Company(1, "name1", "ticker1")
8989
, new Company(2, "name2", "ticker2")
9090
, new Company(3, "name3", "ticker3"));
91-
String actual = mapper.writer(filterProvider).with(schema).writeValueAsString(companies);
91+
String actual = MAPPER.writer(filterProvider).with(schema).writeValueAsString(companies);
9292
// System.out.println(actual);
9393

9494
BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
@@ -98,4 +98,29 @@ public void testWithJsonFilter() throws Exception
9898
assertEquals(",name3,ticker3", br.readLine());
9999
assertNull(br.readLine());
100100
}
101+
102+
public void testWithJsonFilterFieldSuppressed() throws Exception
103+
{
104+
final CsvSchema schema = new CsvSchema.Builder()
105+
.addColumn("name")
106+
.addColumn("ticker")
107+
.setLineSeparator("\n").setUseHeader(true)
108+
.build();
109+
110+
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
111+
.addFilter(COMPANY_FILTER, FilterExceptFilter.filterOutAllExcept("name", "ticker"));
112+
113+
List<Company> companies = Arrays.asList(
114+
new Company(1, "name1", "ticker1")
115+
, new Company(2, "name2", "ticker2")
116+
, new Company(3, "name3", "ticker3"));
117+
String actual = MAPPER.writer(filterProvider).with(schema).writeValueAsString(companies);
118+
119+
BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
120+
assertEquals("name,ticker", br.readLine());
121+
assertEquals("name1,ticker1", br.readLine());
122+
assertEquals("name2,ticker2", br.readLine());
123+
assertEquals("name3,ticker3", br.readLine());
124+
assertNull(br.readLine());
125+
}
101126
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.fasterxml.jackson.dataformat.csv.ser;
2+
3+
import java.io.*;
4+
import java.util.ArrayList;
5+
import java.util.HashSet;
6+
import java.util.List;
7+
8+
import com.fasterxml.jackson.databind.*;
9+
import com.fasterxml.jackson.databind.introspect.Annotated;
10+
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
11+
import com.fasterxml.jackson.databind.ser.FilterProvider;
12+
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
13+
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
14+
import com.fasterxml.jackson.dataformat.csv.*;
15+
16+
@SuppressWarnings("serial")
17+
public class FilteringTest extends ModuleTestBase
18+
{
19+
static class Entity {
20+
public String name;
21+
public String unusedFieldBetween;
22+
public String description;
23+
public String unusedField;
24+
25+
public Entity(String name, String description, String unusedField) {
26+
this.name = name;
27+
this.description = description;
28+
this.unusedField = unusedField;
29+
}
30+
}
31+
32+
private final static String CSV_FILTER_NAME = "csvFilter";
33+
34+
static class CsvJacksonWriter {
35+
public void writeObjects(OutputStream outputStream,
36+
List<?> objects, CsvSchema csvSchema ) throws IOException
37+
{
38+
HashSet<String> columnNames = new HashSet<String>();
39+
for (CsvSchema.Column column : csvSchema) {
40+
columnNames.add( column.getName() );
41+
}
42+
43+
SimpleBeanPropertyFilter csvReponseFilter =
44+
new SimpleBeanPropertyFilter.FilterExceptFilter(columnNames);
45+
FilterProvider filterProvider = new SimpleFilterProvider().addFilter( CSV_FILTER_NAME, csvReponseFilter );
46+
47+
CsvMapper csvMapper = new CsvMapper();
48+
csvMapper.setFilterProvider( filterProvider );
49+
csvMapper.setAnnotationIntrospector(new CsvAnnotationIntrospector());
50+
51+
ObjectWriter objectWriter = csvMapper.writer(csvSchema);
52+
objectWriter.writeValue( outputStream, objects);
53+
}
54+
}
55+
56+
static class CsvAnnotationIntrospector extends JacksonAnnotationIntrospector {
57+
@Override
58+
public Object findFilterId(Annotated a) {
59+
return CSV_FILTER_NAME;
60+
}
61+
}
62+
63+
public void testWriteObjects() throws Exception {
64+
List<Entity> entities = new ArrayList<Entity>();
65+
entities.add( new Entity("Test entity 1", "Test description 1", "Test unused field"));
66+
entities.add(new Entity("Test entity 2", "Test description 2", "Test unused field"));
67+
68+
CsvSchema csvSchema = CsvSchema.builder()
69+
.addColumn("name")
70+
.addColumn("description")
71+
.setUseHeader( true )
72+
.build()
73+
.withLineSeparator("\r\n");
74+
75+
CsvJacksonWriter csvWriter = new CsvJacksonWriter();
76+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
77+
csvWriter.writeObjects(outputStream, entities, csvSchema);
78+
79+
StringBuffer expectedResults = new StringBuffer();
80+
expectedResults.append( "name,description\r\n" );
81+
expectedResults.append( "\"Test entity 1\",\"Test description 1\"\r\n" );
82+
expectedResults.append( "\"Test entity 2\",\"Test description 2\"\r\n");
83+
84+
assertEquals( expectedResults.toString(), outputStream.toString() );
85+
}
86+
}

0 commit comments

Comments
 (0)