9e17b5dc559a27ac5bdf9c7429724ce39338d51a
[OpenSRF.git] / src / java / org / opensrf / util / JSON.java
1 package org.opensrf.util;
2
3 import java.io.*;
4 import java.util.*;
5
6 /**
7  * JSON utilities.
8  */
9 public class JSON {
10
11     /** Special OpenSRF serializable object netClass key */
12     public static final String JSON_CLASS_KEY = "__c";
13
14     /** Special OpenSRF serializable object payload key */
15     public static final String JSON_PAYLOAD_KEY = "__p";
16
17
18     /**
19      * @see toJSON(Object, StringBuffer)
20      */
21     public static String toJSON(Object obj) {
22         StringBuffer sb = new StringBuffer();
23         toJSON(obj, sb);
24         return sb.toString();
25     }
26
27
28     /**
29      * Encodes a java object to JSON.
30      * Maps (HashMaps, etc.) are encoded as JSON objects.  
31      * Iterable's (Lists, etc.) are encoded as JSON arrays
32      */
33     public static void toJSON(Object obj, StringBuffer sb) {
34
35         /** JSON null */
36         if(obj == null) {
37             sb.append("null");
38             return;
39         }
40
41         /** JSON string */
42         if(obj instanceof String) {
43             sb.append('"');
44             Utils.escape((String) obj, sb);
45             sb.append('"');
46             return;
47         }
48
49         /** JSON number */
50         if(obj instanceof Number) {
51             sb.append(obj.toString());
52             return;
53         }
54
55         /** JSON array */
56         if(obj instanceof Iterable) {
57             encodeJSONArray((Iterable) obj, sb);
58             return;
59         }
60
61         /** OpenSRF serializable objects */
62         if(obj instanceof OSRFSerializable) {
63             encodeOSRFSerializable((OSRFSerializable) obj, sb);
64             return;
65         }
66
67         /** JSON object */
68         if(obj instanceof Map) {
69             encodeJSONObject((Map) obj, sb);
70             return;
71         }
72
73         /** JSON boolean */
74         if(obj instanceof Boolean) {
75             sb.append((((Boolean) obj).booleanValue() ? "true" : "false"));
76             return;
77         }
78     }
79
80
81     /**
82      * Encodes a List as a JSON array
83      */
84     private static void encodeJSONArray(Iterable iterable, StringBuffer sb) {
85         Iterator itr = iterable.iterator();
86         sb.append("[");
87         boolean some = false;
88
89         while(itr.hasNext()) {
90             some = true;
91             toJSON(itr.next(), sb);
92             sb.append(',');
93         }
94
95         /* remove the trailing comma if the array has any items*/
96         if(some) 
97             sb.deleteCharAt(sb.length()-1); 
98         sb.append("]");
99     }
100
101
102     /**
103      * Encodes a Map to a JSON object
104      */
105     private static void encodeJSONObject(Map map, StringBuffer sb) {
106         Iterator itr = map.keySet().iterator();
107         sb.append("{");
108         Object key = null;
109
110         while(itr.hasNext()) {
111             key = itr.next();
112             toJSON(key, sb);
113             sb.append(':');
114             toJSON(map.get(key), sb);
115             sb.append(',');
116         }
117
118         /* remove the trailing comma if the object has any items*/
119         if(key != null) 
120             sb.deleteCharAt(sb.length()-1); 
121         sb.append("}");
122     }
123
124
125     /**
126      * Encodes a network-serializable OpenSRF object
127      */
128     private static void encodeOSRFSerializable(OSRFSerializable obj, StringBuffer sb) {
129
130         OSRFRegistry reg = obj.getRegistry();
131         String[] fields = reg.getFields();
132         Map<String, Object> map = new HashMap<String, Object>();
133         map.put(JSON_CLASS_KEY, reg.getNetClass());
134
135         if( reg.getWireProtocol() == OSRFRegistry.WireProtocol.ARRAY ) {
136
137             List<Object> list = new ArrayList<Object>(fields.length);
138             for(String s : fields)
139                 list.add(obj.get(s));
140             map.put(JSON_PAYLOAD_KEY, list);
141
142         } else {
143             //map.put(JSON_PAYLOAD_KEY, new HashMap<String, Object>(obj));
144             Map<String, Object> subMap = new HashMap<String, Object>();
145             for(String s : fields)
146                 map.put(s, obj.get(s));
147                 
148         }
149
150         /** now serialize the encoded object */
151         toJSON(map, sb);
152     }
153 }
154
155
156