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