KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > debug > tty > Commands


1 /*
2  * @(#)Commands.java 1.89 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-2001 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34
35 package com.sun.tools.example.debug.tty;
36
37 import com.sun.jdi.*;
38 import com.sun.jdi.connect.Connector;
39 import com.sun.jdi.request.*;
40 import com.sun.tools.example.debug.expr.ExpressionParser;
41 import com.sun.tools.example.debug.expr.ParseException;
42
43 import java.text.*;
44 import java.util.*;
45 import java.io.*;
46
47 class Commands {
48
49     abstract class AsyncExecution {
50     abstract void action();
51
52     AsyncExecution() {
53             execute();
54     }
55
56     void execute() {
57             /*
58              * Save current thread and stack frame. (BugId 4296031)
59              */

60             final ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
61             final int stackFrame = threadInfo == null? 0 : threadInfo.getCurrentFrameIndex();
62             Thread JavaDoc thread = new Thread JavaDoc("asynchronous jdb command") {
63                     public void run() {
64                         try {
65                             action();
66                         } catch (UnsupportedOperationException JavaDoc uoe) {
67                             //(BugId 4453329)
68
MessageOutput.println("Operation is not supported on the target VM");
69                         } catch (Exception JavaDoc e) {
70                             MessageOutput.println("Internal exception during operation:",
71                                                   e.getMessage());
72                         } finally {
73                             /*
74                              * This was an asynchronous command. Events may have been
75                              * processed while it was running. Restore the thread and
76                              * stack frame the user was looking at. (BugId 4296031)
77                              */

78                             if (threadInfo != null) {
79                                 ThreadInfo.setCurrentThreadInfo(threadInfo);
80                                 try {
81                                     threadInfo.setCurrentFrameIndex(stackFrame);
82                                 } catch (IncompatibleThreadStateException e) {
83                                     MessageOutput.println("Current thread isnt suspended.");
84                                 } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
85                                     MessageOutput.println("Requested stack frame is no longer active:",
86                                                           new Object JavaDoc []{new Integer JavaDoc(stackFrame)});
87                                 }
88                             }
89                             MessageOutput.printPrompt();
90                         }
91                     }
92                 };
93             thread.start();
94     }
95     }
96
97     Commands() {
98     }
99
100     private Value evaluate(String JavaDoc expr) {
101         Value result = null;
102         ExpressionParser.GetFrame frameGetter = null;
103         try {
104             final ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
105             if ((threadInfo != null) && (threadInfo.getCurrentFrame() != null)) {
106                 frameGetter = new ExpressionParser.GetFrame() {
107                         public StackFrame get() throws IncompatibleThreadStateException {
108                             return threadInfo.getCurrentFrame();
109                         }
110                     };
111             }
112             result = ExpressionParser.evaluate(expr, Env.vm(), frameGetter);
113         } catch (InvocationException ie) {
114             MessageOutput.println("Exception in expression:",
115                                   ie.exception().referenceType().name());
116         } catch (Exception JavaDoc ex) {
117             String JavaDoc exMessage = ex.getMessage();
118             if (exMessage == null) {
119                 MessageOutput.printException(exMessage, ex);
120             } else {
121                 String JavaDoc s;
122                 try {
123                     s = MessageOutput.format(exMessage);
124                 } catch (MissingResourceException mex) {
125                     s = ex.toString();
126                 }
127                 MessageOutput.printDirectln(s);// Special case: use printDirectln()
128
}
129         }
130         return result;
131     }
132
133     private String JavaDoc getStringValue() {
134          Value val = null;
135          String JavaDoc valStr = null;
136          try {
137               val = ExpressionParser.getMassagedValue();
138               valStr = val.toString();
139          } catch (ParseException e) {
140               String JavaDoc msg = e.getMessage();
141               if (msg == null) {
142                   MessageOutput.printException(msg, e);
143               } else {
144                   String JavaDoc s;
145                   try {
146                       s = MessageOutput.format(msg);
147                   } catch (MissingResourceException mex) {
148                       s = e.toString();
149                   }
150                   MessageOutput.printDirectln(s);
151               }
152          }
153          return valStr;
154     }
155
156     private ThreadInfo doGetThread(String JavaDoc idToken) {
157         ThreadInfo threadInfo = ThreadInfo.getThreadInfo(idToken);
158         if (threadInfo == null) {
159             MessageOutput.println("is not a valid thread id", idToken);
160         }
161         return threadInfo;
162     }
163
164     String JavaDoc typedName(Method method) {
165         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
166         buf.append(method.name());
167         buf.append("(");
168
169         List args = method.argumentTypeNames();
170         int lastParam = args.size() - 1;
171         // output param types except for the last
172
for (int ii = 0; ii < lastParam; ii++) {
173             buf.append((String JavaDoc)args.get(ii));
174             buf.append(", ");
175         }
176         if (lastParam >= 0) {
177             // output the last param
178
String JavaDoc lastStr = (String JavaDoc)args.get(lastParam);
179             if (method.isVarArgs()) {
180                 // lastParam is an array. Replace the [] with ...
181
buf.append(lastStr.substring(0, lastStr.length() - 2));
182                 buf.append("...");
183             } else {
184                 buf.append(lastStr);
185             }
186         }
187         buf.append(")");
188         return buf.toString();
189     }
190                             
191     void commandConnectors(VirtualMachineManager vmm) {
192         Iterator iter = vmm.allConnectors().iterator();
193         if (iter.hasNext()) {
194             MessageOutput.println("Connectors available");
195         }
196         while (iter.hasNext()) {
197             Connector cc = (Connector)iter.next();
198             String JavaDoc transportName =
199                 cc.transport() == null ? "null" : cc.transport().name();
200             MessageOutput.println();
201             MessageOutput.println("Connector and Transport name",
202                                   new Object JavaDoc [] {cc.name(), transportName});
203             MessageOutput.println("Connector description", cc.description());
204
205             Iterator argIter = cc.defaultArguments().values().iterator();
206             if (argIter.hasNext()) {
207                 while (argIter.hasNext()) {
208                     Connector.Argument aa = (Connector.Argument)argIter.next();
209                     MessageOutput.println();
210                     
211                     boolean requiredArgument = aa.mustSpecify();
212                     if (aa.value() == null || aa.value() == "") {
213                         //no current value and no default.
214
MessageOutput.println(requiredArgument ?
215                                               "Connector required argument nodefault" :
216                                               "Connector argument nodefault", aa.name());
217                     } else {
218                         MessageOutput.println(requiredArgument ?
219                                               "Connector required argument default" :
220                                               "Connector argument default",
221                                               new Object JavaDoc [] {aa.name(), aa.value()});
222                     }
223                     MessageOutput.println("Connector description", aa.description());
224                     
225                 }
226             }
227         }
228         
229     }
230
231     void commandClasses() {
232         List list = Env.vm().allClasses();
233
234         StringBuffer JavaDoc classList = new StringBuffer JavaDoc();
235         for (int i = 0 ; i < list.size() ; i++) {
236             ReferenceType refType = (ReferenceType)list.get(i);
237             classList.append(refType.name());
238             classList.append("\n");
239         }
240         MessageOutput.print("** classes list **", classList.toString());
241     }
242
243     void commandClass(StringTokenizer t) {
244         List list = Env.vm().allClasses();
245
246         if (!t.hasMoreTokens()) {
247             MessageOutput.println("No class specified.");
248             return;
249         }
250
251         String JavaDoc idClass = t.nextToken();
252         boolean showAll = false;
253
254         if (t.hasMoreTokens()) {
255             if (t.nextToken().toLowerCase().equals("all")) {
256                 showAll = true;
257             } else {
258                 MessageOutput.println("Invalid option on class command");
259                 return;
260             }
261         }
262         ReferenceType type = Env.getReferenceTypeFromToken(idClass);
263         if (type == null) {
264             MessageOutput.println("is not a valid id or class name", idClass);
265             return;
266         }
267         if (type instanceof ClassType) {
268             ClassType clazz = (ClassType)type;
269             MessageOutput.println("Class:", clazz.name());
270
271             ClassType superclass = clazz.superclass();
272             while (superclass != null) {
273                 MessageOutput.println("extends:", superclass.name());
274                 superclass = showAll ? superclass.superclass() : null;
275             }
276
277             List interfaces = showAll ? clazz.allInterfaces()
278                                       : clazz.interfaces();
279             Iterator iter = interfaces.iterator();
280             while (iter.hasNext()) {
281                 InterfaceType interfaze = (InterfaceType)iter.next();
282                 MessageOutput.println("implements:", interfaze.name());
283             }
284
285             List subs = clazz.subclasses();
286             iter = subs.iterator();
287             while (iter.hasNext()) {
288                 ClassType sub = (ClassType)iter.next();
289                 MessageOutput.println("subclass:", sub.name());
290             }
291             List nested = clazz.nestedTypes();
292             iter = nested.iterator();
293             while (iter.hasNext()) {
294                 ReferenceType nest = (ReferenceType)iter.next();
295                 MessageOutput.println("nested:", nest.name());
296             }
297         } else if (type instanceof InterfaceType) {
298             InterfaceType interfaze = (InterfaceType)type;
299             MessageOutput.println("Interface:", interfaze.name());
300             List supers = interfaze.superinterfaces();
301             Iterator iter = supers.iterator();
302             while (iter.hasNext()) {
303                 InterfaceType superinterface = (InterfaceType)iter.next();
304                 MessageOutput.println("extends:", superinterface.name());
305             }
306             List subs = interfaze.subinterfaces();
307             iter = subs.iterator();
308             while (iter.hasNext()) {
309                 InterfaceType sub = (InterfaceType)iter.next();
310                 MessageOutput.println("subinterface:", sub.name());
311             }
312             List implementors = interfaze.implementors();
313             iter = implementors.iterator();
314             while (iter.hasNext()) {
315                 ClassType implementor = (ClassType)iter.next();
316                 MessageOutput.println("implementor:", implementor.name());
317             }
318             List nested = interfaze.nestedTypes();
319             iter = nested.iterator();
320             while (iter.hasNext()) {
321                 ReferenceType nest = (ReferenceType)iter.next();
322                 MessageOutput.println("nested:", nest.name());
323             }
324         } else { // array type
325
ArrayType array = (ArrayType)type;
326             MessageOutput.println("Array:", array.name());
327         }
328     }
329
330     void commandMethods(StringTokenizer t) {
331         if (!t.hasMoreTokens()) {
332             MessageOutput.println("No class specified.");
333             return;
334         }
335
336         String JavaDoc idClass = t.nextToken();
337         ReferenceType cls = Env.getReferenceTypeFromToken(idClass);
338         if (cls != null) {
339             List methods = cls.allMethods();
340             StringBuffer JavaDoc methodsList = new StringBuffer JavaDoc();
341             for (int i = 0; i < methods.size(); i++) {
342                 Method method = (Method)methods.get(i);
343                 methodsList.append(method.declaringType().name());
344                 methodsList.append(" ");
345                 methodsList.append(typedName(method));
346                 methodsList.append('\n');
347             }
348             MessageOutput.print("** methods list **", methodsList.toString());
349         } else {
350             MessageOutput.println("is not a valid id or class name", idClass);
351         }
352     }
353
354     void commandFields(StringTokenizer t) {
355         if (!t.hasMoreTokens()) {
356             MessageOutput.println("No class specified.");
357             return;
358         }
359
360         String JavaDoc idClass = t.nextToken();
361         ReferenceType cls = Env.getReferenceTypeFromToken(idClass);
362         if (cls != null) {
363             List fields = cls.allFields();
364             List visible = cls.visibleFields();
365             StringBuffer JavaDoc fieldsList = new StringBuffer JavaDoc();
366             for (int i = 0; i < fields.size(); i++) {
367                 Field field = (Field)fields.get(i);
368                 String JavaDoc s;
369                 if (!visible.contains(field)) {
370                     s = MessageOutput.format("list field typename and name hidden",
371                                              new Object JavaDoc [] {field.typeName(),
372                                                             field.name()});
373                 } else if (!field.declaringType().equals(cls)) {
374                     s = MessageOutput.format("list field typename and name inherited",
375                                              new Object JavaDoc [] {field.typeName(),
376                                                             field.name(),
377                                                             field.declaringType().name()});
378                 } else {
379                     s = MessageOutput.format("list field typename and name",
380                                              new Object JavaDoc [] {field.typeName(),
381                                                             field.name()});
382                 }
383                 fieldsList.append(s);
384             }
385             MessageOutput.print("** fields list **", fieldsList.toString());
386         } else {
387             MessageOutput.println("is not a valid id or class name", idClass);
388         }
389     }
390
391     private void printThreadGroup(ThreadGroupReference tg) {
392         ThreadIterator threadIter = new ThreadIterator(tg);
393
394         MessageOutput.println("Thread Group:", tg.name());
395         int maxIdLength = 0;
396         int maxNameLength = 0;
397         while (threadIter.hasNext()) {
398             ThreadReference thr = (ThreadReference)threadIter.next();
399             maxIdLength = Math.max(maxIdLength,
400                                    Env.description(thr).length());
401             maxNameLength = Math.max(maxNameLength,
402                                      thr.name().length());
403         }
404
405         threadIter = new ThreadIterator(tg);
406         while (threadIter.hasNext()) {
407             ThreadReference thr = (ThreadReference)threadIter.next();
408         if (thr.threadGroup() == null) {
409                 continue;
410             }
411             // Note any thread group changes
412
if (!thr.threadGroup().equals(tg)) {
413                 tg = thr.threadGroup();
414                 MessageOutput.println("Thread Group:", tg.name());
415             }
416
417             /*
418              * Do a bit of filling with whitespace to get thread ID
419              * and thread names to line up in the listing, and also
420              * allow for proper localization. This also works for
421              * very long thread names, at the possible cost of lines
422              * being wrapped by the display device.
423              */

424             StringBuffer JavaDoc idBuffer = new StringBuffer JavaDoc(Env.description(thr));
425             for (int i = idBuffer.length(); i < maxIdLength; i++) {
426                 idBuffer.append(" ");
427             }
428             StringBuffer JavaDoc nameBuffer = new StringBuffer JavaDoc(thr.name());
429             for (int i = nameBuffer.length(); i < maxNameLength; i++) {
430                 nameBuffer.append(" ");
431             }
432             
433             /*
434              * Select the output format to use based on thread status
435              * and breakpoint.
436              */

437             String JavaDoc statusFormat;
438             switch (thr.status()) {
439             case ThreadReference.THREAD_STATUS_UNKNOWN:
440                 if (thr.isAtBreakpoint()) {
441                     statusFormat = "Thread description name unknownStatus BP";
442                 } else {
443                     statusFormat = "Thread description name unknownStatus";
444                 }
445                 break;
446             case ThreadReference.THREAD_STATUS_ZOMBIE:
447                 if (thr.isAtBreakpoint()) {
448                     statusFormat = "Thread description name zombieStatus BP";
449                 } else {
450                     statusFormat = "Thread description name zombieStatus";
451                 }
452                 break;
453             case ThreadReference.THREAD_STATUS_RUNNING:
454                 if (thr.isAtBreakpoint()) {
455                     statusFormat = "Thread description name runningStatus BP";
456                 } else {
457                     statusFormat = "Thread description name runningStatus";
458                 }
459                 break;
460             case ThreadReference.THREAD_STATUS_SLEEPING:
461                 if (thr.isAtBreakpoint()) {
462                     statusFormat = "Thread description name sleepingStatus BP";
463                 } else {
464                     statusFormat = "Thread description name sleepingStatus";
465                 }
466                 break;
467             case ThreadReference.THREAD_STATUS_MONITOR:
468                 if (thr.isAtBreakpoint()) {
469                     statusFormat = "Thread description name waitingStatus BP";
470                 } else {
471                     statusFormat = "Thread description name waitingStatus";
472                 }
473                 break;
474             case ThreadReference.THREAD_STATUS_WAIT:
475                 if (thr.isAtBreakpoint()) {
476                     statusFormat = "Thread description name condWaitstatus BP";
477                 } else {
478                     statusFormat = "Thread description name condWaitstatus";
479                 }
480                 break;
481             default:
482                 throw new InternalError JavaDoc(MessageOutput.format("Invalid thread status."));
483             }
484             MessageOutput.println(statusFormat,
485                                   new Object JavaDoc [] {idBuffer.toString(),
486                                                  nameBuffer.toString()});
487         }
488     }
489
490     void commandThreads(StringTokenizer t) {
491         if (!t.hasMoreTokens()) {
492             printThreadGroup(ThreadInfo.group());
493             return;
494         }
495         String JavaDoc name = t.nextToken();
496         ThreadGroupReference tg = ThreadGroupIterator.find(name);
497         if (tg == null) {
498             MessageOutput.println("is not a valid threadgroup name", name);
499         } else {
500             printThreadGroup(tg);
501         }
502     }
503
504     void commandThreadGroups() {
505         ThreadGroupIterator it = new ThreadGroupIterator();
506         int cnt = 0;
507         while (it.hasNext()) {
508             ThreadGroupReference tg = it.nextThreadGroup();
509             ++cnt;
510             MessageOutput.println("thread group number description name",
511                                   new Object JavaDoc [] { new Integer JavaDoc (cnt),
512                                                   Env.description(tg),
513                                                   tg.name()});
514         }
515     }
516     
517     void commandThread(StringTokenizer t) {
518         if (!t.hasMoreTokens()) {
519             MessageOutput.println("Thread number not specified.");
520             return;
521         }
522         ThreadInfo threadInfo = doGetThread(t.nextToken());
523         if (threadInfo != null) {
524             ThreadInfo.setCurrentThreadInfo(threadInfo);
525         }
526     }
527     
528     void commandThreadGroup(StringTokenizer t) {
529         if (!t.hasMoreTokens()) {
530             MessageOutput.println("Threadgroup name not specified.");
531             return;
532         }
533         String JavaDoc name = t.nextToken();
534         ThreadGroupReference tg = ThreadGroupIterator.find(name);
535         if (tg == null) {
536             MessageOutput.println("is not a valid threadgroup name", name);
537         } else {
538             ThreadInfo.setThreadGroup(tg);
539         }
540     }
541     
542     void commandRun(StringTokenizer t) {
543         /*
544          * The 'run' command makes little sense in a
545          * that doesn't support restarts or multiple VMs. However,
546          * this is an attempt to emulate the behavior of the old
547          * JDB as much as possible. For new users and implementations
548          * it is much more straightforward to launch immedidately
549          * with the -launch option.
550          */

551         VMConnection connection = Env.connection();
552         if (!connection.isLaunch()) {
553             if (!t.hasMoreTokens()) {
554                 commandCont();
555             } else {
556                 MessageOutput.println("run <args> command is valid only with launched VMs");
557             }
558             return;
559         }
560         if (connection.isOpen()) {
561             MessageOutput.println("VM already running. use cont to continue after events.");
562             return;
563         }
564
565         /*
566          * Set the main class and any arguments. Note that this will work
567          * only with the standard launcher, "com.sun.jdi.CommandLineLauncher"
568          */

569         String JavaDoc args;
570         if (t.hasMoreTokens()) {
571             args = t.nextToken("");
572             boolean argsSet = connection.setConnectorArg("main", args);
573             if (!argsSet) {
574                 MessageOutput.println("Unable to set main class and arguments");
575                 return;
576             }
577         } else {
578             args = connection.connectorArg("main");
579             if (args.length() == 0) {
580                 MessageOutput.println("Main class and arguments must be specified");
581                 return;
582             }
583         }
584         MessageOutput.println("run", args);
585
586         /*
587          * Launch the VM.
588          */

589         connection.open();
590         
591     }
592
593     void commandLoad(StringTokenizer t) {
594         MessageOutput.println("The load command is no longer supported.");
595     }
596
597     private List allThreads(ThreadGroupReference group) {
598         List list = new ArrayList();
599         list.addAll(group.threads());
600         Iterator iter = group.threadGroups().iterator();
601         while (iter.hasNext()) {
602             ThreadGroupReference child = (ThreadGroupReference)iter.next();
603             list.addAll(allThreads(child));
604         }
605         return list;
606     }
607
608     void commandSuspend(StringTokenizer t) {
609         if (!t.hasMoreTokens()) {
610             Env.vm().suspend();
611             MessageOutput.println("All threads suspended.");
612         } else {
613             while (t.hasMoreTokens()) {
614                 ThreadInfo threadInfo = doGetThread(t.nextToken());
615                 if (threadInfo != null) {
616                     threadInfo.getThread().suspend();
617                 }
618             }
619         }
620     }
621
622     void commandResume(StringTokenizer t) {
623          if (!t.hasMoreTokens()) {
624              ThreadInfo.invalidateAll();
625              Env.vm().resume();
626              MessageOutput.println("All threads resumed.");
627          } else {
628              while (t.hasMoreTokens()) {
629                 ThreadInfo threadInfo = doGetThread(t.nextToken());
630                 if (threadInfo != null) {
631                     threadInfo.invalidate();
632                     threadInfo.getThread().resume();
633                 }
634             }
635         }
636     }
637
638     void commandCont() {
639         if (ThreadInfo.getCurrentThreadInfo() == null) {
640             MessageOutput.println("Nothing suspended.");
641             return;
642         }
643         ThreadInfo.invalidateAll();
644         Env.vm().resume();
645     }
646
647     void clearPreviousStep(ThreadReference thread) {
648         /*
649          * A previous step may not have completed on this thread;
650          * if so, it gets removed here.
651          */

652          EventRequestManager mgr = Env.vm().eventRequestManager();
653          List requests = mgr.stepRequests();
654          Iterator iter = requests.iterator();
655          while (iter.hasNext()) {
656              StepRequest request = (StepRequest)iter.next();
657              if (request.thread().equals(thread)) {
658                  mgr.deleteEventRequest(request);
659                  break;
660              }
661          }
662     }
663     /* step
664      *
665      */

666     void commandStep(StringTokenizer t) {
667         ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
668         if (threadInfo == null) {
669             MessageOutput.println("Nothing suspended.");
670             return;
671         }
672         int depth;
673         if (t.hasMoreTokens() &&
674                   t.nextToken().toLowerCase().equals("up")) {
675             depth = StepRequest.STEP_OUT;
676         } else {
677             depth = StepRequest.STEP_INTO;
678         }
679
680         clearPreviousStep(threadInfo.getThread());
681         EventRequestManager reqMgr = Env.vm().eventRequestManager();
682         StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(),
683                                                        StepRequest.STEP_LINE, depth);
684         if (depth == StepRequest.STEP_INTO) {
685             Env.addExcludes(request);
686         }
687         // We want just the next step event and no others
688
request.addCountFilter(1);
689         request.enable();
690         ThreadInfo.invalidateAll();
691         Env.vm().resume();
692     }
693
694     /* stepi
695      * step instruction.
696      */

697     void commandStepi() {
698         ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
699         if (threadInfo == null) {
700             MessageOutput.println("Nothing suspended.");
701             return;
702         }
703         clearPreviousStep(threadInfo.getThread());
704         EventRequestManager reqMgr = Env.vm().eventRequestManager();
705         StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(),
706                                                        StepRequest.STEP_MIN,
707                                                        StepRequest.STEP_INTO);
708         Env.addExcludes(request);
709         // We want just the next step event and no others
710
request.addCountFilter(1);
711         request.enable();
712         ThreadInfo.invalidateAll();
713         Env.vm().resume();
714     }
715
716     void commandNext() {
717         ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
718         if (threadInfo == null) {
719             MessageOutput.println("Nothing suspended.");
720             return;
721         }
722         clearPreviousStep(threadInfo.getThread());
723         EventRequestManager reqMgr = Env.vm().eventRequestManager();
724         StepRequest request = reqMgr.createStepRequest(threadInfo.getThread(),
725                                                        StepRequest.STEP_LINE,
726                                                        StepRequest.STEP_OVER);
727         Env.addExcludes(request);
728         // We want just the next step event and no others
729
request.addCountFilter(1);
730         request.enable();
731         ThreadInfo.invalidateAll();
732         Env.vm().resume();
733     }
734
735     void doKill(ThreadReference thread, StringTokenizer t) {
736         if (!t.hasMoreTokens()) {
737             MessageOutput.println("No exception object specified.");
738             return;
739         }
740         String JavaDoc expr = t.nextToken("");
741         Value val = evaluate(expr);
742         if ((val != null) && (val instanceof ObjectReference)) {
743             try {
744                 thread.stop((ObjectReference)val);
745                 MessageOutput.println("killed", thread.toString());
746             } catch (InvalidTypeException e) {
747                 MessageOutput.println("Invalid exception object");
748             }
749         } else {
750             MessageOutput.println("Expression must evaluate to an object");
751         }
752     }
753
754     void doKillThread(final ThreadReference threadToKill,
755                       final StringTokenizer tokenizer) {
756         new AsyncExecution() {
757                 void action() {
758                     doKill(threadToKill, tokenizer);
759                 }
760             };
761     }
762
763     void commandKill(StringTokenizer t) {
764         if (!t.hasMoreTokens()) {
765             MessageOutput.println("Usage: kill <thread id> <throwable>");
766             return;
767         }
768         ThreadInfo threadInfo = doGetThread(t.nextToken());
769         if (threadInfo != null) {
770             MessageOutput.println("killing thread:", threadInfo.getThread().name());
771             doKillThread(threadInfo.getThread(), t);
772             return;
773         }
774     }
775
776     void listCaughtExceptions() {
777         boolean noExceptions = true;
778
779         // Print a listing of the catch patterns currently in place
780
Iterator iter = Env.specList.eventRequestSpecs().iterator();
781         while (iter.hasNext()) {
782             EventRequestSpec spec = (EventRequestSpec)iter.next();
783             if (spec instanceof ExceptionSpec) {
784                 if (noExceptions) {
785                     noExceptions = false;
786                     MessageOutput.println("Exceptions caught:");
787                 }
788                 MessageOutput.println("tab", spec.toString());
789             }
790         }
791         if (noExceptions) {
792             MessageOutput.println("No exceptions caught.");
793         }
794     }
795
796     private EventRequestSpec parseExceptionSpec(StringTokenizer t) {
797         String JavaDoc notification = t.nextToken();
798         boolean notifyCaught = false;
799         boolean notifyUncaught = false;
800         EventRequestSpec spec = null;
801         String JavaDoc classPattern = null;
802         
803         if (notification.equals("uncaught")) {
804             notifyCaught = false;
805             notifyUncaught = true;
806         } else if (notification.equals("caught")) {
807             notifyCaught = true;
808             notifyUncaught = false;
809         } else if (notification.equals("all")) {
810             notifyCaught = true;
811             notifyUncaught = true;
812         } else {
813             /*
814              * Handle the same as "all" for backward
815              * compatibility with existing .jdbrc files.
816              *
817              * Insert an "all" and take the current token as the
818              * intended classPattern
819              *
820              */

821             notifyCaught = true;
822             notifyUncaught = true;
823             classPattern = notification;
824         }
825         if (classPattern == null && t.hasMoreTokens()) {
826             classPattern = t.nextToken();
827         }
828         if ((classPattern != null) && (notifyCaught || notifyUncaught)) {
829             try {
830                 spec = Env.specList.createExceptionCatch(classPattern,
831                                                          notifyCaught,
832                                                          notifyUncaught);
833             } catch (ClassNotFoundException JavaDoc exc) {
834                 MessageOutput.println("is not a valid class name", classPattern);
835             }
836         }
837         return spec;
838     }
839
840     void commandCatchException(StringTokenizer t) {
841         if (!t.hasMoreTokens()) {
842             listCaughtExceptions();
843         } else {
844             EventRequestSpec spec = parseExceptionSpec(t);
845             if (spec != null) {
846                 resolveNow(spec);
847             } else {
848                 MessageOutput.println("Usage: catch exception");
849             }
850         }
851     }
852     
853     void commandIgnoreException(StringTokenizer t) {
854         if (!t.hasMoreTokens()) {
855             listCaughtExceptions();
856         } else {
857             EventRequestSpec spec = parseExceptionSpec(t);
858             if (Env.specList.delete(spec)) {
859                 MessageOutput.println("Removed:", spec.toString());
860             } else {
861                 if (spec != null) {
862                     MessageOutput.println("Not found:", spec.toString());
863                 }
864                 MessageOutput.println("Usage: ignore exception");
865             }
866         }
867     }
868     
869     void commandUp(StringTokenizer t) {
870         ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
871         if (threadInfo == null) {
872             MessageOutput.println("Current thread not set.");
873             return;
874         }
875
876         int nLevels = 1;
877         if (t.hasMoreTokens()) {
878             String JavaDoc idToken = t.nextToken();
879             int i;
880             try {
881                 NumberFormat nf = NumberFormat.getNumberInstance();
882                 nf.setParseIntegerOnly(true);
883                 Number JavaDoc n = nf.parse(idToken);
884                 i = n.intValue();
885             } catch (java.text.ParseException JavaDoc jtpe) {
886                 i = 0;
887             }
888             if (i <= 0) {
889                 MessageOutput.println("Usage: up [n frames]");
890                 return;
891             }
892             nLevels = i;
893         }
894
895         try {
896             threadInfo.up(nLevels);
897         } catch (IncompatibleThreadStateException e) {
898             MessageOutput.println("Current thread isnt suspended.");
899         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
900             MessageOutput.println("End of stack.");
901         }
902     }
903
904     void commandDown(StringTokenizer t) {
905         ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
906         if (threadInfo == null) {
907             MessageOutput.println("Current thread not set.");
908             return;
909         }
910
911         int nLevels = 1;
912         if (t.hasMoreTokens()) {
913             String JavaDoc idToken = t.nextToken();
914             int i;
915             try {
916                 NumberFormat nf = NumberFormat.getNumberInstance();
917                 nf.setParseIntegerOnly(true);
918                 Number JavaDoc n = nf.parse(idToken);
919                 i = n.intValue();
920             } catch (java.text.ParseException JavaDoc jtpe) {
921                 i = 0;
922             }
923             if (i <= 0) {
924                 MessageOutput.println("Usage: down [n frames]");
925                 return;
926             }
927             nLevels = i;
928         }
929
930         try {
931             threadInfo.down(nLevels);
932         } catch (IncompatibleThreadStateException e) {
933             MessageOutput.println("Current thread isnt suspended.");
934         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
935             MessageOutput.println("End of stack.");
936         }
937     }
938
939     private void dumpStack(ThreadInfo threadInfo, boolean showPC) {
940         List stack = null;
941         try {
942             stack = threadInfo.getStack();
943         } catch (IncompatibleThreadStateException e) {
944             MessageOutput.println("Current thread isnt suspended.");
945             return;
946         }
947         if (stack == null) {
948             MessageOutput.println("Thread is not running (no stack).");
949         } else {
950             int nFrames = stack.size();
951             for (int i = threadInfo.getCurrentFrameIndex(); i < nFrames; i++) {
952                 StackFrame frame = (StackFrame)stack.get(i);
953                 dumpFrame (i, showPC, frame);
954             }
955         }
956     }
957
958     private void dumpFrame (int frameNumber, boolean showPC, StackFrame frame) {
959         Location loc = frame.location();
960         long pc = -1;
961         if (showPC) {
962             pc = loc.codeIndex();
963         }
964         Method meth = loc.method();
965
966         long lineNumber = loc.lineNumber();
967         String JavaDoc methodInfo = null;
968         if (meth instanceof Method && ((Method)meth).isNative()) {
969             methodInfo = MessageOutput.format("native method");
970         } else if (lineNumber != -1) {
971             try {
972                 methodInfo = loc.sourceName() +
973                     MessageOutput.format("line number",
974                                          new Object JavaDoc [] {new Long JavaDoc(lineNumber)});
975             } catch (AbsentInformationException e) {
976                 methodInfo = MessageOutput.format("unknown");
977             }
978         }
979         if (pc != -1) {
980             MessageOutput.println("stack frame dump with pc",
981                                   new Object JavaDoc [] {new Integer JavaDoc(frameNumber + 1),
982                                                  meth.declaringType().name(),
983                                                  meth.name(),
984                                                  methodInfo,
985                                                  new Long JavaDoc(pc)});
986         } else {
987             MessageOutput.println("stack frame dump",
988                                   new Object JavaDoc [] {new Integer JavaDoc(frameNumber + 1),
989                                                  meth.declaringType().name(),
990                                                  meth.name(),
991                                                  methodInfo});
992         }
993     }
994
995     void commandWhere(StringTokenizer t, boolean showPC) {
996         if (!t.hasMoreTokens()) {
997             ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
998             if (threadInfo == null) {
999                 MessageOutput.println("No thread specified.");
1000                return;
1001            }
1002            dumpStack(threadInfo, showPC);
1003        } else {
1004            String JavaDoc token = t.nextToken();
1005            if (token.toLowerCase().equals("all")) {
1006                Iterator iter = ThreadInfo.threads().iterator();
1007                while (iter.hasNext()) {
1008                    ThreadInfo threadInfo = (ThreadInfo)iter.next();
1009                    MessageOutput.println("Thread:",
1010                                          threadInfo.getThread().name());
1011                    dumpStack(threadInfo, showPC);
1012                }
1013            } else {
1014                ThreadInfo threadInfo = doGetThread(token);
1015                if (threadInfo != null) {
1016                    ThreadInfo.setCurrentThreadInfo(threadInfo);
1017                    dumpStack(threadInfo, showPC);
1018                }
1019            }
1020        }
1021    }
1022
1023    void commandInterrupt(StringTokenizer t) {
1024        if (!t.hasMoreTokens()) {
1025            ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
1026            if (threadInfo == null) {
1027                MessageOutput.println("No thread specified.");
1028                return;
1029            }
1030            threadInfo.getThread().interrupt();
1031        } else {
1032            ThreadInfo threadInfo = doGetThread(t.nextToken());
1033            if (threadInfo != null) {
1034                threadInfo.getThread().interrupt();
1035            }
1036        }
1037    }
1038
1039    void commandMemory() {
1040        MessageOutput.println("The memory command is no longer supported.");
1041    }
1042
1043    void commandGC() {
1044        MessageOutput.println("The gc command is no longer necessary.");
1045    }
1046
1047    /*
1048     * The next two methods are used by this class and by EventHandler
1049     * to print consistent locations and error messages.
1050     */

1051    static String JavaDoc locationString(Location loc) {
1052        return MessageOutput.format("locationString",
1053                                    new Object JavaDoc [] {loc.declaringType().name(),
1054                                                   loc.method().name(),
1055                                                   new Integer JavaDoc (loc.lineNumber()),
1056                                                   new Long JavaDoc (loc.codeIndex())});
1057    }
1058
1059    void listBreakpoints() {
1060        boolean noBreakpoints = true;
1061
1062        // Print set breakpoints
1063
Iterator iter = Env.specList.eventRequestSpecs().iterator();
1064        while (iter.hasNext()) {
1065            EventRequestSpec spec = (EventRequestSpec)iter.next();
1066            if (spec instanceof BreakpointSpec) {
1067                if (noBreakpoints) {
1068                    noBreakpoints = false;
1069                    MessageOutput.println("Breakpoints set:");
1070                }
1071                MessageOutput.println("tab", spec.toString());
1072            }
1073        }
1074        if (noBreakpoints) {
1075            MessageOutput.println("No breakpoints set.");
1076        }
1077    }
1078
1079
1080    private void printBreakpointCommandUsage(String JavaDoc atForm, String JavaDoc inForm) {
1081        MessageOutput.println("printbreakpointcommandusage",
1082                              new Object JavaDoc [] {atForm, inForm});
1083    }
1084
1085    protected BreakpointSpec parseBreakpointSpec(StringTokenizer t,
1086                                             String JavaDoc atForm, String JavaDoc inForm) {
1087        EventRequestSpec breakpoint = null;
1088        try {
1089            String JavaDoc token = t.nextToken(":( \t\n\r");
1090
1091            // We can't use hasMoreTokens here because it will cause any leading
1092
// paren to be lost.
1093
String JavaDoc rest;
1094            try {
1095                rest = t.nextToken("").trim();
1096            } catch (NoSuchElementException e) {
1097                rest = null;
1098            }
1099
1100            if ((rest != null) && rest.startsWith(":")) {
1101                t = new StringTokenizer(rest.substring(1));
1102                String JavaDoc classId = token;
1103                String JavaDoc lineToken = t.nextToken();
1104
1105                NumberFormat nf = NumberFormat.getNumberInstance();
1106                nf.setParseIntegerOnly(true);
1107                Number JavaDoc n = nf.parse(lineToken);
1108                int lineNumber = n.intValue();
1109
1110                if (t.hasMoreTokens()) {
1111                    printBreakpointCommandUsage(atForm, inForm);
1112                    return null;
1113                }
1114                try {
1115                    breakpoint = Env.specList.createBreakpoint(classId,
1116                                                               lineNumber);
1117                } catch (ClassNotFoundException JavaDoc exc) {
1118                    MessageOutput.println("is not a valid class name", classId);
1119                }
1120            } else {
1121                // Try stripping method from class.method token.
1122
int idot = token.lastIndexOf(".");
1123                if ( (idot <= 0) || /* No dot or dot in first char */
1124                     (idot >= token.length() - 1) ) { /* dot in last char */
1125                    printBreakpointCommandUsage(atForm, inForm);
1126                    return null;
1127                }
1128                String JavaDoc methodName = token.substring(idot + 1);
1129                String JavaDoc classId = token.substring(0, idot);
1130                List argumentList = null;
1131                if (rest != null) {
1132                    if (!rest.startsWith("(") || !rest.endsWith(")")) {
1133                        MessageOutput.println("Invalid method specification:",
1134                                              methodName + rest);
1135                        printBreakpointCommandUsage(atForm, inForm);
1136                        return null;
1137                    }
1138                    // Trim the parens
1139
rest = rest.substring(1, rest.length() - 1);
1140
1141                    argumentList = new ArrayList();
1142                    t = new StringTokenizer(rest, ",");
1143                    while (t.hasMoreTokens()) {
1144                        argumentList.add(t.nextToken());
1145                    }
1146                }
1147                try {
1148                    breakpoint = Env.specList.createBreakpoint(classId,
1149                                                               methodName,
1150                                                               argumentList);
1151                } catch (MalformedMemberNameException exc) {
1152                    MessageOutput.println("is not a valid method name", methodName);
1153                } catch (ClassNotFoundException JavaDoc exc) {
1154                    MessageOutput.println("is not a valid class name", classId);
1155                }
1156            }
1157        } catch (Exception JavaDoc e) {
1158            printBreakpointCommandUsage(atForm, inForm);
1159            return null;
1160        }
1161        return (BreakpointSpec)breakpoint;
1162    }
1163
1164    private void resolveNow(EventRequestSpec spec) {
1165        boolean success = Env.specList.addEagerlyResolve(spec);
1166        if (success && !spec.isResolved()) {
1167            MessageOutput.println("Deferring.", spec.toString());
1168        }
1169    }
1170
1171    void commandStop(StringTokenizer t) {
1172        Location bploc;
1173        String JavaDoc atIn;
1174        byte suspendPolicy = EventRequest.SUSPEND_ALL;
1175
1176        if (t.hasMoreTokens()) {
1177            atIn = t.nextToken();
1178            if (atIn.equals("go") && t.hasMoreTokens()) {
1179                suspendPolicy = EventRequest.SUSPEND_NONE;
1180                atIn = t.nextToken();
1181            } else if (atIn.equals("thread") && t.hasMoreTokens()) {
1182                suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
1183                atIn = t.nextToken();
1184            }
1185        } else {
1186            listBreakpoints();
1187            return;
1188        }
1189
1190        BreakpointSpec spec = parseBreakpointSpec(t, "stop at", "stop in");
1191        if (spec != null) {
1192            // Enforcement of "at" vs. "in". The distinction is really
1193
// unnecessary and we should consider not checking for this
1194
// (and making "at" and "in" optional).
1195
if (atIn.equals("at") && spec.isMethodBreakpoint()) {
1196                MessageOutput.println("Use stop at to set a breakpoint at a line number");
1197                printBreakpointCommandUsage("stop at", "stop in");
1198                return;
1199            }
1200            spec.suspendPolicy = suspendPolicy;
1201            resolveNow(spec);
1202        }
1203    }
1204
1205    void commandClear(StringTokenizer t) {
1206        if (!t.hasMoreTokens()) {
1207            listBreakpoints();
1208            return;
1209        }
1210        
1211        BreakpointSpec spec = parseBreakpointSpec(t, "clear", "clear");
1212        if (spec != null) {
1213            if (Env.specList.delete(spec)) {
1214                MessageOutput.println("Removed:", spec.toString());
1215            } else {
1216                MessageOutput.println("Not found:", spec.toString());
1217            }
1218        }
1219    }
1220
1221    private List parseWatchpointSpec(StringTokenizer t) {
1222        List list = new ArrayList();
1223        boolean access = false;
1224        boolean modification = false;
1225        int suspendPolicy = EventRequest.SUSPEND_ALL;
1226
1227        String JavaDoc fieldName = t.nextToken();
1228        if (fieldName.equals("go")) {
1229            suspendPolicy = EventRequest.SUSPEND_NONE;
1230            fieldName = t.nextToken();
1231        } else if (fieldName.equals("thread")) {
1232            suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
1233            fieldName = t.nextToken();
1234        }
1235        if (fieldName.equals("access")) {
1236            access = true;
1237            fieldName = t.nextToken();
1238        } else if (fieldName.equals("all")) {
1239            access = true;
1240            modification = true;
1241            fieldName = t.nextToken();
1242        } else {
1243            modification = true;
1244        }
1245        int dot = fieldName.lastIndexOf('.');
1246        if (dot < 0) {
1247            MessageOutput.println("Class containing field must be specified.");
1248            return list;
1249        }
1250        String JavaDoc className = fieldName.substring(0, dot);
1251        fieldName = fieldName.substring(dot+1);
1252
1253        try {
1254            EventRequestSpec spec;
1255            if (access) {
1256                spec = Env.specList.createAccessWatchpoint(className,
1257                                                           fieldName);
1258                spec.suspendPolicy = suspendPolicy;
1259                list.add(spec);
1260            }
1261            if (modification) {
1262                spec = Env.specList.createModificationWatchpoint(className,
1263                                                                 fieldName);
1264                spec.suspendPolicy = suspendPolicy;
1265                list.add(spec);
1266            }
1267        } catch (MalformedMemberNameException exc) {
1268            MessageOutput.println("is not a valid field name", fieldName);
1269        } catch (ClassNotFoundException JavaDoc exc) {
1270            MessageOutput.println("is not a valid class name", className);
1271        }
1272        return list;
1273    }
1274
1275    void commandWatch(StringTokenizer t) {
1276        if (!t.hasMoreTokens()) {
1277            MessageOutput.println("Field to watch not specified");
1278            return;
1279        }
1280
1281        Iterator iter = parseWatchpointSpec(t).iterator();
1282        while (iter.hasNext()) {
1283            resolveNow((WatchpointSpec)iter.next());
1284        }
1285    }
1286
1287    void commandUnwatch(StringTokenizer t) {
1288        if (!t.hasMoreTokens()) {
1289            MessageOutput.println("Field to unwatch not specified");
1290            return;
1291        }
1292
1293        Iterator iter = parseWatchpointSpec(t).iterator();
1294        while (iter.hasNext()) {
1295            WatchpointSpec spec = (WatchpointSpec)iter.next();
1296            if (Env.specList.delete(spec)) {
1297                MessageOutput.println("Removed:", spec.toString());
1298            } else {
1299                MessageOutput.println("Not found:", spec.toString());
1300            }
1301        }
1302    }
1303
1304    void turnOnExitTrace(ThreadInfo threadInfo, int suspendPolicy) {
1305        EventRequestManager erm = Env.vm().eventRequestManager();
1306        MethodExitRequest exit = erm.createMethodExitRequest();
1307        if (threadInfo != null) {
1308            exit.addThreadFilter(threadInfo.getThread());
1309        }
1310        Env.addExcludes(exit);
1311        exit.setSuspendPolicy(suspendPolicy);
1312        exit.enable();
1313
1314    }
1315
1316    static String JavaDoc methodTraceCommand = null;
1317
1318    void commandTrace(StringTokenizer t) {
1319        String JavaDoc modif;
1320        int suspendPolicy = EventRequest.SUSPEND_ALL;
1321        ThreadInfo threadInfo = null;
1322        String JavaDoc goStr = " ";
1323
1324        /*
1325         * trace [go] methods [thread]
1326         * trace [go] method exit | exits [thread]
1327         */

1328        if (t.hasMoreTokens()) {
1329            modif = t.nextToken();
1330            if (modif.equals("go")) {
1331                suspendPolicy = EventRequest.SUSPEND_NONE;
1332                goStr = " go ";
1333                if (t.hasMoreTokens()) {
1334                    modif = t.nextToken();
1335                }
1336            } else if (modif.equals("thread")) {
1337                // this is undocumented as it doesn't work right.
1338
suspendPolicy = EventRequest.SUSPEND_EVENT_THREAD;
1339                if (t.hasMoreTokens()) {
1340                    modif = t.nextToken();
1341                }
1342            }
1343                
1344            if (modif.equals("method")) {
1345                String JavaDoc traceCmd = null;
1346        
1347                if (t.hasMoreTokens()) {
1348                    String JavaDoc modif1 = t.nextToken();
1349                    if (modif1.equals("exits") || modif1.equals("exit")) {
1350                        if (t.hasMoreTokens()) {
1351                            threadInfo = doGetThread(t.nextToken());
1352                        }
1353                        if (modif1.equals("exit")) {
1354                            StackFrame frame;
1355                            try {
1356                                frame = ThreadInfo.getCurrentThreadInfo().getCurrentFrame();
1357                            } catch (IncompatibleThreadStateException ee) {
1358                                MessageOutput.println("Current thread isnt suspended.");
1359                                return;
1360                            }
1361                            Env.setAtExitMethod(frame.location().method());
1362                            traceCmd = MessageOutput.format("trace" +
1363                                                    goStr + "method exit " +
1364                                                    "in effect for",
1365                                                    Env.atExitMethod().toString());
1366                        } else {
1367                            traceCmd = MessageOutput.format("trace" +
1368                                                   goStr + "method exits " +
1369                                                   "in effect");
1370                        }
1371                        commandUntrace(new StringTokenizer("methods"));
1372                        turnOnExitTrace(threadInfo, suspendPolicy);
1373                        methodTraceCommand = traceCmd;
1374                        return;
1375                    }
1376                } else {
1377                   MessageOutput.println("Can only trace");
1378                   return;
1379                }
1380            }
1381            if (modif.equals("methods")) {
1382                // Turn on method entry trace
1383
MethodEntryRequest entry;
1384                EventRequestManager erm = Env.vm().eventRequestManager();
1385                if (t.hasMoreTokens()) {
1386                    threadInfo = doGetThread(t.nextToken());
1387                }
1388                if (threadInfo != null) {
1389                    /*
1390                     * To keep things simple we want each 'trace' to cancel
1391                     * previous traces. However in this case, we don't do that
1392                     * to preserve backward compatibility with pre JDK 6.0.
1393                     * IE, you can currently do
1394                     * trace methods 0x21
1395                     * trace methods 0x22
1396                     * and you will get xxx traced just on those two threads
1397                     * But this feature is kind of broken because if you then do
1398                     * untrace 0x21
1399                     * it turns off both traces instead of just the one.
1400                     * Another bogosity is that if you do
1401                     * trace methods
1402                     * trace methods
1403                     * and you will get two traces.
1404                     */

1405
1406                    entry = erm.createMethodEntryRequest();
1407                    entry.addThreadFilter(threadInfo.getThread());
1408                } else {
1409                    commandUntrace(new StringTokenizer("methods"));
1410                    entry = erm.createMethodEntryRequest();
1411                }
1412                Env.addExcludes(entry);
1413                entry.setSuspendPolicy(suspendPolicy);
1414                entry.enable();
1415                turnOnExitTrace(threadInfo, suspendPolicy);
1416                methodTraceCommand = MessageOutput.format("trace" + goStr +
1417                                                          "methods in effect");
1418
1419                return;
1420            }
1421
1422            MessageOutput.println("Can only trace");
1423            return;
1424        }
1425
1426        // trace all by itself.
1427
if (methodTraceCommand != null) {
1428            MessageOutput.printDirectln(methodTraceCommand);
1429        }
1430        
1431        // More trace lines can be added here.
1432
}
1433
1434    void commandUntrace(StringTokenizer t) {
1435        // untrace
1436
// untrace methods
1437

1438        String JavaDoc modif = null;
1439        EventRequestManager erm = Env.vm().eventRequestManager();
1440        if (t.hasMoreTokens()) {
1441            modif = t.nextToken();
1442        }
1443        if (modif == null || modif.equals("methods")) {
1444            erm.deleteEventRequests(erm.methodEntryRequests());
1445            erm.deleteEventRequests(erm.methodExitRequests());
1446            Env.setAtExitMethod(null);
1447            methodTraceCommand = null;
1448        }
1449    }
1450    
1451    void commandList(StringTokenizer t) {
1452        StackFrame frame = null;
1453        ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
1454        if (threadInfo == null) {
1455            MessageOutput.println("No thread specified.");
1456            return;
1457        }
1458        try {
1459            frame = threadInfo.getCurrentFrame();
1460        } catch (IncompatibleThreadStateException e) {
1461            MessageOutput.println("Current thread isnt suspended.");
1462            return;
1463        }
1464
1465        if (frame == null) {
1466            MessageOutput.println("No frames on the current call stack");
1467            return;
1468        }
1469        
1470        Location loc = frame.location();
1471        if (loc.method().isNative()) {
1472            MessageOutput.println("Current method is native");
1473            return;
1474        }
1475
1476        String JavaDoc sourceFileName = null;
1477        try {
1478            sourceFileName = loc.sourceName();
1479
1480            ReferenceType refType = loc.declaringType();
1481            int lineno = loc.lineNumber();
1482    
1483            if (t.hasMoreTokens()) {
1484                String JavaDoc id = t.nextToken();
1485    
1486                // See if token is a line number.
1487
try {
1488                    NumberFormat nf = NumberFormat.getNumberInstance();
1489                    nf.setParseIntegerOnly(true);
1490                    Number JavaDoc n = nf.parse(id);
1491                    lineno = n.intValue();
1492                } catch (java.text.ParseException JavaDoc jtpe) {
1493                    // It isn't -- see if it's a method name.
1494
List meths = refType.methodsByName(id);
1495                        if (meths == null || meths.size() == 0) {
1496                            MessageOutput.println("is not a valid line number or method name for",
1497                                                  new Object JavaDoc [] {id, refType.name()});
1498                            return;
1499                        } else if (meths.size() > 1) {
1500                            MessageOutput.println("is an ambiguous method name in",
1501                                                  new Object JavaDoc [] {id, refType.name()});
1502                            return;
1503                        }
1504                        loc = ((Method)meths.get(0)).location();
1505                        lineno = loc.lineNumber();
1506                }
1507            }
1508            int startLine = Math.max(lineno - 4, 1);
1509            int endLine = startLine + 9;
1510            if (lineno < 0) {
1511                MessageOutput.println("Line number information not available for");
1512            } else if (Env.sourceLine(loc, lineno) == null) {
1513                MessageOutput.println("is an invalid line number for",
1514                                      new Object JavaDoc [] {new Integer JavaDoc (lineno),
1515                                                     refType.name()});
1516            } else {
1517                for (int i = startLine; i <= endLine; i++) {
1518                    String JavaDoc sourceLine = Env.sourceLine(loc, i);
1519                    if (sourceLine == null) {
1520                        break;
1521                    }
1522                    if (i == lineno) {
1523                        MessageOutput.println("source line number current line and line",
1524                                              new Object JavaDoc [] {new Integer JavaDoc (i),
1525                                                             sourceLine});
1526                    } else {
1527                        MessageOutput.println("source line number and line",
1528                                              new Object JavaDoc [] {new Integer JavaDoc (i),
1529                                                             sourceLine});
1530                    }
1531                }
1532            }
1533        } catch (AbsentInformationException e) {
1534            MessageOutput.println("No source information available for:", loc.toString());
1535        } catch(FileNotFoundException exc) {
1536            MessageOutput.println("Source file not found:", sourceFileName);
1537        } catch(IOException exc) {
1538            MessageOutput.println("I/O exception occurred:", exc.toString());
1539        }
1540    }
1541
1542    void commandLines(StringTokenizer t) { // Undocumented command: useful for testing
1543
if (!t.hasMoreTokens()) {
1544            MessageOutput.println("Specify class and method");
1545        } else {
1546            String JavaDoc idClass = t.nextToken();
1547            String JavaDoc idMethod = t.hasMoreTokens() ? t.nextToken() : null;
1548            try {
1549                ReferenceType refType = Env.getReferenceTypeFromToken(idClass);
1550                if (refType != null) {
1551                    List lines = null;
1552                    if (idMethod == null) {
1553                        lines = refType.allLineLocations();
1554                    } else {
1555                        List methods = refType.allMethods();
1556                        Iterator iter = methods.iterator();
1557                        while (iter.hasNext()) {
1558                            Method method = (Method)iter.next();
1559                            if (method.name().equals(idMethod)) {
1560                                lines = method.allLineLocations();
1561                            }
1562                        }
1563                        if (lines == null) {
1564                            MessageOutput.println("is not a valid method name", idMethod);
1565                        }
1566                    }
1567                    Iterator iter = lines.iterator();
1568                    while (iter.hasNext()) {
1569                        Location line = (Location)iter.next();
1570                        MessageOutput.printDirectln(line.toString());// Special case: use printDirectln()
1571
}
1572                } else {
1573                    MessageOutput.println("is not a valid id or class name", idClass);
1574                }
1575            } catch (AbsentInformationException e) {
1576                MessageOutput.println("Line number information not available for", idClass);
1577            }
1578        }
1579    }
1580
1581    void commandClasspath(StringTokenizer t) {
1582        if (Env.vm() instanceof PathSearchingVirtualMachine) {
1583            PathSearchingVirtualMachine vm = (PathSearchingVirtualMachine)Env.vm();
1584            MessageOutput.println("base directory:", vm.baseDirectory());
1585            MessageOutput.println("classpath:", vm.classPath().toString());
1586            MessageOutput.println("bootclasspath:", vm.bootClassPath().toString());
1587        } else {
1588            MessageOutput.println("The VM does not use paths");
1589        }
1590    }
1591
1592    /* Get or set the source file path list. */
1593    void commandUse(StringTokenizer t) {
1594        if (!t.hasMoreTokens()) {
1595            MessageOutput.printDirectln(Env.getSourcePath());// Special case: use printDirectln()
1596
} else {
1597            /*
1598             * Take the remainder of the command line, minus
1599             * leading or trailing whitespace. Embedded
1600             * whitespace is fine.
1601             */

1602            Env.setSourcePath(t.nextToken("").trim());
1603        }
1604    }
1605
1606    /* Print a stack variable */
1607    private void printVar(LocalVariable var, Value value) {
1608        MessageOutput.println("expr is value",
1609                              new Object JavaDoc [] {var.name(),
1610                                             value == null ? "null" : value.toString()});
1611    }
1612
1613    /* Print all local variables in current stack frame. */
1614    void commandLocals() {
1615        StackFrame frame;
1616        ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
1617        if (threadInfo == null) {
1618            MessageOutput.println("No default thread specified:");
1619            return;
1620        }
1621        try {
1622            frame = threadInfo.getCurrentFrame();
1623            if (frame == null) {
1624                throw new AbsentInformationException();
1625            }
1626            List vars = frame.visibleVariables();
1627    
1628            if (vars.size() == 0) {
1629                MessageOutput.println("No local variables");
1630                return;
1631            }
1632            Map values = frame.getValues(vars);
1633
1634            MessageOutput.println("Method arguments:");
1635            for (Iterator it = vars.iterator(); it.hasNext(); ) {
1636                LocalVariable var = (LocalVariable)it.next();
1637                if (var.isArgument()) {
1638                    Value val = (Value)values.get(var);
1639                    printVar(var, val);
1640                }
1641            }
1642            MessageOutput.println("Local variables:");
1643            for (Iterator it = vars.iterator(); it.hasNext(); ) {
1644                LocalVariable var = (LocalVariable)it.next();
1645                if (!var.isArgument()) {
1646                    Value val = (Value)values.get(var);
1647                    printVar(var, val);
1648                }
1649            }
1650        } catch (AbsentInformationException aie) {
1651            MessageOutput.println("Local variable information not available.");
1652        } catch (IncompatibleThreadStateException exc) {
1653            MessageOutput.println("Current thread isnt suspended.");
1654        }
1655    }
1656
1657    private void dump(ObjectReference obj, ReferenceType refType,
1658                      ReferenceType refTypeBase) {
1659        for (Iterator it = refType.fields().iterator(); it.hasNext(); ) {
1660            StringBuffer JavaDoc o = new StringBuffer JavaDoc();
1661            Field field = (Field)it.next();
1662            o.append(" ");
1663            if (!refType.equals(refTypeBase)) {
1664                o.append(refType.name());
1665                o.append(".");
1666            }
1667            o.append(field.name());
1668            o.append(MessageOutput.format("colon space"));
1669            o.append(obj.getValue(field));
1670            MessageOutput.printDirectln(o.toString()); // Special case: use printDirectln()
1671
}
1672        if (refType instanceof ClassType) {
1673            ClassType sup = ((ClassType)refType).superclass();
1674            if (sup != null) {
1675                dump(obj, sup, refTypeBase);
1676            }
1677        } else if (refType instanceof InterfaceType) {
1678            List sups = ((InterfaceType)refType).superinterfaces();
1679            for (Iterator it = sups.iterator(); it.hasNext(); ) {
1680                dump(obj, (ReferenceType)it.next(), refTypeBase);
1681            }
1682        } else {
1683            /* else refType is an instanceof ArrayType */
1684            if (obj instanceof ArrayReference) {
1685                for (Iterator it = ((ArrayReference)obj).getValues().iterator();
1686                     it.hasNext(); ) {
1687                    MessageOutput.printDirect(it.next().toString());// Special case: use printDirect()
1688
if (it.hasNext()) {
1689                        MessageOutput.printDirect(", ");// Special case: use printDirect()
1690
}
1691                }
1692                MessageOutput.println();
1693            }
1694        }
1695    }
1696
1697    /* Print a specified reference.
1698     */

1699    void doPrint(StringTokenizer t, boolean dumpObject) {
1700        if (!t.hasMoreTokens()) {
1701            MessageOutput.println("No objects specified.");
1702            return;
1703        }
1704
1705        while (t.hasMoreTokens()) {
1706            String JavaDoc expr = t.nextToken("");
1707            Value val = evaluate(expr);
1708            if (val == null) {
1709                MessageOutput.println("expr is null", expr.toString());
1710            } else if (dumpObject && (val instanceof ObjectReference) &&
1711                       !(val instanceof StringReference)) {
1712                ObjectReference obj = (ObjectReference)val;
1713                ReferenceType refType = obj.referenceType();
1714                MessageOutput.println("expr is value",
1715                                      new Object JavaDoc [] {expr.toString(),
1716                                                     MessageOutput.format("grouping begin character")});
1717                dump(obj, refType, refType);
1718                MessageOutput.println("grouping end character");
1719            } else {
1720                  String JavaDoc strVal = getStringValue();
1721                  if (strVal != null) {
1722                     MessageOutput.println("expr is value", new Object JavaDoc [] {expr.toString(),
1723                                                                      strVal});
1724                   }
1725            }
1726        }
1727    }
1728
1729    void commandPrint(final StringTokenizer t, final boolean dumpObject) {
1730        new AsyncExecution() {
1731                void action() {
1732                    doPrint(t, dumpObject);
1733                }
1734            };
1735    }
1736
1737    void commandSet(final StringTokenizer t) {
1738        String JavaDoc all = t.nextToken("");
1739
1740        /*
1741         * Bare bones error checking.
1742         */

1743        if (all.indexOf('=') == -1) {
1744            MessageOutput.println("Invalid assignment syntax");
1745            MessageOutput.printPrompt();
1746            return;
1747        }
1748
1749        /*
1750         * The set command is really just syntactic sugar. Pass it on to the
1751         * print command.
1752         */

1753        commandPrint(new StringTokenizer(all), false);
1754    }
1755
1756    void doLock(StringTokenizer t) {
1757        if (!t.hasMoreTokens()) {
1758            MessageOutput.println("No object specified.");
1759            return;
1760        }
1761
1762        String JavaDoc expr = t.nextToken("");
1763        Value val = evaluate(expr);
1764
1765        try {
1766            if ((val != null) && (val instanceof ObjectReference)) {
1767                ObjectReference object = (ObjectReference)val;
1768                String JavaDoc strVal = getStringValue();
1769                if (strVal != null) {
1770                    MessageOutput.println("Monitor information for expr",
1771                                      new Object JavaDoc [] {expr.trim(),
1772                                                     strVal});
1773                }
1774                ThreadReference owner = object.owningThread();
1775                if (owner == null) {
1776                    MessageOutput.println("Not owned");
1777                } else {
1778                    MessageOutput.println("Owned by:",
1779                                          new Object JavaDoc [] {owner.name(),
1780                                                         new Integer JavaDoc (object.entryCount())});
1781                }
1782                List waiters = object.waitingThreads();
1783                if (waiters.size() == 0) {
1784                    MessageOutput.println("No waiters");
1785                } else {
1786                    Iterator iter = waiters.iterator();
1787                    while (iter.hasNext()) {
1788                        ThreadReference waiter = (ThreadReference)iter.next();
1789                        MessageOutput.println("Waiting thread:", waiter.name());
1790                    }
1791                }
1792            } else {
1793                MessageOutput.println("Expression must evaluate to an object");
1794            }
1795        } catch (IncompatibleThreadStateException e) {
1796            MessageOutput.println("Threads must be suspended");
1797        }
1798    }
1799
1800    void commandLock(final StringTokenizer t) {
1801        new AsyncExecution() {
1802                void action() {
1803                    doLock(t);
1804                }
1805            };
1806    }
1807
1808    private void printThreadLockInfo(ThreadInfo threadInfo) {
1809        ThreadReference thread = threadInfo.getThread();
1810        try {
1811            MessageOutput.println("Monitor information for thread", thread.name());
1812            List owned = thread.ownedMonitors();
1813            if (owned.size() == 0) {
1814                MessageOutput.println("No monitors owned");
1815            } else {
1816                Iterator iter = owned.iterator();
1817                while (iter.hasNext()) {
1818                    ObjectReference monitor = (ObjectReference)iter.next();
1819                    MessageOutput.println("Owned monitor:", monitor.toString());
1820                }
1821            }
1822            ObjectReference waiting = thread.currentContendedMonitor();
1823            if (waiting == null) {
1824                MessageOutput.println("Not waiting for a monitor");
1825            } else {
1826                MessageOutput.println("Waiting for monitor:", waiting.toString());
1827            }
1828        } catch (IncompatibleThreadStateException e) {
1829            MessageOutput.println("Threads must be suspended");
1830        }
1831    }
1832
1833    void commandThreadlocks(final StringTokenizer t) {
1834        if (!t.hasMoreTokens()) {
1835            ThreadInfo threadInfo = ThreadInfo.getCurrentThreadInfo();
1836            if (threadInfo == null) {
1837                MessageOutput.println("Current thread not set.");
1838            } else {
1839                printThreadLockInfo(threadInfo);
1840            }
1841            return;
1842        }
1843        String JavaDoc token = t.nextToken();
1844        if (token.toLowerCase().equals("all")) {
1845            Iterator iter = ThreadInfo.threads().iterator();
1846            while (iter.hasNext()) {
1847                ThreadInfo threadInfo = (ThreadInfo)iter.next();
1848                printThreadLockInfo(threadInfo);
1849            }
1850        } else {
1851            ThreadInfo threadInfo = doGetThread(token);
1852            if (threadInfo != null) {
1853                ThreadInfo.setCurrentThreadInfo(threadInfo);
1854                printThreadLockInfo(threadInfo);
1855            }
1856        }
1857    }
1858
1859    void doDisableGC(StringTokenizer t) {
1860        if (!t.hasMoreTokens()) {
1861            MessageOutput.println("No object specified.");
1862            return;
1863        }
1864
1865        String JavaDoc expr = t.nextToken("");
1866        Value val = evaluate(expr);
1867        if ((val != null) && (val instanceof ObjectReference)) {
1868            ObjectReference object = (ObjectReference)val;
1869            object.disableCollection();
1870            String JavaDoc strVal = getStringValue();
1871            if (strVal != null) {
1872                 MessageOutput.println("GC Disabled for", strVal);
1873            }
1874        } else {
1875            MessageOutput.println("Expression must evaluate to an object");
1876        }
1877    }
1878
1879    void commandDisableGC(final StringTokenizer t) {
1880        new AsyncExecution() {
1881                void action() {
1882                    doDisableGC(t);
1883                }
1884            };
1885    }
1886
1887    void doEnableGC(StringTokenizer t) {
1888        if (!t.hasMoreTokens()) {
1889            MessageOutput.println("No object specified.");
1890            return;
1891        }
1892
1893        String JavaDoc expr = t.nextToken("");
1894        Value val = evaluate(expr);
1895        if ((val != null) && (val instanceof ObjectReference)) {
1896            ObjectReference object = (ObjectReference)val;
1897            object.enableCollection();
1898            String JavaDoc strVal = getStringValue();
1899            if (strVal != null) {
1900                 MessageOutput.println("GC Enabled for", strVal);
1901            }
1902        } else {
1903            MessageOutput.println("Expression must evaluate to an object");
1904        }
1905    }
1906
1907    void commandEnableGC(final StringTokenizer t) {
1908        new AsyncExecution() {
1909                void action() {
1910                    doEnableGC(t);
1911                }
1912            };
1913    }
1914
1915    void doSave(StringTokenizer t) {// Undocumented command: useful for testing.
1916
if (!t.hasMoreTokens()) {
1917            MessageOutput.println("No save index specified.");
1918            return;
1919        }
1920
1921        String JavaDoc key = t.nextToken();
1922
1923        if (!t.hasMoreTokens()) {
1924            MessageOutput.println("No expression specified.");
1925            return;
1926        }
1927        String JavaDoc expr = t.nextToken("");
1928        Value val = evaluate(expr);
1929        if (val != null) {
1930            Env.setSavedValue(key, val);
1931            String JavaDoc strVal = getStringValue();
1932            if (strVal != null) {
1933                 MessageOutput.println("saved", strVal);
1934            }
1935        } else {
1936            MessageOutput.println("Expression cannot be void");
1937        }
1938    }
1939
1940    void commandSave(final StringTokenizer t) { // Undocumented command: useful for testing.
1941
if (!t.hasMoreTokens()) {
1942            Set keys = Env.getSaveKeys();
1943            Iterator iter = keys.iterator();
1944            if (!iter.hasNext()) {
1945                MessageOutput.println("No saved values");
1946                return;
1947            }
1948            while (iter.hasNext()) {
1949                String JavaDoc key = (String JavaDoc)iter.next();
1950                Value value = Env.getSavedValue(key);
1951                if ((value instanceof ObjectReference) &&
1952                    ((ObjectReference)value).isCollected()) {
1953                    MessageOutput.println("expr is value <collected>",
1954                                          new Object JavaDoc [] {key, value.toString()});
1955                } else {
1956                    if (value == null){
1957                        MessageOutput.println("expr is null", key);
1958                    } else {
1959                        MessageOutput.println("expr is value",
1960                                              new Object JavaDoc [] {key, value.toString()});
1961                    }
1962                }
1963            }
1964        } else {
1965            new AsyncExecution() {
1966                    void action() {
1967                        doSave(t);
1968                    }
1969                };
1970        }
1971
1972    }
1973
1974   void commandBytecodes(final StringTokenizer t) { // Undocumented command: useful for testing.
1975
if (!t.hasMoreTokens()) {
1976            MessageOutput.println("No class specified.");
1977            return;
1978        }
1979        String JavaDoc className = t.nextToken();
1980
1981        if (!t.hasMoreTokens()) {
1982            MessageOutput.println("No method specified.");
1983            return;
1984        }
1985        // Overloading is not handled here.
1986
String JavaDoc methodName = t.nextToken();
1987
1988        List classes = Env.vm().classesByName(className);
1989        // TO DO: handle multiple classes found
1990
if (classes.size() == 0) {
1991            if (className.indexOf('.') < 0) {
1992                MessageOutput.println("not found (try the full name)", className);
1993            } else {
1994                MessageOutput.println("not found", className);
1995            }
1996            return;
1997        }
1998        
1999        ReferenceType rt = (ReferenceType)classes.get(0);
2000        if (!(rt instanceof ClassType)) {
2001            MessageOutput.println("not a class", className);
2002            return;
2003        }
2004
2005        byte[] bytecodes = null;
2006        List list = rt.methodsByName(methodName);
2007        Iterator iter = list.iterator();
2008        while (iter.hasNext()) {
2009            Method method = (Method)iter.next();
2010            if (!method.isAbstract()) {
2011                bytecodes = method.bytecodes();
2012                break;
2013            }
2014        }
2015
2016        StringBuffer JavaDoc line = new StringBuffer JavaDoc(80);
2017        line.append("0000: ");
2018        for (int i = 0; i < bytecodes.length; i++) {
2019            if ((i > 0) && (i % 16 == 0)) {
2020                MessageOutput.printDirectln(line.toString());// Special case: use printDirectln()
2021
line.setLength(0);
2022                line.append(String.valueOf(i));
2023                line.append(": ");
2024                int len = line.length();
2025                for (int j = 0; j < 6 - len; j++) {
2026                    line.insert(0, '0');
2027                }
2028            }
2029            int val = 0xff & bytecodes[i];
2030            String JavaDoc str = Integer.toHexString(val);
2031            if (str.length() == 1) {
2032                line.append('0');
2033            }
2034            line.append(str);
2035            line.append(' ');
2036        }
2037        if (line.length() > 6) {
2038            MessageOutput.printDirectln(line.toString());// Special case: use printDirectln()
2039
}
2040    }
2041
2042    void commandExclude(StringTokenizer t) {
2043        if (!t.hasMoreTokens()) {
2044            MessageOutput.printDirectln(Env.excludesString());// Special case: use printDirectln()
2045
} else {
2046            String JavaDoc rest = t.nextToken("");
2047            if (rest.equals("none")) {
2048                rest = "";
2049            }
2050            Env.setExcludes(rest);
2051        }
2052    }
2053
2054    void commandRedefine(StringTokenizer t) {
2055        if (!t.hasMoreTokens()) {
2056            MessageOutput.println("Specify classes to redefine");
2057        } else {
2058            String JavaDoc className = t.nextToken();
2059            List classes = Env.vm().classesByName(className);
2060            if (classes.size() == 0) {
2061                MessageOutput.println("No class named", className);
2062                return;
2063            }
2064            if (classes.size() > 1) {
2065                MessageOutput.println("More than one class named", className);
2066                return;
2067            }
2068        Env.setSourcePath(Env.getSourcePath());
2069            ReferenceType refType = (ReferenceType)classes.get(0);
2070            if (!t.hasMoreTokens()) {
2071                MessageOutput.println("Specify file name for class", className);
2072                return;
2073            }
2074            String JavaDoc fileName = t.nextToken();
2075            File phyl = new File(fileName);
2076            byte[] bytes = new byte[(int)phyl.length()];
2077            try {
2078                InputStream in = new FileInputStream(phyl);
2079                in.read(bytes);
2080                in.close();
2081            } catch (Exception JavaDoc exc) {
2082                MessageOutput.println("Error reading file",
2083                             new Object JavaDoc [] {fileName, exc.toString()});
2084                return;
2085            }
2086            Map map = new HashMap();
2087            map.put(refType, bytes);
2088            try {
2089                Env.vm().redefineClasses(map);
2090            } catch (Throwable JavaDoc exc) {
2091                MessageOutput.println("Error redefining class to file",
2092                             new Object JavaDoc [] {className,
2093                                            fileName,
2094                                            exc});
2095            }
2096        }
2097    }
2098
2099    void commandPopFrames(StringTokenizer t, boolean reenter) {
2100        ThreadInfo threadInfo;
2101
2102        if (t.hasMoreTokens()) {
2103            String JavaDoc token = t.nextToken();
2104            threadInfo = doGetThread(token);
2105            if (threadInfo == null) {
2106                return;
2107            }
2108        } else {
2109            threadInfo = ThreadInfo.getCurrentThreadInfo();
2110            if (threadInfo == null) {
2111                MessageOutput.println("No thread specified.");
2112                return;
2113            }
2114        }
2115       
2116        try {
2117            StackFrame frame = threadInfo.getCurrentFrame();
2118            threadInfo.getThread().popFrames(frame);
2119            threadInfo = ThreadInfo.getCurrentThreadInfo();
2120            ThreadInfo.setCurrentThreadInfo(threadInfo);
2121            if (reenter) {
2122                commandStepi();
2123            }
2124        } catch (Throwable JavaDoc exc) {
2125            MessageOutput.println("Error popping frame", exc.toString());
2126        }
2127    }
2128
2129    void commandExtension(StringTokenizer t) {
2130        if (!t.hasMoreTokens()) {
2131            MessageOutput.println("No class specified.");
2132            return;
2133        }
2134
2135        String JavaDoc idClass = t.nextToken();
2136        ReferenceType cls = Env.getReferenceTypeFromToken(idClass);
2137        String JavaDoc extension = null;
2138        if (cls != null) {
2139            try {
2140                extension = cls.sourceDebugExtension();
2141                MessageOutput.println("sourcedebugextension", extension);
2142            } catch (AbsentInformationException e) {
2143                MessageOutput.println("No sourcedebugextension specified");
2144            }
2145        } else {
2146            MessageOutput.println("is not a valid id or class name", idClass);
2147        }
2148    }
2149
2150    void commandVersion(String JavaDoc debuggerName,
2151                        VirtualMachineManager vmm) {
2152        MessageOutput.println("minus version",
2153                              new Object JavaDoc [] { debuggerName,
2154                                              new Integer JavaDoc(vmm.majorInterfaceVersion()),
2155                                              new Integer JavaDoc(vmm.minorInterfaceVersion()),
2156                                                  System.getProperty("java.version")});
2157        if (Env.connection() != null) {
2158            try {
2159                MessageOutput.printDirectln(Env.vm().description());// Special case: use printDirectln()
2160
} catch (VMNotConnectedException e) {
2161                MessageOutput.println("No VM connected");
2162            }
2163        }
2164    }
2165}
2166
Popular Tags