001 package net.sourceforge.javajson;
002
003 import java.io.InputStream;
004 import java.io.Reader;
005 import java.io.StringReader;
006 import java.util.ArrayList;
007 import java.util.Iterator;
008 import java.util.List;
009
010 import net.sourceforge.javajson.parser.ASTparse;
011 import net.sourceforge.javajson.parser.JsonParser;
012 import net.sourceforge.javajson.parser.ParseException;
013 import net.sourceforge.javajson.parser.TokenMgrError;
014
015 public class JsonArray implements Iterable<JsonValue> {
016 private List<JsonValue> list;
017
018 /** Parses a string to a json object. */
019 public static JsonArray parse(String input) throws JsonException {
020 return parse(new StringReader(input));
021 }
022
023 /** Parses a string to a json object. */
024 public static JsonArray parse(Reader reader) throws JsonException {
025 try {
026 JsonParser parser = new JsonParser(reader);
027 ASTparse root = (ASTparse) parser.parse();
028 return root.getJsonArray();
029 } catch (ParseException pe) {
030 throw new JsonException(pe);
031 } catch (TokenMgrError error) {
032 throw new JsonException(error);
033 }
034 }
035
036 /** Parses a string to a json object. */
037 public static JsonArray parse(InputStream is) throws JsonException {
038 try {
039 JsonParser parser = new JsonParser(is);
040 ASTparse root = (ASTparse) parser.parse();
041 return root.getJsonArray();
042 } catch (ParseException pe) {
043 throw new JsonException(pe);
044 } catch (TokenMgrError error) {
045 throw new JsonException(error);
046 }
047 }
048
049 public JsonArray() {
050 list = new ArrayList<JsonValue>();
051 }
052
053 public JsonArray add(boolean value) {
054 list.add(new JsonValue(value));
055 return this;
056 }
057
058 public JsonArray add(double value) {
059 list.add(new JsonValue(value));
060 return this;
061 }
062
063 public JsonArray add(float value) {
064 list.add(new JsonValue(value));
065 return this;
066 }
067
068 public JsonArray add(int value) {
069 list.add(new JsonValue(value));
070 return this;
071 }
072
073 public JsonArray add(long value) {
074 list.add(new JsonValue(value));
075 return this;
076 }
077
078 public JsonArray add(JsonArray value) {
079 list.add(new JsonValue(value));
080 return this;
081 }
082
083 public JsonArray add(JsonObject value) {
084 list.add(new JsonValue(value));
085 return this;
086 }
087
088 public JsonArray add(String value) {
089 list.add(new JsonValue(value));
090 return this;
091 }
092
093 public JsonArray add(Object value) {
094 if (value instanceof Boolean)
095 add(((Boolean) value).booleanValue());
096 else if (value instanceof Double)
097 add(((Double) value).doubleValue());
098 else if (value instanceof Float)
099 add(((Float) value).floatValue());
100 else if (value instanceof Integer)
101 add(((Integer) value).intValue());
102 else if (value instanceof Long)
103 add(((Long) value).longValue());
104 else if (value instanceof JsonArray)
105 add((JsonArray) value);
106 else if (value instanceof JsonObject)
107 add((JsonObject) value);
108 else if (value instanceof JsonValue)
109 list.add((JsonValue) value);
110 else if (value instanceof String)
111 add((String) value);
112 else if (value == null)
113 add((String) null);
114 else
115 throw new ClassCastException("Unrecognized class");
116 return this;
117 }
118
119 /**
120 * @param index
121 * @throws ClassCastException
122 * if the value cannot be converted to a boolean
123 * @throws IndexOutOfBoundsException
124 * if its out of bounds
125 */
126 public boolean getBoolean(int index) {
127 if (index >= 0 && index < list.size())
128 return list.get(index).getBoolean();
129 else
130 throw new IndexOutOfBoundsException();
131 }
132
133 /**
134 * @throws ClassCastException
135 * if the value cannot be converted to a double
136 * @throws IndexOutOfBoundsException
137 * if its out of bounds
138 */
139 public double getDouble(int index) {
140 if (index >= 0 && index < list.size())
141 return list.get(index).getDouble();
142 else
143 throw new IndexOutOfBoundsException();
144 }
145
146 /**
147 * @throws ClassCastException
148 * if the value cannot be converted to a double
149 * @throws IndexOutOfBoundsException
150 * if its out of bounds
151 */
152 public float getFloat(int index) {
153 if (index >= 0 && index < list.size())
154 return list.get(index).getFloat();
155 else
156 throw new IndexOutOfBoundsException();
157 }
158
159 /**
160 * @throws ClassCastException
161 * if the value cannot be converted to a double
162 * @throws IndexOutOfBoundsException
163 * if its out of bounds
164 */
165 public int getInt(int index) {
166 if (index >= 0 && index < list.size())
167 return list.get(index).getInt();
168 else
169 throw new IndexOutOfBoundsException();
170 }
171
172 /**
173 * @throws ClassCastException
174 * if the value cannot be converted to a double
175 * @throws IndexOutOfBoundsException
176 * if its out of bounds
177 */
178 public JsonArray getJsonArray(int index) {
179 if (index >= 0 && index < list.size())
180 return list.get(index).getJsonArray();
181 else
182 throw new IndexOutOfBoundsException();
183 }
184
185 /**
186 * @throws ClassCastException
187 * if the value cannot be converted to a double
188 * @throws IndexOutOfBoundsException
189 * if its out of bounds
190 */
191 public JsonObject getJsonObject(int index) {
192 if (index >= 0 && index < list.size())
193 return list.get(index).getJsonObject();
194 else
195 throw new IndexOutOfBoundsException();
196 }
197
198 /**
199 * @throws ClassCastException
200 * if the value cannot be converted to a double
201 * @throws IndexOutOfBoundsException
202 * if its out of bounds
203 */
204 public long getLong(int index) {
205 if (index >= 0 && index < list.size())
206 return list.get(index).getLong();
207 else
208 throw new IndexOutOfBoundsException();
209 }
210
211 /**
212 * @throws IndexOutOfBoundsException
213 * if its out of bounds
214 */
215 public String getString(int index) {
216 if (index >= 0 && index < list.size())
217 return list.get(index).getString();
218 else
219 throw new IndexOutOfBoundsException();
220 }
221
222 /**
223 * Checks if the item at an index is a boolean. See
224 * {@link JsonValue#isBoolean()} for more information
225 *
226 * @param index
227 * The index of the array to check
228 * @return True if the object contains the item and is a boolean
229 * @throws IndexOutOfBoundsException
230 */
231 public boolean isBoolean(int index) {
232 if (index >= 0 && index < list.size())
233 return list.get(index).isBoolean();
234 else
235 throw new IndexOutOfBoundsException();
236 }
237
238 /**
239 * Checks if the item at an index is a double. See
240 * {@link JsonValue#isLong()} for more information
241 *
242 * @param index
243 * The index of the array to check
244 * @return True if the object contains the item and is a double
245 * @throws IndexOutOfBoundsException
246 */
247 public boolean isDouble(int index) {
248 if (index >= 0 && index < list.size())
249 return list.get(index).isDouble();
250 else
251 throw new IndexOutOfBoundsException();
252 }
253
254 /**
255 * Checks if the item at an index is a float. See
256 * {@link JsonValue#isLong()} for more information
257 *
258 * @param index
259 * The index of the array to check
260 * @return True if the object contains the item and is a float
261 * @throws IndexOutOfBoundsException
262 */
263 public boolean isFloat(int index) {
264 if (index >= 0 && index < list.size())
265 return list.get(index).isFloat();
266 else
267 throw new IndexOutOfBoundsException();
268 }
269
270 /**
271 * Checks if the item at an index is a int. See
272 * {@link JsonValue#isLong()} for more information
273 *
274 * @param index
275 * The index of the array to check
276 * @return True if the object contains the item and is a int
277 * @throws IndexOutOfBoundsException
278 */
279 public boolean isInt(int index) {
280 if (index >= 0 && index < list.size())
281 return list.get(index).isInt();
282 else
283 throw new IndexOutOfBoundsException();
284 }
285
286 /**
287 * Checks if the item at an index is an array. See
288 * {@link JsonValue#isJsonArray()} for more information
289 *
290 * @param index
291 * The index of the array to check
292 * @return True if the object contains the item and is a json array
293 * @throws IndexOutOfBoundsException
294 */
295 public boolean isJsonArray(int index) {
296 if (index >= 0 && index < list.size())
297 return list.get(index).isJsonArray();
298 else
299 throw new IndexOutOfBoundsException();
300 }
301
302 /**
303 * Checks if the item at an index is an object. See
304 * {@link JsonValue#isJsonObject()} for more information
305 *
306 * @param index
307 * The index of the array to check
308 * @return True if the object contains the item and is a json object
309 * @throws IndexOutOfBoundsException
310 */
311 public boolean isJsonObject(int index) {
312 if (index >= 0 && index < list.size())
313 return list.get(index).isJsonObject();
314 else
315 throw new IndexOutOfBoundsException();
316 }
317
318 /**
319 * Checks if the item at an index is a long. See
320 * {@link JsonValue#isLong()} for more information
321 *
322 * @param index
323 * The index of the array to check
324 * @return True if the object contains the item and is a long
325 * @throws IndexOutOfBoundsException
326 */
327 public boolean isLong(int index) {
328 if (index >= 0 && index < list.size())
329 return list.get(index).isLong();
330 else
331 throw new IndexOutOfBoundsException();
332 }
333
334 /**
335 * Checks if the item at an index is an string. See
336 * {@link JsonValue#isString()} for more information
337 *
338 * @param index
339 * The index of the array to check
340 * @return True if the object contains the item and is a json string
341 * @throws IndexOutOfBoundsException
342 */
343 public boolean isString(int index) {
344 if (index >= 0 && index < list.size())
345 return list.get(index).isString();
346 else
347 throw new IndexOutOfBoundsException();
348 }
349
350 /**
351 * Checks if the structure of this json array is similar to that of another
352 * array. It simply checks that each item exists in both objects (same
353 * length of array) and that subobjects (json object or json array) are also
354 * similar.
355 *
356 * @param obj
357 * @return
358 */
359 public boolean isSimilar(JsonArray obj) {
360 if (obj == null)
361 return false;
362
363 if (obj.size() != size())
364 return false;
365
366 for (int i = 0; i < size(); i++) {
367 if (!list.get(i).isSimilar(obj.list.get(i)))
368 return false;
369 }
370
371 return true;
372 }
373
374 public Iterator<JsonValue> iterator() {
375 return list.iterator();
376 }
377
378 public int size() {
379 return list.size();
380 }
381
382 @Override
383 public String toString() {
384 StringBuffer sb = new StringBuffer();
385 boolean hadSome = false;
386 sb.append("[");
387 for (JsonValue val : list) {
388 if (hadSome)
389 sb.append(",");
390 sb.append(val);
391 hadSome = true;
392 }
393 sb.append("]");
394 return sb.toString();
395 }
396
397 /**
398 * Returns a nicely formatted string
399 *
400 * @param spacing
401 * @return
402 */
403 public String toString(int spacing) {
404 return toString(spacing, 0);
405 }
406
407 /**
408 * Called by toString(int) to keep track of the spacing
409 *
410 * @param spacing
411 * @param margin
412 * @return
413 */
414 protected String toString(int spacing, int margin) {
415 if (list.isEmpty())
416 return "[]";
417 else {
418 StringBuffer sb = new StringBuffer();
419 boolean hadSome = false;
420 sb.append("[\n");
421 for (JsonValue val : list) {
422 if (hadSome)
423 sb.append(",\n");
424 sb.append(getSpaces(margin + spacing));
425 sb.append(val.toString(spacing, margin + spacing));
426 hadSome = true;
427 }
428 sb.append("\n");
429 sb.append(getSpaces(margin));
430 sb.append("]");
431
432 return sb.toString();
433 }
434 }
435
436 private String getSpaces(int spaces) {
437 StringBuffer sb = new StringBuffer();
438 for (int i = 0; i < spaces; i++)
439 sb.append(" ");
440 return sb.toString();
441 }
442 }