KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > BeanShell


1 /*
2  * BeanShell.java - BeanShell scripting support
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2000, 2004 Slava Pestov
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22
23 package org.gjt.sp.jedit;
24
25 //{{{ Imports
26
import bsh.*;
27 import bsh.classpath.ClassManagerImpl;
28
29 import java.io.*;
30 import java.lang.ref.*;
31 import java.lang.reflect.InvocationTargetException JavaDoc;
32 import java.util.*;
33 import org.gjt.sp.jedit.io.*;
34 import org.gjt.sp.jedit.gui.BeanShellErrorDialog;
35 import org.gjt.sp.jedit.textarea.*;
36 import org.gjt.sp.util.Log;
37 //}}}
38

39 /**
40  * BeanShell is jEdit's extension language.<p>
41  *
42  * When run from jEdit, BeanShell code has access to the following predefined
43  * variables:
44  *
45  * <ul>
46  * <li><code>view</code> - the currently active {@link View}.</li>
47  * <li><code>editPane</code> - the currently active {@link EditPane}.</li>
48  * <li><code>textArea</code> - the edit pane's {@link JEditTextArea}.</li>
49  * <li><code>buffer</code> - the edit pane's {@link Buffer}.</li>
50  * <li><code>wm</code> - the view's {@link
51  * org.gjt.sp.jedit.gui.DockableWindowManager}.</li>
52  * <li><code>scriptPath</code> - the path name of the currently executing
53  * BeanShell script.</li>
54  * </ul>
55  *
56  * @author Slava Pestov
57  * @version $Id: BeanShell.java 5555 2006-07-07 22:28:15Z kpouer $
58  */

59 public class BeanShell
60 {
61     private static final String JavaDoc REQUIRED_VERSION = "2.0b1.1-jedit-1";
62
63     //{{{ evalSelection() method
64
/**
65      * Evaluates the text selected in the specified text area.
66      * @since jEdit 2.7pre2
67      */

68     public static void evalSelection(View view, JEditTextArea textArea)
69     {
70         String JavaDoc command = textArea.getSelectedText();
71         if(command == null)
72         {
73             view.getToolkit().beep();
74             return;
75         }
76         Object JavaDoc returnValue = eval(view,global,command);
77         if(returnValue != null)
78             textArea.setSelectedText(returnValue.toString());
79     } //}}}
80

81     //{{{ showEvaluateDialog() method
82
/**
83      * Prompts for a BeanShell expression to evaluate.
84      * @since jEdit 2.7pre2
85      */

86     public static void showEvaluateDialog(View view)
87     {
88         String JavaDoc command = GUIUtilities.input(view,"beanshell-eval-input",null);
89         if(command != null)
90         {
91             if(!command.endsWith(";"))
92                 command = command + ";";
93
94             int repeat = view.getInputHandler().getRepeatCount();
95
96             if(view.getMacroRecorder() != null)
97             {
98                 view.getMacroRecorder().record(repeat,command);
99             }
100
101             Object JavaDoc returnValue = null;
102             try
103             {
104                 for(int i = 0; i < repeat; i++)
105                 {
106                     returnValue = _eval(view,global,command);
107                 }
108             }
109             catch(Throwable JavaDoc e)
110             {
111                 Log.log(Log.ERROR,BeanShell.class,e);
112
113                 handleException(view,null,e);
114             }
115
116             if(returnValue != null)
117             {
118                 String JavaDoc[] args = { returnValue.toString() };
119                 GUIUtilities.message(view,"beanshell-eval",args);
120             }
121         }
122     } //}}}
123

124     //{{{ showEvaluateLinesDialog() method
125
/**
126      * Evaluates the specified script for each selected line.
127      * @since jEdit 4.0pre1
128      */

129     public static void showEvaluateLinesDialog(View view)
130     {
131         String JavaDoc command = GUIUtilities.input(view,"beanshell-eval-line",null);
132
133         JEditTextArea textArea = view.getTextArea();
134         Buffer buffer = view.getBuffer();
135
136         if(command == null || command.length() == 0)
137             return;
138
139         Selection[] selection = textArea.getSelection();
140         if(selection.length == 0)
141         {
142             view.getToolkit().beep();
143             return;
144         }
145
146         if(!command.endsWith(";"))
147             command = command + ";";
148
149         String JavaDoc script = "int[] lines = textArea.getSelectedLines();\n"
150             + "for(int i = 0; i < lines.length; i++)\n"
151             + "{\n"
152                 + "line = lines[i];\n"
153                 + "index = line - lines[0];\n"
154                 + "start = buffer.getLineStartOffset(line);\n"
155                 + "end = buffer.getLineEndOffset(line);\n"
156                 + "text = buffer.getText(start,end - start - 1);\n"
157                 + "newText = " + command + "\n"
158                 + "if(newText != null)\n"
159                 + "{\n"
160                     + "buffer.remove(start,end - start - 1);\n"
161                     + "buffer.insert(start,String.valueOf(newText));\n"
162                 + "}\n"
163             + "}\n";
164
165         if(view.getMacroRecorder() != null)
166             view.getMacroRecorder().record(1,script);
167
168         try
169         {
170             buffer.beginCompoundEdit();
171
172             BeanShell.eval(view,global,script);
173         }
174         finally
175         {
176             buffer.endCompoundEdit();
177         }
178
179         textArea.selectNone();
180     } //}}}
181

182     //{{{ runScript() method
183
/**
184      * Runs a BeanShell script. Errors are shown in a dialog box.<p>
185      *
186      * If the <code>in</code> parameter is non-null, the script is
187      * read from that stream; otherwise it is read from the file identified
188      * by <code>path</code>.<p>
189      *
190      * The <code>scriptPath</code> BeanShell variable is set to the path
191      * name of the script.
192      *
193      * @param view The view. Within the script, references to
194      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
195      * are determined with reference to this parameter.
196      * @param path The script file's VFS path.
197      * @param in The reader to read the script from, or <code>null</code>.
198      * @param ownNamespace If set to <code>false</code>, methods and
199      * variables defined in the script will be available to all future
200      * uses of BeanShell; if set to <code>true</code>, they will be lost as
201      * soon as the script finishes executing. jEdit uses a value of
202      * <code>false</code> when running startup scripts, and a value of
203      * <code>true</code> when running all other macros.
204      *
205      * @since jEdit 4.0pre7
206      */

207     public static void runScript(View view, String JavaDoc path, Reader in,
208         boolean ownNamespace)
209     {
210         try
211         {
212             _runScript(view,path,in,ownNamespace);
213         }
214         catch(Throwable JavaDoc e)
215         {
216             Log.log(Log.ERROR,BeanShell.class,e);
217
218             handleException(view,path,e);
219         }
220     } //}}}
221

222     //{{{ runScript() method
223
/**
224      * Runs a BeanShell script. Errors are shown in a dialog box.<p>
225      *
226      * If the <code>in</code> parameter is non-null, the script is
227      * read from that stream; otherwise it is read from the file identified
228      * by <code>path</code>.<p>
229      *
230      * The <code>scriptPath</code> BeanShell variable is set to the path
231      * name of the script.
232      *
233      * @param view The view. Within the script, references to
234      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
235      * are determined with reference to this parameter.
236      * @param path The script file's VFS path.
237      * @param in The reader to read the script from, or <code>null</code>.
238      * @param namespace The namespace to run the script in.
239      *
240      * @since jEdit 4.2pre5
241      */

242     public static void runScript(View view, String JavaDoc path, Reader in,
243         NameSpace namespace)
244     {
245         try
246         {
247             _runScript(view,path,in,namespace);
248         }
249         catch(Throwable JavaDoc e)
250         {
251             Log.log(Log.ERROR,BeanShell.class,e);
252
253             handleException(view,path,e);
254         }
255     } //}}}
256

257     //{{{ _runScript() method
258
/**
259      * Runs a BeanShell script. Errors are passed to the caller.<p>
260      *
261      * If the <code>in</code> parameter is non-null, the script is
262      * read from that stream; otherwise it is read from the file identified
263      * by <code>path</code>.<p>
264      *
265      * The <code>scriptPath</code> BeanShell variable is set to the path
266      * name of the script.
267      *
268      * @param view The view. Within the script, references to
269      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
270      * are determined with reference to this parameter.
271      * @param path The script file's VFS path.
272      * @param in The reader to read the script from, or <code>null</code>.
273      * @param ownNamespace If set to <code>false</code>, methods and
274      * variables defined in the script will be available to all future
275      * uses of BeanShell; if set to <code>true</code>, they will be lost as
276      * soon as the script finishes executing. jEdit uses a value of
277      * <code>false</code> when running startup scripts, and a value of
278      * <code>true</code> when running all other macros.
279      * @exception Exception instances are thrown when various BeanShell errors
280      * occur
281      * @since jEdit 4.0pre7
282      */

283     public static void _runScript(View view, String JavaDoc path, Reader in,
284         boolean ownNamespace) throws Exception JavaDoc
285     {
286         _runScript(view,path,in,ownNamespace
287             ? new NameSpace(global,"namespace")
288             : global);
289     } //}}}
290

291     //{{{ _runScript() method
292
/**
293      * Runs a BeanShell script. Errors are passed to the caller.<p>
294      *
295      * If the <code>in</code> parameter is non-null, the script is
296      * read from that stream; otherwise it is read from the file identified
297      * by <code>path</code>.<p>
298      *
299      * The <code>scriptPath</code> BeanShell variable is set to the path
300      * name of the script.
301      *
302      * @param view The view. Within the script, references to
303      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
304      * are determined with reference to this parameter.
305      * @param path The script file's VFS path.
306      * @param in The reader to read the script from, or <code>null</code>.
307      * @param namespace The namespace to run the script in.
308      * @exception Exception instances are thrown when various BeanShell errors
309      * occur
310      * @since jEdit 4.2pre5
311      */

312     public static void _runScript(View view, String JavaDoc path, Reader in,
313         NameSpace namespace) throws Exception JavaDoc
314     {
315         Log.log(Log.MESSAGE,BeanShell.class,"Running script " + path);
316
317         Interpreter interp = createInterpreter(namespace);
318
319         VFS vfs = null;
320         Object JavaDoc session = null;
321
322         try
323         {
324             if(in == null)
325             {
326                 Buffer buffer = jEdit.openTemporary(null,
327                     null,path,false);
328
329                 if(!buffer.isLoaded())
330                     VFSManager.waitForRequests();
331
332                 in = new StringReader(buffer.getText(0,
333                     buffer.getLength()));
334             }
335
336             setupDefaultVariables(namespace,view);
337             interp.set("scriptPath",path);
338
339             running = true;
340
341             interp.eval(in,namespace,path);
342         }
343         catch(Exception JavaDoc e)
344         {
345             unwrapException(e);
346         }
347         finally
348         {
349             running = false;
350
351             if(session != null)
352             {
353                 try
354                 {
355                     vfs._endVFSSession(session,view);
356                 }
357                 catch(IOException io)
358                 {
359                     Log.log(Log.ERROR,BeanShell.class,io);
360                     GUIUtilities.error(view,"read-error",
361                         new String JavaDoc[] { path, io.toString() });
362                 }
363             }
364
365             try
366             {
367                 // no need to do this for macros!
368
if(namespace == global)
369                 {
370                     resetDefaultVariables(namespace);
371                     interp.unset("scriptPath");
372                 }
373             }
374             catch(EvalError e)
375             {
376                 // do nothing
377
}
378         }
379     } //}}}
380

381     //{{{ eval() method
382
/**
383      * Evaluates the specified BeanShell expression. Errors are reported in
384      * a dialog box.
385      * @param view The view. Within the script, references to
386      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
387      * are determined with reference to this parameter.
388      * @param namespace The namespace
389      * @param command The expression
390      * @since jEdit 4.0pre8
391      */

392     public static Object JavaDoc eval(View view, NameSpace namespace, String JavaDoc command)
393     {
394         try
395         {
396             return _eval(view,namespace,command);
397         }
398         catch(Throwable JavaDoc e)
399         {
400             Log.log(Log.ERROR,BeanShell.class,e);
401
402             handleException(view,null,e);
403         }
404
405         return null;
406     } //}}}
407

408     //{{{ _eval() method
409
/**
410      * Evaluates the specified BeanShell expression. Unlike
411      * <code>eval()</code>, this method passes any exceptions to the caller.
412      *
413      * @param view The view. Within the script, references to
414      * <code>buffer</code>, <code>textArea</code> and <code>editPane</code>
415      * are determined with reference to this parameter.
416      * @param namespace The namespace
417      * @param command The expression
418      * @exception Exception instances are thrown when various BeanShell
419      * errors occur
420      * @since jEdit 3.2pre7
421      */

422     public static Object JavaDoc _eval(View view, NameSpace namespace, String JavaDoc command)
423         throws Exception JavaDoc
424     {
425         Interpreter interp = createInterpreter(namespace);
426
427         try
428         {
429             setupDefaultVariables(namespace,view);
430             if(Debug.BEANSHELL_DEBUG)
431                 Log.log(Log.DEBUG,BeanShell.class,command);
432             return interp.eval(command);
433         }
434         catch(Exception JavaDoc e)
435         {
436             unwrapException(e);
437             // never called
438
return null;
439         }
440         finally
441         {
442             try
443             {
444                 resetDefaultVariables(namespace);
445             }
446             catch(UtilEvalError e)
447             {
448                 // do nothing
449
}
450         }
451     } //}}}
452

453     //{{{ cacheBlock() method
454
/**
455      * Caches a block of code, returning a handle that can be passed to
456      * runCachedBlock().
457      * @param id An identifier. If null, a unique identifier is generated
458      * @param code The code
459      * @param namespace If true, the namespace will be set
460      * @exception Exception instances are thrown when various BeanShell errors
461      * occur
462      * @since jEdit 4.1pre1
463      */

464     public static BshMethod cacheBlock(String JavaDoc id, String JavaDoc code, boolean namespace)
465         throws Exception JavaDoc
466     {
467         String JavaDoc name = "__internal_" + id;
468
469         // evaluate a method declaration
470
if(namespace)
471         {
472             _eval(null,global,name + "(ns) {\nthis.callstack.set(0,ns);\n" + code + "\n}");
473             return global.getMethod(name,new Class JavaDoc[] { NameSpace.class });
474         }
475         else
476         {
477             _eval(null,global,name + "() {\n" + code + "\n}");
478             return global.getMethod(name,new Class JavaDoc[0]);
479         }
480     } //}}}
481

482     //{{{ runCachedBlock() method
483
/**
484      * Runs a cached block of code in the specified namespace. Faster than
485      * evaluating the block each time.
486      * @param method The method instance returned by cacheBlock()
487      * @param view The view
488      * @param namespace The namespace to run the code in
489      * @exception Exception instances are thrown when various BeanShell
490      * errors occur
491      * @since jEdit 4.1pre1
492      */

493     public static Object JavaDoc runCachedBlock(BshMethod method, View view,
494         NameSpace namespace) throws Exception JavaDoc
495     {
496         boolean useNamespace;
497         if(namespace == null)
498         {
499             useNamespace = false;
500             namespace = global;
501         }
502         else
503             useNamespace = true;
504
505         try
506         {
507             setupDefaultVariables(namespace,view);
508
509             Object JavaDoc retVal = method.invoke(useNamespace
510                 ? new Object JavaDoc[] { namespace }
511                 : NO_ARGS,
512                 interpForMethods,new CallStack(), null);
513             if(retVal instanceof Primitive)
514             {
515                 if(retVal == Primitive.VOID)
516                     return null;
517                 else
518                     return ((Primitive)retVal).getValue();
519             }
520             else
521                 return retVal;
522         }
523         catch(Exception JavaDoc e)
524         {
525             unwrapException(e);
526             // never called
527
return null;
528         }
529         finally
530         {
531             resetDefaultVariables(namespace);
532         }
533     } //}}}
534

535     //{{{ isScriptRunning() method
536
/**
537      * Returns if a BeanShell script or macro is currently running.
538      * @since jEdit 2.7pre2
539      */

540     public static boolean isScriptRunning()
541     {
542         return running;
543     } //}}}
544

545     //{{{ getNameSpace() method
546
/**
547      * Returns the global namespace.
548      * @since jEdit 3.2pre5
549      */

550     public static NameSpace getNameSpace()
551     {
552         return global;
553     } //}}}
554

555     //{{{ Deprecated functions
556

557     //{{{ runScript() method
558
/**
559      * @deprecated The <code>rethrowBshErrors</code> parameter is now
560      * obsolete; call <code>_runScript()</code> or <code>runScript()</code>
561      * instead.
562      */

563     public static void runScript(View view, String JavaDoc path,
564         boolean ownNamespace, boolean rethrowBshErrors)
565     {
566         runScript(view,path,null,ownNamespace);
567     } //}}}
568

569     //{{{ runScript() method
570
/**
571      * @deprecated The <code>rethrowBshErrors</code> parameter is now
572      * obsolete; call <code>_runScript()</code> or <code>runScript()</code>
573      * instead.
574      */

575     public static void runScript(View view, String JavaDoc path, Reader in,
576         boolean ownNamespace, boolean rethrowBshErrors)
577     {
578         runScript(view,path,in,ownNamespace);
579     } //}}}
580

581     //{{{ eval() method
582
/**
583      * @deprecated The <code>rethrowBshErrors</code> parameter is now
584      * obsolete; call <code>_eval()</code> or <code>eval()</code> instead.
585      */

586     public static Object JavaDoc eval(View view, String JavaDoc command,
587         boolean rethrowBshErrors)
588     {
589         return eval(view,global,command);
590     } //}}}
591

592     //{{{ eval() method
593
/**
594      * @deprecated The <code>rethrowBshErrors</code> parameter is now
595      * obsolete; call <code>_eval()</code> or <code>eval()</code> instead.
596      */

597     public static Object JavaDoc eval(View view, NameSpace namespace,
598         String JavaDoc command, boolean rethrowBshErrors)
599     {
600         return eval(view,namespace,command);
601     } //}}}
602

603     //}}}
604

605     //{{{ Package-private members
606

607     //{{{ init() method
608
static void init()
609     {
610         /*try
611         {
612             NameSpace.class.getMethod("addCommandPath",
613                 new Class[] { String.class, Class.class });
614         }
615         catch(Exception e)
616         {
617             Log.log(Log.ERROR,BeanShell.class,"You have BeanShell version " + getVersion() + " in your CLASSPATH.");
618             Log.log(Log.ERROR,BeanShell.class,"Please remove it from the CLASSPATH since jEdit can only run with the bundled BeanShell version " + REQUIRED_VERSION);
619             System.exit(1);
620         } */

621
622         classManager = new ClassManagerImpl();
623         classManager.setClassLoader(new JARClassLoader());
624
625         global = new NameSpace(classManager,
626             "jEdit embedded BeanShell interpreter");
627         global.importPackage("org.gjt.sp.jedit");
628         global.importPackage("org.gjt.sp.jedit.browser");
629         global.importPackage("org.gjt.sp.jedit.buffer");
630         global.importPackage("org.gjt.sp.jedit.gui");
631         global.importPackage("org.gjt.sp.jedit.help");
632         global.importPackage("org.gjt.sp.jedit.io");
633         global.importPackage("org.gjt.sp.jedit.menu");
634         global.importPackage("org.gjt.sp.jedit.msg");
635         global.importPackage("org.gjt.sp.jedit.options");
636         global.importPackage("org.gjt.sp.jedit.pluginmgr");
637         global.importPackage("org.gjt.sp.jedit.print");
638         global.importPackage("org.gjt.sp.jedit.search");
639         global.importPackage("org.gjt.sp.jedit.syntax");
640         global.importPackage("org.gjt.sp.jedit.textarea");
641         global.importPackage("org.gjt.sp.util");
642
643         interpForMethods = createInterpreter(global);
644     } //}}}
645

646     //{{{ resetClassManager() method
647
/**
648      * Causes BeanShell internal structures to drop references to cached
649      * Class instances.
650      */

651     static void resetClassManager()
652     {
653         classManager.reset();
654     } //}}}
655

656     //}}}
657

658     //{{{ Private members
659

660     //{{{ Static variables
661
private static final Object JavaDoc[] NO_ARGS = new Object JavaDoc[0];
662     private static BshClassManager classManager;
663     private static Interpreter interpForMethods;
664     private static NameSpace global;
665     private static boolean running;
666     //}}}
667

668     //{{{ setupDefaultVariables() method
669
private static void setupDefaultVariables(NameSpace namespace, View view)
670         throws UtilEvalError
671     {
672         if(view != null)
673         {
674             EditPane editPane = view.getEditPane();
675             namespace.setVariable("view",view, false);
676             namespace.setVariable("editPane",editPane, false);
677             namespace.setVariable("buffer",editPane.getBuffer(), false);
678             namespace.setVariable("textArea",editPane.getTextArea(), false);
679             namespace.setVariable("wm",view.getDockableWindowManager(), false);
680         }
681     } //}}}
682

683     //{{{ resetDefaultVariables() method
684
private static void resetDefaultVariables(NameSpace namespace)
685         throws UtilEvalError
686     {
687         namespace.setVariable("view",null, false);
688         namespace.setVariable("editPane",null, false);
689         namespace.setVariable("buffer",null, false);
690         namespace.setVariable("textArea",null, false);
691         namespace.setVariable("wm",null, false);
692     } //}}}
693

694     //{{{ unwrapException() method
695
/**
696      * This extracts an exception from a 'wrapping' exception, as BeanShell
697      * sometimes throws. This gives the user a more accurate error traceback
698      */

699     private static void unwrapException(Exception JavaDoc e) throws Exception JavaDoc
700     {
701         if(e instanceof TargetError)
702         {
703             Throwable JavaDoc t = ((TargetError)e).getTarget();
704             if(t instanceof Exception JavaDoc)
705                 throw (Exception JavaDoc)t;
706             else if(t instanceof Error JavaDoc)
707                 throw (Error JavaDoc)t;
708         }
709
710         if(e instanceof InvocationTargetException JavaDoc)
711         {
712             Throwable JavaDoc t = ((InvocationTargetException JavaDoc)e).getTargetException();
713             if(t instanceof Exception JavaDoc)
714                 throw (Exception JavaDoc)t;
715             else if(t instanceof Error JavaDoc)
716                 throw (Error JavaDoc)t;
717         }
718
719         throw e;
720     } //}}}
721

722     //{{{ handleException() method
723
private static void handleException(View view, String JavaDoc path, Throwable JavaDoc t)
724     {
725         if(t instanceof IOException)
726         {
727             VFSManager.error(view,path,"ioerror.read-error",
728                 new String JavaDoc[] { t.toString() });
729         }
730         else
731             new BeanShellErrorDialog(view,t);
732     } //}}}
733

734     //{{{ createInterpreter() method
735
private static Interpreter createInterpreter(NameSpace nameSpace)
736     {
737         return new Interpreter(null,System.out,System.err,false,nameSpace);
738     } //}}}
739

740     //{{{ getVersion() method
741
private static String JavaDoc getVersion()
742     {
743         try
744         {
745             return (String JavaDoc)Interpreter.class.getField("VERSION").get(null);
746         }
747         catch(Exception JavaDoc e)
748         {
749             return "unknown";
750         }
751     } //}}}
752

753     //}}}
754

755     //{{{ CustomClassManager class
756
static class CustomClassManager extends ClassManagerImpl
757     {
758         private LinkedList listeners = new LinkedList();
759         private ReferenceQueue refQueue = new ReferenceQueue();
760
761         // copy and paste from bsh/classpath/ClassManagerImpl.java...
762
public synchronized void addListener( Listener l )
763         {
764             listeners.add( new WeakReference( l, refQueue) );
765
766             // clean up old listeners
767
Reference deadref;
768             while ( (deadref = refQueue.poll()) != null )
769             {
770                 boolean ok = listeners.remove( deadref );
771                 if ( ok )
772                 {
773                     //System.err.println("cleaned up weak ref: "+deadref);
774
}
775                 else
776                 {
777                     if ( Interpreter.DEBUG ) Interpreter.debug(
778                         "tried to remove non-existent weak ref: "+deadref);
779                 }
780             }
781         }
782
783         public void removeListener( Listener l )
784         {
785             throw new Error JavaDoc("unimplemented");
786         }
787
788         public void reset()
789         {
790             classLoaderChanged();
791         }
792
793         protected synchronized void classLoaderChanged()
794         {
795             // clear the static caches in BshClassManager
796
clearCaches();
797             if (listeners != null)
798             {
799
800                 for (Iterator iter = listeners.iterator();
801                      iter.hasNext(); )
802                 {
803                     WeakReference wr = (WeakReference)
804                         iter.next();
805                     Listener l = (Listener)wr.get();
806                     if ( l == null ) // garbage collected
807
iter.remove();
808                     else
809                         l.classLoaderChanged();
810                 }
811             }
812         }
813     } //}}}
814
}
815
Popular Tags