Skip to content

Commit fa8a819

Browse files
committed
Start work on #442: add CsvValueDecorator as starting point for configuring processing
1 parent 769a4c4 commit fa8a819

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package com.fasterxml.jackson.dataformat.csv;
2+
3+
import java.io.IOException;
4+
5+
import com.fasterxml.jackson.databind.DeserializationContext;
6+
import com.fasterxml.jackson.databind.SerializerProvider;
7+
8+
/**
9+
* Interface defining API for handlers that can add and remove "decorations"
10+
* to CSV values: for example, brackets around Array (List) values encoded
11+
* in a single physical column.
12+
*<p>
13+
* Decorations are handled after handling other encoding aspects such as
14+
* optional quoting and/or escaping.
15+
*<p>
16+
* Decorators can be handled at both {@link CsvSchema} level (as defaults
17+
* for specific column types or classes) and {@link CsvSchema.Column} level (specific
18+
* to values of given column): if both defined, more specific -- latter, per-Column
19+
* -- is used.
20+
*
21+
* @since 2.17
22+
*/
23+
public interface CsvValueDecorator
24+
{
25+
/**
26+
* Method called during serialization when encoding a value,
27+
* to produce "decorated" value to include in output (possibly
28+
* escaped and/or quoted).
29+
* Note that possible escaping and/or quoting (as per configuration
30+
* of {@link CsvSchema} is applied on decorated value.
31+
*
32+
* @param gen Generator that will be used for actual serialization
33+
* @param ctxt Context passed to give access to configuration
34+
* @param plainValue Value to decorate
35+
*
36+
* @return Decorated value (which may be {@code plainValue} as-is)
37+
*
38+
* @throws IOException if attempt to decorate the value somehow fails
39+
* (typically a {@link com.fasterxml.jackson.core.exc.StreamWriteException})
40+
*/
41+
public String decorateValue(CsvGenerator gen, SerializerProvider ctxt,
42+
String plainValue)
43+
throws IOException;
44+
45+
/**
46+
* Method called during deserialization, to remove possible decoration
47+
* applied with {@link #decorateValue}.
48+
* Call is made after textual value for a cell (column
49+
* value) has been read using {@code parser} and after removing (decoding)
50+
* possible quoting and/or escaping of the value. Value passed in
51+
* has no escaping or quoting left.
52+
*
53+
* @param parser Parser that was used to decode textual value from input
54+
* @param ctxt Context passed to give access to configuration
55+
* @param decoratedValue Value from which to remove decorations, if any
56+
* (some decorators can allow optional decorations; others may fail
57+
* if none found)
58+
*
59+
* @return Value after removing decorations, if any.
60+
*
61+
* @throws IOException if attempt to undecorate the value fails
62+
* (typically a {@link com.fasterxml.jackson.core.exc.StreamReadException})
63+
*/
64+
public String undecorateValue(CsvParser parser, DeserializationContext ctxt,
65+
String decoratedValue)
66+
throws IOException;
67+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.fasterxml.jackson.dataformat.csv.fuzz;
2+
3+
import java.net.URL;
4+
5+
import com.fasterxml.jackson.annotation.*;
6+
7+
import com.fasterxml.jackson.databind.MappingIterator;
8+
9+
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
10+
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
11+
import com.fasterxml.jackson.dataformat.csv.ModuleTestBase;
12+
13+
public class ReadBracketedArrayTest extends ModuleTestBase
14+
{
15+
@JsonPropertyOrder({"id", "title", "url", "score", "time", "comments", "author",
16+
"embeddings"
17+
})
18+
static class Article {
19+
public String id, title, author;
20+
public URL url;
21+
public int comments, score;
22+
public long time; // Unix time
23+
24+
public double[] embeddings;
25+
}
26+
27+
/*
28+
/**********************************************************************
29+
/* Test methods
30+
/**********************************************************************
31+
*/
32+
33+
private final CsvMapper MAPPER = mapperForCsv();
34+
35+
public void testArrayWithBracketsRead() throws Exception
36+
{
37+
byte[] input = readResource("/data/story-100.csv");
38+
CsvSchema schema = MAPPER.schemaFor(Article.class)
39+
.withHeader()
40+
.withArrayElementSeparator(",");
41+
MappingIterator<Article> it = MAPPER.readerFor(Article.class)
42+
.with(schema)
43+
.readValues(input);
44+
45+
Article first = it.nextValue();
46+
assertNotNull(first);
47+
}
48+
}

0 commit comments

Comments
 (0)