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

Change json serialization to Jackson #46

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
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
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@
<artifactId>argon2-jvm</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package io.vlingo.xoom.common.serialization;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.time.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import static io.vlingo.xoom.common.serialization.JsonSerialization.PATTERN;

class GsonJsonSerialization implements JsonSerializationEngine {

private final Gson gson;

{
gson = new GsonBuilder()
.registerTypeAdapter(Class.class, new GsonJsonSerialization.ClassSerializer())
.registerTypeAdapter(Class.class, new GsonJsonSerialization.ClassDeserializer())
.registerTypeAdapter(Date.class, new GsonJsonSerialization.DateSerializer())
.registerTypeAdapter(Date.class, new GsonJsonSerialization.DateDeserializer())
.registerTypeAdapter(LocalDate.class, new GsonJsonSerialization.LocalDateSerializer())
.registerTypeAdapter(LocalDate.class, new GsonJsonSerialization.LocalDateDeserializer())
.registerTypeAdapter(LocalDateTime.class, new GsonJsonSerialization.LocalDateTimeSerializer())
.registerTypeAdapter(LocalDateTime.class, new GsonJsonSerialization.LocalDateTimeDeserializer())
.registerTypeAdapter(OffsetDateTime.class, new GsonJsonSerialization.OffsetDateTimeSerializer())
.registerTypeAdapter(OffsetDateTime.class, new GsonJsonSerialization.OffsetDateTimeDeserializer())
.create();
}

@Override
public <T> T deserialized(String serialization, final Class<T> type) {
T instance = gson.fromJson(serialization, type);
return instance;
}

@Override
public <T> T deserialized(String serialization, final Type type) {
T instance = gson.fromJson(serialization, type);
return instance;
}

@Override
public <T> List<T> deserializedList(String serialization, final Type listOfType) {
final List<T> list = gson.fromJson(serialization, listOfType);
return list;
}

@Override
public String serialized(final Object instance) {
final String serialization = gson.toJson(instance);
return serialization;
}

@Override
public <T> String serialized(final Collection<T> instance) {
final Type collectionOfT = new TypeToken<Collection<T>>() {
}.getType();
final String serialization = gson.toJson(instance, collectionOfT);
return serialization;
}

@Override
public <T> String serialized(final List<T> instance) {
final Type listOfT = new TypeToken<List<T>>() {
}.getType();
final String serialization = gson.toJson(instance, listOfT);
return serialization;
}

@SuppressWarnings("rawtypes")
private static class ClassSerializer implements JsonSerializer<Class> {
@Override
public JsonElement serialize(Class source, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(source.getName());
}
}

@SuppressWarnings("rawtypes")
private static class ClassDeserializer implements JsonDeserializer<Class> {
@Override
public Class deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
final String classname = json.getAsJsonPrimitive().getAsString();
try {
return Class.forName(classname);
} catch (ClassNotFoundException e) {
throw new JsonParseException(e);
}
}
}

private static class DateSerializer implements JsonSerializer<Date> {
@Override
public JsonElement serialize(Date source, Type typeOfSource, JsonSerializationContext context) {
return new JsonPrimitive(Long.toString(source.getTime()));
}
}

private static class DateDeserializer implements JsonDeserializer<Date> {
@Override
public Date deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
long time = Long.parseLong(json.getAsJsonPrimitive().getAsString());
return new Date(time);
}
}

private static class LocalDateSerializer implements JsonSerializer<LocalDate> {
public JsonElement serialize(LocalDate source, Type typeOfSource, JsonSerializationContext context) {
return new JsonPrimitive(Long.toString(source.toEpochDay()));
}
}

private static class LocalDateDeserializer implements JsonDeserializer<LocalDate> {
public LocalDate deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
if (isNumericString(json.getAsJsonPrimitive().getAsString())) {
final long epochDay = Long.parseLong(json.getAsJsonPrimitive().getAsString());
return LocalDate.ofEpochDay(epochDay);
}

return LocalDate.parse(json.getAsJsonPrimitive().getAsString());
}
}

private static class LocalDateTimeSerializer implements JsonSerializer<LocalDateTime> {
public JsonElement serialize(final LocalDateTime source, Type typeOfSource, JsonSerializationContext context) {
return new JsonPrimitive(Long.toString(source.atZone(ZoneOffset.UTC).toInstant().toEpochMilli()));
}
}

private static class LocalDateTimeDeserializer implements JsonDeserializer<LocalDateTime> {
public LocalDateTime deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
if (isNumericString(json.getAsJsonPrimitive().getAsString())) {
final long milli = Long.parseLong(json.getAsJsonPrimitive().getAsString());
return LocalDateTime.ofInstant(Instant.ofEpochMilli(milli), ZoneOffset.UTC);
}

return LocalDateTime.parse(json.getAsJsonPrimitive().getAsString());
}
}

private static class OffsetDateTimeSerializer implements JsonSerializer<OffsetDateTime> {
@Override
public JsonElement serialize(OffsetDateTime source, Type typeOfSource, JsonSerializationContext context) {
return new JsonPrimitive(source.toInstant().toEpochMilli() + ";" + source.getOffset().toString());
}
}

private static class OffsetDateTimeDeserializer implements JsonDeserializer<OffsetDateTime> {
@Override
public OffsetDateTime deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException {
final String[] encoding = json.getAsJsonPrimitive().getAsString().split(";");
final Date date = new Date(Long.parseLong(encoding[0]));
return date.toInstant().atOffset(ZoneOffset.of(encoding[1]));
}
}

private static boolean isNumericString(String element) {
return PATTERN.matcher(element).matches();
}
}
Loading