Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds schema creating csv schema with View #195

Merged
merged 1 commit into from Apr 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,16 +1,21 @@
package com.fasterxml.jackson.dataformat.csv;

import java.util.Collection;

import com.fasterxml.jackson.core.type.TypeReference;

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.cfg.MapperBuilder;
import com.fasterxml.jackson.databind.cfg.MapperBuilderState;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.util.NameTransformer;
import com.fasterxml.jackson.databind.util.SimpleLookupCache;
import com.fasterxml.jackson.databind.util.ViewMatcher;
import java.util.Collection;

/**
* Specialized {@link ObjectMapper}, with extended functionality to
Expand Down Expand Up @@ -364,15 +369,27 @@ public CsvSchema schema() {
* just defined to be exposed as String tokens).
*/
public CsvSchema schemaFor(JavaType pojoType) {
return _schemaFor(pojoType, _untypedSchemas, false);
return _schemaFor(pojoType, _untypedSchemas, false, null);
}

public CsvSchema schemaForWithView(JavaType pojoType, Class<?> view) {
return _schemaFor(pojoType, _untypedSchemas, false, view);
}

public final CsvSchema schemaFor(Class<?> pojoType) {
return _schemaFor(constructType(pojoType), _untypedSchemas, false);
return _schemaFor(constructType(pojoType), _untypedSchemas, false, null);
}

public final CsvSchema schemaForWithView(Class<?> pojoType, Class<?> view) {
return _schemaFor(constructType(pojoType), _untypedSchemas, false, view);
}

public final CsvSchema schemaFor(TypeReference<?> pojoTypeRef) {
return _schemaFor(constructType(pojoTypeRef.getType()), _untypedSchemas, false);
return _schemaFor(constructType(pojoTypeRef.getType()), _untypedSchemas, false, null);
}

public final CsvSchema schemaForWithView(TypeReference<?> pojoTypeRef, Class<?> view) {
return _schemaFor(constructType(pojoTypeRef.getType()), _untypedSchemas, false, view);
}

/**
Expand All @@ -383,15 +400,27 @@ public final CsvSchema schemaFor(TypeReference<?> pojoTypeRef) {
* (especially for numeric types like java.lang.Integer).
*/
public CsvSchema typedSchemaFor(JavaType pojoType) {
return _schemaFor(pojoType, _typedSchemas, true);
return _schemaFor(pojoType, _typedSchemas, true, null);
}

public CsvSchema typedSchemaForWithView(JavaType pojoType, Class<?> view) {
return _schemaFor(pojoType, _typedSchemas, true, view);
}

public final CsvSchema typedSchemaFor(Class<?> pojoType) {
return _schemaFor(constructType(pojoType), _typedSchemas, true);
return _schemaFor(constructType(pojoType), _typedSchemas, true, null);
}

public final CsvSchema typedSchemaForWithView(Class<?> pojoType, Class<?> view) {
return _schemaFor(constructType(pojoType), _typedSchemas, true, view);
}

public final CsvSchema typedSchemaFor(TypeReference<?> pojoTypeRef) {
return _schemaFor(constructType(pojoTypeRef.getType()), _typedSchemas, true);
return _schemaFor(constructType(pojoTypeRef.getType()), _typedSchemas, true, null);
}

public final CsvSchema typedSchemaForWithView(TypeReference<?> pojoTypeRef, Class<?> view) {
return _schemaFor(constructType(pojoTypeRef.getType()), _typedSchemas, true, view);
}

/*
Expand All @@ -401,7 +430,7 @@ public final CsvSchema typedSchemaFor(TypeReference<?> pojoTypeRef) {
*/

protected CsvSchema _schemaFor(JavaType pojoType, SimpleLookupCache<JavaType,CsvSchema> schemas,
boolean typed)
boolean typed, Class<?> view)
{
synchronized (schemas) {
CsvSchema s = schemas.get(pojoType);
Expand All @@ -412,7 +441,7 @@ protected CsvSchema _schemaFor(JavaType pojoType, SimpleLookupCache<JavaType,Csv
// 15-Oct-2019, tatu: Since 3.0, need context for introspection
final SerializerProvider ctxt = _serializerProvider();
CsvSchema.Builder builder = CsvSchema.builder();
_addSchemaProperties(ctxt, builder, typed, pojoType, null);
_addSchemaProperties(ctxt, builder, typed, pojoType, null, view);
CsvSchema result = builder.build();
synchronized (schemas) {
schemas.put(pojoType, result);
Expand Down Expand Up @@ -449,8 +478,7 @@ protected boolean _nonPojoType(JavaType t)
}

protected void _addSchemaProperties(SerializerProvider ctxt, CsvSchema.Builder builder,
boolean typed,
JavaType pojoType, NameTransformer unwrapper)
boolean typed, JavaType pojoType, NameTransformer unwrapper, Class<?> view)
{
// 09-Aug-2015, tatu: From [dataformat-csv#87], realized that one can not have
// real schemas for primitive/wrapper
Expand All @@ -460,6 +488,15 @@ protected void _addSchemaProperties(SerializerProvider ctxt, CsvSchema.Builder b
BeanDescription beanDesc = ctxt.introspectBeanDescription(pojoType);
final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector();
for (BeanPropertyDefinition prop : beanDesc.findProperties()) {
if (view != null) {
Class<?>[] views = prop.findViews();
if (views == null) {
views = beanDesc.findDefaultViews();
}
if (!ViewMatcher.construct(views).isVisibleForView(view)) {
continue;
}
}
// ignore setter-only properties:
if (!prop.couldSerialize()) {
continue;
Expand All @@ -474,7 +511,7 @@ protected void _addSchemaProperties(SerializerProvider ctxt, CsvSchema.Builder b
nextUnwrapper = NameTransformer.chainedTransformer(unwrapper, nextUnwrapper);
}
JavaType nextType = m.getType();
_addSchemaProperties(ctxt, builder, typed, nextType, nextUnwrapper);
_addSchemaProperties(ctxt, builder, typed, nextType, nextUnwrapper, view);
continue;
}
}
Expand Down
@@ -1,15 +1,18 @@
package com.fasterxml.jackson.dataformat.csv.deser;

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

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter.FilterExceptFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvMappingException;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.fasterxml.jackson.dataformat.csv.ModuleTestBase;
import java.io.BufferedReader;
import java.io.StringReader;
import java.util.Arrays;
import java.util.List;

public class TestFiltering extends ModuleTestBase
{
Expand Down Expand Up @@ -76,6 +79,41 @@ public void testWithJsonView() throws Exception
assertEquals("2", result.aa);
assertEquals("7", result.b);
}

public void testSchemaWithJsonViewSerialization() throws Exception
{
CsvSchema schema = MAPPER.schemaForWithView(Bean.class, ViewB.class).withLineSeparator("\n").withHeader();
String actual = MAPPER.writer(schema).withView(ViewB.class).writeValueAsString(new Bean());
MAPPER.writer(schema).withView(ViewB.class);

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

public void testSchemaWithJsonViewDeserialization() throws Exception
{
CsvSchema schema = MAPPER.schemaForWithView(Bean.class, ViewB.class).withLineSeparator("\n").withHeader();
final String input = "a,b\n5,7\n";
Bean result = MAPPER.readerFor(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 testSchemaWithJsonViewDeserializationFail() throws Exception
{
CsvSchema schema = MAPPER.schemaForWithView(Bean.class, ViewB.class).withLineSeparator("\n").withHeader();
final String input = "a,aa,b\n5,6,7\n";
try {
MAPPER.readerFor(Bean.class).with(schema).withView(ViewB.class).readValue(input);
fail();
} catch (CsvMappingException ignore) {
}
}

public void testWithJsonFilter() throws Exception
{
Expand Down