1 package org.opensrf.util;
6 import org.json.JSONTokener;
7 import org.json.JSONObject;
8 import org.json.JSONArray;
14 public class JSONReader {
16 /** Special OpenSRF serializable object netClass key */
17 public static final String JSON_CLASS_KEY = "__c";
19 /** Special OpenSRF serializable object payload key */
20 public static final String JSON_PAYLOAD_KEY = "__p";
22 /** The JSON string to parser */
26 * @param The JSON to parse
28 public JSONReader(String json) {
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
38 public Object read() throws JSONException {
39 JSONTokener tk = new JSONTokener(json);
41 return readSubObject(tk.nextValue());
42 } catch(org.json.JSONException e) {
43 throw new JSONException(e.toString());
48 * Assumes that a JSON array will be read. Returns
49 * the resulting array as a list.
51 public List<?> readArray() throws JSONException {
55 } catch(Exception e) {
56 throw new JSONException("readArray(): JSON cast exception");
61 * Assumes that a JSON object will be read. Returns
62 * the resulting object as a map.
64 public Map<?,?> readObject() throws JSONException {
68 } catch(Exception e) {
69 throw new JSONException("readObject(): JSON cast exception");
75 * Recurse through the object and turn items into maps, lists, etc.
77 private Object readSubObject(Object obj) throws JSONException {
80 obj instanceof String ||
81 obj instanceof Number ||
82 obj instanceof Boolean)
87 if( obj instanceof JSONObject ) {
91 JSONObject jobj = (JSONObject) obj;
92 Map<String, Object> map = new HashMap<String, Object>();
94 for( Iterator e = jobj.keys(); e.hasNext(); ) {
95 key = (String) e.next();
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));
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));
107 map.put(key, readSubObject(jobj.get(key)));
112 if ( obj instanceof JSONArray ) {
114 JSONArray jarr = (JSONArray) obj;
115 int length = jarr.length();
116 List<Object> list = new ArrayList<Object>(length);
118 for( int i = 0; i < length; i++ )
119 list.add(readSubObject(jarr.get(i)));
124 } catch(org.json.JSONException e) {
126 throw new JSONException(e.toString());
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.
139 private OSRFObject buildRegisteredObject(
140 String netClass, Object payload) throws JSONException {
142 OSRFRegistry registry = OSRFRegistry.getRegistry(netClass);
143 OSRFObject obj = new OSRFObject(registry);
146 if( payload instanceof JSONArray ) {
147 JSONArray jarr = (JSONArray) payload;
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)));
157 } else if( payload instanceof JSONObject ) {
159 /* since this is a hash, simply copy the data over */
160 JSONObject jobj = (JSONObject) payload;
162 for( Iterator e = jobj.keys(); e.hasNext(); ) {
163 key = (String) e.next();
164 obj.put(key, readSubObject(jobj.get(key)));
168 } catch(org.json.JSONException e) {
169 throw new JSONException(e.toString());