From 07a463cbfe330aea813c3f2e9c004c1d342c33d2 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Wed, 2 Jan 2019 19:45:55 +0100 Subject: [PATCH] Add JsonSerializer example --- lang/pom.xml | 11 +++- lang/src/main/java/annotations/JsonField.java | 12 ++++ .../JsonSerializeException.java | 7 ++ .../jsonserializer/JsonSerializer.java | 28 ++++++++ .../jsonserializer/SerializableField.java | 19 ++++++ .../SerializableFieldExtractor.java | 32 ++++++++++ .../main/java/patternmatching/Statistics.java | 16 ++--- .../jsonserializer/JsonSerializerTest.java | 64 +++++++++++++++++++ 8 files changed, 178 insertions(+), 11 deletions(-) create mode 100644 lang/src/main/java/annotations/JsonField.java create mode 100644 lang/src/main/java/annotations/jsonserializer/JsonSerializeException.java create mode 100644 lang/src/main/java/annotations/jsonserializer/JsonSerializer.java create mode 100644 lang/src/main/java/annotations/jsonserializer/SerializableField.java create mode 100644 lang/src/main/java/annotations/jsonserializer/SerializableFieldExtractor.java create mode 100644 lang/src/test/java/annotations/jsonserializer/JsonSerializerTest.java diff --git a/lang/pom.xml b/lang/pom.xml index f52cbd7..4afb70a 100644 --- a/lang/pom.xml +++ b/lang/pom.xml @@ -10,11 +10,16 @@ 4.0.0 lang + + + 2.0.0.0 + + - junit - junit - 4.12 + org.hamcrest + hamcrest-junit + ${hamcrest-junit.version} test diff --git a/lang/src/main/java/annotations/JsonField.java b/lang/src/main/java/annotations/JsonField.java new file mode 100644 index 0000000..1aada72 --- /dev/null +++ b/lang/src/main/java/annotations/JsonField.java @@ -0,0 +1,12 @@ +package annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface JsonField { + String value() default ""; +} diff --git a/lang/src/main/java/annotations/jsonserializer/JsonSerializeException.java b/lang/src/main/java/annotations/jsonserializer/JsonSerializeException.java new file mode 100644 index 0000000..5f2abea --- /dev/null +++ b/lang/src/main/java/annotations/jsonserializer/JsonSerializeException.java @@ -0,0 +1,7 @@ +package annotations.jsonserializer; + +class JsonSerializeException extends RuntimeException { + JsonSerializeException(String message) { + super(message); + } +} diff --git a/lang/src/main/java/annotations/jsonserializer/JsonSerializer.java b/lang/src/main/java/annotations/jsonserializer/JsonSerializer.java new file mode 100644 index 0000000..0e519b4 --- /dev/null +++ b/lang/src/main/java/annotations/jsonserializer/JsonSerializer.java @@ -0,0 +1,28 @@ +package annotations.jsonserializer; + +import java.util.Set; +import java.util.stream.Collectors; + +class JsonSerializer { + + private final SerializableFieldExtractor extractor; + + JsonSerializer(SerializableFieldExtractor extractor) { + this.extractor = extractor; + } + + String serializeToString(Object o) { + return toJsonString(serialize(o)); + } + + Set serialize(Object o) { + return extractor.getSerializableFields(o); + } + + String toJsonString(Set jsonElements) { + String elementsString = jsonElements.stream() + .map(entry -> "\"" + entry.getName() + "\":\"" + entry.getValue() + "\"") + .collect(Collectors.joining(",")); + return "{" + elementsString + "}"; + } +} diff --git a/lang/src/main/java/annotations/jsonserializer/SerializableField.java b/lang/src/main/java/annotations/jsonserializer/SerializableField.java new file mode 100644 index 0000000..9c9dc92 --- /dev/null +++ b/lang/src/main/java/annotations/jsonserializer/SerializableField.java @@ -0,0 +1,19 @@ +package annotations.jsonserializer; + +class SerializableField { + private final String name; + private final String value; + + SerializableField(String name, String value) { + this.name = name; + this.value = value; + } + + String getName() { + return name; + } + + String getValue() { + return value; + } +} diff --git a/lang/src/main/java/annotations/jsonserializer/SerializableFieldExtractor.java b/lang/src/main/java/annotations/jsonserializer/SerializableFieldExtractor.java new file mode 100644 index 0000000..d2f4324 --- /dev/null +++ b/lang/src/main/java/annotations/jsonserializer/SerializableFieldExtractor.java @@ -0,0 +1,32 @@ +package annotations.jsonserializer; + +import annotations.JsonField; + +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; + +class SerializableFieldExtractor { + + Set getSerializableFields(Object o) { + final Class objectClass = o.getClass(); + final Set jsonElements = new HashSet<>(); + try { + for (Field field : objectClass.getDeclaredFields()) { + field.setAccessible(true); + if (field.isAnnotationPresent(JsonField.class)) { + jsonElements.add(new SerializableField(getSerializableField(field), (String) field.get(o))); + } + + } + return jsonElements; + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { + throw new JsonSerializeException(e.getMessage()); + } + } + + private String getSerializableField(Field field) { + final String annotationValue = field.getAnnotation(JsonField.class).value(); + return annotationValue.isEmpty() ? field.getName() : annotationValue; + } +} \ No newline at end of file diff --git a/lang/src/main/java/patternmatching/Statistics.java b/lang/src/main/java/patternmatching/Statistics.java index 5e4187c..317a977 100644 --- a/lang/src/main/java/patternmatching/Statistics.java +++ b/lang/src/main/java/patternmatching/Statistics.java @@ -1,6 +1,5 @@ package patternmatching; -import java.io.FileNotFoundException; import java.util.Arrays; import java.util.stream.Collectors; @@ -14,7 +13,7 @@ public final class Statistics { this.data = data; } - double getMean() { + private double getMean() { if (mean == null) { mean = (double) Arrays.stream(data).sum() / data.length; } @@ -22,7 +21,7 @@ public final class Statistics { return mean; } - double getVariance() { + private double getVariance() { if (variance == null) { final double mean = getMean(); double temp = 0; @@ -35,11 +34,11 @@ public final class Statistics { return variance; } - double getStddev() { + private double getStddev() { return Math.sqrt(getVariance()); } - double getMedian() { + private double getMedian() { Arrays.sort(data); if (data.length % 2 == 0) return (data[(data.length / 2) - 1] + data[data.length / 2]) / 2.0; return data[data.length / 2]; @@ -59,8 +58,9 @@ public final class Statistics { ); } - public String asCSv() { - final String csv = Arrays.stream(data).mapToObj(String::valueOf).collect(Collectors.joining(",")); - return csv; + String asCSv() { + return Arrays.stream(data) + .mapToObj(String::valueOf) + .collect(Collectors.joining(",")); } } diff --git a/lang/src/test/java/annotations/jsonserializer/JsonSerializerTest.java b/lang/src/test/java/annotations/jsonserializer/JsonSerializerTest.java new file mode 100644 index 0000000..4449dac --- /dev/null +++ b/lang/src/test/java/annotations/jsonserializer/JsonSerializerTest.java @@ -0,0 +1,64 @@ +package annotations.jsonserializer; + +import annotations.JsonField; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Set; +import java.util.stream.Collectors; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; + +public class JsonSerializerTest { + + private final Logger logger = LoggerFactory.getLogger(getClass().getCanonicalName()); + + @Test(expected = NullPointerException.class) + public void serializeNullObjectEnsureNullPointerExceptionThrown() { + new JsonSerializer(new SerializableFieldExtractor()).serialize(null); + } + + @Test + public void testSerialize() { + final Car car = new Car(); + JsonSerializer serializer = new JsonSerializer(new SerializableFieldExtractor()); + final Set jsonCar = serializer.serialize(car); + final Set names = jsonCar.stream().map(SerializableField::getName).collect(Collectors.toSet()); + final Set values = jsonCar.stream().map(SerializableField::getValue).collect(Collectors.toSet()); + assertThat(names, containsInAnyOrder("model", "manufacturer")); + assertThat(values, containsInAnyOrder("Ford", "F150")); + logger.info(serializer.toJsonString(jsonCar)); + } + + @Test + public void testSerializeToString() { + final Car car = new Car(); + JsonSerializer serializer = new JsonSerializer(new SerializableFieldExtractor()); + final String jsonString = serializer.serializeToString(car); + assertThat(jsonString, containsString("\"manufacturer\":\"Ford\"")); + assertThat(jsonString, containsString("\"model\":\"F150\"")); + } + + private static class Car { + @JsonField("manufacturer") + private final String make; + @JsonField + private final String model; + private final String year; + + Car() { + this.make = "Ford"; + this.model = "F150"; + this.year = "2018"; + } + + @Override + public String toString() { + return year + " " + make + " " + model; + } + } + +} \ No newline at end of file