1 /*
2 * $Id: JSONArray.java,v 1.1 2007/10/22 16:23:08 oeuillot Exp $
3 */
4 package org.rcfaces.core.internal.util.json;
5
6 /*
7 * Copyright (c) 2002 JSON.org
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * The Software shall be used for Good, not Evil.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
30 import java.io.IOException;
31 import java.io.Writer;
32 import java.lang.reflect.Array;
33 import java.util.ArrayList;
34 import java.util.Collection;
35 import java.util.List;
36 import java.util.Map;
37
38 /**
39 * A JSONArray is an ordered sequence of values. Its external text form is a
40 * string wrapped in square brackets with commas separating the values. The
41 * internal form is an object having <code>get</code> and <code>opt</code>
42 * methods for accessing the values by index, and <code>put</code> methods for
43 * adding or replacing values. The values can be any of these types:
44 * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
45 * <code>Number</code>, <code>String</code>, or the
46 * <code>JSONObject.NULL object</code>.
47 * <p>
48 * The constructor can convert a JSON text into a Java object. The
49 * <code>toString</code> method converts to JSON text.
50 * <p>
51 * A <code>get</code> method returns a value if one can be found, and throws
52 * an exception if one cannot be found. An <code>opt</code> method returns a
53 * default value instead of throwing an exception, and so is useful for
54 * obtaining optional values.
55 * <p>
56 * The generic <code>get()</code> and <code>opt()</code> methods return an
57 * object which you can cast or query for type. There are also typed
58 * <code>get</code> and <code>opt</code> methods that do type checking and
59 * type coersion for you.
60 * <p>
61 * The texts produced by the <code>toString</code> methods strictly conform to
62 * JSON syntax rules. The constructors are more forgiving in the texts they will
63 * accept:
64 * <ul>
65 * <li>An extra <code>,</code> <small>(comma)</small> may appear just
66 * before the closing bracket.</li>
67 * <li>The <code>null</code> value will be inserted when there is
68 * <code>,</code> <small>(comma)</small> elision.</li>
69 * <li>Strings may be quoted with <code>'</code> <small>(single quote)</small>.</li>
70 * <li>Strings do not need to be quoted at all if they do not begin with a
71 * quote or single quote, and if they do not contain leading or trailing spaces,
72 * and if they do not contain any of these characters:
73 * <code>{ } [ ] / \ : , = ; #</code> and if they do not look like numbers and
74 * if they are not the reserved words <code>true</code>, <code>false</code>,
75 * or <code>null</code>.</li>
76 * <li>Values can be separated by <code>;</code> <small>(semicolon)</small>
77 * as well as by <code>,</code> <small>(comma)</small>.</li>
78 * <li>Numbers may have the <code>0-</code> <small>(octal)</small> or
79 * <code>0x-</code> <small>(hex)</small> prefix.</li>
80 * <li>Comments written in the slashshlash, slashstar, and hash conventions
81 * will be ignored.</li>
82 * </ul>
83 *
84 * @author JSON.org
85 * @version 2
86 */
87 public class JSONArray {
88
89 /**
90 * The arrayList where the JSONArray's properties are kept.
91 */
92 private List myArrayList;
93
94 /**
95 * Construct an empty JSONArray.
96 */
97 public JSONArray() {
98 this.myArrayList = new ArrayList();
99 }
100
101 /**
102 * Construct a JSONArray from a JSONTokener.
103 *
104 * @param x
105 * A JSONTokener
106 * @throws JSONException
107 * If there is a syntax error.
108 */
109 public JSONArray(JSONTokener x) throws JSONException {
110 this();
111 if (x.nextClean() != '[') {
112 throw x.syntaxError("A JSONArray text must start with '['");
113 }
114 if (x.nextClean() == ']') {
115 return;
116 }
117 x.back();
118 for (;;) {
119 if (x.nextClean() == ',') {
120 x.back();
121 this.myArrayList.add(null);
122 } else {
123 x.back();
124 this.myArrayList.add(x.nextValue());
125 }
126 switch (x.nextClean()) {
127 case ';':
128 case ',':
129 if (x.nextClean() == ']') {
130 return;
131 }
132 x.back();
133 break;
134 case ']':
135 return;
136 default:
137 throw x.syntaxError("Expected a ',' or ']'");
138 }
139 }
140 }
141
142 /**
143 * Construct a JSONArray from a source JSON text.
144 *
145 * @param source
146 * A string that begins with <code>[</code> <small>(left
147 * bracket)</small> and ends with <code>]</code> <small>(right
148 * bracket)</small>.
149 * @throws JSONException
150 * If there is a syntax error.
151 */
152 public JSONArray(String source) throws JSONException {
153 this(new JSONTokener(source));
154 }
155
156 /**
157 * Construct a JSONArray from a Collection.
158 *
159 * @param collection
160 * A Collection.
161 */
162 public JSONArray(Collection collection) {
163 this.myArrayList = (collection == null) ? new ArrayList()
164 : new ArrayList(collection);
165 }
166
167 /**
168 * Construct a JSONArray from an array
169 *
170 * @throws JSONException
171 * If not an array.
172 */
173 public JSONArray(Object array) throws JSONException {
174 this();
175 if (array.getClass().isArray()) {
176 int length = Array.getLength(array);
177 for (int i = 0; i < length; i += 1) {
178 this.put(Array.get(array, i));
179 }
180 } else {
181 throw new JSONException(
182 "JSONArray initial value should be a string or collection or array.");
183 }
184 }
185
186 /**
187 * Get the object value associated with an index.
188 *
189 * @param index
190 * The index must be between 0 and length() - 1.
191 * @return An object value.
192 * @throws JSONException
193 * If there is no value for the index.
194 */
195 public Object get(int index) throws JSONException {
196 Object o = opt(index);
197 if (o == null) {
198 throw new JSONException("JSONArray[" + index + "] not found.");
199 }
200 return o;
201 }
202
203 /**
204 * Get the boolean value associated with an index. The string values "true"
205 * and "false" are converted to boolean.
206 *
207 * @param index
208 * The index must be between 0 and length() - 1.
209 * @return The truth.
210 * @throws JSONException
211 * If there is no value for the index or if the value is not
212 * convertable to boolean.
213 */
214 public boolean getBoolean(int index) throws JSONException {
215 Object o = get(index);
216 if (o.equals(Boolean.FALSE)
217 || (o instanceof String && ((String) o)
218 .equalsIgnoreCase("false"))) {
219 return false;
220 } else if (o.equals(Boolean.TRUE)
221 || (o instanceof String && ((String) o)
222 .equalsIgnoreCase("true"))) {
223 return true;
224 }
225 throw new JSONException("JSONArray[" + index + "] is not a Boolean.");
226 }
227
228 /**
229 * Get the double value associated with an index.
230 *
231 * @param index
232 * The index must be between 0 and length() - 1.
233 * @return The value.
234 * @throws JSONException
235 * If the key is not found or if the value cannot be converted
236 * to a number.
237 */
238 public double getDouble(int index) throws JSONException {
239 Object o = get(index);
240 try {
241 return o instanceof Number ? ((Number) o).doubleValue() : Double
242 .valueOf((String) o).doubleValue();
243 } catch (Exception e) {
244 throw new JSONException("JSONArray[" + index + "] is not a number.");
245 }
246 }
247
248 /**
249 * Get the int value associated with an index.
250 *
251 * @param index
252 * The index must be between 0 and length() - 1.
253 * @return The value.
254 * @throws JSONException
255 * If the key is not found or if the value cannot be converted
256 * to a number. if the value cannot be converted to a number.
257 */
258 public int getInt(int index) throws JSONException {
259 Object o = get(index);
260 return o instanceof Number ? ((Number) o).intValue()
261 : (int) getDouble(index);
262 }
263
264 /**
265 * Get the JSONArray associated with an index.
266 *
267 * @param index
268 * The index must be between 0 and length() - 1.
269 * @return A JSONArray value.
270 * @throws JSONException
271 * If there is no value for the index. or if the value is not a
272 * JSONArray
273 */
274 public JSONArray getJSONArray(int index) throws JSONException {
275 Object o = get(index);
276 if (o instanceof JSONArray) {
277 return (JSONArray) o;
278 }
279 throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
280 }
281
282 /**
283 * Get the JSONObject associated with an index.
284 *
285 * @param index
286 * subscript
287 * @return A JSONObject value.
288 * @throws JSONException
289 * If there is no value for the index or if the value is not a
290 * JSONObject
291 */
292 public JSONObject getJSONObject(int index) throws JSONException {
293 Object o = get(index);
294 if (o instanceof JSONObject) {
295 return (JSONObject) o;
296 }
297 throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
298 }
299
300 /**
301 * Get the long value associated with an index.
302 *
303 * @param index
304 * The index must be between 0 and length() - 1.
305 * @return The value.
306 * @throws JSONException
307 * If the key is not found or if the value cannot be converted
308 * to a number.
309 */
310 public long getLong(int index) throws JSONException {
311 Object o = get(index);
312 return o instanceof Number ? ((Number) o).longValue()
313 : (long) getDouble(index);
314 }
315
316 /**
317 * Get the string associated with an index.
318 *
319 * @param index
320 * The index must be between 0 and length() - 1.
321 * @return A string value.
322 * @throws JSONException
323 * If there is no value for the index.
324 */
325 public String getString(int index) throws JSONException {
326 return get(index).toString();
327 }
328
329 /**
330 * Determine if the value is null.
331 *
332 * @param index
333 * The index must be between 0 and length() - 1.
334 * @return true if the value at the index is null, or if there is no value.
335 */
336 public boolean isNull(int index) {
337 return JSONObject.NULL.equals(opt(index));
338 }
339
340 /**
341 * Make a string from the contents of this JSONArray. The
342 * <code>separator</code> string is inserted between each element.
343 * Warning: This method assumes that the data structure is acyclical.
344 *
345 * @param separator
346 * A string that will be inserted between the elements.
347 * @return a string.
348 * @throws JSONException
349 * If the array contains an invalid number.
350 */
351 public String join(String separator) throws JSONException {
352 int len = length();
353 StringBuffer sb = new StringBuffer();
354
355 for (int i = 0; i < len; i += 1) {
356 if (i > 0) {
357 sb.append(separator);
358 }
359 sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
360 }
361 return sb.toString();
362 }
363
364 /**
365 * Get the number of elements in the JSONArray, included nulls.
366 *
367 * @return The length (or size).
368 */
369 public int length() {
370 return this.myArrayList.size();
371 }
372
373 /**
374 * Get the optional object value associated with an index.
375 *
376 * @param index
377 * The index must be between 0 and length() - 1.
378 * @return An object value, or null if there is no object at that index.
379 */
380 public Object opt(int index) {
381 return (index < 0 || index >= length()) ? null : this.myArrayList
382 .get(index);
383 }
384
385 /**
386 * Get the optional boolean value associated with an index. It returns false
387 * if there is no value at that index, or if the value is not Boolean.TRUE
388 * or the String "true".
389 *
390 * @param index
391 * The index must be between 0 and length() - 1.
392 * @return The truth.
393 */
394 public boolean optBoolean(int index) {
395 return optBoolean(index, false);
396 }
397
398 /**
399 * Get the optional boolean value associated with an index. It returns the
400 * defaultValue if there is no value at that index or if it is not a Boolean
401 * or the String "true" or "false" (case insensitive).
402 *
403 * @param index
404 * The index must be between 0 and length() - 1.
405 * @param defaultValue
406 * A boolean default.
407 * @return The truth.
408 */
409 public boolean optBoolean(int index, boolean defaultValue) {
410 try {
411 return getBoolean(index);
412 } catch (Exception e) {
413 return defaultValue;
414 }
415 }
416
417 /**
418 * Get the optional double value associated with an index. NaN is returned
419 * if there is no value for the index, or if the value is not a number and
420 * cannot be converted to a number.
421 *
422 * @param index
423 * The index must be between 0 and length() - 1.
424 * @return The value.
425 */
426 public double optDouble(int index) {
427 return optDouble(index, Double.NaN);
428 }
429
430 /**
431 * Get the optional double value associated with an index. The defaultValue
432 * is returned if there is no value for the index, or if the value is not a
433 * number and cannot be converted to a number.
434 *
435 * @param index
436 * subscript
437 * @param defaultValue
438 * The default value.
439 * @return The value.
440 */
441 public double optDouble(int index, double defaultValue) {
442 try {
443 return getDouble(index);
444 } catch (Exception e) {
445 return defaultValue;
446 }
447 }
448
449 /**
450 * Get the optional int value associated with an index. Zero is returned if
451 * there is no value for the index, or if the value is not a number and
452 * cannot be converted to a number.
453 *
454 * @param index
455 * The index must be between 0 and length() - 1.
456 * @return The value.
457 */
458 public int optInt(int index) {
459 return optInt(index, 0);
460 }
461
462 /**
463 * Get the optional int value associated with an index. The defaultValue is
464 * returned if there is no value for the index, or if the value is not a
465 * number and cannot be converted to a number.
466 *
467 * @param index
468 * The index must be between 0 and length() - 1.
469 * @param defaultValue
470 * The default value.
471 * @return The value.
472 */
473 public int optInt(int index, int defaultValue) {
474 try {
475 return getInt(index);
476 } catch (Exception e) {
477 return defaultValue;
478 }
479 }
480
481 /**
482 * Get the optional JSONArray associated with an index.
483 *
484 * @param index
485 * subscript
486 * @return A JSONArray value, or null if the index has no value, or if the
487 * value is not a JSONArray.
488 */
489 public JSONArray optJSONArray(int index) {
490 Object o = opt(index);
491 return o instanceof JSONArray ? (JSONArray) o : null;
492 }
493
494 /**
495 * Get the optional JSONObject associated with an index. Null is returned if
496 * the key is not found, or null if the index has no value, or if the value
497 * is not a JSONObject.
498 *
499 * @param index
500 * The index must be between 0 and length() - 1.
501 * @return A JSONObject value.
502 */
503 public JSONObject optJSONObject(int index) {
504 Object o = opt(index);
505 return o instanceof JSONObject ? (JSONObject) o : null;
506 }
507
508 /**
509 * Get the optional long value associated with an index. Zero is returned if
510 * there is no value for the index, or if the value is not a number and
511 * cannot be converted to a number.
512 *
513 * @param index
514 * The index must be between 0 and length() - 1.
515 * @return The value.
516 */
517 public long optLong(int index) {
518 return optLong(index, 0);
519 }
520
521 /**
522 * Get the optional long value associated with an index. The defaultValue is
523 * returned if there is no value for the index, or if the value is not a
524 * number and cannot be converted to a number.
525 *
526 * @param index
527 * The index must be between 0 and length() - 1.
528 * @param defaultValue
529 * The default value.
530 * @return The value.
531 */
532 public long optLong(int index, long defaultValue) {
533 try {
534 return getLong(index);
535 } catch (Exception e) {
536 return defaultValue;
537 }
538 }
539
540 /**
541 * Get the optional string value associated with an index. It returns an
542 * empty string if there is no value at that index. If the value is not a
543 * string and is not null, then it is coverted to a string.
544 *
545 * @param index
546 * The index must be between 0 and length() - 1.
547 * @return A String value.
548 */
549 public String optString(int index) {
550 return optString(index, "");
551 }
552
553 /**
554 * Get the optional string associated with an index. The defaultValue is
555 * returned if the key is not found.
556 *
557 * @param index
558 * The index must be between 0 and length() - 1.
559 * @param defaultValue
560 * The default value.
561 * @return A String value.
562 */
563 public String optString(int index, String defaultValue) {
564 Object o = opt(index);
565 return o != null ? o.toString() : defaultValue;
566 }
567
568 /**
569 * Append a boolean value. This increases the array's length by one.
570 *
571 * @param value
572 * A boolean value.
573 * @return this.
574 */
575 public JSONArray put(boolean value) {
576 put(value ? Boolean.TRUE : Boolean.FALSE);
577 return this;
578 }
579
580 /**
581 * Put a value in the JSONArray, where the value will be a JSONArray which
582 * is produced from a Collection.
583 *
584 * @param value
585 * A Collection value.
586 * @return this.
587 */
588 public JSONArray put(Collection value) {
589 put(new JSONArray(value));
590 return this;
591 }
592
593 /**
594 * Append a double value. This increases the array's length by one.
595 *
596 * @param value
597 * A double value.
598 * @throws JSONException
599 * if the value is not finite.
600 * @return this.
601 */
602 public JSONArray put(double value) throws JSONException {
603 Double d = new Double(value);
604 JSONObject.testValidity(d);
605 put(d);
606 return this;
607 }
608
609 /**
610 * Append an int value. This increases the array's length by one.
611 *
612 * @param value
613 * An int value.
614 * @return this.
615 */
616 public JSONArray put(int value) {
617 put(new Integer(value));
618 return this;
619 }
620
621 /**
622 * Append an long value. This increases the array's length by one.
623 *
624 * @param value
625 * A long value.
626 * @return this.
627 */
628 public JSONArray put(long value) {
629 put(new Long(value));
630 return this;
631 }
632
633 /**
634 * Put a value in the JSONArray, where the value will be a JSONObject which
635 * is produced from a Map.
636 *
637 * @param value
638 * A Map value.
639 * @return this.
640 */
641 public JSONArray put(Map value) {
642 put(new JSONObject(value));
643 return this;
644 }
645
646 /**
647 * Append an object value. This increases the array's length by one.
648 *
649 * @param value
650 * An object value. The value should be a Boolean, Double,
651 * Integer, JSONArray, JSONObject, Long, or String, or the
652 * JSONObject.NULL object.
653 * @return this.
654 */
655 public JSONArray put(Object value) {
656 this.myArrayList.add(value);
657 return this;
658 }
659
660 /**
661 * Put or replace a boolean value in the JSONArray. If the index is greater
662 * than the length of the JSONArray, then null elements will be added as
663 * necessary to pad it out.
664 *
665 * @param index
666 * The subscript.
667 * @param value
668 * A boolean value.
669 * @return this.
670 * @throws JSONException
671 * If the index is negative.
672 */
673 public JSONArray put(int index, boolean value) throws JSONException {
674 put(index, value ? Boolean.TRUE : Boolean.FALSE);
675 return this;
676 }
677
678 /**
679 * Put a value in the JSONArray, where the value will be a JSONArray which
680 * is produced from a Collection.
681 *
682 * @param index
683 * The subscript.
684 * @param value
685 * A Collection value.
686 * @return this.
687 * @throws JSONException
688 * If the index is negative or if the value is not finite.
689 */
690 public JSONArray put(int index, Collection value) throws JSONException {
691 put(index, new JSONArray(value));
692 return this;
693 }
694
695 /**
696 * Put or replace a double value. If the index is greater than the length of
697 * the JSONArray, then null elements will be added as necessary to pad it
698 * out.
699 *
700 * @param index
701 * The subscript.
702 * @param value
703 * A double value.
704 * @return this.
705 * @throws JSONException
706 * If the index is negative or if the value is not finite.
707 */
708 public JSONArray put(int index, double value) throws JSONException {
709 put(index, new Double(value));
710 return this;
711 }
712
713 /**
714 * Put or replace an int value. If the index is greater than the length of
715 * the JSONArray, then null elements will be added as necessary to pad it
716 * out.
717 *
718 * @param index
719 * The subscript.
720 * @param value
721 * An int value.
722 * @return this.
723 * @throws JSONException
724 * If the index is negative.
725 */
726 public JSONArray put(int index, int value) throws JSONException {
727 put(index, new Integer(value));
728 return this;
729 }
730
731 /**
732 * Put or replace a long value. If the index is greater than the length of
733 * the JSONArray, then null elements will be added as necessary to pad it
734 * out.
735 *
736 * @param index
737 * The subscript.
738 * @param value
739 * A long value.
740 * @return this.
741 * @throws JSONException
742 * If the index is negative.
743 */
744 public JSONArray put(int index, long value) throws JSONException {
745 put(index, new Long(value));
746 return this;
747 }
748
749 /**
750 * Put a value in the JSONArray, where the value will be a JSONObject which
751 * is produced from a Map.
752 *
753 * @param index
754 * The subscript.
755 * @param value
756 * The Map value.
757 * @return this.
758 * @throws JSONException
759 * If the index is negative or if the the value is an invalid
760 * number.
761 */
762 public JSONArray put(int index, Map value) throws JSONException {
763 put(index, new JSONObject(value));
764 return this;
765 }
766
767 /**
768 * Put or replace an object value in the JSONArray. If the index is greater
769 * than the length of the JSONArray, then null elements will be added as
770 * necessary to pad it out.
771 *
772 * @param index
773 * The subscript.
774 * @param value
775 * The value to put into the array. The value should be a
776 * Boolean, Double, Integer, JSONArray, JSONObject, Long, or
777 * String, or the JSONObject.NULL object.
778 * @return this.
779 * @throws JSONException
780 * If the index is negative or if the the value is an invalid
781 * number.
782 */
783 public JSONArray put(int index, Object value) throws JSONException {
784 JSONObject.testValidity(value);
785 if (index < 0) {
786 throw new JSONException("JSONArray[" + index + "] not found.");
787 }
788 if (index < length()) {
789 this.myArrayList.set(index, value);
790 } else {
791 while (index != length()) {
792 put(JSONObject.NULL);
793 }
794 put(value);
795 }
796 return this;
797 }
798
799 /**
800 * Produce a JSONObject by combining a JSONArray of names with the values of
801 * this JSONArray.
802 *
803 * @param names
804 * A JSONArray containing a list of key strings. These will be
805 * paired with the values.
806 * @return A JSONObject, or null if there are no names or if this JSONArray
807 * has no values.
808 * @throws JSONException
809 * If any of the names are null.
810 */
811 public JSONObject toJSONObject(JSONArray names) throws JSONException {
812 if (names == null || names.length() == 0 || length() == 0) {
813 return null;
814 }
815 JSONObject jo = new JSONObject();
816 for (int i = 0; i < names.length(); i += 1) {
817 jo.put(names.getString(i), this.opt(i));
818 }
819 return jo;
820 }
821
822 /**
823 * Make a JSON text of this JSONArray. For compactness, no unnecessary
824 * whitespace is added. If it is not possible to produce a syntactically
825 * correct JSON text then null will be returned instead. This could occur if
826 * the array contains an invalid number.
827 * <p>
828 * Warning: This method assumes that the data structure is acyclical.
829 *
830 * @return a printable, displayable, transmittable representation of the
831 * array.
832 */
833 public String toString() {
834 try {
835 return '[' + join(",") + ']';
836 } catch (Exception e) {
837 return null;
838 }
839 }
840
841 /**
842 * Make a prettyprinted JSON text of this JSONArray. Warning: This method
843 * assumes that the data structure is acyclical.
844 *
845 * @param indentFactor
846 * The number of spaces to add to each level of indentation.
847 * @return a printable, displayable, transmittable representation of the
848 * object, beginning with <code>[</code> <small>(left
849 * bracket)</small> and ending with <code>]</code> <small>(right
850 * bracket)</small>.
851 * @throws JSONException
852 */
853 public String toString(int indentFactor) throws JSONException {
854 return toString(indentFactor, 0);
855 }
856
857 /**
858 * Make a prettyprinted JSON text of this JSONArray. Warning: This method
859 * assumes that the data structure is acyclical.
860 *
861 * @param indentFactor
862 * The number of spaces to add to each level of indentation.
863 * @param indent
864 * The indention of the top level.
865 * @return a printable, displayable, transmittable representation of the
866 * array.
867 * @throws JSONException
868 */
869 String toString(int indentFactor, int indent) throws JSONException {
870 int len = length();
871 if (len == 0) {
872 return "[]";
873 }
874 int i;
875 StringBuffer sb = new StringBuffer("[");
876 if (len == 1) {
877 sb.append(JSONObject.valueToString(this.myArrayList.get(0),
878 indentFactor, indent));
879 } else {
880 int newindent = indent + indentFactor;
881 sb.append('\n');
882 for (i = 0; i < len; i += 1) {
883 if (i > 0) {
884 sb.append(",\n");
885 }
886 for (int j = 0; j < newindent; j += 1) {
887 sb.append(' ');
888 }
889 sb.append(JSONObject.valueToString(this.myArrayList.get(i),
890 indentFactor, newindent));
891 }
892 sb.append('\n');
893 for (i = 0; i < indent; i += 1) {
894 sb.append(' ');
895 }
896 }
897 sb.append(']');
898 return sb.toString();
899 }
900
901 /**
902 * Write the contents of the JSONArray as JSON text to a writer. For
903 * compactness, no whitespace is added.
904 * <p>
905 * Warning: This method assumes that the data structure is acyclical.
906 *
907 * @return The writer.
908 * @throws JSONException
909 */
910 public Writer write(Writer writer) throws JSONException {
911 try {
912 boolean b = false;
913 int len = length();
914
915 writer.write('[');
916
917 for (int i = 0; i < len; i += 1) {
918 if (b) {
919 writer.write(',');
920 }
921 Object v = this.myArrayList.get(i);
922 if (v instanceof JSONObject) {
923 ((JSONObject) v).write(writer);
924 } else if (v instanceof JSONArray) {
925 ((JSONArray) v).write(writer);
926 } else {
927 writer.write(JSONObject.valueToString(v));
928 }
929 b = true;
930 }
931 writer.write(']');
932 return writer;
933 } catch (IOException e) {
934 throw new JSONException(e);
935 }
936 }
937 }