View Javadoc

1   package atg.taglib.json.util;
2   
3   /*
4   Copyright (c) 2002 JSON.org
5   
6   Permission is hereby granted, free of charge, to any person obtaining a copy
7   of this software and associated documentation files (the "Software"), to deal
8   in the Software without restriction, including without limitation the rights
9   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  copies of the Software, and to permit persons to whom the Software is
11  furnished to do so, subject to the following conditions:
12  
13  The above copyright notice and this permission notice shall be included in all
14  copies or substantial portions of the Software.
15  
16  The Software shall be used for Good, not Evil.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  SOFTWARE.
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>&nbsp;<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>&nbsp;<small>(comma)</small> elision.</li>
68   * <li>Strings may be quoted with <code>'</code>&nbsp;<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>&nbsp;<small>(left bracket)</small>
147      *  and ends with <code>]</code>&nbsp;<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>&nbsp;<small>(left bracket)</small> and ending
737      *  with <code>]</code>&nbsp;<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         // this shouldn't happen, since we are Cloneable
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 }