KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > armedbear > j > jdb > Jdb


1 /*
2  * Jdb.java
3  *
4  * Copyright (C) 2000-2003 Peter Graves
5  * $Id: Jdb.java,v 1.28 2003/06/09 16:35:30 piso Exp $
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */

21
22 package org.armedbear.j.jdb;
23
24 import com.sun.jdi.AbsentInformationException;
25 import com.sun.jdi.ArrayReference;
26 import com.sun.jdi.Field;
27 import com.sun.jdi.LocalVariable;
28 import com.sun.jdi.Location;
29 import com.sun.jdi.Method;
30 import com.sun.jdi.ObjectReference;
31 import com.sun.jdi.ReferenceType;
32 import com.sun.jdi.StackFrame;
33 import com.sun.jdi.StringReference;
34 import com.sun.jdi.ThreadReference;
35 import com.sun.jdi.VMDisconnectedException;
36 import com.sun.jdi.Value;
37 import com.sun.jdi.VirtualMachine;
38 import com.sun.jdi.event.ClassPrepareEvent;
39 import com.sun.jdi.event.LocatableEvent;
40 import com.sun.jdi.request.ClassPrepareRequest;
41 import com.sun.jdi.request.EventRequest;
42 import com.sun.jdi.request.EventRequestManager;
43 import com.sun.jdi.request.ExceptionRequest;
44 import com.sun.jdi.request.StepRequest;
45 import com.sun.jdi.request.ThreadDeathRequest;
46 import com.sun.jdi.request.ThreadStartRequest;
47 import java.io.IOException JavaDoc;
48 import java.io.InputStream JavaDoc;
49 import java.io.OutputStream JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.Map JavaDoc;
54 import java.util.Set JavaDoc;
55 import java.util.StringTokenizer JavaDoc;
56 import javax.swing.Icon JavaDoc;
57 import javax.swing.SwingUtilities JavaDoc;
58 import org.armedbear.j.Annotation;
59 import org.armedbear.j.Buffer;
60 import org.armedbear.j.BufferIterator;
61 import org.armedbear.j.Debug;
62 import org.armedbear.j.Editor;
63 import org.armedbear.j.EditorIterator;
64 import org.armedbear.j.EditorList;
65 import org.armedbear.j.File;
66 import org.armedbear.j.FastStringBuffer;
67 import org.armedbear.j.JavaMode;
68 import org.armedbear.j.JavaSource;
69 import org.armedbear.j.Line;
70 import org.armedbear.j.Log;
71 import org.armedbear.j.Platform;
72 import org.armedbear.j.Position;
73 import org.armedbear.j.ReaderThread;
74 import org.armedbear.j.SimpleEdit;
75 import org.armedbear.j.Utilities;
76
77 public final class Jdb extends Buffer implements JdbConstants
78 {
79     private static int catchMode = CATCH_UNCAUGHT;
80
81     private JdbSession session;
82     private VirtualMachine vm;
83     private ThreadReference currentThread;
84     private StackFrame currentStackFrame;
85     private Location location;
86     private String JavaDoc mainClass;
87     private String JavaDoc mainClassArgs;
88     private String JavaDoc classPath;
89     private String JavaDoc javaHome;
90     private String JavaDoc javaExecutable;
91     private String JavaDoc vmArgs;
92     private boolean startSuspended;
93     private boolean isSuspended = true;
94     private String JavaDoc sourcePath;
95     private JdbControlDialog controlDialog;
96     private Position posEndOfBuffer;
97     private ArrayList JavaDoc breakpointListeners = new ArrayList JavaDoc();
98     private ArrayList JavaDoc contextListeners = new ArrayList JavaDoc();
99     private int lastCommand;
100     private final List JavaDoc breakpoints = new ArrayList JavaDoc();
101
102     public static synchronized void jdb()
103     {
104         final Editor editor = Editor.currentEditor();
105         final Buffer buffer = editor.getBuffer();
106         Jdb jdb = findJdb();
107         if (jdb != null) {
108             if (!jdb.equals(buffer)) {
109                 editor.getFrame().unsplitWindow();
110                 editor.makeNext(jdb);
111                 editor.activateInOtherWindow(jdb);
112                 editor.updateDisplay();
113             }
114             if (jdb.getVM() != null)
115                 return; // Debugger is running.
116
}
117         JdbDialog d = new JdbDialog(editor);
118         editor.centerDialog(d);
119         d.show();
120         editor.getFrame().setWaitCursor();
121         editor.repaintNow();
122         if (!d.cancelled()) {
123             JdbSession session = d.getSession();
124             if (jdb != null) {
125                 jdb.setSession(session);
126                 jdb.startProcess();
127             } else {
128                 jdb = new Jdb(session);
129                 if (jdb != null) {
130                     JavaMode.setJdb(jdb);
131                     editor.getFrame().unsplitWindow();
132                     editor.makeNext(jdb);
133                     editor.activateInOtherWindow(jdb);
134                     jdb.showControlDialog();
135                     jdb.startProcess();
136                 }
137             }
138         }
139         editor.getFrame().setDefaultCursor();
140     }
141
142     private Jdb(JdbSession session)
143     {
144         super();
145         supportsUndo = false;
146         mode = JdbMode.getMode();
147         formatter = mode.getFormatter(this);
148         readOnly = true;
149         setSession(session);
150     }
151
152     public VirtualMachine getVM()
153     {
154         return vm;
155     }
156
157     public void setVM(VirtualMachine vm)
158     {
159         this.vm = vm;
160         if (vm == null) {
161             isSuspended = true;
162             currentThread = null;
163             currentStackFrame = null;
164         }
165     }
166
167     public String JavaDoc getMainClass()
168     {
169         return mainClass;
170     }
171
172     public String JavaDoc getMainClassArgs()
173     {
174         return mainClassArgs;
175     }
176
177     public String JavaDoc getClassPath()
178     {
179         return classPath;
180     }
181
182     public String JavaDoc getJavaHome()
183     {
184         return javaHome;
185     }
186
187     public String JavaDoc getJavaExecutable()
188     {
189         return javaExecutable;
190     }
191
192     public String JavaDoc getVMArgs()
193     {
194         return vmArgs;
195     }
196
197     public boolean getStartSuspended()
198     {
199         return startSuspended;
200     }
201
202     public String JavaDoc getSourcePath()
203     {
204         return sourcePath;
205     }
206
207     public int getLastCommand()
208     {
209         return lastCommand;
210     }
211
212     public void setLocation(Location location)
213     {
214         this.location = location;
215     }
216
217     public void setCurrentThread(ThreadReference threadRef)
218     {
219         currentThread = threadRef;
220     }
221
222     public ThreadReference getCurrentThread()
223     {
224         return currentThread;
225     }
226
227     public boolean isSuspended()
228     {
229         return isSuspended;
230     }
231
232     public void setSuspended(boolean b)
233     {
234         isSuspended = b;
235     }
236
237     public synchronized void setCurrentStackFrame(StackFrame stackFrame)
238     {
239         currentStackFrame = stackFrame;
240     }
241
242     public synchronized StackFrame getCurrentStackFrame()
243     {
244         return currentStackFrame;
245     }
246
247     public List JavaDoc getBreakpoints()
248     {
249         return breakpoints;
250     }
251
252     public void addBreakpointListener(BreakpointListener listener)
253     {
254         synchronized(breakpointListeners) {
255             breakpointListeners.add(listener);
256         }
257     }
258
259     public void fireBreakpointChanged()
260     {
261         synchronized(breakpointListeners) {
262             Iterator JavaDoc iter = breakpointListeners.iterator();
263             while (iter.hasNext())
264                 ((BreakpointListener)iter.next()).breakpointChanged();
265         }
266     }
267
268     public void addContextListener(ContextListener listener)
269     {
270         synchronized(contextListeners) {
271             contextListeners.add(listener);
272         }
273     }
274
275     private final Runnable JavaDoc fireContextChangedRunnable = new Runnable JavaDoc() {
276         public void run()
277         {
278             synchronized (contextListeners) {
279                 for (Iterator JavaDoc it = contextListeners.iterator(); it.hasNext();)
280                     ((ContextListener)it.next()).contextChanged();
281             }
282         }
283     };
284
285     public void fireContextChanged()
286     {
287         if (SwingUtilities.isEventDispatchThread())
288             fireContextChangedRunnable.run();
289         else
290             SwingUtilities.invokeLater(fireContextChangedRunnable);
291     }
292
293     public void initialize()
294     {
295         // Nothing to do.
296
}
297
298     public synchronized int load()
299     {
300         if (!isLoaded()) {
301             try {
302                 lockWrite();
303             }
304             catch (InterruptedException JavaDoc e) {
305                 Log.debug(e);
306                 return LOAD_FAILED; // Shouldn't happen.
307
}
308             try {
309                 appendLine("");
310                 setLoaded(true);
311                 posEndOfBuffer = new Position(getFirstLine(), 0);
312             }
313             finally {
314                 unlockWrite();
315             }
316         }
317         return LOAD_COMPLETED;
318     }
319
320     private void showControlDialog()
321     {
322         if (controlDialog == null) {
323             controlDialog = new JdbControlDialog(this);
324             controlDialog.show();
325         }
326     }
327
328     public JdbControlDialog getControlDialog()
329     {
330         return controlDialog;
331     }
332
333     public void doCommand(String JavaDoc input)
334     {
335         String JavaDoc s = input.trim();
336         String JavaDoc cmd, args;
337         int index = s.indexOf(' ');
338         if (index >= 0) {
339             cmd = s.substring(0, index);
340             args = s.substring(index+1).trim();
341         } else {
342             cmd = s;
343             args = null;
344         }
345         // Command may be abbreviated.
346
int command = JdbCommands.findCommand(cmd);
347         if (command < 0) {
348             // Not found.
349
logCommand(cmd);
350             log("Command not found");
351         } else {
352             doCommand(command, args);
353             lastCommand = command;
354         }
355     }
356
357     public void doCommand(int command, String JavaDoc args)
358     {
359         switch (command) {
360             case JDB_BREAK:
361                 logCommand("break", args);
362                 doBreak(args, false);
363                 break;
364             case JDB_CATCH:
365                 logCommand("catch", args);
366                 doCatch(args);
367                 break;
368             case JDB_CLEAR:
369                 logCommand("clear", args);
370                 doClear(args);
371                 break;
372             case JDB_FINISH:
373                 logCommand("finish");
374                 doFinish();
375                 break;
376             case JDB_LOCALS:
377                 logCommand("locals");
378                 doLocals();
379                 break;
380             case JDB_NEXT:
381                 logCommand("next");
382                 doNext(args);
383                 break;
384             case JDB_PRINT:
385                 logCommand("print", args);
386                 doPrint(args);
387                 break;
388             case JDB_QUIT:
389                 logCommand("quit");
390                 quit();
391                 break;
392             case JDB_RESTART:
393                 logCommand("restart");
394                 restart();
395                 break;
396             case JDB_CONTINUE:
397                 logCommand("continue");
398                 doContinue();
399                 break;
400             case JDB_STDIN:
401                 doStdin(args);
402                 break;
403             case JDB_STEP:
404                 logCommand("step", args);
405                 doStep(args);
406                 break;
407             case JDB_SUSPEND:
408                 logCommand("suspend");
409                 doSuspend();
410                 break;
411             case JDB_TBREAK:
412                 logCommand("tbreak", args);
413                 doBreak(args, true);
414                 break;
415             default:
416                 Log.error("Jdb.doCommand unknown command " + command);
417                 Debug.bug();
418                 break;
419         }
420     }
421
422     private static final String JavaDoc prompt = "jdb> ";
423
424     public static final String JavaDoc getPrompt()
425     {
426         return prompt;
427     }
428
429     public void prompt()
430     {
431         Runnable JavaDoc r = new Runnable JavaDoc() {
432             public void run()
433             {
434                 appendString(prompt, true, JdbFormatter.JDB_FORMAT_PROMPT);
435             }
436         };
437         if (SwingUtilities.isEventDispatchThread())
438             r.run();
439         else
440             SwingUtilities.invokeLater(r);
441     }
442
443     private void logCommand(String JavaDoc command)
444     {
445         log(prompt.concat(command));
446     }
447
448     private void logCommand(String JavaDoc command, String JavaDoc remainder)
449     {
450         FastStringBuffer sb = new FastStringBuffer(prompt);
451         sb.append(command);
452         if (remainder != null && remainder.length() > 0) {
453             sb.append(' ');
454             sb.append(remainder);
455         }
456         log(sb.toString());
457     }
458
459     public void log(String JavaDoc s)
460     {
461         log(s, true);
462     }
463
464     private void log(String JavaDoc s, boolean forceNewLine)
465     {
466         log(s, forceNewLine, JdbFormatter.JDB_FORMAT_LOG);
467     }
468
469     private void log(final String JavaDoc s, final boolean forceNewLine, final int flags)
470     {
471         Runnable JavaDoc r = new Runnable JavaDoc() {
472             public void run()
473             {
474                 Log.debug(s);
475                 appendString(s.concat("\n"), forceNewLine,
476                     flags);
477             }
478         };
479         if (SwingUtilities.isEventDispatchThread())
480             r.run();
481         else
482             SwingUtilities.invokeLater(r);
483     }
484
485     private void appendString(String JavaDoc s, boolean forceNewLine, int flags)
486     {
487         try {
488             lockWrite();
489         }
490         catch (InterruptedException JavaDoc e) {
491             Log.error(e);
492             return;
493         }
494         try {
495             Position posStart = posEndOfBuffer.copy();
496             if (forceNewLine) {
497                 if (posEndOfBuffer.getOffset() > 0) {
498                     if (!posEndOfBuffer.getLine().getText().equals(prompt)) {
499                         insertLineSeparator(posEndOfBuffer);
500                         posEndOfBuffer.getLine().setFlags(flags);
501                     }
502                 }
503             }
504             if (posEndOfBuffer.getOffset() > 0 && s.startsWith(prompt)) {
505                 if (posEndOfBuffer.getLine().getText().equals(prompt))
506                     s = s.substring(prompt.length());
507             }
508             insertString(posEndOfBuffer, s);
509             if (needsRenumbering())
510                 renumber();
511             Line line = posStart.getLine();
512             if (posStart.getOffset() > 0)
513                 line = line.next();
514             while (line != null) {
515                 line.setFlags(flags);
516                 line = line.next();
517             }
518         }
519         finally {
520             unlockWrite();
521         }
522         for (EditorIterator it = new EditorIterator(); it.hasNext();) {
523             Editor ed = it.nextEditor();
524             if (ed.getBuffer() == this) {
525                 ed.eob();
526                 ed.getDisplay().setReframe(-2);
527                 ed.setUpdateFlag(REPAINT);
528                 ed.updateDisplay();
529             }
530         }
531     }
532
533     public void printCurrentLocation(LocatableEvent event)
534     {
535         printCurrentLocation(event.thread(), event.location());
536     }
537
538     public void printCurrentLocation(ThreadReference threadRef, Location location)
539     {
540         FastStringBuffer sb = new FastStringBuffer("[");
541         sb.append(threadRef.name());
542         sb.append("] ");
543         sb.append(location.declaringType().name());
544         sb.append('.');
545         Method method = location.method();
546         sb.append(method.name());
547         try {
548             sb.append(" (");
549             if (method.isNative()) {
550                 sb.append("native method");
551             } else {
552                 String JavaDoc sourceName = location.sourceName();
553                 sb.append(location.sourceName());
554                 int lineNumber = location.lineNumber();
555                 if (lineNumber > 0) {
556                     sb.append(':');
557                     sb.append(lineNumber);
558                 }
559             }
560             sb.append(')');
561         }
562         catch (AbsentInformationException e) {
563             Log.error(e);
564         }
565         log(sb.toString());
566     }
567
568     public void displayRemoteOutput(InputStream JavaDoc inputStream) {
569         ReaderThread readerThread = new ReaderThread(inputStream) {
570             public void update(final String JavaDoc s)
571             {
572                 Runnable JavaDoc runnable = new Runnable JavaDoc() {
573                     public void run()
574                     {
575                         appendString(s, false, JdbFormatter.JDB_FORMAT_OUTPUT);
576                     }
577                 };
578                 SwingUtilities.invokeLater(runnable);
579             }
580         };
581         readerThread.setPriority(Thread.MAX_PRIORITY-1);
582         readerThread.start();
583     }
584
585     private void addBreakpoint(ResolvableBreakpoint bp)
586     {
587         breakpoints.add(bp);
588         FastStringBuffer sb = new FastStringBuffer();
589         if (bp.isTemporary())
590             sb.append("Temporary b");
591         else
592             sb.append('B');
593         sb.append("reakpoint added: ");
594         sb.append(bp.getLocationString());
595         log(sb.toString());
596         if (isSuspended())
597             prompt();
598     }
599
600     public void deleteBreakpoint(ResolvableBreakpoint bp)
601     {
602         bp.clear();
603         breakpoints.remove(bp);
604         FastStringBuffer sb = new FastStringBuffer();
605         if (bp.isTemporary())
606             sb.append("Temporary b");
607         else
608             sb.append('B');
609         sb.append("reakpoint deleted: ");
610         sb.append(bp.getLocationString());
611         log(sb.toString());
612         if (isSuspended())
613             prompt();
614     }
615
616     public static void jdbToggleBreakpoint()
617     {
618         Jdb jdb = findJdb();
619         if (jdb == null)
620             return;
621         final Editor editor = Editor.currentEditor();
622         final Line line = editor.getDotLine();
623         Annotation annotation = line.getAnnotation();
624         if (annotation instanceof BreakpointAnnotation)
625             jdbDeleteBreakpoint();
626         else
627             jdbSetBreakpoint();
628     }
629
630     public static void jdbSetBreakpoint()
631     {
632         setBreakpointAtCurrentLine(false);
633     }
634
635     public static void jdbRunToCurrentLine()
636     {
637         Jdb jdb = findJdb();
638         if (jdb == null)
639             return;
640         setBreakpointAtCurrentLine(true);
641         jdb.logCommand("continue");
642         jdb.doContinue();
643     }
644
645     private static void setBreakpointAtCurrentLine(boolean temporary)
646     {
647         Jdb jdb = findJdb();
648         if (jdb == null)
649             return;
650         final Editor editor = Editor.currentEditor();
651         final Buffer buffer = editor.getBuffer();
652         final File file = buffer.getFile();
653         if (file != null && file.getName().toLowerCase().endsWith(".java")) {
654             final Line line = editor.getDotLine();
655             FastStringBuffer sb = new FastStringBuffer();
656             if (temporary)
657                 sb.append('t');
658             sb.append("break ");
659             sb.append(file.getName());
660             sb.append(':');
661             sb.append(line.lineNumber() + 1);
662             jdb.logCommand(sb.toString());
663             LineNumberBreakpoint bp =
664                 new LineNumberBreakpoint(jdb, buffer, editor.getDotLine());
665             if (temporary)
666                 bp.setTemporary();
667             try {
668                 EventRequest eventRequest = bp.resolveAgainstPreparedClasses();
669                 if (eventRequest != null) {
670                     eventRequest.enable();
671                 } else {
672                     EventRequestManager mgr = jdb.getVM().eventRequestManager();
673                     ClassPrepareRequest cpr = mgr.createClassPrepareRequest();
674                     String JavaDoc packageName = JavaSource.getPackageName(buffer);
675                     String JavaDoc classFilter;
676                     if (packageName != null) {
677                         classFilter =
678                             packageName.concat(".").concat(file.getName());
679                     } else {
680                         classFilter = file.getName();
681                     }
682                     if (classFilter.toLowerCase().endsWith(".java")) {
683                         classFilter =
684                             classFilter.substring(0, classFilter.length()-5);
685                     }
686                     cpr.addClassFilter(classFilter);
687                     cpr.enable();
688                 }
689                 jdb.addBreakpoint(bp);
690                 jdb.saveSession();
691                 jdb.fireBreakpointChanged();
692             }
693             catch (AbsentInformationException absent) {
694                 jdb.log("Line number information is not available.");
695             }
696             catch (Exception JavaDoc e) {
697                 Log.error(e);
698             }
699         }
700     }
701
702     public static void jdbDeleteBreakpoint()
703     {
704         Jdb jdb = findJdb();
705         if (jdb == null)
706             return;
707         final Editor editor = Editor.currentEditor();
708         final Line line = editor.getDotLine();
709         Annotation annotation = line.getAnnotation();
710         if (annotation instanceof BreakpointAnnotation) {
711             ResolvableBreakpoint bp =
712                 ((BreakpointAnnotation)annotation).getBreakpoint();
713             jdb.log("clear " + bp.getLocationString());
714             jdb.deleteBreakpoint(bp);
715             File file = bp.getFile();
716             if (file != null) {
717                 Buffer buffer = Editor.getBufferList().findBuffer(file);
718                 if (buffer != null)
719                     buffer.repaint();
720             }
721             jdb.saveSession();
722             jdb.fireBreakpointChanged();
723         }
724     }
725
726     public synchronized void doContinue()
727     {
728         if (vm != null) {
729             currentThread = null;
730             currentStackFrame = null;
731             vm.resume();
732             isSuspended = false;
733             fireContextChanged();
734         }
735     }
736
737     public synchronized void doSuspend()
738     {
739         if (vm != null && !isSuspended) {
740             vm.suspend();
741             isSuspended = true;
742             log("VM suspended");
743             ThreadReference threadRef = null;
744             List JavaDoc threads = vm.allThreads();
745             for (int i = 0; i < threads.size(); i++) {
746                 ThreadReference tr = (ThreadReference) threads.get(i);
747                 if ("main".equals(tr.name()))
748                     threadRef = tr;
749             }
750             if (threadRef == null) {
751                 if (threads.size() > 0)
752                     threadRef = (ThreadReference) threads.get(0);
753             }
754             setCurrentThread(threadRef);
755             fireContextChanged();
756             prompt();
757         }
758     }
759
760     public static Jdb findJdb()
761     {
762         return (Jdb) JavaMode.getJdb();
763     }
764
765     public void startProcess()
766     {
767         Runnable JavaDoc r = new Runnable JavaDoc() {
768             public void run()
769             {
770                 startProcessInternal();
771             }
772         };
773         new Thread JavaDoc(r).start();
774     }
775
776     private void startProcessInternal()
777     {
778         VMConnection connection = VMConnection.getConnection(this);
779         if (connection != null) {
780             vm = connection.open(this);
781             if (vm != null) {
782                 EventRequestManager mgr = vm.eventRequestManager();
783                 if (catchMode != CATCH_NONE) {
784                     ExceptionRequest exceptionRequest =
785                         mgr.createExceptionRequest(null,
786                             catchMode == CATCH_ALL, true);
787                     exceptionRequest.enable();
788                 }
789                 ThreadStartRequest tsr = mgr.createThreadStartRequest();
790                 tsr.enable();
791                 ThreadDeathRequest tdr = mgr.createThreadDeathRequest();
792                 tdr.enable();
793                 if (breakpoints.size() > 0) {
794                     Iterator JavaDoc iter = breakpoints.iterator();
795                     while (iter.hasNext()) {
796                         Object JavaDoc obj = iter.next();
797                         if (obj instanceof ResolvableBreakpoint) {
798                             ResolvableBreakpoint bp =
799                                 (ResolvableBreakpoint) obj;
800                             String JavaDoc className = bp.getClassName();
801                             if (className != null) {
802                                 Log.debug("adding class prepare request for |" + className + "|");
803                                 ClassPrepareRequest cpr =
804                                     mgr.createClassPrepareRequest();
805                                 cpr.addClassFilter(className);
806                                 cpr.enable();
807                             }
808                         }
809                     }
810                 } else {
811                     Log.debug("startProcessInternal adding default breakpoint");
812                     breakpoints.add(new MethodBreakpoint(this, mainClass,
813                         "main"));
814                     fireBreakpointChanged();
815                 }
816                 ClassPrepareRequest cpr = mgr.createClassPrepareRequest();
817                 cpr.addClassFilter(mainClass);
818                 cpr.enable();
819                 if (!startSuspended) {
820                     vm.resume();
821                     isSuspended = false;
822                     fireContextChanged();
823                 }
824             }
825         }
826     }
827
828     public void resolveDeferredRequests(ClassPrepareEvent event)
829     {
830         synchronized (breakpoints) {
831             Iterator JavaDoc iter = breakpoints.iterator();
832             while (iter.hasNext()) {
833                 ResolvableBreakpoint bp = (ResolvableBreakpoint) iter.next();
834                 if (!bp.isResolved()) {
835                     try {
836                         Log.debug("bp.getClassName() = " + bp.getClassName());
837                         EventRequest eventRequest = bp.resolveAgainstPreparedClasses();
838                         if (eventRequest != null) {
839                             Log.debug("bp was resolved");
840                             eventRequest.enable();
841                         } else
842                             Log.debug("bp was NOT resolved");
843                     }
844                     catch (Exception JavaDoc e) {
845                         Log.error(e);
846                     }
847                 }
848             }
849         }
850     }
851
852     public JdbSession getSession()
853     {
854         return session;
855     }
856
857     private void setSession(JdbSession session)
858     {
859         this.session = session;
860         mainClass = session.getMainClass();
861         mainClassArgs = session.getMainClassArgs();
862         classPath = session.getClassPath();
863         javaHome = session.getJavaHome();
864         javaExecutable = session.getJavaExecutable();
865         vmArgs = session.getVMArgs();
866         startSuspended = session.getStartSuspended();
867         sourcePath = session.getSourcePath();
868         initializeBreakpoints();
869     }
870
871     private void initializeBreakpoints()
872     {
873         breakpoints.clear();
874         List JavaDoc breakpointSpecifications = session.getBreakpointSpecifications();
875         if (breakpointSpecifications != null) {
876             Iterator JavaDoc iter = breakpointSpecifications.iterator();
877             while (iter.hasNext()) {
878                 BreakpointSpecification spec =
879                     (BreakpointSpecification) iter.next();
880                 Log.debug(spec.toString());
881                 int lineNumber = spec.getLineNumber();
882                 if (spec.getLineNumber() > 0){
883                     File file = File.getInstance(spec.getFileName());
884                     if (file != null && file.isFile()) {
885                         LineNumberBreakpoint bp =
886                             new LineNumberBreakpoint(this, spec.getClassName(),
887                                 file, lineNumber);
888                         breakpoints.add(bp);
889                     }
890                 } else {
891                     String JavaDoc className = spec.getClassName();
892                     String JavaDoc methodName = spec.getMethodName();
893                     if (className != null && methodName != null) {
894                         MethodBreakpoint bp =
895                             new MethodBreakpoint(this, className, methodName);
896                         breakpoints.add(bp);
897                     }
898                 }
899             }
900         }
901         fireBreakpointChanged();
902     }
903
904     public void saveSession()
905     {
906         session.setBreakpoints(breakpoints);
907         session.saveDefaults();
908     }
909
910     public void source()
911     {
912         source(Editor.currentEditor());
913     }
914
915     public void source(final Editor editor)
916     {
917         Runnable JavaDoc r = new Runnable JavaDoc() {
918             public void run()
919             {
920                 if (location == null)
921                     return;
922                 Method method = location.method();
923                 if (method != null && method.isNative())
924                     return;
925                 String JavaDoc className = location.declaringType().name();
926                 String JavaDoc sourceName = null;
927                 try {
928                     sourceName = location.sourceName();
929                     Log.debug("sourceName = |" + sourceName + "|");
930                 }
931                 catch (AbsentInformationException e) {
932                     Log.error(e);
933                 }
934                 int lineNumber = location.lineNumber();
935                 Log.debug("lineNumber = " + lineNumber);
936                 Log.debug(location.declaringType().name());
937                 if (sourceName != null)
938                     follow(editor, className, sourceName, lineNumber - 1);
939             }
940         };
941         if (SwingUtilities.isEventDispatchThread())
942             r.run();
943         else
944             SwingUtilities.invokeLater(r);
945     }
946
947     private boolean follow(Editor editor, String JavaDoc className, String JavaDoc fileName,
948         int lineNumber)
949     {
950         int index = className.indexOf('$');
951         if (index >= 0)
952             className = className.substring(0, index);
953         File file = JavaSource.findSource(className, sourcePath);
954         if (file == null) {
955             file = Utilities.findFileInPath(fileName, sourcePath,
956                 getCurrentDirectory());
957         }
958         if (file == null)
959             return false;
960         if (!file.exists())
961             return false;
962         final Buffer buf = Editor.getBuffer(file);
963         if (buf == null)
964             return false;
965         Editor ed = null;
966         final Buffer currentBuffer = editor.getBuffer();
967         if (buf == currentBuffer) {
968             ed = editor;
969         } else {
970             editor.makeNext(buf);
971             if (currentBuffer instanceof Jdb) {
972                 ed = editor.activateInOtherWindow(buf);
973             } else {
974                 // Re-use current editor.
975
ed = editor;
976                 ed.activate(buf);
977             }
978         }
979         Line line = buf.getLine(lineNumber);
980         if (line == null) {
981             ed.eob();
982         } else {
983             ed.addUndo(SimpleEdit.MOVE);
984             ed.unmark();
985             ed.update(ed.getDotLine());
986             ed.setDot(line, 0);
987             ed.update(ed.getDotLine());
988             ed.moveCaretToDotCol();
989             ed.updateDisplay();
990         }
991         return true;
992     }
993
994     public void dispose()
995     {
996         killVM();
997         if (controlDialog != null) {
998             controlDialog.dispose();
999             controlDialog = null;
1000        }
1001        saveSession();
1002        removeAnnotations();
1003        synchronized (Jdb.class) {
1004            if (JavaMode.getJdb() != this)
1005                Debug.bug();
1006            JavaMode.setJdb(null);
1007        }
1008    }
1009
1010    private void removeAnnotations()
1011    {
1012        if (breakpoints != null) {
1013            for (Iterator JavaDoc it = breakpoints.iterator(); it.hasNext();) {
1014                Object JavaDoc obj = it.next();
1015                if (obj instanceof ResolvableBreakpoint) {
1016                    ResolvableBreakpoint bp = (ResolvableBreakpoint) obj;
1017                    Line line = bp.getLine();
1018                    if (line != null)
1019                        line.setAnnotation(null);
1020                }
1021            }
1022            // Repaint editors with buffers in Java mode.
1023
for (EditorIterator it = new EditorIterator(); it.hasNext();) {
1024                Editor ed = it.nextEditor();
1025                if (ed.getModeId() == JAVA_MODE)
1026                    ed.repaint();
1027            }
1028        }
1029    }
1030
1031    private void quit()
1032    {
1033        killVM();
1034        removeAnnotations();
1035        // Copy editor list since unsplitWindow() may close an editor.
1036
ArrayList JavaDoc editors = new ArrayList JavaDoc();
1037        for (EditorIterator it = new EditorIterator(); it.hasNext();)
1038            editors.add(it.next());
1039        EditorList editorList = Editor.getEditorList();
1040        for (Iterator JavaDoc it = editors.iterator(); it.hasNext();) {
1041            Editor ed = (Editor) it.next();
1042            if (editorList.contains(ed)) {
1043                if (ed.getBuffer() == this) {
1044                    Editor other = ed.getOtherEditor();
1045                    if (other != null) {
1046                        Editor.setCurrentEditor(other);
1047                        ed.getFrame().unsplitWindow();
1048                    }
1049                }
1050            }
1051        }
1052        kill();
1053    }
1054
1055    private void restart()
1056    {
1057        killVM();
1058        saveSession();
1059        removeAnnotations();
1060        session.loadDefaults();
1061        initializeBreakpoints();
1062        startProcess();
1063        fireContextChanged();
1064    }
1065
1066    private synchronized void killVM()
1067    {
1068        if (vm != null) {
1069            try {
1070                vm.exit(0);
1071            }
1072            catch (VMDisconnectedException e) {
1073                // Already exited.
1074
}
1075            setVM(null);
1076        }
1077    }
1078
1079    private void doBreak(String JavaDoc arg, boolean temporary)
1080    {
1081        try {
1082            if (vm == null)
1083                return;
1084            if (arg == null) {
1085                log("No location specified");
1086                return;
1087            }
1088            int index = arg.indexOf(':');
1089            if (index >= 0) {
1090                String JavaDoc fileName = arg.substring(0, index);
1091                try {
1092                    int lineNumber =
1093                        Integer.parseInt(arg.substring(index + 1).trim());
1094                    doBreakAtLineNumber(fileName, lineNumber, temporary);
1095                }
1096                catch (NumberFormatException JavaDoc e) {
1097                    log("Invalid line number");
1098                }
1099            } else {
1100                index = arg.lastIndexOf('.');
1101                if (index < 0) {
1102                    log("No class specified");
1103                    return;
1104                }
1105                String JavaDoc className = arg.substring(0, index);
1106                String JavaDoc methodName = arg.substring(index + 1);
1107                doBreakAtMethod(className, methodName, temporary);
1108            }
1109        }
1110        finally {
1111            if (isSuspended())
1112                prompt();
1113        }
1114    }
1115
1116    private void doBreakAtLineNumber(String JavaDoc fileName, int lineNumber,
1117        boolean temporary)
1118    {
1119        File file = findSourceFile(fileName);
1120        if (file == null) {
1121            log("File not found: ".concat(fileName));
1122            return;
1123        }
1124        String JavaDoc className = file.getName();
1125        if (className.toLowerCase().endsWith(".java"))
1126            className = className.substring(0, className.length() - 5);
1127        Buffer buffer = Editor.getBuffer(file);
1128        if (buffer != null) {
1129            if (!buffer.initialized())
1130                buffer.initialize();
1131            if (!buffer.isLoaded())
1132                buffer.load();
1133            String JavaDoc packageName = JavaSource.getPackageName(buffer);
1134            if (packageName != null)
1135                className = packageName.concat(".").concat(className);
1136            LineNumberBreakpoint bp =
1137                new LineNumberBreakpoint(this, className, file, lineNumber);
1138            if (temporary)
1139                bp.setTemporary();
1140            try {
1141                EventRequest eventRequest = bp.resolveAgainstPreparedClasses();
1142                if (eventRequest != null) {
1143                    eventRequest.enable();
1144                } else {
1145                    EventRequestManager mgr = vm.eventRequestManager();
1146                    ClassPrepareRequest cpr = mgr.createClassPrepareRequest();
1147                    String JavaDoc classFilter = className;
1148                    cpr.addClassFilter(classFilter);
1149                    cpr.enable();
1150                }
1151                addBreakpoint(bp);
1152                saveSession();
1153                fireBreakpointChanged();
1154            }
1155            catch (AbsentInformationException absent) {
1156                log("Line number information is not available.");
1157            }
1158            catch (Exception JavaDoc e) {
1159                Log.error(e);
1160            }
1161        }
1162    }
1163
1164    private File findSourceFile(String JavaDoc fileName)
1165    {
1166        String JavaDoc canonicalPath = null;
1167        if (Utilities.isFilenameAbsolute(fileName)) {
1168            File file = File.getInstance(fileName);
1169            if (file != null && file.isFile())
1170                return file;
1171            // File does not exist.
1172
return null;
1173        }
1174        // Filename is not absolute.
1175
File mainFile = JavaSource.findSource(mainClass, sourcePath);
1176        if (mainFile != null && mainFile.isFile()) {
1177            File dir = mainFile.getParentFile();
1178            if (dir != null) {
1179                File file = File.getInstance(dir, fileName);
1180                if (file != null && file.isFile())
1181                    return file;
1182            }
1183        }
1184        // Try current directory.
1185
File dir = Editor.currentEditor().getCurrentDirectory();
1186        Log.debug("trying dir = " + dir);
1187        File file = File.getInstance(dir, fileName);
1188        if (file != null && file.isFile())
1189            return file;
1190        // Look for match in buffer list.
1191
List JavaDoc dirs = Utilities.getDirectoriesInPath(sourcePath);
1192        for (BufferIterator iter = new BufferIterator(); iter.hasNext();) {
1193            Buffer b = iter.nextBuffer();
1194            file = b.getFile();
1195            if (file.getName().equals(fileName)) {
1196                File rootDir = JavaSource.getPackageRootDirectory(b);
1197                for (Iterator JavaDoc it = dirs.iterator(); it.hasNext();) {
1198                    String JavaDoc dirname = (String JavaDoc) it.next();
1199                    if (dirname.equals(rootDir.canonicalPath()))
1200                        return file;
1201                }
1202            }
1203            if (Platform.isPlatformWindows()) {
1204                if (file.getName().equalsIgnoreCase(fileName)) {
1205                    File rootDir = JavaSource.getPackageRootDirectory(b);
1206                    for (Iterator JavaDoc it = dirs.iterator(); it.hasNext();) {
1207                        String JavaDoc dirname = (String JavaDoc) it.next();
1208                        if (dirname.equalsIgnoreCase(rootDir.canonicalPath()))
1209                            return file;
1210                    }
1211                }
1212            }
1213        }
1214        // Not found.
1215
return null;
1216    }
1217
1218    private void doBreakAtMethod(String JavaDoc className, String JavaDoc methodName,
1219        boolean temporary)
1220    {
1221        if (className.indexOf(".") < 0) {
1222            // No package prefix.
1223
String JavaDoc fileName = className.concat(".java");
1224            File file = findSourceFile(fileName);
1225            if (file != null) {
1226                Buffer buffer = Editor.getBuffer(file);
1227                if (buffer != null) {
1228                    if (!buffer.initialized())
1229                        buffer.initialize();
1230                    if (!buffer.isLoaded())
1231                        buffer.load();
1232                    String JavaDoc packageName = JavaSource.getPackageName(buffer);
1233                    if (packageName != null)
1234                        className = packageName.concat(".").concat(className);
1235                }
1236            }
1237        }
1238        MethodBreakpoint bp = new MethodBreakpoint(this, className, methodName);
1239        if (temporary)
1240            bp.setTemporary();
1241        try {
1242            EventRequest eventRequest = bp.resolveAgainstPreparedClasses();
1243            if (eventRequest != null) {
1244                eventRequest.enable();
1245            } else {
1246                EventRequestManager mgr = vm.eventRequestManager();
1247                ClassPrepareRequest cpr = mgr.createClassPrepareRequest();
1248                cpr.addClassFilter(className);
1249                cpr.enable();
1250            }
1251            addBreakpoint(bp);
1252            saveSession();
1253            fireBreakpointChanged();
1254        }
1255        catch (Exception JavaDoc e) {
1256            Log.error(e);
1257        }
1258    }
1259
1260    // e.g. "clear Jdb.java:877"
1261
private void doClear(String JavaDoc arg)
1262    {
1263        if (arg == null) {
1264            log("No breakpoint specified");
1265            return;
1266        }
1267        if (arg.equals("all"))
1268            doClearAll();
1269        else if (arg.indexOf(':') >= 0)
1270            doClearLineNumberBreakpoint(arg);
1271        else
1272            doClearMethodBreakpoint(arg);
1273        // Repaint editors with buffers in Java mode.
1274
for (EditorIterator it = new EditorIterator(); it.hasNext();) {
1275            Editor ed = it.nextEditor();
1276            if (ed.getModeId() == JAVA_MODE)
1277                ed.repaint();
1278        }
1279    }
1280
1281    private void doClearAll()
1282    {
1283        // Disable resolved breakpoints.
1284
for (Iterator JavaDoc it = breakpoints.iterator(); it.hasNext();) {
1285            Object JavaDoc obj = it.next();
1286            if (obj instanceof ResolvableBreakpoint)
1287                ((ResolvableBreakpoint)obj).clear();
1288        }
1289        // Clear the list.
1290
breakpoints.clear();
1291        fireBreakpointChanged();
1292        if (isSuspended())
1293            prompt();
1294    }
1295
1296    private void doClearLineNumberBreakpoint(String JavaDoc arg)
1297    {
1298        int index = arg.indexOf(':');
1299        String JavaDoc fileName = arg.substring(0, index);
1300        if (!fileName.toLowerCase().endsWith(".java"))
1301            fileName = fileName.concat(".java");
1302        int lineNumber = -1;
1303        try {
1304            lineNumber = Integer.parseInt(arg.substring(index + 1));
1305        }
1306        catch (NumberFormatException JavaDoc e) {}
1307        if (lineNumber < 1) {
1308            log("Invalid breakpoint");
1309            return;
1310        }
1311        for (Iterator JavaDoc it = breakpoints.iterator(); it.hasNext();) {
1312            Object JavaDoc obj = it.next();
1313            if (obj instanceof LineNumberBreakpoint) {
1314                LineNumberBreakpoint bp = (LineNumberBreakpoint) obj;
1315                File file = bp.getFile();
1316                if (file != null) {
1317                    if (fileName.equals(file.getName())) {
1318                        if (lineNumber == bp.getLineNumber()) {
1319                            // Found it.
1320
deleteBreakpoint(bp);
1321                            fireBreakpointChanged();
1322                            return;
1323                        }
1324                    }
1325                }
1326            }
1327        }
1328        log("No breakpoint at " + arg);
1329    }
1330
1331    private void doClearMethodBreakpoint(String JavaDoc arg)
1332    {
1333        String JavaDoc className, methodName;
1334        int index = arg.lastIndexOf('.');
1335        if (index >= 0) {
1336            className = arg.substring(0, index);
1337            methodName = arg.substring(index + 1);
1338        } else {
1339            className = null;
1340            methodName = arg;
1341        }
1342        for (Iterator JavaDoc it = breakpoints.iterator(); it.hasNext();) {
1343            Object JavaDoc obj = it.next();
1344            if (obj instanceof MethodBreakpoint) {
1345                MethodBreakpoint bp = (MethodBreakpoint) obj;
1346                if (className != null) {
1347                    if (className.equals(bp.getClassName())) {
1348                        if (methodName.equals(bp.getMethodName())) {
1349                            // Found it.
1350
deleteBreakpoint(bp);
1351                            fireBreakpointChanged();
1352                            return;
1353                        }
1354                    }
1355                } else {
1356                    // No class name specified.
1357
if (methodName.equals(bp.getMethodName())) {
1358                        // Found it.
1359
deleteBreakpoint(bp);
1360                        fireBreakpointChanged();
1361                        return;
1362                    }
1363                }
1364            }
1365        }
1366        log("No breakpoint at " + arg);
1367    }
1368
1369    private synchronized void doCatch(String JavaDoc arg)
1370    {
1371        try {
1372            if (vm == null)
1373                return;
1374            int newCatchMode = -1;
1375            if (arg.equals("none"))
1376                newCatchMode = CATCH_NONE;
1377            else if (arg.equals("uncaught"))
1378                newCatchMode = CATCH_UNCAUGHT;
1379            else if (arg.equals("all"))
1380                newCatchMode = CATCH_ALL;
1381            else {
1382                log("Invalid argument");
1383                return;
1384            }
1385            if (newCatchMode == catchMode)
1386                return; // No change.
1387
EventRequestManager mgr = vm.eventRequestManager();
1388            if (catchMode != CATCH_NONE) {
1389                List JavaDoc list = mgr.exceptionRequests();
1390                Log.debug("exception request count = " + list.size());
1391                mgr.deleteEventRequests(list);
1392            }
1393            if (newCatchMode != CATCH_NONE) {
1394                ExceptionRequest exceptionRequest =
1395                    mgr.createExceptionRequest(null,
1396                        newCatchMode == CATCH_ALL, true);
1397                exceptionRequest.enable();
1398            }
1399            catchMode = newCatchMode;
1400        }
1401        finally {
1402            if (isSuspended())
1403                prompt();
1404        }
1405    }
1406
1407    private void doNext(String JavaDoc args)
1408    {
1409        if (vm == null)
1410            return;
1411        if (currentThread == null) {
1412            Log.debug("currentThread is null");
1413            return;
1414        }
1415        Log.debug("currentThread = " + currentThread.name());
1416        int count = 1;
1417        if (args != null) {
1418            try {
1419                count = Integer.parseInt(args);
1420            }
1421            catch (NumberFormatException JavaDoc e) {
1422                log("Invalid argument");
1423                return;
1424            }
1425        }
1426        clearStepForThread(currentThread);
1427        EventRequestManager erm = vm.eventRequestManager();
1428        StepRequest request = erm.createStepRequest(currentThread,
1429            StepRequest.STEP_LINE, StepRequest.STEP_OVER);
1430        request.addCountFilter(count);
1431        request.enable();
1432        doContinue();
1433    }
1434
1435    private void doStep(String JavaDoc args)
1436    {
1437        if (vm == null)
1438            return;
1439        if (currentThread == null) {
1440            Log.debug("currentThread is null");
1441            return;
1442        }
1443        Log.debug("currentThread = " + currentThread.name());
1444        boolean out = false;
1445        int count = 1;
1446        if (args != null) {
1447            if (args.equals("out")) {
1448                out = true;
1449            } else {
1450                try {
1451                    count = Integer.parseInt(args);
1452                }
1453                catch (NumberFormatException JavaDoc e) {
1454                    log("Invalid argument");
1455                    return;
1456                }
1457            }
1458        }
1459        clearStepForThread(currentThread);
1460        EventRequestManager erm = vm.eventRequestManager();
1461        StepRequest request =
1462            erm.createStepRequest(currentThread, StepRequest.STEP_LINE,
1463                out ? StepRequest.STEP_OUT : StepRequest.STEP_INTO);
1464        request.addCountFilter(count);
1465        request.enable();
1466        doContinue();
1467    }
1468
1469    private void doFinish()
1470    {
1471        if (vm == null)
1472            return;
1473        if (currentThread == null) {
1474            Log.debug("currentThread is null");
1475            return;
1476        }
1477        clearStepForThread(currentThread);
1478        EventRequestManager erm = vm.eventRequestManager();
1479        StepRequest request =
1480            erm.createStepRequest(currentThread, StepRequest.STEP_LINE,
1481                StepRequest.STEP_OUT);
1482        request.addCountFilter(1);
1483        request.enable();
1484        doContinue();
1485    }
1486
1487    private void doPrint(String JavaDoc what)
1488    {
1489        if (!isSuspended()) {
1490            log("VM is not suspended");
1491            return;
1492        }
1493        try {
1494            if (what == null || what.length() < 1) {
1495                log("Missing argument");
1496                return;
1497            }
1498            if (currentStackFrame == null) {
1499                log("No stack frame");
1500                return;
1501            }
1502            Value value = getValue(what, currentStackFrame);
1503            if (value == null) {
1504                log("null");
1505            } else if (value instanceof StringReference) {
1506                log(value.toString());
1507            } else if (value instanceof ArrayReference) {
1508                log(value.toString());
1509                log(getStringValueOfArray(what, (ArrayReference)value));
1510            } else {
1511                log(value.toString());
1512                if (value instanceof ObjectReference) {
1513                    String JavaDoc s = getStringValueOfObject((ObjectReference)value,
1514                        currentThread);
1515                    if (s != null) {
1516                        Log.debug(s);
1517                        log(s);
1518                    }
1519                    // getStringValueOfObject() resumes the current thread, so
1520
// the context has changed...
1521
Log.debug("doPrint calling fireContextChanged");
1522                    fireContextChanged();
1523                }
1524            }
1525        }
1526        catch (AbsentInformationException e) {
1527            Log.debug(e);
1528            log("Local variable information is not available.");
1529            log("Compile with -g to generate local variable information.");
1530        }
1531        catch (NoSuchFieldException JavaDoc e) {
1532            log("No such field");
1533        }
1534        catch (Exception JavaDoc e) {
1535            log(e.toString());
1536            Log.error(e);
1537        }
1538        finally {
1539            if (isSuspended())
1540                prompt();
1541        }
1542    }
1543
1544    private void doStdin(String JavaDoc s)
1545    {
1546        Process JavaDoc process = vm.process();
1547        if (process != null) {
1548            OutputStream JavaDoc out = process.getOutputStream();
1549            try {
1550                if (s != null) {
1551                    out.write(s.getBytes());
1552                    // Format stdin like stdout. JDB_FORMAT_INPUT is for
1553
// debugger commands.
1554
log(s, false, JdbFormatter.JDB_FORMAT_OUTPUT);
1555                }
1556                out.write('\n');
1557                out.flush();
1558            }
1559            catch (IOException JavaDoc e) {
1560                Log.error(e);
1561            }
1562        }
1563    }
1564
1565    private void doLocals()
1566    {
1567        if (vm == null)
1568            return;
1569        if (currentThread == null) {
1570            Log.debug("currentThread is null");
1571            return;
1572        }
1573        boolean contextChanged = false;
1574        try {
1575            StackFrame stackFrame = currentStackFrame;
1576            if (stackFrame == null && currentThread.frameCount() > 0)
1577                stackFrame = currentThread.frame(0);
1578            List JavaDoc variables = stackFrame.visibleVariables();
1579            Map JavaDoc map = stackFrame.getValues(variables);
1580            Set JavaDoc entrySet = map.entrySet();
1581            Iterator JavaDoc iter = entrySet.iterator();
1582            while (iter.hasNext()) {
1583                Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iter.next();
1584                LocalVariable variable = (LocalVariable) entry.getKey();
1585                Value value = (Value) entry.getValue();
1586                FastStringBuffer sb = new FastStringBuffer(variable.typeName());
1587                sb.append(' ');
1588                sb.append(variable.name());
1589                sb.append(" = ");
1590                sb.append(value);
1591                if (value instanceof StringReference) {
1592                    ;
1593                } else if (value instanceof ArrayReference) {
1594                    String JavaDoc s = getStringValueOfArray(variable.name(),
1595                        (ArrayReference)value);
1596                    if (s.length() > 0) {
1597                        sb.append('\n');
1598                        sb.append(s);
1599                    }
1600                } else if (value instanceof ObjectReference) {
1601                    String JavaDoc s = getStringValueOfObject((ObjectReference)value,
1602                        currentThread);
1603                    if (s != null) {
1604                        sb.append(' ');
1605                        sb.append(s);
1606                    }
1607                    // getStringValueOfObject() resumes the current thread, so
1608
// the context has changed...
1609
contextChanged = true;
1610                }
1611                log(sb.toString());
1612            }
1613        }
1614        catch (AbsentInformationException e) {
1615            Log.debug(e);
1616            log("Local variable information is not available.");
1617            log("Compile with -g to generate local variable information.");
1618        }
1619        catch (Exception JavaDoc e) {
1620            Log.error(e);
1621        }
1622        if (contextChanged)
1623            fireContextChanged();
1624        if (isSuspended())
1625            prompt();
1626    }
1627
1628    private String JavaDoc getStringValueOfObject(ObjectReference objRef,
1629        ThreadReference threadRef)
1630    {
1631        try {
1632            // Get index of current stack frame so we can restore it later.
1633
List JavaDoc frames = threadRef.frames();
1634            int index = -1;
1635            if (frames.size() > 0) {
1636                for (int i = 0; i < frames.size(); i++) {
1637                    StackFrame frame = (StackFrame) frames.get(i);
1638                    if (frame != null && frame.equals(currentStackFrame)) {
1639                        index = i;
1640                        break;
1641                    }
1642                }
1643            }
1644
1645            ReferenceType refType = objRef.referenceType();
1646            List JavaDoc methods =
1647                refType.methodsByName("toString", "()Ljava/lang/String;");
1648            Method method = (Method) methods.get(0);
1649            Value value = objRef.invokeMethod(threadRef, method,
1650                new ArrayList JavaDoc(), ObjectReference.INVOKE_SINGLE_THREADED);
1651
1652            // Restore current stack frame if possible.
1653
frames = threadRef.frames();
1654            if (frames != null && index >= 0 && index < frames.size())
1655                currentStackFrame = (StackFrame) frames.get(index);
1656
1657            if (value != null)
1658                return value.toString();
1659        }
1660        catch (Exception JavaDoc e) {
1661            Log.error(e);
1662        }
1663        return null;
1664    }
1665
1666    private static String JavaDoc getStringValueOfArray(String JavaDoc name, ArrayReference ar)
1667    {
1668        FastStringBuffer sb = new FastStringBuffer();
1669        final int limit = ar.length();
1670        for (int i = 0; i < limit; i++) {
1671            sb.append(" ");
1672            sb.append(name);
1673            sb.append('[');
1674            sb.append(i);
1675            sb.append("]: ");
1676            Value v = ar.getValue(i);
1677            sb.append(v == null ? "null" : v.toString());
1678            if (i < limit-1)
1679                sb.append('\n');
1680        }
1681        return sb.toString();
1682    }
1683
1684    private void clearStepForThread(ThreadReference threadRef)
1685    {
1686        EventRequestManager erm = vm.eventRequestManager();
1687        List JavaDoc requests = erm.stepRequests();
1688        Iterator JavaDoc iter = requests.iterator();
1689        while (iter.hasNext()) {
1690            StepRequest request = (StepRequest) iter.next();
1691            if (request.thread().equals(threadRef)) {
1692                erm.deleteEventRequest(request);
1693                break; // There should be only one!
1694
}
1695        }
1696    }
1697
1698    private static Value getValue(String JavaDoc expression, StackFrame frame)
1699        throws Exception JavaDoc
1700    {
1701        Log.debug("getValue");
1702        StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(expression, "[].");
1703        if (!st.hasMoreTokens()) {
1704            Log.debug("no more tokens");
1705            throw new NoSuchFieldException JavaDoc();
1706        }
1707        String JavaDoc token = st.nextToken();
1708        Log.debug("token = |" + token + "|");
1709        Value currentValue = null;
1710        Field currentField = null;
1711        ObjectReference obj = null;
1712        LocalVariable local = null;
1713        if (token.equals("this")) {
1714            currentValue = frame.thisObject();
1715            if (currentValue == null)
1716                throw new NoSuchFieldException JavaDoc(token);
1717        } else {
1718            Log.debug("calling visibleVariableByName");
1719            local = frame.visibleVariableByName(token);
1720            Log.debug("local = " + local);
1721            if (local != null) {
1722                currentValue = frame.getValue(local);
1723                Log.debug("currentValue = " + currentValue);
1724            } else {
1725                ReferenceType refType = frame.location().declaringType();
1726                Log.debug("refType = " + refType);
1727                obj = frame.thisObject();
1728                if (obj == null) {
1729                    // Static method.
1730
Log.debug("static method");
1731                    currentField = refType.fieldByName(token);
1732                    if (currentField != null && currentField.isStatic())
1733                        currentValue = refType.getValue(currentField);
1734                    else
1735                        throw new NoSuchFieldException JavaDoc();
1736                } else {
1737                    currentField = refType.fieldByName(token);
1738                    if (currentField != null)
1739                        currentValue = obj.getValue(currentField);
1740                    else {
1741                        Log.debug("throwing NoSuchFieldException ...");
1742                        throw new NoSuchFieldException JavaDoc();
1743                    }
1744                }
1745            }
1746        }
1747        while (st.hasMoreTokens() && currentValue != null) {
1748            String JavaDoc prevToken = token;
1749            token = st.nextToken();
1750            Log.debug("while loop token = |" + token + "|");
1751            Object JavaDoc arg;
1752            try {
1753                arg = new Integer JavaDoc(token);
1754            } catch (NumberFormatException JavaDoc e) {
1755                arg = token;
1756            }
1757            if (currentValue instanceof ArrayReference) {
1758                int count = -1;
1759                if (arg instanceof Integer JavaDoc)
1760                    count = ((Integer JavaDoc)arg).intValue();
1761                if (count >= 0 && count < ((ArrayReference)currentValue).length())
1762                    currentValue = ((ArrayReference)currentValue).getValue(count);
1763                else
1764                    throw new ArrayIndexOutOfBoundsException JavaDoc();
1765            } else if (currentValue instanceof ObjectReference &&
1766                arg instanceof String JavaDoc) {
1767                Log.debug("object reference, string");
1768                obj = (ObjectReference) currentValue;
1769                ReferenceType refType = obj.referenceType();
1770                currentField = refType.fieldByName(token);
1771                if (currentField != null)
1772                    currentValue = obj.getValue(currentField);
1773            } else
1774                throw new Exception JavaDoc();
1775        }
1776        Log.debug("getValue returning currentValue = " + currentValue);
1777        return currentValue;
1778    }
1779
1780    public boolean isModified()
1781    {
1782        return false;
1783    }
1784
1785    // For the buffer list.
1786
public String JavaDoc toString()
1787    {
1788        return "jdb";
1789    }
1790
1791    public String JavaDoc getTitle()
1792    {
1793        return "jdb";
1794    }
1795
1796    public Icon JavaDoc getIcon()
1797    {
1798        return Utilities.getIconFromFile("jpty.png");
1799    }
1800}
1801
Popular Tags