Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/com/company/json-20151123.jar
Binary file not shown.
15 changes: 15 additions & 0 deletions src/com/company/json/Ignore.java
Original file line number Diff line number Diff line change
@@ -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 {

}
101 changes: 101 additions & 0 deletions src/com/company/json/JsonSerializer.java
Original file line number Diff line number Diff line change
@@ -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<Class> simpleTypes = new HashSet<Class>(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;
}
}
20 changes: 20 additions & 0 deletions src/com/company/json/adapters/CollectionAdapter.java
Original file line number Diff line number Diff line change
@@ -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<Collection> {
@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;
}
}
13 changes: 13 additions & 0 deletions src/com/company/json/adapters/ColorAdapter.java
Original file line number Diff line number Diff line change
@@ -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<Color> {
@Override
public Object toJson(Color o) {
return "(" + o.getRed() + "," + o.getGreen() + "," + o.getBlue() + ")";
}
}
20 changes: 20 additions & 0 deletions src/com/company/json/adapters/DateAdapter.java
Original file line number Diff line number Diff line change
@@ -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<Date> {
@Override
public Object toJson(Date date) {
//implement me
DateFormat newFormat = new SimpleDateFormat();
String formated = newFormat.format(date);
return formated;
}
}
11 changes: 11 additions & 0 deletions src/com/company/json/adapters/JsonDataAdapter.java
Original file line number Diff line number Diff line change
@@ -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 <T> determines type adapter works with.
*/
public interface JsonDataAdapter<T> {
Object toJson(T o) throws JSONException;
}
22 changes: 22 additions & 0 deletions src/com/company/json/adapters/MapAdapter.java
Original file line number Diff line number Diff line change
@@ -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<Map> {
@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;
}
}
15 changes: 15 additions & 0 deletions src/com/company/json/adapters/UseDataAdapter.java
Original file line number Diff line number Diff line change
@@ -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<? extends JsonDataAdapter> value();
}
86 changes: 86 additions & 0 deletions src/com/company/test/Cat.java
Original file line number Diff line number Diff line change
@@ -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<Integer> whiskers = new ArrayList<>();

@UseDataAdapter(MapAdapter.class)
private Map<String, com.company.test.Paw> 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<String, com.company.test.Paw> getPaws() {
return paws;
}

public void setPaws(Map<String, com.company.test.Paw> paws) {
this.paws = paws;
}

public List<Integer> getWhiskers() {
return whiskers;
}

public void setWhiskers(List<Integer> whiskers) {
this.whiskers = whiskers;
}

public Cat getMyself() {
return myself;
}

public void setMyself(Cat myself) {
this.myself = myself;
}
}
30 changes: 30 additions & 0 deletions src/com/company/test/Paw.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
32 changes: 32 additions & 0 deletions src/com/company/test/Test.java
Original file line number Diff line number Diff line change
@@ -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<Integer> 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));
}
}