Reinventing the Wheel: JSON Conversion Library (Ⅰ)

Building a Java library which implements JSON conversion between JSON strings and Java beans. The source code is available in here.

Types

At the beginning, we may need a basic class that represents all the data types of JSON including array [], object {}, value 112358.0, and even null or undefined. It provides interfaces accessing and modifying itself or its sub-elements. Like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public abstract class JSONElement {

public JSONElement peek(Object k) {
// TODO: return the specific sub-element
return null;
}

public JSONElement offer(Object v) {
// TODO: add the value to the array

// return the element itself for method chaining
return this;
}

public JSONElement offer(Object k, Object v) {
// TODO: add the value to the object with specified key

// return the element itself for method chaining
return this;
}

}

And the derived classes representing each JSON data type. Using List to simulate [], and Map to simulate {}.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
final class JSONList extends JSONElement {
private List<JSONElement> _sub_elements;
}

final class JSONMap extends JSONElement {
private Map<Object, JSONElement> _sub_elements;
}

final class JSONPrimitive extends JSONElement {
private Object _value;
}

final class JSONVoid extends JSONElement {
/**
* The singleton instance of {@link JSONVoid}.
*/
static final JSONVoid INSTANCE = new JSONVoid();
}

Interfaces

A JSON class that providing methods named JS-like (JSON.stringify, JSON.parse) may helps while using.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public abstract class JSON {

/**
* Serializes Java {@link Object} to {@link JSONElement}.
*
* @param o the {@link Object} to be serialized.
* @return the {@link JSONElement} serialized.
*/
public static JSONElement serialize(Object o) {
if (o instanceof JSONElement) {
return (JSONElement) o;
} else {
return ObjectAnalyzer.analyze(o);
}
}

/**
* Deserializes JSON {@link String} to {@link JSONElement}.
*
* @param json the JSON {@link String} to be deserialized.
* @return the {@link JSONElement} deserialized.
*/
public static JSONElement deserialize(String json) {
return StringAnalyzer.analyze(json);
}

/**
* Directly serializes Java {@link Object} to JSON {@link String}.
*
* @param o the {@link Object} to be serialized.
* @return the JSON {@link String} serialized.
*/
public static String stringify(Object o) {
if (o instanceof JSONElement) {
return StringAnalyzer.analyze((JSONElement) o);
} else {
return DirectAnalyzer.analyze(o);
}
}

/**
* Directly deserializes JSON {@link String} to Java {@link Object}.
*
* @param json the JSON {@link String} to be deserialized.
* @param target the target {@link Type}.
* @param <T> the target {@link Type}.
* @return the Java {@link Object} deserialized.
*/
public static <T> T parse(String json, Type target) {
if (target instanceof Class && JSONElement.class.isAssignableFrom((Class) target)) {
return (T) StringAnalyzer.analyze(json);
} else {
return DirectAnalyzer.analyze(json, target);
}
}

}

So far, nothing special but that we created some contentless classes. Completing the StringAnalyzer and ObjectAnalyzer in the next posts.