-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added Jackson Engine and updated tests
- Loading branch information
Patrick Adamek
committed
Dec 20, 2021
1 parent
aeb1cbf
commit 60bfa53
Showing
6 changed files
with
556 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
162 changes: 162 additions & 0 deletions
162
src/main/java/io/vlingo/xoom/common/serialization/GsonJsonSerialization.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
Oops, something went wrong.