Add JsonSerializer example

This commit is contained in:
Thibaud Gasser 2019-01-02 19:45:55 +01:00
parent 35cc5abdf0
commit 07a463cbfe
8 changed files with 178 additions and 11 deletions

View File

@ -10,11 +10,16 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>lang</artifactId>
<properties>
<hamcrest-junit.version>2.0.0.0</hamcrest-junit.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
<version>${hamcrest-junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@ -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 "";
}

View File

@ -0,0 +1,7 @@
package annotations.jsonserializer;
class JsonSerializeException extends RuntimeException {
JsonSerializeException(String message) {
super(message);
}
}

View File

@ -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<SerializableField> serialize(Object o) {
return extractor.getSerializableFields(o);
}
String toJsonString(Set<SerializableField> jsonElements) {
String elementsString = jsonElements.stream()
.map(entry -> "\"" + entry.getName() + "\":\"" + entry.getValue() + "\"")
.collect(Collectors.joining(","));
return "{" + elementsString + "}";
}
}

View File

@ -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;
}
}

View File

@ -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<SerializableField> getSerializableFields(Object o) {
final Class<?> objectClass = o.getClass();
final Set<SerializableField> 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;
}
}

View File

@ -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(","));
}
}

View File

@ -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<SerializableField> jsonCar = serializer.serialize(car);
final Set<String> names = jsonCar.stream().map(SerializableField::getName).collect(Collectors.toSet());
final Set<String> 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;
}
}
}