diff --git a/src/com/company/json-20151123.jar b/src/com/company/json-20151123.jar new file mode 100644 index 0000000..472b253 Binary files /dev/null and b/src/com/company/json-20151123.jar differ diff --git a/src/com/company/json/Ignore.java b/src/com/company/json/Ignore.java new file mode 100644 index 0000000..99fa39f --- /dev/null +++ b/src/com/company/json/Ignore.java @@ -0,0 +1,15 @@ +package com.company.json; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Mark its annotated field to be ignored during serialization or other operation that needs access to the field. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Ignore { + +} diff --git a/src/com/company/json/JsonSerializer.java b/src/com/company/json/JsonSerializer.java new file mode 100644 index 0000000..3c415b1 --- /dev/null +++ b/src/com/company/json/JsonSerializer.java @@ -0,0 +1,101 @@ +package com.company.json; + +import com.company.json.adapters.JsonDataAdapter; +import com.company.json.adapters.UseDataAdapter; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + + +/** + * JsonSerializer converts Java objects to JSON representation. + * + */ +public class JsonSerializer { + + /** + * simpleTypes contains java classes for which we should not make any deeper serialization and we should return object as is + * and use toString() method to get it serialized representation + */ + private static Set simpleTypes = new HashSet(Arrays.asList( + JSONObject.class, + JSONArray.class, + String.class, + Integer.class, + Short.class, + Long.class, + Byte.class, + Double.class, + Float.class, + Character.class, + Boolean.class, + int.class, + short.class, + long.class, + byte.class, + double.class, + float.class, + char.class, + boolean.class + )); + + /** + * Main method to convert Java object to JSON. If type of the object is part of the simpleTypes object itself will be returned. + * If object is null String value "null" will be returned. + * @param o object to serialize. + * @return JSON representation of the object. + */ + public static Object serialize(Object o) { + if (null == o) { + return "null"; + } + if (simpleTypes.contains(o.getClass())) { + return o; + } else { + try { + return toJsonObject(o); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + } + + /** + * Converts Java object to JSON. Uses reflection to access object fields. + * Uses JsonDataAdapter to serialize complex values. Ignores @Ignore annotated fields. + * @param o object to serialize to JSON + * @return JSON object. + * @throws IllegalAccessException + * @throws InstantiationException + */ + private static JSONObject toJsonObject(Object o) throws Exception { + //implement me + Class clases = o.getClass(); + Field [] fields = clases.getDeclaredFields(); + JSONObject jsonObject = new JSONObject(); + for (Field field : fields) { + try { + field.setAccessible(true); + if (!field.isAnnotationPresent(Ignore.class)) { + if (!field.isAnnotationPresent(UseDataAdapter.class)) { + jsonObject.put(field.getName(), field.get(o)); + } else { + UseDataAdapter annotation = field.getAnnotation(UseDataAdapter.class); + Class annotationClass = annotation.value(); + JsonDataAdapter dataAdapter = (JsonDataAdapter) annotationClass.newInstance(); + jsonObject.put(field.getName(), dataAdapter.toJson(field.get(o))); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + return jsonObject; + } +} diff --git a/src/com/company/json/adapters/CollectionAdapter.java b/src/com/company/json/adapters/CollectionAdapter.java new file mode 100644 index 0000000..145b10f --- /dev/null +++ b/src/com/company/json/adapters/CollectionAdapter.java @@ -0,0 +1,20 @@ +package com.company.json.adapters; + +import com.company.json.JsonSerializer; +import org.json.JSONArray; +import org.json.JSONException; + +import java.util.Collection; + +/** + * Converts all objects that extends java.util.Collections to JSONArray. + */ +public class CollectionAdapter implements com.company.json.adapters.JsonDataAdapter { + @Override + public Object toJson(Collection c) throws JSONException{ + //implement me + JSONArray jsonArray = new JSONArray(); + c.stream().forEach(object -> jsonArray.put(JsonSerializer.serialize (object))); + return jsonArray; + } +} diff --git a/src/com/company/json/adapters/ColorAdapter.java b/src/com/company/json/adapters/ColorAdapter.java new file mode 100644 index 0000000..c7c3ddd --- /dev/null +++ b/src/com/company/json/adapters/ColorAdapter.java @@ -0,0 +1,13 @@ +package com.company.json.adapters; + +import java.awt.Color; + +/** + * Converts object of type java.awt.Color to its String representation. i.e. Color.GRAY = "(128,128,128)" + */ +public class ColorAdapter implements JsonDataAdapter { + @Override + public Object toJson(Color o) { + return "(" + o.getRed() + "," + o.getGreen() + "," + o.getBlue() + ")"; + } +} diff --git a/src/com/company/json/adapters/DateAdapter.java b/src/com/company/json/adapters/DateAdapter.java new file mode 100644 index 0000000..d487c3e --- /dev/null +++ b/src/com/company/json/adapters/DateAdapter.java @@ -0,0 +1,20 @@ +package com.company.json.adapters; + +import sun.util.calendar.BaseCalendar; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Converts object of type java.util.Date to String by using dd/MM/yyyy format + */ +public class DateAdapter implements JsonDataAdapter { + @Override + public Object toJson(Date date) { + //implement me + DateFormat newFormat = new SimpleDateFormat(); + String formated = newFormat.format(date); + return formated; + } +} diff --git a/src/com/company/json/adapters/JsonDataAdapter.java b/src/com/company/json/adapters/JsonDataAdapter.java new file mode 100644 index 0000000..6b5ee85 --- /dev/null +++ b/src/com/company/json/adapters/JsonDataAdapter.java @@ -0,0 +1,11 @@ +package com.company.json.adapters; + +import org.json.JSONException; + +/** + * JsonDataAdapter contains instructions how to serialize Java object to Json representation. + * @param determines type adapter works with. + */ +public interface JsonDataAdapter { + Object toJson(T o) throws JSONException; +} diff --git a/src/com/company/json/adapters/MapAdapter.java b/src/com/company/json/adapters/MapAdapter.java new file mode 100644 index 0000000..d69e52a --- /dev/null +++ b/src/com/company/json/adapters/MapAdapter.java @@ -0,0 +1,22 @@ +package com.company.json.adapters; + +import com.company.json.JsonSerializer; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Map; + +/** + * Converts all objects that extends java.util.Map to JSONObject. + */ + +public class MapAdapter implements JsonDataAdapter { + @Override + public Object toJson(Map map) throws JSONException { + JSONObject m = new JSONObject(); + for (Object key : map.keySet()) { + m.put(key.toString(), JsonSerializer.serialize(map.get(key))); + } + return m; + } +} diff --git a/src/com/company/json/adapters/UseDataAdapter.java b/src/com/company/json/adapters/UseDataAdapter.java new file mode 100644 index 0000000..6f1710a --- /dev/null +++ b/src/com/company/json/adapters/UseDataAdapter.java @@ -0,0 +1,15 @@ +package com.company.json.adapters; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Determines class of JsonDataAdapter that should be used to serialize annotated field value. + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface UseDataAdapter { + Class value(); +} diff --git a/src/com/company/test/Cat.java b/src/com/company/test/Cat.java new file mode 100644 index 0000000..faa99d1 --- /dev/null +++ b/src/com/company/test/Cat.java @@ -0,0 +1,86 @@ +package com.company.test; + +import com.company.json.adapters.*; + +import java.awt.*; +import java.util.*; +import java.util.List; + +/** + * Simple Cat that will be used for testing JSON serialization. + */ +public class Cat { + private int age; + private String name; + private Cat myself; + + private Date birthDate; + + @UseDataAdapter(ColorAdapter.class) + private Color color; + + private List whiskers = new ArrayList<>(); + + @UseDataAdapter(MapAdapter.class) + private Map paws = new HashMap<>(); + + public Cat() { + myself = this; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getBirthDate() { + return birthDate; + } + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } + + public Map getPaws() { + return paws; + } + + public void setPaws(Map paws) { + this.paws = paws; + } + + public List getWhiskers() { + return whiskers; + } + + public void setWhiskers(List whiskers) { + this.whiskers = whiskers; + } + + public Cat getMyself() { + return myself; + } + + public void setMyself(Cat myself) { + this.myself = myself; + } +} \ No newline at end of file diff --git a/src/com/company/test/Paw.java b/src/com/company/test/Paw.java new file mode 100644 index 0000000..05bc17e --- /dev/null +++ b/src/com/company/test/Paw.java @@ -0,0 +1,30 @@ +package com.company.test; + +import java.awt.*; + +public class Paw { + private Integer length; + + private Color color; + + public Paw(Integer length, Color color) { + this.length = length; + this.color = color; + } + + public Integer getLength() { + return length; + } + + public void setLength(Integer length) { + this.length = length; + } + + public Color getColor() { + return color; + } + + public void setColor(Color color) { + this.color = color; + } +} \ No newline at end of file diff --git a/src/com/company/test/Test.java b/src/com/company/test/Test.java new file mode 100644 index 0000000..8745fa4 --- /dev/null +++ b/src/com/company/test/Test.java @@ -0,0 +1,32 @@ +package com.company.test; + +import com.company.json.JsonSerializer; + +import java.awt.*; +import java.util.*; +import java.util.List; + +public class Test { + public static void main(String[] args) throws IllegalAccessException { + Cat cat = new Cat(); + cat.setColor(Color.GRAY); + cat.setAge(4); + cat.setName("Tom"); + + List whiskers = cat.getWhiskers(); + whiskers.add(1); + whiskers.add(2); + whiskers.add(3); + whiskers.add(4); + whiskers.add(5); + whiskers.add(6); + + cat.setBirthDate(new Date()); + cat.getPaws().put("front-left", new Paw(23, Color.GRAY)); + cat.getPaws().put("front-right", new Paw(24, Color.WHITE)); + cat.getPaws().put("back-left", new Paw(23, Color.BLACK)); + cat.getPaws().put("back-right", new Paw(22, Color.GRAY)); + + System.out.println(JsonSerializer.serialize(cat)); + } +}