@@ -519,9 +519,42 @@ interface OnReady {
519519 void callbackReady (String name );
520520 }
521521
522- private class Item implements Runnable {
522+ private abstract class Item {
523523 final int id ;
524524 final Item prev ;
525+
526+ Item (int id , Item prev ) {
527+ this .id = id ;
528+ this .prev = prev ;
529+ }
530+
531+ abstract void result (String typeof , String res );
532+ abstract void noLongerNeeded ();
533+ abstract void inJava ();
534+ abstract String inJavaScript (int [] finishedId );
535+ abstract void header (StringBuilder sb , String sep );
536+
537+ final void toString (StringBuilder sb , String sep ) {
538+ header (sb , sep );
539+ if (prev != null ) {
540+ sb .append (", prev=\n " );
541+ prev .toString (sb , " " + sep );
542+ sb .append ("\n " ).append (sep );
543+ }
544+ sb .append ("]" );
545+ }
546+
547+ @ Override
548+ public final String toString () {
549+ synchronized (lock ()) {
550+ StringBuilder sb = new StringBuilder ();
551+ toString (sb , "" );
552+ return sb .toString ();
553+ }
554+ }
555+ }
556+
557+ private class JavaItem extends Item implements Runnable {
525558 Boolean done ;
526559 boolean resultObtained ;
527560
@@ -530,48 +563,32 @@ private class Item implements Runnable {
530563 final Object [] params ;
531564 Object result ;
532565
533- Item (int id , Item prev , Method method , Object thiz , Object [] params ) {
534- this .id = id ;
535- this .prev = prev ;
566+ JavaItem (int id , Item prev , Method method , Object thiz , Object [] params ) {
567+ super (id , prev );
536568 this .method = method ;
537569 this .thiz = thiz ;
538570 this .params = adaptParams (method , Arrays .asList (params ));
539- this .toExec = null ;
540571 }
541572
542573 @ Override
543- public String toString () {
544- synchronized (lock ()) {
545- StringBuilder sb = new StringBuilder ();
546- toString (sb , "" );
547- return sb .toString ();
548- }
549- }
550-
551- private void toString (StringBuilder sb , String sep ) {
552- sb .append (sep ).append ("Item[id=" ).append (id ).append (", " );
553- if (method != null ) {
554- sb .append ("method=" ).append (method .getName ());
555- } else {
556- sb .append ("javascript" );
557- }
558- if (prev != null ) {
559- sb .append (", prev=\n " );
560- prev .toString (sb , " " + sep );
561- sb .append ("\n " ).append (sep );
562- }
563- sb .append ("]" );
574+ final void header (StringBuilder sb , String sep ) {
575+ sb .append (sep ).append ("JavaItem[id=" ).append (id ).append (", " );
576+ sb .append ("method=" ).append (method .getName ());
564577 }
565578
579+ @ Override
566580 protected final String inJavaScript (int [] finished ) {
567581 assert Thread .holdsLock (lock ());
568- if (this .method != null ) {
569- return js (finished );
570- } else {
571- return sj (finished );
582+ if (Boolean .TRUE .equals (done )) {
583+ StringBuilder sb = new StringBuilder ();
584+ encodeObject (result , false , sb , null );
585+ finished [0 ] = -1 ;
586+ return sb .toString ();
572587 }
588+ return null ;
573589 }
574590
591+ @ Override
575592 protected final void inJava () {
576593 assert Thread .holdsLock (lock ());
577594 if (this .method == null ) {
@@ -591,40 +608,51 @@ protected final void inJava() {
591608 }
592609 }
593610
594- @ Override public void run () {
611+ @ Override
612+ public void run () {
595613 synchronized (lock ()) {
596614 log (Level .FINE , "run: {0}" , this );
597615 inJava ();
598616 lock ().notifyAll ();
599617 }
600618 }
601-
602619
603- protected String js (int [] finished ) {
604- assert Thread .holdsLock (lock ());
605- if (Boolean .TRUE .equals (done )) {
606- StringBuilder sb = new StringBuilder ();
607- encodeObject (result , false , sb , null );
608- finished [0 ] = -1 ;
609- return sb .toString ();
610- }
611- return null ;
620+ @ Override
621+ void result (String typeof , String res ) {
612622 }
613623
624+ @ Override
625+ void noLongerNeeded () {
626+ resultObtained = true ;
627+ }
628+ }
629+
630+ private final class JsItem extends Item {
614631 private final String toExec ;
615632 private String typeof ;
633+ private Boolean done ;
634+ private String result ;
616635
617- Item (int id , Item prev , String toExec ) {
618- this .id = id ;
619- this .prev = prev ;
636+ JsItem (int id , Item prev , String toExec ) {
637+ super (id , prev );
620638 this .toExec = toExec ;
621-
622- this .method = null ;
623- this .params = null ;
624- this .thiz = null ;
625639 }
626640
627- protected String sj (int [] finished ) {
641+ @ Override
642+ protected final void result (String newType , String newResult ) {
643+ assert Thread .holdsLock (lock ());
644+ this .typeof = newType ;
645+ this .result = newResult ;
646+ log (Level .FINE , "result ({0}): {1} for {2}" , typeof , result , toExec );
647+ }
648+
649+ @ Override
650+ protected final void noLongerNeeded () {
651+ }
652+
653+ @ Override
654+ protected final String inJavaScript (int [] finished ) {
655+ assert Thread .holdsLock (lock ());
628656 assert Thread .holdsLock (lock ());
629657 if (Boolean .TRUE .equals (done )) {
630658 return null ;
@@ -633,20 +661,16 @@ protected String sj(int[] finished) {
633661 return "javascript:" + finished [0 ] + "/" + toExec ;
634662 }
635663
636- protected final void result (String newType , String newResult ) {
637- assert Thread .holdsLock (lock ());
638- if (this .method != null ) {
639- throw new UnsupportedOperationException ();
640- }
641- this .typeof = newType ;
642- this .result = newResult ;
643- log (Level .FINE , "result ({0}): {1} for {2}" , typeof , result , toExec );
664+ @ Override
665+ protected final void inJava () {
644666 }
645667
646- protected final void noLongerNeeded () {
647- assert Thread .holdsLock (lock ());
648- this .resultObtained = true ;
668+ @ Override
669+ final void header (StringBuilder sb , String sep ) {
670+ sb .append (sep ).append ("JsItem[id=" ).append (id ).append (", " );
671+ sb .append ("javascript" );
649672 }
673+
650674 } // end of Item
651675
652676 final void result (String counterId , String typeof , String res ) {
@@ -664,7 +688,7 @@ final void result(String counterId, String typeof, String res) {
664688 return ;
665689 }
666690 final int id = Integer .parseInt (counterId );
667- final Item top = topMostCall ();
691+ final Item top = topMostCall (null );
668692 Item my = findCall (id );
669693 if (top == my ) {
670694 top .result (typeof , res );
@@ -701,10 +725,10 @@ final String javacall(
701725 }
702726 params .addAll (Arrays .asList ((Object []) args ));
703727 Object [] converted = adaptParams (method , params );
704- Item top = topMostCall ();
728+ Item top = topMostCall (null );
705729 boolean first = top == null ;
706- log (Level .FINE , "jc: {0}@{1}args: {2} is first: {3}, now: {4}" , new Object []{method .getName (), vm , params , first , topMostCall ()});
707- Item newItem = registerCall (new Item (nextCallId (), top , method , vm , converted ));
730+ log (Level .FINE , "jc: {0}@{1}args: {2} is first: {3}, now: {4}" , new Object []{method .getName (), vm , params , first , topMostCall (null )});
731+ JavaItem newItem = registerCall (new JavaItem (nextCallId (), top , method , vm , converted ));
708732 try {
709733 if (first || synchronous ) {
710734 dispatch (newItem );
@@ -726,7 +750,7 @@ final String javaresult(int reqId) throws IllegalStateException, InterruptedExce
726750 deferred = null ;
727751 return ret ;
728752 }
729- final Item top = topMostCall ();
753+ final Item top = topMostCall (null );
730754 String jsToExec = top .inJavaScript (finishedId );
731755 log (Level .FINE , "jr: {0} jsToExec: {1} finished: {2}" , new Object []{top , jsToExec , finishedId [0 ]});
732756 if (jsToExec != null ) {
@@ -760,7 +784,7 @@ public final void loadScript(final Reader reader) throws Exception {
760784
761785 final void deferExec (StringBuilder sb ) {
762786 synchronized (lock ()) {
763- log (Level .FINE , "deferExec: {0} empty: {1}, call: {2}" , new Object []{sb , deferred == null , topMostCall ()});
787+ log (Level .FINE , "deferExec: {0} empty: {1}, call: {2}" , new Object []{sb , deferred == null , topMostCall (null )});
764788 if (deferred == null ) {
765789 deferred = sb ;
766790 } else {
@@ -795,15 +819,15 @@ final Object exec(int id, String fn) {
795819 log (Level .FINE , "Flushing {0}" , fn );
796820 }
797821
798- Item myCall ;
822+ JsItem myCall ;
799823 boolean load ;
800- final Item top = topMostCall ();
824+ final Item top = topMostCall (null );
801825 if (top != null ) {
802- myCall = registerCall (new Item (id , top , fn ));
826+ myCall = registerCall (new JsItem (id , top , fn ));
803827 load = synchronous ;
804828 first = false ;
805829 } else {
806- myCall = registerCall (new Item (id , null , null ));
830+ myCall = registerCall (new JsItem (id , null , null ));
807831 load = true ;
808832 first = true ;
809833 }
@@ -820,7 +844,7 @@ final Object exec(int id, String fn) {
820844 } catch (InterruptedException ex ) {
821845 log (Level .SEVERE , null , ex );
822846 }
823- Item c = topMostCall ();
847+ Item c = topMostCall (null );
824848 if (c != null ) {
825849 c .inJava ();
826850 }
@@ -1034,9 +1058,14 @@ void register() {
10341058 }
10351059 }
10361060
1037- private Item topMostCall () {
1061+ private Item topMostCall (Class <? extends Item > type ) {
10381062 assert Thread .holdsLock (lock ());
1039- return call ;
1063+ for (Item it = call ; it != null ; it = it .prev ) {
1064+ if (type == null || type .isInstance (it )) {
1065+ return it ;
1066+ }
1067+ }
1068+ return null ;
10401069 }
10411070
10421071 private Item findCall (int reqId ) {
@@ -1050,7 +1079,7 @@ private Item findCall(int reqId) {
10501079 }
10511080 }
10521081
1053- private Item registerCall (Item call ) {
1082+ private < T extends Item > T registerCall (T call ) {
10541083 assert Thread .holdsLock (lock ());
10551084 this .call = call ;
10561085 lock ().notifyAll ();
0 commit comments