Skip to content

Commit

Permalink
Added Jackson Engine and updated tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Adamek committed Dec 20, 2021
1 parent aeb1cbf commit 60bfa53
Show file tree
Hide file tree
Showing 6 changed files with 556 additions and 155 deletions.
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

0 comments on commit 60bfa53

Please sign in to comment.