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

Added ability to use a custom mapper for serialization #1217

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions json/src/main/java/tech/tablesaw/io/json/JsonWriteOptions.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
package tech.tablesaw.io.json;

import java.io.Writer;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import tech.tablesaw.io.Destination;
import tech.tablesaw.io.WriteOptions;

public class JsonWriteOptions extends WriteOptions {

private final boolean asObjects;
private final boolean header;
private final ObjectMapper mapper;

private JsonWriteOptions(Builder builder) {
super(builder);
this.asObjects = builder.asObjects;
this.header = builder.header;
this.mapper = builder.mapper;
}

public boolean asObjects() {
Expand All @@ -23,6 +28,8 @@ public boolean header() {
return header;
}

public ObjectMapper mapper() { return mapper; }

public static Builder builder(Writer writer) {
return new Builder(new Destination(writer));
}
Expand All @@ -35,6 +42,7 @@ public static class Builder extends WriteOptions.Builder {

private boolean asObjects = true;
private boolean header = false;
private ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

protected Builder(Destination destination) {
super(destination);
Expand All @@ -52,6 +60,11 @@ public JsonWriteOptions.Builder header(boolean header) {
return this;
}

public JsonWriteOptions.Builder mapper(ObjectMapper mapper) {
this.mapper = mapper;
return this;
}

public JsonWriteOptions build() {
return new JsonWriteOptions(this);
}
Expand Down
18 changes: 8 additions & 10 deletions json/src/main/java/tech/tablesaw/io/json/JsonWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
public class JsonWriter implements DataWriter<JsonWriteOptions> {

private static final JsonWriter INSTANCE = new JsonWriter();
private static final ObjectMapper mapper =
new ObjectMapper().registerModule(new JavaTimeModule());

static {
register(Table.defaultWriterRegistry);
Expand All @@ -43,33 +41,33 @@ public static void register(WriterRegistry registry) {
}

public void write(Table table, JsonWriteOptions options) {
ArrayNode output = mapper.createArrayNode();
ArrayNode output = options.mapper().createArrayNode();
if (options.asObjects()) {
for (int r = 0; r < table.rowCount(); r++) {
ObjectNode row = mapper.createObjectNode();
ObjectNode row = options.mapper().createObjectNode();
for (int c = 0; c < table.columnCount(); c++) {
row.set(table.column(c).name(), mapper.convertValue(table.get(r, c), JsonNode.class));
row.set(table.column(c).name(), options.mapper().convertValue(table.get(r, c), JsonNode.class));
}
output.add(row);
}
} else {
if (options.header()) {
ArrayNode row = mapper.createArrayNode();
ArrayNode row = options.mapper().createArrayNode();
for (int c = 0; c < table.columnCount(); c++) {
row.add(mapper.convertValue(table.column(c).name(), JsonNode.class));
row.add(options.mapper().convertValue(table.column(c).name(), JsonNode.class));
}
output.add(row);
}
for (int r = 0; r < table.rowCount(); r++) {
ArrayNode row = mapper.createArrayNode();
ArrayNode row = options.mapper().createArrayNode();
for (int c = 0; c < table.columnCount(); c++) {
row.add(mapper.convertValue(table.get(r, c), JsonNode.class));
row.add(options.mapper().convertValue(table.get(r, c), JsonNode.class));
}
output.add(row);
}
}
try (Writer writer = options.destination().createWriter()) {
String str = mapper.writeValueAsString(output);
String str = options.mapper().writeValueAsString(output);
writer.write(str);
} catch (IOException e) {
throw new RuntimeIOException(e);
Expand Down
29 changes: 29 additions & 0 deletions json/src/test/java/tech/tablesaw/io/json/JsonWriterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,20 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.junit.jupiter.api.Test;
import tech.tablesaw.api.Table;
import tech.tablesaw.io.Destination;

public class JsonWriterTest {

Expand Down Expand Up @@ -54,4 +64,23 @@ public void arrayOfObjects() {
String output = table.write().toString("json");
assertEquals(json, output);
}

@Test
public void withCustomMapper() {
var json = "[{\"a\":\"2021-01-01\"}, {\"a\":\"2021-02-01\"}]";
var table = Table.read().string(json, "json");
var mapper = new ObjectMapper();
mapper.registerModule(new SimpleModule().addSerializer(new StdSerializer<LocalDate>(LocalDate.class) {
final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");
@Override
public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString(FORMATTER.format(localDate));
}
}));

var baos = new ByteArrayOutputStream();
new JsonWriter().write(table, new JsonWriteOptions.Builder(new Destination(baos)).mapper(mapper).build());
assertEquals(new String(baos.toByteArray()), "[{\"a\":\"2021/01/01\"},{\"a\":\"2021/02/01\"}]");
}
}