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