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 json The JSON to parse
28 public JSONReader(String json) {
33 * Parses JSON and creates an object.
34 * @return The resulting object which may be a List,
35 * Map, Number, String, Boolean, or null
37 public Object read() throws JSONException {
38 JSONTokener tk = new JSONTokener(json);
40 return readSubObject(tk.nextValue());
41 } catch(org.json.JSONException e) {
42 throw new JSONException(e.toString());
47 * Assumes that a JSON array will be read. Returns
48 * the resulting array as a list.
50 public List<?> readArray() throws JSONException {
54 } catch(Exception e) {
55 throw new JSONException("readArray(): JSON cast exception");
60 * Assumes that a JSON object will be read. Returns
61 * the resulting object as a map.
63 public Map<?,?> readObject() throws JSONException {
67 } catch(Exception e) {
68 throw new JSONException("readObject(): JSON cast exception");
74 * Recurse through the object and turn items into maps, lists, etc.
76 private Object readSubObject(Object obj) throws JSONException {
79 obj instanceof String ||
80 obj instanceof Number ||
81 obj instanceof Boolean)
86 if( obj instanceof JSONObject ) {
90 JSONObject jobj = (JSONObject) obj;
91 Map<String, Object> map = new HashMap<String, Object>();
93 for( Iterator e = jobj.keys(); e.hasNext(); ) {
94 key = (String) e.next();
96 /* we encoutered the special class key */
97 if( JSON_CLASS_KEY.equals(key) )
98 return buildRegisteredObject(
99 (String) jobj.get(key), jobj.get(JSON_PAYLOAD_KEY));
101 /* we encountered the data key */
102 if( JSON_PAYLOAD_KEY.equals(key) )
103 return buildRegisteredObject(
104 (String) jobj.get(JSON_CLASS_KEY), jobj.get(key));
106 map.put(key, readSubObject(jobj.get(key)));
111 if ( obj instanceof JSONArray ) {
113 JSONArray jarr = (JSONArray) obj;
114 int length = jarr.length();
115 List<Object> list = new ArrayList<Object>(length);
117 for( int i = 0; i < length; i++ )
118 list.add(readSubObject(jarr.get(i)));
123 } catch(org.json.JSONException e) {
125 throw new JSONException(e.toString());
134 * Builds an OSRFObject map registered OSRFHash object based on the JSON object data.
135 * @param netClass The network class hint for this object.
136 * @param paylaod The actual object on the wire.
138 private OSRFObject buildRegisteredObject(
139 String netClass, Object payload) throws JSONException {
141 OSRFRegistry registry = OSRFRegistry.getRegistry(netClass);
142 OSRFObject obj = new OSRFObject(registry);
145 if( payload instanceof JSONArray ) {
146 JSONArray jarr = (JSONArray) payload;
148 /* for each array item, instert the item into the hash. the hash
149 * key is found by extracting the fields array from the registered
150 * object at the current array index */
151 String fields[] = registry.getFields();
152 for( int i = 0; i < jarr.length(); i++ ) {
153 obj.put(fields[i], readSubObject(jarr.get(i)));
156 } else if( payload instanceof JSONObject ) {
158 /* since this is a hash, simply copy the data over */
159 JSONObject jobj = (JSONObject) payload;
161 for( Iterator e = jobj.keys(); e.hasNext(); ) {
162 key = (String) e.next();
163 obj.put(key, readSubObject(jobj.get(key)));
167 } catch(org.json.JSONException e) {
168 throw new JSONException(e.toString());