diff --git a/pom.xml b/pom.xml index 6a730a7..4e17df5 100644 --- a/pom.xml +++ b/pom.xml @@ -114,6 +114,16 @@ argon2-jvm 2.10.1 + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.13.0 + org.graalvm.sdk graal-sdk diff --git a/src/main/java/io/vlingo/xoom/common/serialization/GsonJsonSerialization.java b/src/main/java/io/vlingo/xoom/common/serialization/GsonJsonSerialization.java new file mode 100644 index 0000000..3ca9fc7 --- /dev/null +++ b/src/main/java/io/vlingo/xoom/common/serialization/GsonJsonSerialization.java @@ -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 deserialized(String serialization, final Class type) { + T instance = gson.fromJson(serialization, type); + return instance; + } + + @Override + public T deserialized(String serialization, final Type type) { + T instance = gson.fromJson(serialization, type); + return instance; + } + + @Override + public List deserializedList(String serialization, final Type listOfType) { + final List list = gson.fromJson(serialization, listOfType); + return list; + } + + @Override + public String serialized(final Object instance) { + final String serialization = gson.toJson(instance); + return serialization; + } + + @Override + public String serialized(final Collection instance) { + final Type collectionOfT = new TypeToken>() { + }.getType(); + final String serialization = gson.toJson(instance, collectionOfT); + return serialization; + } + + @Override + public String serialized(final List instance) { + final Type listOfT = new TypeToken>() { + }.getType(); + final String serialization = gson.toJson(instance, listOfT); + return serialization; + } + + @SuppressWarnings("rawtypes") + private static class ClassSerializer implements JsonSerializer { + @Override + public JsonElement serialize(Class source, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(source.getName()); + } + } + + @SuppressWarnings("rawtypes") + private static class ClassDeserializer implements JsonDeserializer { + @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 { + @Override + public JsonElement serialize(Date source, Type typeOfSource, JsonSerializationContext context) { + return new JsonPrimitive(Long.toString(source.getTime())); + } + } + + private static class DateDeserializer implements JsonDeserializer { + @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 { + public JsonElement serialize(LocalDate source, Type typeOfSource, JsonSerializationContext context) { + return new JsonPrimitive(Long.toString(source.toEpochDay())); + } + } + + private static class LocalDateDeserializer implements JsonDeserializer { + 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 { + 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 { + 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 { + @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 { + @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(); + } +} diff --git a/src/main/java/io/vlingo/xoom/common/serialization/JacksonJsonSerialization.java b/src/main/java/io/vlingo/xoom/common/serialization/JacksonJsonSerialization.java new file mode 100644 index 0000000..02df2f1 --- /dev/null +++ b/src/main/java/io/vlingo/xoom/common/serialization/JacksonJsonSerialization.java @@ -0,0 +1,273 @@ +package io.vlingo.xoom.common.serialization; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; + +import java.io.IOException; +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 JacksonJsonSerialization implements JsonSerializationEngine { + + private final ObjectMapper mapper; + + { + SimpleModule module = new SimpleModule(); + module.addSerializer(Date.class, new JacksonJsonSerialization.DateJacksonSerializer()); + module.addDeserializer(Date.class, new JacksonJsonSerialization.DateJacksonDeserializer()); + module.addSerializer(LocalDate.class, new JacksonJsonSerialization.LocalDateJacksonSerializer()); + module.addDeserializer(LocalDate.class, new JacksonJsonSerialization.LocalDateJacksonDeserializer()); + module.addSerializer(LocalDateTime.class, new JacksonJsonSerialization.LocalDateTimeJacksonSerializer()); + module.addDeserializer(LocalDateTime.class, new JacksonJsonSerialization.LocalDateTimeJacksonDeserializer()); + module.addSerializer(OffsetDateTime.class, new JacksonJsonSerialization.OffsetDateTimeJacksonSerializer()); + module.addDeserializer(OffsetDateTime.class, new JacksonJsonSerialization.OffsetDateTimeJacksonDeserializer()); + + mapper = JsonMapper.builder() + .addModule(module) + .addModule(new Jdk8Module()) + .build(); + + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + } + + + @Override + public T deserialized(String serialization, Class type) { + T instance = null; + try { + instance = mapper.readValue(serialization, type); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return instance; + } + + @Override + public T deserialized(String serialization, Type type) { + T instance = null; + try { + instance = mapper.readValue(serialization, mapper.constructType(type)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return instance; + } + + @Override + public List deserializedList(String serialization, Type listOfType) { + List list = null; + try { + list = mapper.readValue(serialization, mapper.constructType(listOfType)); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return list; + } + + @Override + public String serialized(Object instance) { + String serialization = null; + try { + serialization = mapper.writeValueAsString(instance); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return serialization; + } + + @Override + public String serialized(Collection instance) { + String serialization = null; + try { + serialization = mapper.writeValueAsString(instance); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return serialization; + } + + @Override + public String serialized(List instance) { + String serialization = null; + try { + serialization = mapper.writeValueAsString(instance); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return serialization; + } + + private static class DateJacksonSerializer extends StdSerializer { + + public DateJacksonSerializer() { + this(null); + } + + public DateJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize( + Date value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + jgen.writeString(Long.toString(value.getTime())); + } + } + + private static class DateJacksonDeserializer extends StdDeserializer { + + public DateJacksonDeserializer() { + this(null); + } + + public DateJacksonDeserializer(Class t) { + super(t); + } + + @Override + public Date deserialize(com.fasterxml.jackson.core.JsonParser p, DeserializationContext ctxt) throws IOException { + long time = Long.parseLong(p.getValueAsString()); + return new Date(time); + } + } + + private static class LocalDateJacksonSerializer extends StdSerializer { + + public LocalDateJacksonSerializer() { + this(null); + } + + public LocalDateJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize( + LocalDate value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + jgen.writeString(Long.toString(value.toEpochDay())); + } + } + + private static class LocalDateJacksonDeserializer extends StdDeserializer { + + public LocalDateJacksonDeserializer() { + this(null); + } + + public LocalDateJacksonDeserializer(Class t) { + super(t); + } + + @Override + public LocalDate deserialize(com.fasterxml.jackson.core.JsonParser p, DeserializationContext ctxt) throws IOException { + + if (isNumericString(p.getValueAsString())) { + final long epochDay = Long.parseLong(p.getValueAsString()); + return LocalDate.ofEpochDay(epochDay); + } + + return LocalDate.parse(p.getValueAsString()); + + } + } + + private static class LocalDateTimeJacksonSerializer extends StdSerializer { + + public LocalDateTimeJacksonSerializer() { + this(null); + } + + public LocalDateTimeJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize( + LocalDateTime value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + jgen.writeString(Long.toString(value.atZone(ZoneOffset.UTC).toInstant().toEpochMilli())); + } + } + + private static class LocalDateTimeJacksonDeserializer extends StdDeserializer { + + public LocalDateTimeJacksonDeserializer() { + this(null); + } + + public LocalDateTimeJacksonDeserializer(Class t) { + super(t); + } + + @Override + public LocalDateTime deserialize(com.fasterxml.jackson.core.JsonParser p, DeserializationContext ctxt) throws IOException { + + if (isNumericString(p.getValueAsString())) { + final long milli = Long.parseLong(p.getValueAsString()); + return LocalDateTime.ofInstant(Instant.ofEpochMilli(milli), ZoneOffset.UTC); + } + + return LocalDateTime.parse(p.getValueAsString()); + } + } + + private static class OffsetDateTimeJacksonSerializer extends StdSerializer { + + public OffsetDateTimeJacksonSerializer() { + this(null); + } + + public OffsetDateTimeJacksonSerializer(Class t) { + super(t); + } + + @Override + public void serialize( + OffsetDateTime value, JsonGenerator jgen, SerializerProvider provider) + throws IOException { + jgen.writeString(value.toInstant().toEpochMilli() + ";" + value.getOffset().toString()); + } + } + + private static class OffsetDateTimeJacksonDeserializer extends StdDeserializer { + + public OffsetDateTimeJacksonDeserializer() { + this(null); + } + + public OffsetDateTimeJacksonDeserializer(Class t) { + super(t); + } + + @Override + public OffsetDateTime deserialize(com.fasterxml.jackson.core.JsonParser p, DeserializationContext ctxt) throws IOException { + final String[] encoding = p.getValueAsString().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(); + } +} diff --git a/src/main/java/io/vlingo/xoom/common/serialization/JsonSerialization.java b/src/main/java/io/vlingo/xoom/common/serialization/JsonSerialization.java index a849928..1c241cc 100644 --- a/src/main/java/io/vlingo/xoom/common/serialization/JsonSerialization.java +++ b/src/main/java/io/vlingo/xoom/common/serialization/JsonSerialization.java @@ -7,9 +7,20 @@ package io.vlingo.xoom.common.serialization; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.google.gson.*; import com.google.gson.reflect.TypeToken; +import java.io.IOException; import java.lang.reflect.Type; import java.time.*; import java.util.Collection; @@ -18,143 +29,36 @@ import java.util.regex.Pattern; public class JsonSerialization { - private final static Gson gson; - private final static Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); + public final static Pattern PATTERN = Pattern.compile("-?\\d+(\\.\\d+)?"); - static { - gson = new GsonBuilder() - .registerTypeAdapter(Class.class, new ClassSerializer()) - .registerTypeAdapter(Class.class, new ClassDeserializer()) - .registerTypeAdapter(Date.class, new DateSerializer()) - .registerTypeAdapter(Date.class, new DateDeserializer()) - .registerTypeAdapter(LocalDate.class, new LocalDateSerializer()) - .registerTypeAdapter(LocalDate.class, new LocalDateDeserializer()) - .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeSerializer()) - .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeDeserializer()) - .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeSerializer()) - .registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeDeserializer()) - .create(); - } - - public static T deserialized(String serialization, final Class type) { - T instance = gson.fromJson(serialization, type); - return instance; - } - - public static T deserialized(String serialization, final Type type) { - T instance = gson.fromJson(serialization, type); - return instance; - } - - public static List deserializedList(String serialization, final Type listOfType) { - final List list = gson.fromJson(serialization, listOfType); - return list; - } - - public static String serialized(final Object instance) { - final String serialization = gson.toJson(instance); - return serialization; - } - - public static String serialized(final Collection instance) { - final Type collectionOfT = new TypeToken>() {}.getType(); - final String serialization = gson.toJson(instance, collectionOfT); - return serialization; - } - - public static String serialized(final List instance) { - final Type listOfT = new TypeToken>() {}.getType(); - final String serialization = gson.toJson(instance, listOfT); - return serialization; - } - - @SuppressWarnings("rawtypes") - private static class ClassSerializer implements JsonSerializer { - @Override - public JsonElement serialize(Class source, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(source.getName()); + public static void setEngine(JsonSerializationEngine engine) { + JsonSerialization.engine = engine; } - } - @SuppressWarnings("rawtypes") - private static class ClassDeserializer implements JsonDeserializer { - @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 { - @Override - public JsonElement serialize(Date source, Type typeOfSource, JsonSerializationContext context) { - return new JsonPrimitive(Long.toString(source.getTime())); - } - } + private static JsonSerializationEngine engine = new GsonJsonSerialization(); - private static class DateDeserializer implements JsonDeserializer { - @Override - public Date deserialize(JsonElement json, Type typeOfTarget, JsonDeserializationContext context) throws JsonParseException { - long time = Long.parseLong(json.getAsJsonPrimitive().getAsString()); - return new Date(time); + public static T deserialized(String serialization, final Class type) { + return engine.deserialized(serialization, type); } - } - private static class LocalDateSerializer implements JsonSerializer { - public JsonElement serialize(LocalDate source, Type typeOfSource, JsonSerializationContext context) { - return new JsonPrimitive(Long.toString(source.toEpochDay())); + public static T deserialized(String serialization, final Type type) { + return engine.deserialized(serialization, type); } - } - - private static class LocalDateDeserializer implements JsonDeserializer { - 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()); + public static List deserializedList(String serialization, final Type listOfType) { + return engine.deserializedList(serialization, listOfType); } - } - - private static class LocalDateTimeSerializer implements JsonSerializer { - 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 { - 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()); + public static String serialized(final Object instance) { + return engine.serialized(instance); } - } - private static class OffsetDateTimeSerializer implements JsonSerializer { - @Override - public JsonElement serialize(OffsetDateTime source, Type typeOfSource, JsonSerializationContext context) { - return new JsonPrimitive(source.toInstant().toEpochMilli() + ";" + source.getOffset().toString()); + public static String serialized(final Collection instance) { + return engine.serialized(instance); } - } - private static class OffsetDateTimeDeserializer implements JsonDeserializer { - @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])); + public static String serialized(final List instance) { + return engine.serialized(instance); } - } - private static boolean isNumericString(String element) { - return pattern.matcher(element).matches(); - } } diff --git a/src/main/java/io/vlingo/xoom/common/serialization/JsonSerializationEngine.java b/src/main/java/io/vlingo/xoom/common/serialization/JsonSerializationEngine.java new file mode 100644 index 0000000..b8cd2c5 --- /dev/null +++ b/src/main/java/io/vlingo/xoom/common/serialization/JsonSerializationEngine.java @@ -0,0 +1,19 @@ +package io.vlingo.xoom.common.serialization; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.List; + +public interface JsonSerializationEngine { + T deserialized(String serialization, Class type); + + T deserialized(String serialization, Type type); + + List deserializedList(String serialization, Type listOfType); + + String serialized(Object instance); + + String serialized(Collection instance); + + String serialized(List instance); +} diff --git a/src/test/java/io/vlingo/xoom/common/serialization/JsonSerializationTest.java b/src/test/java/io/vlingo/xoom/common/serialization/JsonSerializationTest.java index bda1787..e4190ec 100644 --- a/src/test/java/io/vlingo/xoom/common/serialization/JsonSerializationTest.java +++ b/src/test/java/io/vlingo/xoom/common/serialization/JsonSerializationTest.java @@ -1,6 +1,10 @@ package io.vlingo.xoom.common.serialization; +import com.fasterxml.jackson.core.JsonProcessingException; import com.google.gson.reflect.TypeToken; +import io.vlingo.xoom.common.Completes; +import io.vlingo.xoom.common.completes.FutureCompletes; +import org.junit.Ignore; import org.junit.Test; import java.lang.reflect.Type; @@ -9,109 +13,118 @@ import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.util.*; +import java.util.function.Consumer; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class JsonSerializationTest { + void executeJsonTest(Runnable assertFunction){ + JsonSerialization.setEngine(new JacksonJsonSerialization()); + assertFunction.run(); + JsonSerialization.setEngine(new GsonJsonSerialization()); + assertFunction.run(); + } + @Test public void canSerializeAString() { - assertEquals("\"some text\"", JsonSerialization.serialized("some text")); + executeJsonTest(() -> assertEquals("\"some text\"", JsonSerialization.serialized("some text"))); } @Test public void canDeserializeAString() { - assertEquals("some text", JsonSerialization.deserialized("\"some text\"", String.class)); - assertEquals("some text", JsonSerialization.deserialized("\"some text\"", (Type) String.class)); + executeJsonTest(() -> assertEquals("some text", JsonSerialization.deserialized("\"some text\"", String.class))); + executeJsonTest(() -> assertEquals("some text", JsonSerialization.deserialized("\"some text\"", (Type) String.class))); } @Test public void canSerializeAnInt() { - assertEquals("5", JsonSerialization.serialized(5)); + executeJsonTest(() -> assertEquals("5", JsonSerialization.serialized(5))); } @Test public void canDeserializeAnInt() { - assertEquals(5, (int) JsonSerialization.deserialized("5", Integer.TYPE)); - assertEquals(5, (int) JsonSerialization.deserialized("5", (Type) Integer.TYPE)); + executeJsonTest(() -> assertEquals(5, (int) JsonSerialization.deserialized("5", Integer.TYPE))); + executeJsonTest(() -> assertEquals(5, (int) JsonSerialization.deserialized("5", (Type) Integer.TYPE))); } @Test public void canSerializeTestObject() { - assertEquals("{\"myString\":\"the string\",\"myInt\":6}", JsonSerialization.serialized(new TestObject("the string", 6))); + executeJsonTest(() -> assertEquals("{\"myString\":\"the string\",\"myInt\":6}", JsonSerialization.serialized(new TestObject("the string", 6)))); } @Test public void canDeserializeTestObject() { - assertEquals(new TestObject("the string", 6), JsonSerialization.deserialized("{\"myString\":\"the string\",\"myInt\":6}", TestObject.class)); - assertEquals(new TestObject("the string", 6), JsonSerialization.deserialized("{\"myString\":\"the string\",\"myInt\":6}", (Type) TestObject.class)); + executeJsonTest(() -> assertEquals(new TestObject("the string", 6), JsonSerialization.deserialized("{\"myString\":\"the string\",\"myInt\":6}", TestObject.class))); + executeJsonTest(() -> assertEquals(new TestObject("the string", 6), JsonSerialization.deserialized("{\"myString\":\"the string\",\"myInt\":6}", (Type) TestObject.class))); } @Test public void canSerializeAClass() { - assertEquals("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", JsonSerialization.serialized(TestObject.class)); + executeJsonTest(() -> assertEquals("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", JsonSerialization.serialized(TestObject.class))); } @Test public void canDeserializeAClass() { - assertEquals(TestObject.class, JsonSerialization.deserialized("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", Class.class)); - assertEquals(TestObject.class, JsonSerialization.deserialized("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", (Type) Class.class)); + executeJsonTest(() -> assertEquals(TestObject.class, JsonSerialization.deserialized("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", Class.class))); + executeJsonTest(() -> assertEquals(TestObject.class, JsonSerialization.deserialized("\"io.vlingo.xoom.common.serialization.JsonSerializationTest$TestObject\"", (Type) Class.class))); } @Test public void canSerializeADate() { - assertEquals("\"61598790000000\"", JsonSerialization.serialized(new Date(2021, 11, 28))); + executeJsonTest(() -> assertEquals("\"61598790000000\"", JsonSerialization.serialized(new Date(2021, 11, 28)))); } @Test public void canDeserializeADate() { - assertEquals(new Date(2021, 11, 28), JsonSerialization.deserialized("\"61598790000000\"", Date.class)); - assertEquals(new Date(2021, 11, 28), JsonSerialization.deserialized("\"61598790000000\"", (Type) Date.class)); + executeJsonTest(() -> assertEquals(new Date(2021, 11, 28), JsonSerialization.deserialized("\"61598790000000\"", Date.class))); + executeJsonTest(() -> assertEquals(new Date(2021, 11, 28), JsonSerialization.deserialized("\"61598790000000\"", (Type) Date.class))); } @Test public void canSerializeLocalDate() { - assertEquals("\"18959\"", JsonSerialization.serialized(LocalDate.of(2021, 11, 28))); + executeJsonTest(() -> assertEquals("\"18959\"", JsonSerialization.serialized(LocalDate.of(2021, 11, 28)))); } @Test public void canDeserializeLocalDate() { - assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"18959\"", LocalDate.class)); - assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"18959\"", (Type) LocalDate.class)); + executeJsonTest(() -> assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"18959\"", LocalDate.class))); + executeJsonTest(() -> assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"18959\"", (Type) LocalDate.class))); } @Test public void canDeserializeLocalDateFromJson() { - assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("2021-11-28", LocalDate.class)); - assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("2021-11-28", (Type) LocalDate.class)); + executeJsonTest(() -> assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"2021-11-28\"", LocalDate.class))); + executeJsonTest(() -> assertEquals(LocalDate.of(2021, 11, 28), JsonSerialization.deserialized("\"2021-11-28\"", (Type) LocalDate.class))); } @Test public void canSerializeLocalDateTime() { - assertEquals("\"1638102780000\"", JsonSerialization.serialized(LocalDateTime.of(2021, 11, 28, 12, 33))); + executeJsonTest(() -> assertEquals("\"1638102780000\"", JsonSerialization.serialized(LocalDateTime.of(2021, 11, 28, 12, 33)))); } @Test public void canDeserializeLocalDateTime() { - assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33), JsonSerialization.deserialized("\"1638102780000\"", LocalDateTime.class)); - assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33), JsonSerialization.deserialized("\"1638102780000\"", (Type) LocalDateTime.class)); + executeJsonTest(() -> assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33), JsonSerialization.deserialized("\"1638102780000\"", LocalDateTime.class))); + executeJsonTest(() -> assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33), JsonSerialization.deserialized("\"1638102780000\"", (Type) LocalDateTime.class))); } @Test public void canDeserializeLocalDateTimeFromJson() { - assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33, 5), JsonSerialization.deserialized("\"2021-11-28T12:33:05\"", LocalDateTime.class)); - assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33, 5), JsonSerialization.deserialized("\"2021-11-28T12:33:05\"", (Type) LocalDateTime.class)); + executeJsonTest(() -> assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33, 5), JsonSerialization.deserialized("\"2021-11-28T12:33:05\"", LocalDateTime.class))); + executeJsonTest(() -> assertEquals(LocalDateTime.of(2021, 11, 28, 12, 33, 5), JsonSerialization.deserialized("\"2021-11-28T12:33:05\"", (Type) LocalDateTime.class))); } @Test public void canSerializeOffsetDateTime() { - assertEquals("\"1638095585000;+02:00\"", JsonSerialization.serialized(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 30, ZoneOffset.of("+02:00")))); + executeJsonTest(() -> assertEquals("\"1638095585000;+02:00\"", JsonSerialization.serialized(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 30, ZoneOffset.of("+02:00"))))); } @Test public void canDeserializeOffsetDateTime() { - assertEquals(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 00, ZoneOffset.of("+02:00")), JsonSerialization.deserialized("\"1638095585000;+02:00\"", OffsetDateTime.class)); - assertEquals(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 00, ZoneOffset.of("+02:00")), JsonSerialization.deserialized("\"1638095585000;+02:00\"", (Type) OffsetDateTime.class)); + executeJsonTest(() -> assertEquals(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 00, ZoneOffset.of("+02:00")), JsonSerialization.deserialized("\"1638095585000;+02:00\"", OffsetDateTime.class))); + executeJsonTest(() -> assertEquals(OffsetDateTime.of(2021, 11, 28, 12, 33, 05, 00, ZoneOffset.of("+02:00")), JsonSerialization.deserialized("\"1638095585000;+02:00\"", (Type) OffsetDateTime.class))); } @Test @@ -120,7 +133,7 @@ public void canSerializeAList() { list.add(new TestObject("text1", 1)); list.add(new TestObject("text2", 2)); list.add(new TestObject("text3", 3)); - assertEquals("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", JsonSerialization.serialized(list)); + executeJsonTest(() -> assertEquals("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", JsonSerialization.serialized(list))); } @Test @@ -129,7 +142,8 @@ public void canSerializeACollection() { list.add(new TestObject("text1", 1)); list.add(new TestObject("text2", 2)); list.add(new TestObject("text3", 3)); - assertEquals("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", JsonSerialization.serialized(list)); + executeJsonTest(() -> assertEquals("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", JsonSerialization.serialized(list))); + } @Test @@ -139,8 +153,25 @@ public void canDeserializeAList() { expectedList.add(new TestObject("text2", 2)); expectedList.add(new TestObject("text3", 3)); - assertEquals(expectedList, JsonSerialization.deserializedList("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", new TypeToken>() { - }.getType())); + executeJsonTest(() -> assertEquals(expectedList, JsonSerialization.deserializedList("[{\"myString\":\"text1\",\"myInt\":1},{\"myString\":\"text2\",\"myInt\":2},{\"myString\":\"text3\",\"myInt\":3}]", new TypeToken>() { + }.getType()))); + } + + @Test + @Ignore + public void canSerializeCompletes() { + JsonSerialization.setEngine(new GsonJsonSerialization()); + //assertEquals("{\"state\":{\"futureFactory\":{},\"future\":{\"value\":{\"result\":\"Success\"}},\"failed\":false,\"failureValue\":{},\"handlesFailure\":false,\"id\":{\"id\":\"1\"},\"outcome\":{\"value\":{}},\"outcomeType\":\"Some\",\"timedOut\":false,\"repeats\":false}}", JsonSerialization.serialized(Completes.withSuccess("Success"))); + JsonSerialization.setEngine(new JacksonJsonSerialization()); + //assertEquals("{\"state\":{\"futureFactory\":{},\"future\":{\"done\":true,\"numberOfDependents\":0,\"cancelled\":false,\"completedExceptionally\":false},\"failed\":false,\"failureValue\":null,\"handlesFailure\":false,\"id\":{\"id\":\"2\"},\"outcome\":{\"outcome\":\"Success\",\"completed\":true},\"outcomeType\":\"Some\",\"timedOut\":false,\"repeats\":false},\"completed\":true}", JsonSerialization.serialized(Completes.withSuccess("Success"))); + } + + @Test + @Ignore + public void canSerializeOptionals() { + // assertEquals("{\"myOpt\":\"test\",\"next\":null}", JsonSerialization.serialized(new MyOptional(Optional.of("test"), Optional.empty()))); + // assertEquals("{\"myOpt\":{\"value\":\"test\"},\"next\":{}}", JsonSerialization.serialized(new MyOptional(Optional.of("test"), Optional.empty()))); + } private static class TestObject { @@ -152,6 +183,8 @@ public TestObject(String myString, int myInt) { this.myInt = myInt; } + private TestObject() {} + @Override public boolean equals(Object o) { if (this == o) return true;