]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/java/org/opensrf/util/JSONReader.java
634c249435074df741eaa75da6c012a326332d2e
[OpenSRF.git] / src / java / org / opensrf / util / JSONReader.java
1 package org.opensrf.util;
2
3 import java.io.*;
4 import java.util.*;
5
6 import org.json.JSONTokener;
7 import org.json.JSONObject;
8 import org.json.JSONArray;
9
10
11 /**
12  * JSON utilities.
13  */
14 public class JSONReader {
15
16     /** Special OpenSRF serializable object netClass key */
17     public static final String JSON_CLASS_KEY = "__c";
18
19     /** Special OpenSRF serializable object payload key */
20     public static final String JSON_PAYLOAD_KEY = "__p";
21
22     /** The JSON string to parser */
23     private String json;
24
25     /**
26      * @param The JSON to parse
27      */
28     public JSONReader(String json) {
29         this.json = json;
30     }
31
32     /**
33      * Parses JSON and creates an object.
34      * @param json The JSON string to parse
35      * @return The resulting object which may be a List, 
36      * Map, Number, String, Boolean, or null
37      */
38     public Object read() throws JSONException {
39         JSONTokener tk = new JSONTokener(json);
40         try {
41             return readSubObject(tk.nextValue());
42         } catch(org.json.JSONException e) {
43             throw new JSONException(e.toString());
44         }
45     }
46
47     /**
48      * Assumes that a JSON array will be read.  Returns
49      * the resulting array as a list.
50      */
51     public List<?> readArray() throws JSONException {
52         Object o = read();
53         try {
54             return (List<?>) o;
55         } catch(Exception e) {
56             throw new JSONException("readArray(): JSON cast exception");
57         }
58     }
59
60     /**
61      * Assumes that a JSON object will be read.  Returns 
62      * the resulting object as a map.
63      */
64     public Map<?,?> readObject() throws JSONException {
65         Object o = read();
66         try {
67             return (Map<?,?>) o;
68         } catch(Exception e) {
69             throw new JSONException("readObject(): JSON cast exception");
70         }
71     }
72
73
74     /**
75      * Recurse through the object and turn items into maps, lists, etc.
76      */
77     private Object readSubObject(Object obj) throws JSONException {
78
79         if( obj == null || 
80             obj instanceof String || 
81             obj instanceof Number ||
82             obj instanceof Boolean)
83                 return obj;
84
85         try {
86
87             if( obj instanceof JSONObject ) {
88
89                 /* read objects */
90                 String key;
91                 JSONObject jobj = (JSONObject) obj;
92                 Map<String, Object> map = new HashMap<String, Object>();
93
94                 for( Iterator e = jobj.keys(); e.hasNext(); ) {
95                     key = (String) e.next();
96
97                     /* we encoutered the special class key */
98                     if( JSON_CLASS_KEY.equals(key) ) 
99                         return buildRegisteredObject(
100                             (String) jobj.get(key), jobj.get(JSON_PAYLOAD_KEY));
101
102                     /* we encountered the data key */
103                     if( JSON_PAYLOAD_KEY.equals(key) ) 
104                         return buildRegisteredObject(
105                             (String) jobj.get(JSON_CLASS_KEY), jobj.get(key));
106
107                     map.put(key, readSubObject(jobj.get(key)));
108                 }
109                 return map;
110             } 
111             
112             if ( obj instanceof JSONArray ) {
113
114                 JSONArray jarr = (JSONArray) obj;
115                 int length = jarr.length();
116                 List<Object> list = new ArrayList<Object>(length);
117
118                 for( int i = 0; i < length; i++ ) 
119                     list.add(readSubObject(jarr.get(i)));   
120                 return list;
121                 
122             }
123
124         } catch(org.json.JSONException e) {
125
126             throw new JSONException(e.toString());
127         }
128
129         return null;
130     }
131
132
133
134     /**
135      * Builds an OSRFObject map registered OSRFHash object based on the JSON object data.
136      * @param netClass The network class hint for this object.
137      * @param paylaod The actual object on the wire.
138      */
139     private OSRFObject buildRegisteredObject(
140         String netClass, Object payload) throws JSONException {
141
142         OSRFRegistry registry = OSRFRegistry.getRegistry(netClass);
143         OSRFObject obj = new OSRFObject(registry);
144
145         try {
146             if( payload instanceof JSONArray ) {
147                 JSONArray jarr = (JSONArray) payload;
148
149                 /* for each array item, instert the item into the hash.  the hash 
150                  * key is found by extracting the fields array from the registered 
151                  * object at the current array index */
152                 String fields[] = registry.getFields();
153                 for( int i = 0; i < jarr.length(); i++ ) {
154                     obj.put(fields[i], readSubObject(jarr.get(i)));   
155                 }
156
157             } else if( payload instanceof JSONObject ) {
158
159                 /* since this is a hash, simply copy the data over */
160                 JSONObject jobj = (JSONObject) payload;
161                 String key;
162                 for( Iterator e = jobj.keys(); e.hasNext(); ) {
163                     key = (String) e.next();
164                     obj.put(key, readSubObject(jobj.get(key)));
165                 }
166             }
167
168         } catch(org.json.JSONException e) {
169             throw new JSONException(e.toString());
170         }
171
172         return obj;
173     }
174 }
175
176
177