diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/Init.java b/core-java-8/src/main/java/com/baeldung/customannotations/Init.java new file mode 100644 index 0000000000..265e7ba1d6 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/Init.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(METHOD) +public @interface Init { + +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java new file mode 100644 index 0000000000..e41a5b1e30 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonElement.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({ FIELD }) +public @interface JsonElement { + public String key() default ""; +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java new file mode 100644 index 0000000000..48eeb09a1b --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializable.java @@ -0,0 +1,13 @@ +package com.baeldung.customannotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target(TYPE) +public @interface JsonSerializable { + +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java new file mode 100644 index 0000000000..f2c29855ac --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/JsonSerializationException.java @@ -0,0 +1,10 @@ +package com.baeldung.customannotations; + +public class JsonSerializationException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public JsonSerializationException(String message) { + super(message); + } +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java new file mode 100644 index 0000000000..dd126be8ed --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/ObjectToJsonConverter.java @@ -0,0 +1,67 @@ +package com.baeldung.customannotations; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +public class ObjectToJsonConverter { + public String convertToJson(Object object) throws JsonSerializationException { + try { + + checkIfSerializable(object); + initializeObject(object); + return getJsonString(object); + + } catch (Exception e) { + throw new JsonSerializationException(e.getMessage()); + } + } + + private void checkIfSerializable(Object object) { + if (Objects.isNull(object)) { + throw new JsonSerializationException("Can't serialize a null object"); + } + + Class clazz = object.getClass(); + if (!clazz.isAnnotationPresent(JsonSerializable.class)) { + throw new JsonSerializationException("The class " + clazz.getSimpleName() + " is not annotated with JsonSerializable"); + } + } + + private void initializeObject(Object object) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Class clazz = object.getClass(); + for (Method method : clazz.getDeclaredMethods()) { + if (method.isAnnotationPresent(Init.class)) { + method.setAccessible(true); + method.invoke(object); + } + } + } + + private String getJsonString(Object object) throws IllegalArgumentException, IllegalAccessException { + Class clazz = object.getClass(); + Map jsonElementsMap = new HashMap<>(); + for (Field field : clazz.getDeclaredFields()) { + field.setAccessible(true); + if (field.isAnnotationPresent(JsonElement.class)) { + jsonElementsMap.put(getKey(field), (String) field.get(object)); + } + } + + String jsonString = jsonElementsMap.entrySet() + .stream() + .map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"") + .collect(Collectors.joining(",")); + return "{" + jsonString + "}"; + } + + private String getKey(Field field) { + String value = field.getAnnotation(JsonElement.class) + .key(); + return value.isEmpty() ? field.getName() : value; + } +} diff --git a/core-java-8/src/main/java/com/baeldung/customannotations/Person.java b/core-java-8/src/main/java/com/baeldung/customannotations/Person.java new file mode 100644 index 0000000000..5db1a7f279 --- /dev/null +++ b/core-java-8/src/main/java/com/baeldung/customannotations/Person.java @@ -0,0 +1,66 @@ +package com.baeldung.customannotations; + +@JsonSerializable +public class Person { + @JsonElement + private String firstName; + @JsonElement + private String lastName; + @JsonElement(key = "personAge") + private String age; + + private String address; + + public Person(String firstName, String lastName) { + super(); + this.firstName = firstName; + this.lastName = lastName; + } + + public Person(String firstName, String lastName, String age) { + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + } + + @Init + private void initNames() { + this.firstName = this.firstName.substring(0, 1) + .toUpperCase() + this.firstName.substring(1); + this.lastName = this.lastName.substring(0, 1) + .toUpperCase() + this.lastName.substring(1); + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + +} diff --git a/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java new file mode 100644 index 0000000000..f24b37aef7 --- /dev/null +++ b/core-java-8/src/test/java/com/baeldung/customannotations/JsonSerializerUnitTest.java @@ -0,0 +1,26 @@ +package com.baeldung.customannotations; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class JsonSerializerUnitTest { + + @Test + public void givenObjectNotSerializedThenExceptionThrown() throws JsonSerializationException { + Object object = new Object(); + ObjectToJsonConverter serializer = new ObjectToJsonConverter(); + assertThrows(JsonSerializationException.class, () -> { + serializer.convertToJson(object); + }); + } + + @Test + public void givenObjectSerializedThenTrueReturned() throws JsonSerializationException { + Person person = new Person("soufiane", "cheouati", "34"); + ObjectToJsonConverter serializer = new ObjectToJsonConverter(); + String jsonString = serializer.convertToJson(person); + assertEquals("{\"personAge\":\"34\",\"firstName\":\"Soufiane\",\"lastName\":\"Cheouati\"}", jsonString); + } +}