6
6
7
7
package org .mozilla .javascript ;
8
8
9
+ import java .lang .reflect .Array ;
9
10
import java .util .Arrays ;
10
11
import java .util .Collection ;
11
12
import java .util .Iterator ;
@@ -297,9 +298,12 @@ private static Object str(Object key, Scriptable holder, StringifyState state) {
297
298
value = ((NativeBoolean ) value ).getDefaultValue (ScriptRuntime .BooleanClass );
298
299
} else if (value instanceof NativeJavaObject ) {
299
300
unwrappedJavaValue = ((NativeJavaObject ) value ).unwrap ();
300
- if (!isComplexJavaObject (unwrappedJavaValue )) {
301
+ if (!(unwrappedJavaValue instanceof Map
302
+ || unwrappedJavaValue instanceof Collection
303
+ || unwrappedJavaValue .getClass ().isArray ())) {
301
304
value = unwrappedJavaValue ;
302
305
} else {
306
+ // Don't unwrap Java objects to be processed by jo() or ja()
303
307
unwrappedJavaValue = null ;
304
308
}
305
309
} else if (value instanceof XMLObject ) {
@@ -351,22 +355,18 @@ private static String join(Collection<Object> objs, String delimiter) {
351
355
}
352
356
353
357
private static String jo (Scriptable value , StringifyState state ) {
354
- Object trackValue = value ;
355
- final boolean isTrackValueUnwrapped ;
358
+ Object trackValue = value , unwrapped = null ;
356
359
if (value instanceof Wrapper ) {
357
- trackValue = ((Wrapper ) value ).unwrap ();
358
- isTrackValueUnwrapped = true ;
359
- } else {
360
- isTrackValueUnwrapped = false ;
360
+ trackValue = unwrapped = ((Wrapper ) value ).unwrap ();
361
361
}
362
362
363
363
if (state .stack .search (trackValue ) != -1 ) {
364
364
throw ScriptRuntime .typeErrorById ("msg.cyclic.value" , trackValue .getClass ().getName ());
365
365
}
366
366
state .stack .push (trackValue );
367
367
368
- if (isTrackValueUnwrapped && ( trackValue instanceof Map ) ) {
369
- Map <?, ?> map = (Map <?, ?>) trackValue ;
368
+ if (unwrapped instanceof Map ) {
369
+ Map <?, ?> map = (Map <?, ?>) unwrapped ;
370
370
Scriptable nObj = state .cx .newObject (state .scope );
371
371
for (Map .Entry <?, ?> entry : map .entrySet ()) {
372
372
if (entry .getKey () instanceof Symbol ) continue ;
@@ -437,9 +437,9 @@ private static String jo(Scriptable value, StringifyState state) {
437
437
}
438
438
439
439
private static String ja (Scriptable value , StringifyState state ) {
440
- Object trackValue = value ;
440
+ Object trackValue = value , unwrapped = null ;
441
441
if (value instanceof Wrapper ) {
442
- trackValue = ((Wrapper ) value ).unwrap ();
442
+ trackValue = unwrapped = ((Wrapper ) value ).unwrap ();
443
443
}
444
444
if (state .stack .search (trackValue ) != -1 ) {
445
445
throw ScriptRuntime .typeErrorById ("msg.cyclic.value" , trackValue .getClass ().getName ());
@@ -450,17 +450,25 @@ private static String ja(Scriptable value, StringifyState state) {
450
450
state .indent = state .indent + state .gap ;
451
451
List <Object > partial = new LinkedList <Object >();
452
452
453
- if (trackValue instanceof Collection ) {
454
- Collection <?> col = (Collection <?>) trackValue ;
455
- trackValue = col .toArray (new Object [col .size ()]);
456
- }
457
- if (trackValue instanceof Object []) {
458
- Object [] elements = (Object []) trackValue ;
459
- elements =
460
- Arrays .stream (elements )
461
- .map (o -> Context .javaToJS (o , state .scope , state .cx ))
462
- .toArray ();
463
- value = state .cx .newArray (state .scope , elements );
453
+ if (unwrapped != null ) {
454
+ Object [] elements = null ;
455
+ if (unwrapped .getClass ().isArray ()) {
456
+ int length = Array .getLength (unwrapped );
457
+ elements = new Object [length ];
458
+ for (int i = 0 ; i < length ; i ++) {
459
+ elements [i ] = Context .javaToJS (Array .get (unwrapped , i ), state .scope , state .cx );
460
+ }
461
+ } else if (unwrapped instanceof Collection ) {
462
+ Collection <?> collection = (Collection <?>) unwrapped ;
463
+ elements = new Object [collection .size ()];
464
+ int i = 0 ;
465
+ for (Object o : collection ) {
466
+ elements [i ++] = Context .javaToJS (o , state .scope , state .cx );
467
+ }
468
+ }
469
+ if (elements != null ) {
470
+ value = state .cx .newArray (state .scope , elements );
471
+ }
464
472
}
465
473
466
474
long len = ((NativeArray ) value ).getLength ();
@@ -548,17 +556,13 @@ private static Object javaToJSON(Object value, StringifyState state) {
548
556
return stringify (state .cx , state .scope , value , state .replacer , state .gap );
549
557
}
550
558
551
- private static boolean isComplexJavaObject (Object o ) {
552
- return (o instanceof Map ) || (o instanceof Collection ) || (o instanceof Object []);
553
- }
554
-
555
559
private static boolean isObjectArrayLike (Object o ) {
556
560
if (o instanceof NativeArray ) {
557
561
return true ;
558
562
}
559
563
if (o instanceof NativeJavaObject ) {
560
- o = ((NativeJavaObject ) o ).unwrap ();
561
- return (o instanceof Collection ) || (o instanceof Object [] );
564
+ Object unwrapped = ((NativeJavaObject ) o ).unwrap ();
565
+ return (unwrapped instanceof Collection ) || (unwrapped . getClass (). isArray () );
562
566
}
563
567
return false ;
564
568
}
0 commit comments