1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.json;
17
18 import java.io.IOException;
19 import java.io.Writer;
20 import java.lang.reflect.Array;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.ConcurrentModificationException;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.ListIterator;
28 import java.util.Map;
29 import java.util.NoSuchElementException;
30 import java.util.Set;
31
32 import net.sf.ezmorph.Morpher;
33 import net.sf.ezmorph.object.IdentityObjectMorpher;
34 import net.sf.json.processors.JsonValueProcessor;
35 import net.sf.json.processors.JsonVerifier;
36 import net.sf.json.util.JSONTokener;
37 import net.sf.json.util.JSONUtils;
38
39 import org.apache.commons.lang.StringUtils;
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public final class JSONArray extends AbstractJSON implements JSON, List, Comparable {
90
91
92
93
94
95
96
97
98
99 public static JSONArray fromObject( Object object ) {
100 return fromObject( object, new JsonConfig() );
101 }
102
103
104
105
106
107
108
109
110
111
112 public static JSONArray fromObject( Object object, JsonConfig jsonConfig ) {
113 if( object instanceof JSONString ){
114 return _fromJSONString( (JSONString) object, jsonConfig );
115 }else if( object instanceof JSONArray ){
116 return _fromJSONArray( (JSONArray) object, jsonConfig );
117 }else if( object instanceof Collection ){
118 return _fromCollection( (Collection) object, jsonConfig );
119 }else if( object instanceof JSONTokener ){
120 return _fromJSONTokener( (JSONTokener) object, jsonConfig );
121 }else if( object instanceof String ){
122 return _fromString( (String) object, jsonConfig );
123 }else if( object != null && object.getClass()
124 .isArray() ){
125 Class type = object.getClass()
126 .getComponentType();
127 if( !type.isPrimitive() ){
128 return _fromArray( (Object[]) object, jsonConfig );
129 }else{
130 if( type == Boolean.TYPE ){
131 return _fromArray( (boolean[]) object, jsonConfig );
132 }else if( type == Byte.TYPE ){
133 return _fromArray( (byte[]) object, jsonConfig );
134 }else if( type == Short.TYPE ){
135 return _fromArray( (short[]) object, jsonConfig );
136 }else if( type == Integer.TYPE ){
137 return _fromArray( (int[]) object, jsonConfig );
138 }else if( type == Long.TYPE ){
139 return _fromArray( (long[]) object, jsonConfig );
140 }else if( type == Float.TYPE ){
141 return _fromArray( (float[]) object, jsonConfig );
142 }else if( type == Double.TYPE ){
143 return _fromArray( (double[]) object, jsonConfig );
144 }else if( type == Character.TYPE ){
145 return _fromArray( (char[]) object, jsonConfig );
146 }else{
147 throw new JSONException( "Unsupported type" );
148 }
149 }
150 }else if( JSONUtils.isBoolean( object ) || JSONUtils.isFunction( object )
151 || JSONUtils.isNumber( object ) || JSONUtils.isNull( object )
152 || JSONUtils.isString( object ) || object instanceof JSON ){
153 fireArrayStartEvent( jsonConfig );
154 JSONArray jsonArray = new JSONArray().element( object, jsonConfig );
155 fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig );
156 fireArrayStartEvent( jsonConfig );
157 return jsonArray;
158 }else if( JSONUtils.isObject( object ) ){
159 fireArrayStartEvent( jsonConfig );
160 JSONArray jsonArray = new JSONArray().element( JSONObject.fromObject( object, jsonConfig ) );
161 fireElementAddedEvent( 0, jsonArray.get( 0 ), jsonConfig );
162 fireArrayStartEvent( jsonConfig );
163 return jsonArray;
164 }else{
165 throw new JSONException( "Unsupported type" );
166 }
167 }
168
169
170
171
172 public static int[] getDimensions( JSONArray jsonArray ) {
173
174 if( jsonArray == null || jsonArray.isEmpty() ){
175 return new int[] { 0 };
176 }
177
178 List dims = new ArrayList();
179 processArrayDimensions( jsonArray, dims, 0 );
180 int[] dimensions = new int[dims.size()];
181 int j = 0;
182 for( Iterator i = dims.iterator(); i.hasNext(); ){
183 dimensions[j++] = ((Integer) i.next()).intValue();
184 }
185 return dimensions;
186 }
187
188
189
190
191 public static Object toArray( JSONArray jsonArray ) {
192 return toArray( jsonArray, new JsonConfig() );
193 }
194
195
196
197
198 public static Object toArray( JSONArray jsonArray, Class objectClass ) {
199 JsonConfig jsonConfig = new JsonConfig();
200 jsonConfig.setRootClass( objectClass );
201 return toArray( jsonArray, jsonConfig );
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 public static Object toArray( JSONArray jsonArray, Class objectClass, Map classMap ) {
216 JsonConfig jsonConfig = new JsonConfig();
217 jsonConfig.setRootClass( objectClass );
218 jsonConfig.setClassMap( classMap );
219 return toArray( jsonArray, jsonConfig );
220 }
221
222
223
224
225 public static Object toArray( JSONArray jsonArray, JsonConfig jsonConfig ) {
226 Class objectClass = jsonConfig.getRootClass();
227 Map classMap = jsonConfig.getClassMap();
228
229 if( jsonArray.size() == 0 ){
230 return Array.newInstance( objectClass == null ? Object.class : objectClass, 0 );
231 }
232
233 int[] dimensions = JSONArray.getDimensions( jsonArray );
234 Object array = Array.newInstance( objectClass == null ? Object.class : objectClass,
235 dimensions );
236 int size = jsonArray.size();
237 for( int i = 0; i < size; i++ ){
238 Object value = jsonArray.get( i );
239 if( JSONUtils.isNull( value ) ){
240 Array.set( array, i, null );
241 }else{
242 Class type = value.getClass();
243 if( JSONArray.class.isAssignableFrom( type ) ){
244 Array.set( array, i, toArray( (JSONArray) value, objectClass, classMap ) );
245 }else if( String.class.isAssignableFrom( type )
246 || Boolean.class.isAssignableFrom( type )
247 || Character.class.isAssignableFrom( type )
248 || JSONFunction.class.isAssignableFrom( type ) ){
249 if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
250 value = JSONUtils.getMorpherRegistry()
251 .morph( objectClass, value );
252 }
253 Array.set( array, i, value );
254 }else if( JSONUtils.isNumber( type ) ){
255 if( objectClass != null
256 && (Byte.class.isAssignableFrom( objectClass ) || Byte.TYPE.isAssignableFrom( objectClass )) ){
257 Array.set( array, i, Byte.valueOf( String.valueOf( value ) ) );
258 }else if( objectClass != null
259 && (Short.class.isAssignableFrom( objectClass ) || Short.TYPE.isAssignableFrom( objectClass )) ){
260 Array.set( array, i, Short.valueOf( String.valueOf( value ) ) );
261 }else{
262 Array.set( array, i, value );
263 }
264 }else{
265 if( objectClass != null ){
266 JsonConfig jsc = jsonConfig.copy();
267 jsc.setRootClass( objectClass );
268 jsc.setClassMap( classMap );
269 Array.set( array, i, JSONObject.toBean( (JSONObject) value, jsc ) );
270 }else{
271 Array.set( array, i, JSONObject.toBean( (JSONObject) value ) );
272 }
273 }
274 }
275 }
276 return array;
277 }
278
279
280
281
282 public static Object toArray( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) {
283 Class objectClass = root.getClass();
284 if( jsonArray.size() == 0 ){
285 return Array.newInstance( objectClass, 0 );
286 }
287
288 int[] dimensions = JSONArray.getDimensions( jsonArray );
289 Object array = Array.newInstance( objectClass == null ? Object.class : objectClass,
290 dimensions );
291 int size = jsonArray.size();
292 for( int i = 0; i < size; i++ ){
293 Object value = jsonArray.get( i );
294 if( JSONUtils.isNull( value ) ){
295 Array.set( array, i, null );
296 }else{
297 Class type = value.getClass();
298 if( JSONArray.class.isAssignableFrom( type ) ){
299 Array.set( array, i, toArray( (JSONArray) value, root, jsonConfig ) );
300 }else if( String.class.isAssignableFrom( type )
301 || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
302 || Character.class.isAssignableFrom( type )
303 || JSONFunction.class.isAssignableFrom( type ) ){
304 if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
305 value = JSONUtils.getMorpherRegistry()
306 .morph( objectClass, value );
307 }
308 Array.set( array, i, value );
309 }else{
310 try{
311 Object newRoot = jsonConfig.getNewBeanInstanceStrategy()
312 .newInstance( root.getClass(), null );
313 Array.set( array, i, JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) );
314 }catch( JSONException jsone ){
315 throw jsone;
316 }catch( Exception e ){
317 throw new JSONException( e );
318 }
319 }
320 }
321 }
322 return array;
323 }
324
325
326
327
328 public static Collection toCollection( JSONArray jsonArray ) {
329 return toCollection( jsonArray, new JsonConfig() );
330 }
331
332
333
334
335 public static Collection toCollection( JSONArray jsonArray, Class objectClass ) {
336 JsonConfig jsonConfig = new JsonConfig();
337 jsonConfig.setRootClass( objectClass );
338 return toCollection( jsonArray, jsonConfig );
339 }
340
341
342
343
344
345 public static Collection toCollection( JSONArray jsonArray, JsonConfig jsonConfig ) {
346 Collection collection = null;
347 Class collectionType = jsonConfig.getCollectionType();
348
349 if( collectionType.isInterface() ){
350 if( collectionType.equals( List.class ) ){
351 collection = new ArrayList();
352 }else if( collectionType.equals( Set.class ) ){
353 collection = new HashSet();
354 }else{
355 throw new JSONException( "unknown interface: " + collectionType );
356 }
357 }else{
358 try{
359 collection = (Collection) collectionType.newInstance();
360 }catch( InstantiationException e ){
361 throw new JSONException( e );
362 }catch( IllegalAccessException e ){
363 throw new JSONException( e );
364 }
365 }
366
367 Class objectClass = jsonConfig.getRootClass();
368 Map classMap = jsonConfig.getClassMap();
369
370 int size = jsonArray.size();
371 for( int i = 0; i < size; i++ ){
372 Object value = jsonArray.get( i );
373
374 if( JSONUtils.isNull( value ) ){
375 collection.add( null );
376 }else{
377 Class type = value.getClass();
378 if( JSONArray.class.isAssignableFrom( value.getClass() ) ){
379 collection.add( toCollection( (JSONArray) value, jsonConfig ) );
380 }else if( String.class.isAssignableFrom( type )
381 || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
382 || Character.class.isAssignableFrom( type )
383 || JSONFunction.class.isAssignableFrom( type ) ){
384
385 if( !value.getClass()
386 .isAssignableFrom( type ) ){
387 throw new JSONException( "can't assign value " + value + " of type "
388 + value.getClass() + " to Collection of type " + type );
389 }
390 collection.add( value );
391 }else{
392 if( objectClass != null ){
393 JsonConfig jsc = jsonConfig.copy();
394 jsc.setRootClass( objectClass );
395 jsc.setClassMap( classMap );
396 collection.add( JSONObject.toBean( (JSONObject) value, jsc ) );
397 }else{
398 collection.add( JSONObject.toBean( (JSONObject) value ) );
399 }
400 }
401 }
402 }
403
404 return collection;
405 }
406
407
408
409
410
411
412
413 public static List toList( JSONArray jsonArray ) {
414 return toList( jsonArray, new JsonConfig() );
415 }
416
417
418
419
420
421
422
423 public static List toList( JSONArray jsonArray, Class objectClass ) {
424 JsonConfig jsonConfig = new JsonConfig();
425 jsonConfig.setRootClass( objectClass );
426 return toList( jsonArray, jsonConfig );
427 }
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443 public static List toList( JSONArray jsonArray, Class objectClass, Map classMap ) {
444 JsonConfig jsonConfig = new JsonConfig();
445 jsonConfig.setRootClass( objectClass );
446 jsonConfig.setClassMap( classMap );
447 return toList( jsonArray, jsonConfig );
448 }
449
450
451
452
453
454
455
456 public static List toList( JSONArray jsonArray, JsonConfig jsonConfig ) {
457 if( jsonArray.size() == 0 ){
458 return new ArrayList();
459 }
460
461 Class objectClass = jsonConfig.getRootClass();
462 Map classMap = jsonConfig.getClassMap();
463
464 List list = new ArrayList();
465 int size = jsonArray.size();
466 for( int i = 0; i < size; i++ ){
467 Object value = jsonArray.get( i );
468 if( JSONUtils.isNull( value ) ){
469 list.add( null );
470 }else{
471 Class type = value.getClass();
472 if( JSONArray.class.isAssignableFrom( type ) ){
473 list.add( toList( (JSONArray) value, objectClass, classMap ) );
474 }else if( String.class.isAssignableFrom( type )
475 || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
476 || Character.class.isAssignableFrom( type )
477 || JSONFunction.class.isAssignableFrom( type ) ){
478 if( objectClass != null && !objectClass.isAssignableFrom( type ) ){
479 value = JSONUtils.getMorpherRegistry()
480 .morph( objectClass, value );
481 }
482 list.add( value );
483 }else{
484 if( objectClass != null ){
485 JsonConfig jsc = jsonConfig.copy();
486 jsc.setRootClass( objectClass );
487 jsc.setClassMap( classMap );
488 list.add( JSONObject.toBean( (JSONObject) value, jsc ) );
489 }else{
490 list.add( JSONObject.toBean( (JSONObject) value ) );
491 }
492 }
493 }
494 }
495 return list;
496 }
497
498
499
500
501 public static List toList( JSONArray jsonArray, Object root, JsonConfig jsonConfig ) {
502 if( jsonArray.size() == 0 || root == null ){
503 return new ArrayList();
504 }
505
506 List list = new ArrayList();
507 int size = jsonArray.size();
508 for( int i = 0; i < size; i++ ){
509 Object value = jsonArray.get( i );
510 if( JSONUtils.isNull( value ) ){
511 list.add( null );
512 }else{
513 Class type = value.getClass();
514 if( JSONArray.class.isAssignableFrom( type ) ){
515 list.add( toList( (JSONArray) value, root, jsonConfig ) );
516 }else if( String.class.isAssignableFrom( type )
517 || Boolean.class.isAssignableFrom( type ) || JSONUtils.isNumber( type )
518 || Character.class.isAssignableFrom( type )
519 || JSONFunction.class.isAssignableFrom( type ) ){
520 list.add( value );
521 }else{
522 try{
523 Object newRoot = jsonConfig.getNewBeanInstanceStrategy()
524 .newInstance( root.getClass(), null );
525 list.add( JSONObject.toBean( (JSONObject) value, newRoot, jsonConfig ) );
526 }catch( JSONException jsone ){
527 throw jsone;
528 }catch( Exception e ){
529 throw new JSONException( e );
530 }
531 }
532 }
533 }
534 return list;
535 }
536
537
538
539
540
541
542 private static JSONArray _fromArray( boolean[] array, JsonConfig jsonConfig ) {
543 if( !addInstance( array ) ){
544 try{
545 return jsonConfig.getCycleDetectionStrategy()
546 .handleRepeatedReferenceAsArray( array );
547 }catch( JSONException jsone ){
548 removeInstance( array );
549 fireErrorEvent( jsone, jsonConfig );
550 throw jsone;
551 }catch( RuntimeException e ){
552 removeInstance( array );
553 JSONException jsone = new JSONException( e );
554 fireErrorEvent( jsone, jsonConfig );
555 throw jsone;
556 }
557 }
558 fireArrayStartEvent( jsonConfig );
559
560 JSONArray jsonArray = new JSONArray();
561 for( int i = 0; i < array.length; i++ ){
562 Boolean b = array[i] ? Boolean.TRUE : Boolean.FALSE;
563 jsonArray.addValue( b, jsonConfig );
564 fireElementAddedEvent( i, b, jsonConfig );
565 }
566
567 removeInstance( array );
568 fireArrayEndEvent( jsonConfig );
569 return jsonArray;
570 }
571
572
573
574
575
576
577 private static JSONArray _fromArray( byte[] array, JsonConfig jsonConfig ) {
578 if( !addInstance( array ) ){
579 try{
580 return jsonConfig.getCycleDetectionStrategy()
581 .handleRepeatedReferenceAsArray( array );
582 }catch( JSONException jsone ){
583 removeInstance( array );
584 fireErrorEvent( jsone, jsonConfig );
585 throw jsone;
586 }catch( RuntimeException e ){
587 removeInstance( array );
588 JSONException jsone = new JSONException( e );
589 fireErrorEvent( jsone, jsonConfig );
590 throw jsone;
591 }
592 }
593 fireArrayStartEvent( jsonConfig );
594
595 JSONArray jsonArray = new JSONArray();
596 for( int i = 0; i < array.length; i++ ){
597 Number n = JSONUtils.transformNumber( new Byte( array[i] ) );
598 jsonArray.addValue( n, jsonConfig );
599 fireElementAddedEvent( i, n, jsonConfig );
600 }
601
602 removeInstance( array );
603 fireArrayEndEvent( jsonConfig );
604 return jsonArray;
605 }
606
607
608
609
610
611
612 private static JSONArray _fromArray( char[] array, JsonConfig jsonConfig ) {
613 if( !addInstance( array ) ){
614 try{
615 return jsonConfig.getCycleDetectionStrategy()
616 .handleRepeatedReferenceAsArray( array );
617 }catch( JSONException jsone ){
618 removeInstance( array );
619 fireErrorEvent( jsone, jsonConfig );
620 throw jsone;
621 }catch( RuntimeException e ){
622 removeInstance( array );
623 JSONException jsone = new JSONException( e );
624 fireErrorEvent( jsone, jsonConfig );
625 throw jsone;
626 }
627 }
628 fireArrayStartEvent( jsonConfig );
629
630 JSONArray jsonArray = new JSONArray();
631 for( int i = 0; i < array.length; i++ ){
632 Character c = new Character( array[i] );
633 jsonArray.addValue( c, jsonConfig );
634 fireElementAddedEvent( i, c, jsonConfig );
635 }
636
637 removeInstance( array );
638 fireArrayEndEvent( jsonConfig );
639 return jsonArray;
640 }
641
642
643
644
645
646
647 private static JSONArray _fromArray( double[] array, JsonConfig jsonConfig ) {
648 if( !addInstance( array ) ){
649 try{
650 return jsonConfig.getCycleDetectionStrategy()
651 .handleRepeatedReferenceAsArray( array );
652 }catch( JSONException jsone ){
653 removeInstance( array );
654 fireErrorEvent( jsone, jsonConfig );
655 throw jsone;
656 }catch( RuntimeException e ){
657 removeInstance( array );
658 JSONException jsone = new JSONException( e );
659 fireErrorEvent( jsone, jsonConfig );
660 throw jsone;
661 }
662 }
663 fireArrayStartEvent( jsonConfig );
664
665 JSONArray jsonArray = new JSONArray();
666 try{
667 for( int i = 0; i < array.length; i++ ){
668 Double d = new Double( array[i] );
669 JSONUtils.testValidity( d );
670 jsonArray.addValue( d, jsonConfig );
671 fireElementAddedEvent( i, d, jsonConfig );
672 }
673 }catch( JSONException jsone ){
674 removeInstance( array );
675 fireErrorEvent( jsone, jsonConfig );
676 throw jsone;
677 }
678
679 removeInstance( array );
680 fireArrayEndEvent( jsonConfig );
681 return jsonArray;
682 }
683
684
685
686
687
688
689 private static JSONArray _fromArray( float[] array, JsonConfig jsonConfig ) {
690 if( !addInstance( array ) ){
691 try{
692 return jsonConfig.getCycleDetectionStrategy()
693 .handleRepeatedReferenceAsArray( array );
694 }catch( JSONException jsone ){
695 removeInstance( array );
696 fireErrorEvent( jsone, jsonConfig );
697 throw jsone;
698 }catch( RuntimeException e ){
699 removeInstance( array );
700 JSONException jsone = new JSONException( e );
701 fireErrorEvent( jsone, jsonConfig );
702 throw jsone;
703 }
704 }
705 fireArrayStartEvent( jsonConfig );
706
707 JSONArray jsonArray = new JSONArray();
708 try{
709 for( int i = 0; i < array.length; i++ ){
710 Float f = new Float( array[i] );
711 JSONUtils.testValidity( f );
712 jsonArray.addValue( f, jsonConfig );
713 fireElementAddedEvent( i, f, jsonConfig );
714 }
715 }catch( JSONException jsone ){
716 removeInstance( array );
717 fireErrorEvent( jsone, jsonConfig );
718 throw jsone;
719 }
720
721 removeInstance( array );
722 fireArrayEndEvent( jsonConfig );
723 return jsonArray;
724 }
725
726
727
728
729
730
731 private static JSONArray _fromArray( int[] array, JsonConfig jsonConfig ) {
732 if( !addInstance( array ) ){
733 try{
734 return jsonConfig.getCycleDetectionStrategy()
735 .handleRepeatedReferenceAsArray( array );
736 }catch( JSONException jsone ){
737 removeInstance( array );
738 fireErrorEvent( jsone, jsonConfig );
739 throw jsone;
740 }catch( RuntimeException e ){
741 removeInstance( array );
742 JSONException jsone = new JSONException( e );
743 fireErrorEvent( jsone, jsonConfig );
744 throw jsone;
745 }
746 }
747 fireArrayStartEvent( jsonConfig );
748
749 JSONArray jsonArray = new JSONArray();
750 for( int i = 0; i < array.length; i++ ){
751 Number n = new Integer( array[i] );
752 jsonArray.addValue( n, jsonConfig );
753 fireElementAddedEvent( i, n, jsonConfig );
754 }
755
756 removeInstance( array );
757 fireArrayEndEvent( jsonConfig );
758 return jsonArray;
759 }
760
761
762
763
764
765
766 private static JSONArray _fromArray( long[] array, JsonConfig jsonConfig ) {
767 if( !addInstance( array ) ){
768 try{
769 return jsonConfig.getCycleDetectionStrategy()
770 .handleRepeatedReferenceAsArray( array );
771 }catch( JSONException jsone ){
772 removeInstance( array );
773 fireErrorEvent( jsone, jsonConfig );
774 throw jsone;
775 }catch( RuntimeException e ){
776 removeInstance( array );
777 JSONException jsone = new JSONException( e );
778 fireErrorEvent( jsone, jsonConfig );
779 throw jsone;
780 }
781 }
782 fireArrayStartEvent( jsonConfig );
783
784 JSONArray jsonArray = new JSONArray();
785 for( int i = 0; i < array.length; i++ ){
786 Number n = JSONUtils.transformNumber( new Long( array[i] ) );
787 jsonArray.addValue( n, jsonConfig );
788 fireElementAddedEvent( i, n, jsonConfig );
789 }
790
791 removeInstance( array );
792 fireArrayEndEvent( jsonConfig );
793 return jsonArray;
794 }
795
796
797
798 private static JSONArray _fromArray( Object[] array, JsonConfig jsonConfig ) {
799 if( !addInstance( array ) ){
800 try{
801 return jsonConfig.getCycleDetectionStrategy()
802 .handleRepeatedReferenceAsArray( array );
803 }catch( JSONException jsone ){
804 removeInstance( array );
805 fireErrorEvent( jsone, jsonConfig );
806 throw jsone;
807 }catch( RuntimeException e ){
808 removeInstance( array );
809 JSONException jsone = new JSONException( e );
810 fireErrorEvent( jsone, jsonConfig );
811 throw jsone;
812 }
813 }
814 fireArrayStartEvent( jsonConfig );
815
816 JSONArray jsonArray = new JSONArray();
817 try{
818 for( int i = 0; i < array.length; i++ ){
819 Object element = array[i];
820 jsonArray.addValue( element, jsonConfig );
821 fireElementAddedEvent( i, jsonArray.get( i ), jsonConfig );
822 }
823 }catch( JSONException jsone ){
824 removeInstance( array );
825 fireErrorEvent( jsone, jsonConfig );
826 throw jsone;
827 }catch( RuntimeException e ){
828 removeInstance( array );
829 JSONException jsone = new JSONException( e );
830 fireErrorEvent( jsone, jsonConfig );
831 throw jsone;
832 }
833
834 removeInstance( array );
835 fireArrayEndEvent( jsonConfig );
836 return jsonArray;
837 }
838
839
840
841
842
843
844 private static JSONArray _fromArray( short[] array, JsonConfig jsonConfig ) {
845 if( !addInstance( array ) ){
846 try{
847 return jsonConfig.getCycleDetectionStrategy()
848 .handleRepeatedReferenceAsArray( array );
849 }catch( JSONException jsone ){
850 removeInstance( array );
851 fireErrorEvent( jsone, jsonConfig );
852 throw jsone;
853 }catch( RuntimeException e ){
854 removeInstance( array );
855 JSONException jsone = new JSONException( e );
856 fireErrorEvent( jsone, jsonConfig );
857 throw jsone;
858 }
859 }
860 fireArrayStartEvent( jsonConfig );
861
862 JSONArray jsonArray = new JSONArray();
863 for( int i = 0; i < array.length; i++ ){
864 Number n = JSONUtils.transformNumber( new Short( array[i] ) );
865 jsonArray.addValue( n, jsonConfig );
866 fireElementAddedEvent( i, n, jsonConfig );
867 }
868
869 removeInstance( array );
870 fireArrayEndEvent( jsonConfig );
871 return jsonArray;
872 }
873
874 private static JSONArray _fromCollection( Collection collection, JsonConfig jsonConfig ) {
875 if( !addInstance( collection ) ){
876 try{
877 return jsonConfig.getCycleDetectionStrategy()
878 .handleRepeatedReferenceAsArray( collection );
879 }catch( JSONException jsone ){
880 removeInstance( collection );
881 fireErrorEvent( jsone, jsonConfig );
882 throw jsone;
883 }catch( RuntimeException e ){
884 removeInstance( collection );
885 JSONException jsone = new JSONException( e );
886 fireErrorEvent( jsone, jsonConfig );
887 throw jsone;
888 }
889 }
890 fireArrayStartEvent( jsonConfig );
891
892 JSONArray jsonArray = new JSONArray();
893 try{
894 int i = 0;
895 for( Iterator elements = collection.iterator(); elements.hasNext(); ){
896 Object element = elements.next();
897 jsonArray.addValue( element, jsonConfig );
898 fireElementAddedEvent( i, jsonArray.get( i++ ), jsonConfig );
899 }
900 }catch( JSONException jsone ){
901 removeInstance( collection );
902 fireErrorEvent( jsone, jsonConfig );
903 throw jsone;
904 }catch( RuntimeException e ){
905 removeInstance( collection );
906 JSONException jsone = new JSONException( e );
907 fireErrorEvent( jsone, jsonConfig );
908 throw jsone;
909 }
910
911 removeInstance( collection );
912 fireArrayEndEvent( jsonConfig );
913 return jsonArray;
914 }
915
916 private static JSONArray _fromJSONArray( JSONArray array, JsonConfig jsonConfig ) {
917 if( !addInstance( array ) ){
918 try{
919 return jsonConfig.getCycleDetectionStrategy()
920 .handleRepeatedReferenceAsArray( array );
921 }catch( JSONException jsone ){
922 removeInstance( array );
923 fireErrorEvent( jsone, jsonConfig );
924 throw jsone;
925 }catch( RuntimeException e ){
926 removeInstance( array );
927 JSONException jsone = new JSONException( e );
928 fireErrorEvent( jsone, jsonConfig );
929 throw jsone;
930 }
931 }
932 fireArrayStartEvent( jsonConfig );
933
934 JSONArray jsonArray = new JSONArray();
935 int index = 0;
936 for( Iterator elements = array.iterator(); elements.hasNext(); ){
937 Object element = elements.next();
938 jsonArray.addValue( element, jsonConfig );
939 fireElementAddedEvent( index++, element, jsonConfig );
940 }
941
942 removeInstance( array );
943 fireArrayEndEvent( jsonConfig );
944 return jsonArray;
945 }
946
947 private static JSONArray _fromJSONString( JSONString string, JsonConfig jsonConfig ) {
948 return _fromJSONTokener( new JSONTokener( string.toJSONString() ), jsonConfig );
949 }
950
951 private static JSONArray _fromJSONTokener( JSONTokener tokener, JsonConfig jsonConfig ) {
952 JSONArray jsonArray = new JSONArray();
953 int index = 0;
954
955 try{
956 if( tokener.nextClean() != '[' ){
957 throw tokener.syntaxError( "A JSONArray text must start with '['" );
958 }
959
960 fireArrayStartEvent( jsonConfig );
961 if( tokener.nextClean() == ']' ){
962 fireArrayEndEvent( jsonConfig );
963 return jsonArray;
964 }
965 tokener.back();
966 for( ;; ){
967 if( tokener.nextClean() == ',' ){
968 tokener.back();
969 jsonArray.elements.add( JSONNull.getInstance() );
970 fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
971 }else{
972 tokener.back();
973 Object v = tokener.nextValue( jsonConfig );
974 if( !JSONUtils.isFunctionHeader( v ) ){
975 if( v instanceof String && JSONUtils.mayBeJSON( (String) v ) ){
976 jsonArray.addValue( JSONUtils.DOUBLE_QUOTE + v + JSONUtils.DOUBLE_QUOTE,
977 jsonConfig );
978 }else{
979 jsonArray.addValue( v, jsonConfig );
980 }
981 fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
982 }else{
983
984 String params = JSONUtils.getFunctionParams( (String) v );
985
986 int i = 0;
987 StringBuffer sb = new StringBuffer();
988 for( ;; ){
989 char ch = tokener.next();
990 if( ch == 0 ){
991 break;
992 }
993 if( ch == '{' ){
994 i++;
995 }
996 if( ch == '}' ){
997 i--;
998 }
999 sb.append( ch );
1000 if( i == 0 ){
1001 break;
1002 }
1003 }
1004 if( i != 0 ){
1005 throw tokener.syntaxError( "Unbalanced '{' or '}' on prop: " + v );
1006 }
1007
1008 String text = sb.toString();
1009 text = text.substring( 1, text.length() - 1 )
1010 .trim();
1011 jsonArray.addValue( new JSONFunction( (params != null) ? StringUtils.split(
1012 params, "," ) : null, text ), jsonConfig );
1013 fireElementAddedEvent( index, jsonArray.get( index++ ), jsonConfig );
1014 }
1015 }
1016 switch( tokener.nextClean() ){
1017 case ';':
1018 case ',':
1019 if( tokener.nextClean() == ']' ){
1020 fireArrayEndEvent( jsonConfig );
1021 return jsonArray;
1022 }
1023 tokener.back();
1024 break;
1025 case ']':
1026 fireArrayEndEvent( jsonConfig );
1027 return jsonArray;
1028 default:
1029 throw tokener.syntaxError( "Expected a ',' or ']'" );
1030 }
1031 }
1032 }catch( JSONException jsone ){
1033 fireErrorEvent( jsone, jsonConfig );
1034 throw jsone;
1035 }
1036 }
1037
1038 private static JSONArray _fromString( String string, JsonConfig jsonConfig ) {
1039 return _fromJSONTokener( new JSONTokener( string ), jsonConfig );
1040 }
1041
1042 private static void processArrayDimensions( JSONArray jsonArray, List dims, int index ) {
1043 if( dims.size() <= index ){
1044 dims.add( new Integer( jsonArray.size() ) );
1045 }else{
1046 int i = ((Integer) dims.get( index )).intValue();
1047 if( jsonArray.size() > i ){
1048 dims.set( index, new Integer( jsonArray.size() ) );
1049 }
1050 }
1051 for( Iterator i = jsonArray.iterator(); i.hasNext(); ){
1052 Object item = i.next();
1053 if( item instanceof JSONArray ){
1054 processArrayDimensions( (JSONArray) item, dims, index + 1 );
1055 }
1056 }
1057 }
1058
1059
1060
1061
1062
1063
1064 private List elements;
1065
1066
1067
1068
1069 private boolean expandElements;
1070
1071
1072
1073
1074 public JSONArray() {
1075 this.elements = new ArrayList();
1076 }
1077
1078 public void add( int index, Object value ) {
1079 add( index, value, new JsonConfig() );
1080 }
1081
1082 public void add( int index, Object value, JsonConfig jsonConfig ) {
1083 this.elements.add( index, processValue( value, jsonConfig ) );
1084 }
1085
1086 public boolean add( Object value ) {
1087 return add( value, new JsonConfig() );
1088 }
1089
1090 public boolean add( Object value, JsonConfig jsonConfig ) {
1091 element( value, jsonConfig );
1092 return true;
1093 }
1094
1095 public boolean addAll( Collection collection ) {
1096 return addAll( collection, new JsonConfig() );
1097 }
1098
1099 public boolean addAll( Collection collection, JsonConfig jsonConfig ) {
1100 if( collection == null || collection.size() == 0 ){
1101 return false;
1102 }
1103 for( Iterator i = collection.iterator(); i.hasNext(); ){
1104 element( i.next(), jsonConfig );
1105 }
1106 return true;
1107 }
1108
1109 public boolean addAll( int index, Collection collection ) {
1110 return addAll( index, collection, new JsonConfig() );
1111 }
1112
1113 public boolean addAll( int index, Collection collection, JsonConfig jsonConfig ) {
1114 if( collection == null || collection.size() == 0 ){
1115 return false;
1116 }
1117 int offset = 0;
1118 for( Iterator i = collection.iterator(); i.hasNext(); ){
1119 this.elements.add( index + (offset++), processValue( i.next(), jsonConfig ) );
1120 }
1121 return true;
1122 }
1123
1124 public void clear() {
1125 elements.clear();
1126 }
1127
1128 public int compareTo( Object obj ) {
1129 if( obj != null && (obj instanceof JSONArray) ){
1130 JSONArray other = (JSONArray) obj;
1131 int size1 = size();
1132 int size2 = other.size();
1133 if( size1 < size2 ){
1134 return -1;
1135 }else if( size1 > size2 ){
1136 return 1;
1137 }else if( this.equals( other ) ){
1138 return 0;
1139 }
1140 }
1141 return -1;
1142 }
1143
1144 public boolean contains( Object o ) {
1145 return contains( o, new JsonConfig() );
1146 }
1147
1148 public boolean contains( Object o, JsonConfig jsonConfig ) {
1149 return elements.contains( processValue( o, jsonConfig ) );
1150 }
1151
1152 public boolean containsAll( Collection collection ) {
1153 return containsAll( collection, new JsonConfig() );
1154 }
1155
1156 public boolean containsAll( Collection collection, JsonConfig jsonConfig ) {
1157 return elements.containsAll( fromObject( collection, jsonConfig ) );
1158 }
1159
1160
1161
1162
1163
1164
1165
1166 public JSONArray discard( int index ) {
1167 elements.remove( index );
1168 return this;
1169 }
1170
1171
1172
1173
1174
1175
1176
1177 public JSONArray discard( Object o ) {
1178 elements.remove( o );
1179 return this;
1180 }
1181
1182
1183
1184
1185
1186
1187
1188 public JSONArray element( boolean value ) {
1189 return element( value ? Boolean.TRUE : Boolean.FALSE );
1190 }
1191
1192
1193
1194
1195
1196
1197
1198
1199 public JSONArray element( Collection value ) {
1200 return element( value, new JsonConfig() );
1201 }
1202
1203
1204
1205
1206
1207
1208
1209
1210 public JSONArray element( Collection value, JsonConfig jsonConfig ) {
1211 if( value instanceof JSONArray ){
1212 elements.add( value );
1213 return this;
1214 }else{
1215 return element( _fromCollection( value, jsonConfig ) );
1216 }
1217 }
1218
1219
1220
1221
1222
1223
1224
1225
1226 public JSONArray element( double value ) {
1227 Double d = new Double( value );
1228 JSONUtils.testValidity( d );
1229 return element( d );
1230 }
1231
1232
1233
1234
1235
1236
1237
1238 public JSONArray element( int value ) {
1239 return element( new Integer( value ) );
1240 }
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252 public JSONArray element( int index, boolean value ) {
1253 return element( index, value ? Boolean.TRUE : Boolean.FALSE );
1254 }
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266 public JSONArray element( int index, Collection value ) {
1267 return element( index, value, new JsonConfig() );
1268 }
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280 public JSONArray element( int index, Collection value, JsonConfig jsonConfig ) {
1281 if( value instanceof JSONArray ){
1282 if( index < 0 ){
1283 throw new JSONException( "JSONArray[" + index + "] not found." );
1284 }
1285 if( index < size() ){
1286 elements.set( index, value );
1287 }else{
1288 while( index != size() ){
1289 element( JSONNull.getInstance() );
1290 }
1291 element( value, jsonConfig );
1292 }
1293 return this;
1294 }else{
1295 return element( index, _fromCollection( value, jsonConfig ) );
1296 }
1297 }
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310 public JSONArray element( int index, double value ) {
1311 return element( index, new Double( value ) );
1312 }
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324 public JSONArray element( int index, int value ) {
1325 return element( index, new Integer( value ) );
1326 }
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338 public JSONArray element( int index, long value ) {
1339 return element( index, new Long( value ) );
1340 }
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 public JSONArray element( int index, Map value ) {
1353 return element( index, value, new JsonConfig() );
1354 }
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366 public JSONArray element( int index, Map value, JsonConfig jsonConfig ) {
1367 if( value instanceof JSONObject ){
1368 if( index < 0 ){
1369 throw new JSONException( "JSONArray[" + index + "] not found." );
1370 }
1371 if( index < size() ){
1372 elements.set( index, value );
1373 }else{
1374 while( index != size() ){
1375 element( JSONNull.getInstance() );
1376 }
1377 element( value, jsonConfig );
1378 }
1379 return this;
1380 }else{
1381 return element( index, JSONObject.fromObject( value, jsonConfig ) );
1382 }
1383 }
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398 public JSONArray element( int index, Object value ) {
1399 return element( index, value, new JsonConfig() );
1400 }
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415 public JSONArray element( int index, Object value, JsonConfig jsonConfig ) {
1416 JSONUtils.testValidity( value );
1417 if( index < 0 ){
1418 throw new JSONException( "JSONArray[" + index + "] not found." );
1419 }
1420 if( index < size() ){
1421 this.elements.set( index, processValue( value, jsonConfig ) );
1422 }else{
1423 while( index != size() ){
1424 element( JSONNull.getInstance() );
1425 }
1426 element( value, jsonConfig );
1427 }
1428 return this;
1429 }
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444 public JSONArray element( int index, String value ) {
1445 return element( index, value, new JsonConfig() );
1446 }
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461 public JSONArray element( int index, String value, JsonConfig jsonConfig ) {
1462 if( index < 0 ){
1463 throw new JSONException( "JSONArray[" + index + "] not found." );
1464 }
1465 if( index < size() ){
1466 if( value == null ){
1467 this.elements.set( index, "" );
1468 }else if( JSONUtils.mayBeJSON( value ) ){
1469 try{
1470 this.elements.set( index, JSONSerializer.toJSON( value, jsonConfig ) );
1471 }catch( JSONException jsone ){
1472 this.elements.set( index, JSONUtils.stripQuotes( value ) );
1473 }
1474 }else{
1475 this.elements.set( index, JSONUtils.stripQuotes( value ) );
1476 }
1477 }else{
1478 while( index != size() ){
1479 element( JSONNull.getInstance() );
1480 }
1481 element( value, jsonConfig );
1482 }
1483 return this;
1484 }
1485
1486
1487
1488
1489
1490
1491
1492 public JSONArray element( JSONNull value ) {
1493 this.elements.add( value );
1494 return this;
1495 }
1496
1497
1498
1499
1500
1501
1502
1503 public JSONArray element( JSONObject value ) {
1504 this.elements.add( value );
1505 return this;
1506 }
1507
1508
1509
1510
1511
1512
1513
1514 public JSONArray element( long value ) {
1515 return element( JSONUtils.transformNumber( new Long( value ) ) );
1516 }
1517
1518
1519
1520
1521
1522
1523
1524
1525 public JSONArray element( Map value ) {
1526 return element( value, new JsonConfig() );
1527 }
1528
1529
1530
1531
1532
1533
1534
1535
1536 public JSONArray element( Map value, JsonConfig jsonConfig ) {
1537 if( value instanceof JSONObject ){
1538 elements.add( value );
1539 return this;
1540 }else{
1541 return element( JSONObject.fromObject( value, jsonConfig ) );
1542 }
1543 }
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553 public JSONArray element( Object value ) {
1554 return element( value, new JsonConfig() );
1555 }
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565 public JSONArray element( Object value, JsonConfig jsonConfig ) {
1566 return addValue( value, jsonConfig );
1567 }
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577 public JSONArray element( String value ) {
1578 return element( value, new JsonConfig() );
1579 }
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589 public JSONArray element( String value, JsonConfig jsonConfig ) {
1590 if( value == null ) {
1591 this.elements.add("");
1592 } else if( JSONUtils.hasQuotes( value )) {
1593 this.elements.add(value);
1594 } else if( JSONNull.getInstance().equals( value )) {
1595 this.elements.add( JSONNull.getInstance() );
1596 } else if( JSONUtils.isJsonKeyword(value,jsonConfig)) {
1597 if( jsonConfig.isJavascriptCompliant() && "undefined".equals( value )){
1598 this.elements.add( JSONNull.getInstance() );
1599 }else{
1600 this.elements.add(value);
1601 }
1602 } else if( JSONUtils.mayBeJSON( value ) ){
1603 try{
1604 this.elements.add( JSONSerializer.toJSON( value, jsonConfig ) );
1605 }catch( JSONException jsone ){
1606 this.elements.add( value );
1607 }
1608 } else {
1609 this.elements.add(value);
1610 }
1611 return this;
1612 }
1613
1614 public boolean equals( Object obj ) {
1615 if( obj == this ){
1616 return true;
1617 }
1618 if( obj == null ){
1619 return false;
1620 }
1621
1622 if( !(obj instanceof JSONArray) ){
1623 return false;
1624 }
1625
1626 JSONArray other = (JSONArray) obj;
1627
1628 if( other.size() != size() ){
1629 return false;
1630 }
1631
1632 int max = size();
1633 for( int i = 0; i < max; i++ ){
1634 Object o1 = get( i );
1635 Object o2 = other.get( i );
1636
1637
1638 if( JSONNull.getInstance()
1639 .equals( o1 ) ){
1640 if( JSONNull.getInstance()
1641 .equals( o2 ) ){
1642 continue;
1643 }else{
1644 return false;
1645 }
1646 }else{
1647 if( JSONNull.getInstance()
1648 .equals( o2 ) ){
1649 return false;
1650 }
1651 }
1652
1653 if( o1 instanceof JSONArray && o2 instanceof JSONArray ){
1654 JSONArray e = (JSONArray) o1;
1655 JSONArray a = (JSONArray) o2;
1656 if( !a.equals( e ) ){
1657 return false;
1658 }
1659 }else{
1660 if( o1 instanceof String && o2 instanceof JSONFunction ){
1661 if( !o1.equals( String.valueOf( o2 ) ) ){
1662 return false;
1663 }
1664 }else if( o1 instanceof JSONFunction && o2 instanceof String ){
1665 if( !o2.equals( String.valueOf( o1 ) ) ){
1666 return false;
1667 }
1668 }else if( o1 instanceof JSONObject && o2 instanceof JSONObject ){
1669 if( !o1.equals( o2 ) ){
1670 return false;
1671 }
1672 }else if( o1 instanceof JSONArray && o2 instanceof JSONArray ){
1673 if( !o1.equals( o2 ) ){
1674 return false;
1675 }
1676 }else if( o1 instanceof JSONFunction && o2 instanceof JSONFunction ){
1677 if( !o1.equals( o2 ) ){
1678 return false;
1679 }
1680 }else{
1681 if( o1 instanceof String ){
1682 if( !o1.equals( String.valueOf( o2 ) ) ){
1683 return false;
1684 }
1685 }else if( o2 instanceof String ){
1686 if( !o2.equals( String.valueOf( o1 ) ) ){
1687 return false;
1688 }
1689 }else{
1690 Morpher m1 = JSONUtils.getMorpherRegistry()
1691 .getMorpherFor( o1.getClass() );
1692 Morpher m2 = JSONUtils.getMorpherRegistry()
1693 .getMorpherFor( o2.getClass() );
1694 if( m1 != null && m1 != IdentityObjectMorpher.getInstance() ){
1695 if( !o1.equals( JSONUtils.getMorpherRegistry()
1696 .morph( o1.getClass(), o2 ) ) ){
1697 return false;
1698 }
1699 }else if( m2 != null && m2 != IdentityObjectMorpher.getInstance() ){
1700 if( !JSONUtils.getMorpherRegistry()
1701 .morph( o1.getClass(), o1 )
1702 .equals( o2 ) ){
1703 return false;
1704 }
1705 }else{
1706 if( !o1.equals( o2 ) ){
1707 return false;
1708 }
1709 }
1710 }
1711 }
1712 }
1713 }
1714 return true;
1715 }
1716
1717
1718
1719
1720
1721
1722
1723 public Object get( int index ) {
1724
1725
1726
1727
1728 return this.elements.get( index );
1729 }
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 public boolean getBoolean( int index ) {
1741 Object o = get( index );
1742 if( o != null ){
1743 if( o.equals( Boolean.FALSE )
1744 || (o instanceof String && ((String) o).equalsIgnoreCase( "false" )) ){
1745 return false;
1746 }else if( o.equals( Boolean.TRUE )
1747 || (o instanceof String && ((String) o).equalsIgnoreCase( "true" )) ){
1748 return true;
1749 }
1750 }
1751 throw new JSONException( "JSONArray[" + index + "] is not a Boolean." );
1752 }
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 public double getDouble( int index ) {
1763 Object o = get( index );
1764 if( o != null ){
1765 try{
1766 return o instanceof Number ? ((Number) o).doubleValue()
1767 : Double.parseDouble( (String) o );
1768 }catch( Exception e ){
1769 throw new JSONException( "JSONArray[" + index + "] is not a number." );
1770 }
1771 }
1772 throw new JSONException( "JSONArray[" + index + "] is not a number." );
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784 public int getInt( int index ) {
1785 Object o = get( index );
1786 if( o != null ){
1787 return o instanceof Number ? ((Number) o).intValue() : (int) getDouble( index );
1788 }
1789 throw new JSONException( "JSONArray[" + index + "] is not a number." );
1790 }
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800 public JSONArray getJSONArray( int index ) {
1801 Object o = get( index );
1802 if( o != null && o instanceof JSONArray ){
1803 return (JSONArray) o;
1804 }
1805 throw new JSONException( "JSONArray[" + index + "] is not a JSONArray." );
1806 }
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816 public JSONObject getJSONObject( int index ) {
1817 Object o = get( index );
1818 if( JSONNull.getInstance()
1819 .equals( o ) ){
1820 return new JSONObject( true );
1821 }else if( o instanceof JSONObject ){
1822 return (JSONObject) o;
1823 }
1824 throw new JSONException( "JSONArray[" + index + "] is not a JSONObject." );
1825 }
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835 public long getLong( int index ) {
1836 Object o = get( index );
1837 if( o != null ){
1838 return o instanceof Number ? ((Number) o).longValue() : (long) getDouble( index );
1839 }
1840 throw new JSONException( "JSONArray[" + index + "] is not a number." );
1841 }
1842
1843
1844
1845
1846
1847
1848
1849
1850 public String getString( int index ) {
1851 Object o = get( index );
1852 if( o != null ){
1853 return o.toString();
1854 }
1855 throw new JSONException( "JSONArray[" + index + "] not found." );
1856 }
1857
1858 public int hashCode() {
1859 int hashcode = 29;
1860
1861 for( Iterator e = elements.iterator(); e.hasNext(); ){
1862 Object element = e.next();
1863 hashcode += JSONUtils.hashCode( element );
1864 }
1865 return hashcode;
1866 }
1867
1868 public int indexOf( Object o ) {
1869 return elements.indexOf( o );
1870 }
1871
1872 public boolean isArray() {
1873 return true;
1874 }
1875
1876 public boolean isEmpty() {
1877 return this.elements.isEmpty();
1878 }
1879
1880 public boolean isExpandElements() {
1881 return expandElements;
1882 }
1883
1884
1885
1886
1887 public Iterator iterator() {
1888 return new JSONArrayListIterator();
1889 }
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900 public String join( String separator ) {
1901 return join( separator, false );
1902 }
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913 public String join( String separator, boolean stripQuotes ) {
1914 int len = size();
1915 StringBuffer sb = new StringBuffer();
1916
1917 for( int i = 0; i < len; i += 1 ){
1918 if( i > 0 ){
1919 sb.append( separator );
1920 }
1921 String value = JSONUtils.valueToString( this.elements.get( i ) );
1922 sb.append( stripQuotes ? JSONUtils.stripQuotes( value ) : value );
1923 }
1924 return sb.toString();
1925 }
1926
1927 public int lastIndexOf( Object o ) {
1928 return elements.lastIndexOf( o );
1929 }
1930
1931 public ListIterator listIterator() {
1932 return listIterator( 0 );
1933 }
1934
1935 public ListIterator listIterator( int index ) {
1936 if( index < 0 || index > size() )
1937 throw new IndexOutOfBoundsException( "Index: " + index );
1938
1939 return new JSONArrayListIterator( index );
1940 }
1941
1942
1943
1944
1945
1946
1947
1948 public Object opt( int index ) {
1949 return (index < 0 || index >= size()) ? null : this.elements.get( index );
1950 }
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960 public boolean optBoolean( int index ) {
1961 return optBoolean( index, false );
1962 }
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973 public boolean optBoolean( int index, boolean defaultValue ) {
1974 try{
1975 return getBoolean( index );
1976 }catch( Exception e ){
1977 return defaultValue;
1978 }
1979 }
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989 public double optDouble( int index ) {
1990 return optDouble( index, Double.NaN );
1991 }
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002 public double optDouble( int index, double defaultValue ) {
2003 try{
2004 return getDouble( index );
2005 }catch( Exception e ){
2006 return defaultValue;
2007 }
2008 }
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018 public int optInt( int index ) {
2019 return optInt( index, 0 );
2020 }
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031 public int optInt( int index, int defaultValue ) {
2032 try{
2033 return getInt( index );
2034 }catch( Exception e ){
2035 return defaultValue;
2036 }
2037 }
2038
2039
2040
2041
2042
2043
2044
2045
2046 public JSONArray optJSONArray( int index ) {
2047 Object o = opt( index );
2048 return o instanceof JSONArray ? (JSONArray) o : null;
2049 }
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059 public JSONObject optJSONObject( int index ) {
2060 Object o = opt( index );
2061 return o instanceof JSONObject ? (JSONObject) o : null;
2062 }
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072 public long optLong( int index ) {
2073 return optLong( index, 0 );
2074 }
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085 public long optLong( int index, long defaultValue ) {
2086 try{
2087 return getLong( index );
2088 }catch( Exception e ){
2089 return defaultValue;
2090 }
2091 }
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101 public String optString( int index ) {
2102 return optString( index, "" );
2103 }
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113 public String optString( int index, String defaultValue ) {
2114 Object o = opt( index );
2115 return o != null ? o.toString() : defaultValue;
2116 }
2117
2118 public Object remove( int index ) {
2119 return elements.remove( index );
2120 }
2121
2122 public boolean remove( Object o ) {
2123 return elements.remove( o );
2124 }
2125
2126 public boolean removeAll( Collection collection ) {
2127 return removeAll( collection, new JsonConfig() );
2128 }
2129
2130 public boolean removeAll( Collection collection, JsonConfig jsonConfig ) {
2131 return elements.removeAll( fromObject( collection, jsonConfig ) );
2132 }
2133
2134 public boolean retainAll( Collection collection ) {
2135 return retainAll( collection, new JsonConfig() );
2136 }
2137
2138 public boolean retainAll( Collection collection, JsonConfig jsonConfig ) {
2139 return elements.retainAll( fromObject( collection, jsonConfig ) );
2140 }
2141
2142 public Object set( int index, Object value ) {
2143 return set( index, value, new JsonConfig() );
2144 }
2145
2146 public Object set( int index, Object value, JsonConfig jsonConfig ) {
2147 Object previous = get( index );
2148 element( index, value, jsonConfig );
2149 return previous;
2150 }
2151
2152 public void setExpandElements( boolean expandElements ) {
2153 this.expandElements = expandElements;
2154 }
2155
2156
2157
2158
2159
2160
2161 public int size() {
2162 return this.elements.size();
2163 }
2164
2165 public List subList( int fromIndex, int toIndex ) {
2166 return elements.subList( fromIndex, toIndex );
2167 }
2168
2169
2170
2171
2172 public Object[] toArray() {
2173 return this.elements.toArray();
2174 }
2175
2176 public Object[] toArray( Object[] array ) {
2177 return elements.toArray( array );
2178 }
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190 public JSONObject toJSONObject( JSONArray names ) {
2191 if( names == null || names.size() == 0 || size() == 0 ){
2192 return null;
2193 }
2194 JSONObject jo = new JSONObject();
2195 for( int i = 0; i < names.size(); i++ ){
2196 jo.element( names.getString( i ), this.opt( i ) );
2197 }
2198 return jo;
2199 }
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 public String toString() {
2213 try{
2214 return '[' + join( "," ) + ']';
2215 }catch( Exception e ){
2216 return null;
2217 }
2218 }
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232 public String toString( int indentFactor ) {
2233 if( indentFactor == 0 ){
2234 return this.toString();
2235 }
2236 return toString( indentFactor, 0 );
2237 }
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250 public String toString( int indentFactor, int indent ) {
2251 int len = size();
2252 if( len == 0 ){
2253 return "[]";
2254 }
2255 if( indentFactor == 0 ){
2256 return this.toString();
2257 }
2258 int i;
2259 StringBuffer sb = new StringBuffer( "[" );
2260 if( len == 1 ){
2261 sb.append( JSONUtils.valueToString( this.elements.get( 0 ), indentFactor, indent ) );
2262 }else{
2263 int newindent = indent + indentFactor;
2264 sb.append( '\n' );
2265 for( i = 0; i < len; i += 1 ){
2266 if( i > 0 ){
2267 sb.append( ",\n" );
2268 }
2269 for( int j = 0; j < newindent; j += 1 ){
2270 sb.append( ' ' );
2271 }
2272 sb.append( JSONUtils.valueToString( this.elements.get( i ), indentFactor, newindent ) );
2273 }
2274 sb.append( '\n' );
2275 for( i = 0; i < indent; i += 1 ){
2276 sb.append( ' ' );
2277 }
2278 for( i = 0; i < indent; i += 1 ){
2279 sb.insert( 0, ' ' );
2280 }
2281 }
2282 sb.append( ']' );
2283 return sb.toString();
2284 }
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295 public Writer write( Writer writer ) {
2296 try{
2297 boolean b = false;
2298 int len = size();
2299
2300 writer.write( '[' );
2301
2302 for( int i = 0; i < len; i += 1 ){
2303 if( b ){
2304 writer.write( ',' );
2305 }
2306 Object v = this.elements.get( i );
2307 if( v instanceof JSONObject ){
2308 ((JSONObject) v).write( writer );
2309 }else if( v instanceof JSONArray ){
2310 ((JSONArray) v).write( writer );
2311 }else{
2312 writer.write( JSONUtils.valueToString( v ) );
2313 }
2314 b = true;
2315 }
2316 writer.write( ']' );
2317 return writer;
2318 }catch( IOException e ){
2319 throw new JSONException( e );
2320 }
2321 }
2322
2323
2324
2325
2326 protected JSONArray addString( String str ) {
2327 if( str != null ){
2328 elements.add( str );
2329 }
2330 return this;
2331 }
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341 private JSONArray _addValue( Object value, JsonConfig jsonConfig ) {
2342 this.elements.add(value);
2343 return this;
2344 }
2345
2346 protected Object _processValue( Object value, JsonConfig jsonConfig ) {
2347 if( value instanceof JSONTokener ) {
2348 return _fromJSONTokener( (JSONTokener) value, jsonConfig );
2349 }
2350 return super._processValue( value, jsonConfig );
2351 }
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361 private JSONArray addValue( Object value, JsonConfig jsonConfig ) {
2362 return _addValue( processValue( value, jsonConfig ), jsonConfig );
2363 }
2364
2365 private Object processValue( Object value, JsonConfig jsonConfig ) {
2366 if( value != null ){
2367 JsonValueProcessor jsonValueProcessor = jsonConfig.findJsonValueProcessor( value.getClass() );
2368 if( jsonValueProcessor != null ){
2369 value = jsonValueProcessor.processArrayValue( value, jsonConfig );
2370 if( !JsonVerifier.isValidJsonValue( value ) ){
2371 throw new JSONException( "Value is not a valid JSON value. " + value );
2372 }
2373 }
2374 }
2375 return _processValue( value, jsonConfig );
2376 }
2377
2378 private class JSONArrayListIterator implements ListIterator {
2379 int currentIndex = 0;
2380 int lastIndex = -1;
2381
2382 JSONArrayListIterator() {
2383
2384 }
2385
2386 JSONArrayListIterator( int index ) {
2387 currentIndex = index;
2388 }
2389
2390 public boolean hasNext() {
2391 return currentIndex != size();
2392 }
2393
2394 public Object next() {
2395 try {
2396 Object next = get( currentIndex );
2397 lastIndex = currentIndex++;
2398 return next;
2399 } catch( IndexOutOfBoundsException e ) {
2400 throw new NoSuchElementException();
2401 }
2402 }
2403
2404 public void remove() {
2405 if( lastIndex == -1 )
2406 throw new IllegalStateException();
2407 try {
2408 JSONArray.this.remove( lastIndex );
2409 if( lastIndex < currentIndex ){
2410 currentIndex--;
2411 }
2412 lastIndex = -1;
2413 } catch( IndexOutOfBoundsException e ) {
2414 throw new ConcurrentModificationException();
2415 }
2416 }
2417
2418 public boolean hasPrevious() {
2419 return currentIndex != 0;
2420 }
2421
2422 public Object previous() {
2423 try {
2424 int index = currentIndex - 1;
2425 Object previous = get( index );
2426 lastIndex = currentIndex = index;
2427 return previous;
2428 } catch( IndexOutOfBoundsException e ) {
2429 throw new NoSuchElementException();
2430 }
2431 }
2432
2433 public int nextIndex() {
2434 return currentIndex;
2435 }
2436
2437 public int previousIndex() {
2438 return currentIndex - 1;
2439 }
2440
2441 public void set( Object obj ) {
2442 if( lastIndex == -1 ){
2443 throw new IllegalStateException();
2444 }
2445
2446 try {
2447 JSONArray.this.set( lastIndex, obj );
2448 } catch( IndexOutOfBoundsException ex ) {
2449 throw new ConcurrentModificationException();
2450 }
2451 }
2452
2453 public void add( Object obj ) {
2454 try {
2455 JSONArray.this.add( currentIndex++, obj );
2456 lastIndex = -1;
2457 } catch( IndexOutOfBoundsException ex ) {
2458 throw new ConcurrentModificationException();
2459 }
2460 }
2461 }
2462 }