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

Commit fe42a36

Browse files
committed
Implement #20 to some degree
1 parent 84407c9 commit fe42a36

File tree

3 files changed

+145
-6
lines changed

3 files changed

+145
-6
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Version: 2.3.0 (xx-xxx-2013)
33

44
#11: Default `CsvMapper` to use alphabetic sorting of properties (since
55
alternative is basically undefined; and with JDK 1.7+, unstable too)
6+
#20: Support filtering (`@JsonView`, `@JsonFilter`) with CSV
7+
(requested by mablaev@github)
68
- Add support for `JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN`
79

810
------------------------------------------------------------------------

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

+45-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.fasterxml.jackson.core.base.GeneratorBase;
1010
import com.fasterxml.jackson.core.json.JsonWriteContext;
1111
import com.fasterxml.jackson.core.io.IOContext;
12-
1312
import com.fasterxml.jackson.dataformat.csv.impl.CsvWriter;
1413

1514
public class CsvGenerator extends GeneratorBase
@@ -158,11 +157,6 @@ public CsvGenerator setPrettyPrinter(PrettyPrinter pp) {
158157
public Object getOutputTarget() {
159158
return _writer.getOutputTarget();
160159
}
161-
162-
@Override
163-
public boolean canUseSchema(FormatSchema schema) {
164-
return (schema instanceof CsvSchema);
165-
}
166160

167161
@Override
168162
public void setSchema(FormatSchema schema)
@@ -177,6 +171,23 @@ public void setSchema(FormatSchema schema)
177171
}
178172
}
179173

174+
/*
175+
/**********************************************************
176+
/* Public API, capability introspection methods
177+
/**********************************************************
178+
*/
179+
180+
@Override
181+
public boolean canUseSchema(FormatSchema schema) {
182+
return (schema instanceof CsvSchema);
183+
}
184+
185+
@Override
186+
public boolean canOmitFields() {
187+
// Nope: CSV requires at least a placeholder
188+
return false;
189+
}
190+
180191
/*
181192
/**********************************************************************
182193
/* Overridden methods; writing field names
@@ -537,6 +548,34 @@ public void writeNumber(String encodedValue) throws IOException,JsonGenerationEx
537548
_verifyValueWrite("write number");
538549
_writer.write(_columnIndex(), encodedValue);
539550
}
551+
552+
/*
553+
/**********************************************************
554+
/* Overrides for field methods
555+
/**********************************************************
556+
*/
557+
558+
@Override
559+
public void writeOmittedField(String fieldName)
560+
throws IOException, JsonGenerationException
561+
{
562+
// basically combination of "writeFieldName()" and "writeNull()"
563+
if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) {
564+
_reportError("Can not skip a field, expecting a value");
565+
}
566+
// Hmmh. Should we require a match? Actually, let's use logic: if field found,
567+
// assumption is we must add a placeholder; if not, we can merely ignore
568+
CsvSchema.Column col = _schema.column(fieldName);
569+
if (col == null) {
570+
// assumed to have been removed from schema too
571+
} else {
572+
// and all we do is just note index to use for following value write
573+
_nextColumnByName = col.getIndex();
574+
// We can basically copy what 'writeNull()' does...
575+
_verifyValueWrite("skip positional value due to filtering");
576+
_writer.write(_columnIndex(), "");
577+
}
578+
}
540579

541580
/*
542581
/**********************************************************
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.fasterxml.jackson.dataformat.csv;
2+
3+
import java.io.BufferedReader;
4+
import java.io.StringReader;
5+
import java.util.*;
6+
7+
import com.fasterxml.jackson.annotation.*;
8+
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.FilterExceptFilter;
9+
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
10+
11+
public class TestFiltering extends ModuleTestBase
12+
{
13+
// Classes that represent views
14+
static class ViewA { }
15+
static class ViewAA extends ViewA { }
16+
static class ViewB { }
17+
static class ViewBB extends ViewB { }
18+
19+
@JsonPropertyOrder({ "a", "aa", "b" })
20+
static class Bean
21+
{
22+
@JsonView({ ViewA.class, ViewB.class })
23+
public String a = "1";
24+
25+
@JsonView({ViewAA.class })
26+
public String aa = "2";
27+
28+
@JsonView(ViewB.class)
29+
public String b = "3";
30+
}
31+
32+
static final String COMPANY_FILTER = "COMPANY_FILTER";
33+
34+
@JsonPropertyOrder({ "id", "name", "ticker" })
35+
@JsonFilter(COMPANY_FILTER)
36+
public static class Company {
37+
public int id;
38+
public String name;
39+
public String ticker;
40+
41+
Company() { }
42+
Company(int id, String name, String ticker) {
43+
this.id = id;
44+
this.name = name;
45+
this.ticker = ticker;
46+
}
47+
}
48+
49+
/*
50+
/**********************************************************
51+
/* Test methods
52+
/**********************************************************
53+
*/
54+
55+
public void testWithJsonView() throws Exception
56+
{
57+
CsvMapper mapper = mapperForCsv();
58+
CsvSchema schema = mapper.schemaFor(Bean.class).withLineSeparator("\n").withHeader();
59+
String actual = mapper.writer(schema).withView(ViewB.class).writeValueAsString(new Bean());
60+
// System.out.println(actual);
61+
62+
BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
63+
assertEquals("a,aa,b", br.readLine());
64+
assertEquals("1,,3", br.readLine());
65+
assertNull(br.readLine());
66+
67+
// plus read back?
68+
final String INPUT = "a,aa,b\n5,6,7\n";
69+
Bean result = mapper.reader(Bean.class).with(schema).withView(ViewB.class).readValue(INPUT);
70+
assertEquals("5", result.a);
71+
// due to filtering, ought to use default
72+
assertEquals("2", result.aa);
73+
assertEquals("7", result.b);
74+
}
75+
76+
public void testWithJsonFilter() throws Exception
77+
{
78+
CsvMapper mapper = mapperForCsv();
79+
CsvSchema schema = mapper.schemaFor(Company.class).withLineSeparator("\n").withHeader();
80+
81+
SimpleFilterProvider filterProvider = new SimpleFilterProvider()
82+
.addFilter(COMPANY_FILTER, FilterExceptFilter.filterOutAllExcept("name", "ticker"));
83+
84+
List<Company> companies = Arrays.asList(
85+
new Company(1, "name1", "ticker1")
86+
, new Company(2, "name2", "ticker2")
87+
, new Company(3, "name3", "ticker3"));
88+
String actual = mapper.writer(filterProvider).withSchema(schema).writeValueAsString(companies);
89+
// System.out.println(actual);
90+
91+
BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
92+
assertEquals("id,name,ticker", br.readLine());
93+
assertEquals(",name1,ticker1", br.readLine());
94+
assertEquals(",name2,ticker2", br.readLine());
95+
assertEquals(",name3,ticker3", br.readLine());
96+
assertNull(br.readLine());
97+
}
98+
}

0 commit comments

Comments
 (0)