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