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

Commit

Permalink
Implement #20 to some degree
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Aug 11, 2013
1 parent 84407c9 commit fe42a36
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 6 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Version: 2.3.0 (xx-xxx-2013)

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

------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.fasterxml.jackson.core.base.GeneratorBase;
import com.fasterxml.jackson.core.json.JsonWriteContext;
import com.fasterxml.jackson.core.io.IOContext;

import com.fasterxml.jackson.dataformat.csv.impl.CsvWriter;

public class CsvGenerator extends GeneratorBase
Expand Down Expand Up @@ -158,11 +157,6 @@ public CsvGenerator setPrettyPrinter(PrettyPrinter pp) {
public Object getOutputTarget() {
return _writer.getOutputTarget();
}

@Override
public boolean canUseSchema(FormatSchema schema) {
return (schema instanceof CsvSchema);
}

@Override
public void setSchema(FormatSchema schema)
Expand All @@ -177,6 +171,23 @@ public void setSchema(FormatSchema schema)
}
}

/*
/**********************************************************
/* Public API, capability introspection methods
/**********************************************************
*/

@Override
public boolean canUseSchema(FormatSchema schema) {
return (schema instanceof CsvSchema);
}

@Override
public boolean canOmitFields() {
// Nope: CSV requires at least a placeholder
return false;
}

/*
/**********************************************************************
/* Overridden methods; writing field names
Expand Down Expand Up @@ -537,6 +548,34 @@ public void writeNumber(String encodedValue) throws IOException,JsonGenerationEx
_verifyValueWrite("write number");
_writer.write(_columnIndex(), encodedValue);
}

/*
/**********************************************************
/* Overrides for field methods
/**********************************************************
*/

@Override
public void writeOmittedField(String fieldName)
throws IOException, JsonGenerationException
{
// basically combination of "writeFieldName()" and "writeNull()"
if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) {
_reportError("Can not skip a field, expecting a value");
}
// Hmmh. Should we require a match? Actually, let's use logic: if field found,
// assumption is we must add a placeholder; if not, we can merely ignore
CsvSchema.Column col = _schema.column(fieldName);
if (col == null) {
// assumed to have been removed from schema too
} else {
// and all we do is just note index to use for following value write
_nextColumnByName = col.getIndex();
// We can basically copy what 'writeNull()' does...
_verifyValueWrite("skip positional value due to filtering");
_writer.write(_columnIndex(), "");
}
}

/*
/**********************************************************
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.fasterxml.jackson.dataformat.csv;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.*;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.FilterExceptFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

public class TestFiltering extends ModuleTestBase
{
// Classes that represent views
static class ViewA { }
static class ViewAA extends ViewA { }
static class ViewB { }
static class ViewBB extends ViewB { }

@JsonPropertyOrder({ "a", "aa", "b" })
static class Bean
{
@JsonView({ ViewA.class, ViewB.class })
public String a = "1";

@JsonView({ViewAA.class })
public String aa = "2";

@JsonView(ViewB.class)
public String b = "3";
}

static final String COMPANY_FILTER = "COMPANY_FILTER";

@JsonPropertyOrder({ "id", "name", "ticker" })
@JsonFilter(COMPANY_FILTER)
public static class Company {
public int id;
public String name;
public String ticker;

Company() { }
Company(int id, String name, String ticker) {
this.id = id;
this.name = name;
this.ticker = ticker;
}
}

/*
/**********************************************************
/* Test methods
/**********************************************************
*/

public void testWithJsonView() throws Exception
{
CsvMapper mapper = mapperForCsv();
CsvSchema schema = mapper.schemaFor(Bean.class).withLineSeparator("\n").withHeader();
String actual = mapper.writer(schema).withView(ViewB.class).writeValueAsString(new Bean());
// System.out.println(actual);

BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
assertEquals("a,aa,b", br.readLine());
assertEquals("1,,3", br.readLine());
assertNull(br.readLine());

// plus read back?
final String INPUT = "a,aa,b\n5,6,7\n";
Bean result = mapper.reader(Bean.class).with(schema).withView(ViewB.class).readValue(INPUT);
assertEquals("5", result.a);
// due to filtering, ought to use default
assertEquals("2", result.aa);
assertEquals("7", result.b);
}

public void testWithJsonFilter() throws Exception
{
CsvMapper mapper = mapperForCsv();
CsvSchema schema = mapper.schemaFor(Company.class).withLineSeparator("\n").withHeader();

SimpleFilterProvider filterProvider = new SimpleFilterProvider()
.addFilter(COMPANY_FILTER, FilterExceptFilter.filterOutAllExcept("name", "ticker"));

List<Company> companies = Arrays.asList(
new Company(1, "name1", "ticker1")
, new Company(2, "name2", "ticker2")
, new Company(3, "name3", "ticker3"));
String actual = mapper.writer(filterProvider).withSchema(schema).writeValueAsString(companies);
// System.out.println(actual);

BufferedReader br = new BufferedReader(new StringReader(actual.trim()));
assertEquals("id,name,ticker", br.readLine());
assertEquals(",name1,ticker1", br.readLine());
assertEquals(",name2,ticker2", br.readLine());
assertEquals(",name3,ticker3", br.readLine());
assertNull(br.readLine());
}
}

0 comments on commit fe42a36

Please sign in to comment.