From 5b83683c7df5f3de552b2d540c38f15d611543a3 Mon Sep 17 00:00:00 2001 From: slinkydeveloper Date: Thu, 11 Apr 2019 13:41:13 +0200 Subject: [PATCH] JsonCodecLoader experiment Signed-off-by: slinkydeveloper --- .../io/vertx/core/json/JsonCodecLoader.java | 45 ++++++++++++++++ .../java/io/vertx/core/json/JsonDecoder.java | 2 + .../java/io/vertx/core/json/JsonEncoder.java | 2 + .../vertx/core/json/JsonCodecLoaderTest.java | 35 +++++++++++++ .../vertx/core/json/codecs/MyBooleanPojo.java | 50 ++++++++++++++++++ .../io/vertx/core/json/codecs/MyCharPojo.java | 50 ++++++++++++++++++ .../vertx/core/json/codecs/MyDoublePojo.java | 50 ++++++++++++++++++ .../vertx/core/json/codecs/MyFloatPojo.java | 50 ++++++++++++++++++ .../vertx/core/json/codecs/MyIntegerPojo.java | 50 ++++++++++++++++++ .../core/json/codecs/MyJsonArrayPojo.java | 52 +++++++++++++++++++ .../core/json/codecs/MyJsonObjectPojo.java | 51 ++++++++++++++++++ .../io/vertx/core/json/codecs/MyLongPojo.java | 50 ++++++++++++++++++ .../vertx/core/json/codecs/MyShortPojo.java | 50 ++++++++++++++++++ .../services/io.vertx.core.json.JsonCodec | 9 ++++ 14 files changed, 546 insertions(+) create mode 100644 src/main/java/io/vertx/core/json/JsonCodecLoader.java create mode 100644 src/test/java/io/vertx/core/json/JsonCodecLoaderTest.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyBooleanPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyCharPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyDoublePojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyFloatPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyIntegerPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyJsonArrayPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyJsonObjectPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyLongPojo.java create mode 100644 src/test/java/io/vertx/core/json/codecs/MyShortPojo.java create mode 100644 src/test/resources/META-INF/services/io.vertx.core.json.JsonCodec diff --git a/src/main/java/io/vertx/core/json/JsonCodecLoader.java b/src/main/java/io/vertx/core/json/JsonCodecLoader.java new file mode 100644 index 000000000..e26518a9e --- /dev/null +++ b/src/main/java/io/vertx/core/json/JsonCodecLoader.java @@ -0,0 +1,45 @@ +package io.vertx.core.json; + +import io.vertx.core.buffer.Buffer; + +import java.util.HashMap; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.function.Function; + +public class JsonCodecLoader { + + Map jsonCodecMap; + + private JsonCodecLoader(Map jsonCodecMap) { + this.jsonCodecMap = jsonCodecMap; + } + + public static JsonCodecLoader loadCodecsFromSPI() { + Map codecs = new HashMap<>(); + ServiceLoader codecServiceLoader = ServiceLoader.load(JsonCodec.class); + for (JsonCodec j : codecServiceLoader) { + codecs.put(j.getTargetClass(), j); + } + return new JsonCodecLoader(codecs); + } + + @SuppressWarnings("unchecked") + public T decode(Buffer value, Class c) { + Object json = value.toJson(); + try { + return (T) jsonCodecMap.get(c).decode(json); + } catch (Exception e) { + throw new IllegalStateException("Unable to find codec for class " + c.getCanonicalName(), e); + } + } + + @SuppressWarnings("unchecked") + public Buffer encode(Object value) { + try { + return Buffer.buffer(jsonCodecMap.get(value.getClass()).encode(value).toString()); + } catch (Exception e) { + throw new IllegalStateException("Unable to find codec for class " + value.getClass().getCanonicalName(), e); + } + } +} diff --git a/src/main/java/io/vertx/core/json/JsonDecoder.java b/src/main/java/io/vertx/core/json/JsonDecoder.java index c9bbf7685..bfed61838 100644 --- a/src/main/java/io/vertx/core/json/JsonDecoder.java +++ b/src/main/java/io/vertx/core/json/JsonDecoder.java @@ -16,4 +16,6 @@ public interface JsonDecoder { * @throws IllegalArgumentException when it cannot decode the value */ TARGET_TYPE decode(JSON_TYPE value) throws IllegalArgumentException; + + Class getTargetClass(); } diff --git a/src/main/java/io/vertx/core/json/JsonEncoder.java b/src/main/java/io/vertx/core/json/JsonEncoder.java index 868d87241..513d1b49a 100644 --- a/src/main/java/io/vertx/core/json/JsonEncoder.java +++ b/src/main/java/io/vertx/core/json/JsonEncoder.java @@ -16,4 +16,6 @@ public interface JsonEncoder { * @throws IllegalArgumentException when it cannot encode the value */ JSON_TYPE encode(TARGET_TYPE value) throws IllegalArgumentException; + + Class getTargetClass(); } diff --git a/src/test/java/io/vertx/core/json/JsonCodecLoaderTest.java b/src/test/java/io/vertx/core/json/JsonCodecLoaderTest.java new file mode 100644 index 000000000..d447d033f --- /dev/null +++ b/src/test/java/io/vertx/core/json/JsonCodecLoaderTest.java @@ -0,0 +1,35 @@ +package io.vertx.core.json; + +import io.vertx.core.buffer.Buffer; +import io.vertx.core.json.codecs.MyBooleanPojo; +import io.vertx.core.json.codecs.MyCharPojo; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class JsonCodecLoaderTest { + + JsonCodecLoader jsonCodecLoader; + + @Before + public void setUp() throws Exception { + this.jsonCodecLoader = JsonCodecLoader.loadCodecsFromSPI(); + } + + @Test + public void booleanCodecTest() { + MyBooleanPojo pojo = new MyBooleanPojo(); + pojo.setValue(true); + assertEquals(Buffer.buffer("true"), jsonCodecLoader.encode(pojo)); + assertEquals(pojo, jsonCodecLoader.decode(Buffer.buffer("true"), MyBooleanPojo.class)); + } + + @Test + public void charCodecTest() { + MyCharPojo pojo = new MyCharPojo(); + pojo.setValue('a'); + assertEquals('a', jsonCodecLoader.decode(Buffer.buffer(new byte[] {(byte)'a'}), MyCharPojo.class)); + } + +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyBooleanPojo.java b/src/test/java/io/vertx/core/json/codecs/MyBooleanPojo.java new file mode 100644 index 000000000..c72b74532 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyBooleanPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyBooleanPojo { + + public static class MyBooleanPojoJsonCodec implements JsonCodec { + + @Override + public MyBooleanPojo decode(Boolean value) throws IllegalArgumentException { + return new MyBooleanPojo().setValue(value); + } + + @Override + public Boolean encode(MyBooleanPojo value) throws IllegalArgumentException { + return value.isValue(); + } + + @Override + public Class getTargetClass() { + return MyBooleanPojo.class; + } + } + + boolean value; + + public boolean isValue() { + return value; + } + + public MyBooleanPojo setValue(boolean value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyBooleanPojo that = (MyBooleanPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyCharPojo.java b/src/test/java/io/vertx/core/json/codecs/MyCharPojo.java new file mode 100644 index 000000000..6a6034b16 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyCharPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyCharPojo { + + public static class MyCharPojoJsonCodec implements JsonCodec { + + @Override + public MyCharPojo decode(Character value) throws IllegalArgumentException { + return new MyCharPojo().setValue(value); + } + + @Override + public Character encode(MyCharPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyCharPojo.class; + } + } + + char value; + + public char getValue() { + return value; + } + + public MyCharPojo setValue(char value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyCharPojo that = (MyCharPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyDoublePojo.java b/src/test/java/io/vertx/core/json/codecs/MyDoublePojo.java new file mode 100644 index 000000000..cd4d22342 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyDoublePojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyDoublePojo { + + public static class MyDoublePojoJsonCodec implements JsonCodec { + + @Override + public MyDoublePojo decode(Double value) throws IllegalArgumentException { + return new MyDoublePojo().setValue(value); + } + + @Override + public Double encode(MyDoublePojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyDoublePojo.class; + } + } + + double value; + + public double getValue() { + return value; + } + + public MyDoublePojo setValue(double value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyDoublePojo that = (MyDoublePojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyFloatPojo.java b/src/test/java/io/vertx/core/json/codecs/MyFloatPojo.java new file mode 100644 index 000000000..f08004c20 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyFloatPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyFloatPojo { + + public static class MyFloatPojoJsonCodec implements JsonCodec { + + @Override + public MyFloatPojo decode(Float value) throws IllegalArgumentException { + return new MyFloatPojo().setValue(value); + } + + @Override + public Float encode(MyFloatPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyFloatPojo.class; + } + } + + float value; + + public float getValue() { + return value; + } + + public MyFloatPojo setValue(float value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyFloatPojo that = (MyFloatPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyIntegerPojo.java b/src/test/java/io/vertx/core/json/codecs/MyIntegerPojo.java new file mode 100644 index 000000000..b3bf0e284 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyIntegerPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyIntegerPojo { + + public static class MyIntegerPojoJsonCodec implements JsonCodec { + + @Override + public MyIntegerPojo decode(Integer value) throws IllegalArgumentException { + return new MyIntegerPojo().setValue(value); + } + + @Override + public Integer encode(MyIntegerPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyIntegerPojo.class; + } + } + + int value; + + public int getValue() { + return value; + } + + public MyIntegerPojo setValue(int value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyIntegerPojo that = (MyIntegerPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyJsonArrayPojo.java b/src/test/java/io/vertx/core/json/codecs/MyJsonArrayPojo.java new file mode 100644 index 000000000..843bcb5ae --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyJsonArrayPojo.java @@ -0,0 +1,52 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; +import io.vertx.core.json.JsonArray; + +import java.util.Arrays; +import java.util.Objects; + +public class MyJsonArrayPojo { + + public static class MyJsonArrayPojoJsonCodec implements JsonCodec { + + @Override + public MyJsonArrayPojo decode(JsonArray value) throws IllegalArgumentException { + return new MyJsonArrayPojo().setValue(value); + } + + @Override + public JsonArray encode(MyJsonArrayPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyJsonArrayPojo.class; + } + } + + JsonArray value; + + public JsonArray getValue() { + return value; + } + + public MyJsonArrayPojo setValue(JsonArray value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyJsonArrayPojo that = (MyJsonArrayPojo) o; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyJsonObjectPojo.java b/src/test/java/io/vertx/core/json/codecs/MyJsonObjectPojo.java new file mode 100644 index 000000000..8f717754b --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyJsonObjectPojo.java @@ -0,0 +1,51 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; +import io.vertx.core.json.JsonObject; + +import java.util.Objects; + +public class MyJsonObjectPojo { + + public static class MyJsonObjectPojoJsonCodec implements JsonCodec { + + @Override + public MyJsonObjectPojo decode(JsonObject value) throws IllegalArgumentException { + return new MyJsonObjectPojo().setValue(value); + } + + @Override + public JsonObject encode(MyJsonObjectPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyJsonObjectPojo.class; + } + } + + JsonObject value; + + public JsonObject getValue() { + return value; + } + + public MyJsonObjectPojo setValue(JsonObject value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyJsonObjectPojo that = (MyJsonObjectPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyLongPojo.java b/src/test/java/io/vertx/core/json/codecs/MyLongPojo.java new file mode 100644 index 000000000..f694ddf3e --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyLongPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyLongPojo { + + public static class MyLongPojoJsonCodec implements JsonCodec { + + @Override + public MyLongPojo decode(Long value) throws IllegalArgumentException { + return new MyLongPojo().setValue(value); + } + + @Override + public Long encode(MyLongPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyLongPojo.class; + } + } + + long value; + + public long getValue() { + return value; + } + + public MyLongPojo setValue(long value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyLongPojo that = (MyLongPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/java/io/vertx/core/json/codecs/MyShortPojo.java b/src/test/java/io/vertx/core/json/codecs/MyShortPojo.java new file mode 100644 index 000000000..7741294d0 --- /dev/null +++ b/src/test/java/io/vertx/core/json/codecs/MyShortPojo.java @@ -0,0 +1,50 @@ +package io.vertx.core.json.codecs; + +import io.vertx.core.json.JsonCodec; + +import java.util.Objects; + +public class MyShortPojo { + + public static class MyShortPojoJsonCodec implements JsonCodec { + + @Override + public MyShortPojo decode(Short value) throws IllegalArgumentException { + return new MyShortPojo().setValue(value); + } + + @Override + public Short encode(MyShortPojo value) throws IllegalArgumentException { + return value.getValue(); + } + + @Override + public Class getTargetClass() { + return MyShortPojo.class; + } + } + + short value; + + public short getValue() { + return value; + } + + public MyShortPojo setValue(short value) { + this.value = value; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MyShortPojo that = (MyShortPojo) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hash(value); + } +} diff --git a/src/test/resources/META-INF/services/io.vertx.core.json.JsonCodec b/src/test/resources/META-INF/services/io.vertx.core.json.JsonCodec new file mode 100644 index 000000000..1f061e04f --- /dev/null +++ b/src/test/resources/META-INF/services/io.vertx.core.json.JsonCodec @@ -0,0 +1,9 @@ +io.vertx.core.json.codecs.MyBooleanPojo$MyBooleanPojoJsonCodec +io.vertx.core.json.codecs.MyCharPojo$MyCharPojoJsonCodec +io.vertx.core.json.codecs.MyDoublePojo$MyDoublePojoJsonCodec +io.vertx.core.json.codecs.MyFloatPojo$MyFloatPojoJsonCodec +io.vertx.core.json.codecs.MyIntegerPojo$MyIntegerPojoJsonCodec +io.vertx.core.json.codecs.MyJsonArrayPojo$MyJsonArrayPojoJsonCodec +io.vertx.core.json.codecs.MyJsonObjectPojo$MyJsonObjectPojoJsonCodec +io.vertx.core.json.codecs.MyLongPojo$MyLongPojoJsonCodec +io.vertx.core.json.codecs.MyShortPojo$MyShortPojoJsonCodec