blob: d74aabceb8e1e4b15be67f8b6c7cb4fd164da40b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.tools.example.debug.gui;
27
28import java.io.*;
29import java.util.*;
30
31import javax.swing.*;
32import java.awt.BorderLayout;
33import java.awt.event.*;
34
35import com.sun.jdi.*;
36import com.sun.jdi.event.*;
37
38import com.sun.tools.example.debug.bdi.*;
39import com.sun.tools.example.debug.event.*;
40
41public class CommandTool extends JPanel {
42
43 private Environment env;
44
45 private ContextManager context;
46 private ExecutionManager runtime;
47 private SourceManager sourceManager;
48
49 private TypeScript script;
50
51 private static final String DEFAULT_CMD_PROMPT = "Command:";
52
53 public CommandTool(Environment env) {
54
55 super(new BorderLayout());
56
57 this.env = env;
58 this.context = env.getContextManager();
59 this.runtime = env.getExecutionManager();
60 this.sourceManager = env.getSourceManager();
61
62 script = new TypeScript(DEFAULT_CMD_PROMPT, false); //no echo
63 this.add(script);
64
65 final CommandInterpreter interpreter =
66 new CommandInterpreter(env);
67
68 // Establish handler for incoming commands.
69
70 script.addActionListener(new ActionListener() {
71 public void actionPerformed(ActionEvent e) {
72 interpreter.executeCommand(script.readln());
73 }
74 });
75
76 // Establish ourselves as the listener for VM diagnostics.
77
78 OutputListener diagnosticsListener =
79 new TypeScriptOutputListener(script, true);
80 runtime.addDiagnosticsListener(diagnosticsListener);
81
82 // Establish ourselves as the shared debugger typescript.
83
84 env.setTypeScript(new PrintWriter(new TypeScriptWriter(script)));
85
86 // Handle VM events.
87
88 TTYDebugListener listener = new TTYDebugListener(diagnosticsListener);
89
90 runtime.addJDIListener(listener);
91 runtime.addSessionListener(listener);
92 runtime.addSpecListener(listener);
93 context.addContextListener(listener);
94
95 //### remove listeners on exit!
96
97 }
98
99 private class TTYDebugListener implements
100 JDIListener, SessionListener, SpecListener, ContextListener {
101
102 private OutputListener diagnostics;
103
104 TTYDebugListener(OutputListener diagnostics) {
105 this.diagnostics = diagnostics;
106 }
107
108 // JDIListener
109
110 public void accessWatchpoint(AccessWatchpointEventSet e) {
111 setThread(e);
112 for (EventIterator it = e.eventIterator(); it.hasNext(); ) {
113 Event evt = it.nextEvent();
114 diagnostics.putString("Watchpoint hit: " +
115 locationString(e));
116 }
117 }
118
119 public void classPrepare(ClassPrepareEventSet e) {
120 if (context.getVerboseFlag()) {
121 String name = e.getReferenceType().name();
122 diagnostics.putString("Class " + name + " loaded");
123 }
124 }
125
126 public void classUnload(ClassUnloadEventSet e) {
127 if (context.getVerboseFlag()) {
128 diagnostics.putString("Class " + e.getClassName() +
129 " unloaded.");
130 }
131 }
132
133 public void exception(ExceptionEventSet e) {
134 setThread(e);
135 String name = e.getException().referenceType().name();
136 diagnostics.putString("Exception: " + name);
137 }
138
139 public void locationTrigger(LocationTriggerEventSet e) {
140 String locString = locationString(e);
141 setThread(e);
142 for (EventIterator it = e.eventIterator(); it.hasNext(); ) {
143 Event evt = it.nextEvent();
144 if (evt instanceof BreakpointEvent) {
145 diagnostics.putString("Breakpoint hit: " + locString);
146 } else if (evt instanceof StepEvent) {
147 diagnostics.putString("Step completed: " + locString);
148 } else if (evt instanceof MethodEntryEvent) {
149 diagnostics.putString("Method entered: " + locString);
150 } else if (evt instanceof MethodExitEvent) {
151 diagnostics.putString("Method exited: " + locString);
152 } else {
153 diagnostics.putString("UNKNOWN event: " + e);
154 }
155 }
156 }
157
158 public void modificationWatchpoint(ModificationWatchpointEventSet e) {
159 setThread(e);
160 for (EventIterator it = e.eventIterator(); it.hasNext(); ) {
161 Event evt = it.nextEvent();
162 diagnostics.putString("Watchpoint hit: " +
163 locationString(e));
164 }
165 }
166
167 public void threadDeath(ThreadDeathEventSet e) {
168 if (context.getVerboseFlag()) {
169 diagnostics.putString("Thread " + e.getThread() +
170 " ended.");
171 }
172 }
173
174 public void threadStart(ThreadStartEventSet e) {
175 if (context.getVerboseFlag()) {
176 diagnostics.putString("Thread " + e.getThread() +
177 " started.");
178 }
179 }
180
181 public void vmDeath(VMDeathEventSet e) {
182 script.setPrompt(DEFAULT_CMD_PROMPT);
183 diagnostics.putString("VM exited");
184 }
185
186 public void vmDisconnect(VMDisconnectEventSet e) {
187 script.setPrompt(DEFAULT_CMD_PROMPT);
188 diagnostics.putString("Disconnected from VM");
189 }
190
191 public void vmStart(VMStartEventSet e) {
192 script.setPrompt(DEFAULT_CMD_PROMPT);
193 diagnostics.putString("VM started");
194 }
195
196 // SessionListener
197
198 public void sessionStart(EventObject e) {}
199
200 public void sessionInterrupt(EventObject e) {
201 Thread.yield(); // fetch output
202 diagnostics.putString("VM interrupted by user.");
203 script.setPrompt(DEFAULT_CMD_PROMPT);
204 }
205
206 public void sessionContinue(EventObject e) {
207 diagnostics.putString("Execution resumed.");
208 script.setPrompt(DEFAULT_CMD_PROMPT);
209 }
210
211 // SpecListener
212
213 public void breakpointSet(SpecEvent e) {
214 EventRequestSpec spec = e.getEventRequestSpec();
215 diagnostics.putString("Breakpoint set at " + spec + ".");
216 }
217 public void breakpointDeferred(SpecEvent e) {
218 EventRequestSpec spec = e.getEventRequestSpec();
219 diagnostics.putString("Breakpoint will be set at " +
220 spec + " when its class is loaded.");
221 }
222 public void breakpointDeleted(SpecEvent e) {
223 EventRequestSpec spec = e.getEventRequestSpec();
224 diagnostics.putString("Breakpoint at " + spec.toString() + " deleted.");
225 }
226 public void breakpointResolved(SpecEvent e) {
227 EventRequestSpec spec = e.getEventRequestSpec();
228 diagnostics.putString("Breakpoint resolved to " + spec.toString() + ".");
229 }
230 public void breakpointError(SpecErrorEvent e) {
231 EventRequestSpec spec = e.getEventRequestSpec();
232 diagnostics.putString("Deferred breakpoint at " +
233 spec + " could not be resolved:" +
234 e.getReason());
235 }
236
237//### Add info for watchpoints and exceptions
238
239 public void watchpointSet(SpecEvent e) {
240 }
241 public void watchpointDeferred(SpecEvent e) {
242 }
243 public void watchpointDeleted(SpecEvent e) {
244 }
245 public void watchpointResolved(SpecEvent e) {
246 }
247 public void watchpointError(SpecErrorEvent e) {
248 }
249
250 public void exceptionInterceptSet(SpecEvent e) {
251 }
252 public void exceptionInterceptDeferred(SpecEvent e) {
253 }
254 public void exceptionInterceptDeleted(SpecEvent e) {
255 }
256 public void exceptionInterceptResolved(SpecEvent e) {
257 }
258 public void exceptionInterceptError(SpecErrorEvent e) {
259 }
260
261
262 // ContextListener.
263
264 // If the user selects a new current thread or frame, update prompt.
265
266 public void currentFrameChanged(CurrentFrameChangedEvent e) {
267 // Update prompt only if affect thread is current.
268 ThreadReference thread = e.getThread();
269 if (thread == context.getCurrentThread()) {
270 script.setPrompt(promptString(thread, e.getIndex()));
271 }
272 }
273
274 }
275
276 private String locationString(LocatableEventSet e) {
277 Location loc = e.getLocation();
278 return "thread=\"" + e.getThread().name() +
279 "\", " + Utils.locationString(loc);
280 }
281
282 private void setThread(LocatableEventSet e) {
283 if (!e.suspendedNone()) {
284 Thread.yield(); // fetch output
285 script.setPrompt(promptString(e.getThread(), 0));
286 //### Current thread should be set elsewhere, e.g.,
287 //### in ContextManager
288 //### context.setCurrentThread(thread);
289 }
290 }
291
292 private String promptString(ThreadReference thread, int frameIndex) {
293 if (thread == null) {
294 return DEFAULT_CMD_PROMPT;
295 } else {
296 // Frame indices are presented to user as indexed from 1.
297 return (thread.name() + "[" + (frameIndex + 1) + "]:");
298 }
299 }
300}