/* * Copyright 1998-1999 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Sun designates this * particular file as subject to the "Classpath" exception as provided * by Sun in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ package com.sun.tools.example.debug.gui; import java.io.*; import java.util.*; import javax.swing.*; import java.awt.BorderLayout; import java.awt.event.*; import com.sun.jdi.*; import com.sun.jdi.event.*; import com.sun.tools.example.debug.bdi.*; import com.sun.tools.example.debug.event.*; public class CommandTool extends JPanel { private Environment env; private ContextManager context; private ExecutionManager runtime; private SourceManager sourceManager; private TypeScript script; private static final String DEFAULT_CMD_PROMPT = "Command:"; public CommandTool(Environment env) { super(new BorderLayout()); this.env = env; this.context = env.getContextManager(); this.runtime = env.getExecutionManager(); this.sourceManager = env.getSourceManager(); script = new TypeScript(DEFAULT_CMD_PROMPT, false); //no echo this.add(script); final CommandInterpreter interpreter = new CommandInterpreter(env); // Establish handler for incoming commands. script.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { interpreter.executeCommand(script.readln()); } }); // Establish ourselves as the listener for VM diagnostics. OutputListener diagnosticsListener = new TypeScriptOutputListener(script, true); runtime.addDiagnosticsListener(diagnosticsListener); // Establish ourselves as the shared debugger typescript. env.setTypeScript(new PrintWriter(new TypeScriptWriter(script))); // Handle VM events. TTYDebugListener listener = new TTYDebugListener(diagnosticsListener); runtime.addJDIListener(listener); runtime.addSessionListener(listener); runtime.addSpecListener(listener); context.addContextListener(listener); //### remove listeners on exit! } private class TTYDebugListener implements JDIListener, SessionListener, SpecListener, ContextListener { private OutputListener diagnostics; TTYDebugListener(OutputListener diagnostics) { this.diagnostics = diagnostics; } // JDIListener public void accessWatchpoint(AccessWatchpointEventSet e) { setThread(e); for (EventIterator it = e.eventIterator(); it.hasNext(); ) { Event evt = it.nextEvent(); diagnostics.putString("Watchpoint hit: " + locationString(e)); } } public void classPrepare(ClassPrepareEventSet e) { if (context.getVerboseFlag()) { String name = e.getReferenceType().name(); diagnostics.putString("Class " + name + " loaded"); } } public void classUnload(ClassUnloadEventSet e) { if (context.getVerboseFlag()) { diagnostics.putString("Class " + e.getClassName() + " unloaded."); } } public void exception(ExceptionEventSet e) { setThread(e); String name = e.getException().referenceType().name(); diagnostics.putString("Exception: " + name); } public void locationTrigger(LocationTriggerEventSet e) { String locString = locationString(e); setThread(e); for (EventIterator it = e.eventIterator(); it.hasNext(); ) { Event evt = it.nextEvent(); if (evt instanceof BreakpointEvent) { diagnostics.putString("Breakpoint hit: " + locString); } else if (evt instanceof StepEvent) { diagnostics.putString("Step completed: " + locString); } else if (evt instanceof MethodEntryEvent) { diagnostics.putString("Method entered: " + locString); } else if (evt instanceof MethodExitEvent) { diagnostics.putString("Method exited: " + locString); } else { diagnostics.putString("UNKNOWN event: " + e); } } } public void modificationWatchpoint(ModificationWatchpointEventSet e) { setThread(e); for (EventIterator it = e.eventIterator(); it.hasNext(); ) { Event evt = it.nextEvent(); diagnostics.putString("Watchpoint hit: " + locationString(e)); } } public void threadDeath(ThreadDeathEventSet e) { if (context.getVerboseFlag()) { diagnostics.putString("Thread " + e.getThread() + " ended."); } } public void threadStart(ThreadStartEventSet e) { if (context.getVerboseFlag()) { diagnostics.putString("Thread " + e.getThread() + " started."); } } public void vmDeath(VMDeathEventSet e) { script.setPrompt(DEFAULT_CMD_PROMPT); diagnostics.putString("VM exited"); } public void vmDisconnect(VMDisconnectEventSet e) { script.setPrompt(DEFAULT_CMD_PROMPT); diagnostics.putString("Disconnected from VM"); } public void vmStart(VMStartEventSet e) { script.setPrompt(DEFAULT_CMD_PROMPT); diagnostics.putString("VM started"); } // SessionListener public void sessionStart(EventObject e) {} public void sessionInterrupt(EventObject e) { Thread.yield(); // fetch output diagnostics.putString("VM interrupted by user."); script.setPrompt(DEFAULT_CMD_PROMPT); } public void sessionContinue(EventObject e) { diagnostics.putString("Execution resumed."); script.setPrompt(DEFAULT_CMD_PROMPT); } // SpecListener public void breakpointSet(SpecEvent e) { EventRequestSpec spec = e.getEventRequestSpec(); diagnostics.putString("Breakpoint set at " + spec + "."); } public void breakpointDeferred(SpecEvent e) { EventRequestSpec spec = e.getEventRequestSpec(); diagnostics.putString("Breakpoint will be set at " + spec + " when its class is loaded."); } public void breakpointDeleted(SpecEvent e) { EventRequestSpec spec = e.getEventRequestSpec(); diagnostics.putString("Breakpoint at " + spec.toString() + " deleted."); } public void breakpointResolved(SpecEvent e) { EventRequestSpec spec = e.getEventRequestSpec(); diagnostics.putString("Breakpoint resolved to " + spec.toString() + "."); } public void breakpointError(SpecErrorEvent e) { EventRequestSpec spec = e.getEventRequestSpec(); diagnostics.putString("Deferred breakpoint at " + spec + " could not be resolved:" + e.getReason()); } //### Add info for watchpoints and exceptions public void watchpointSet(SpecEvent e) { } public void watchpointDeferred(SpecEvent e) { } public void watchpointDeleted(SpecEvent e) { } public void watchpointResolved(SpecEvent e) { } public void watchpointError(SpecErrorEvent e) { } public void exceptionInterceptSet(SpecEvent e) { } public void exceptionInterceptDeferred(SpecEvent e) { } public void exceptionInterceptDeleted(SpecEvent e) { } public void exceptionInterceptResolved(SpecEvent e) { } public void exceptionInterceptError(SpecErrorEvent e) { } // ContextListener. // If the user selects a new current thread or frame, update prompt. public void currentFrameChanged(CurrentFrameChangedEvent e) { // Update prompt only if affect thread is current. ThreadReference thread = e.getThread(); if (thread == context.getCurrentThread()) { script.setPrompt(promptString(thread, e.getIndex())); } } } private String locationString(LocatableEventSet e) { Location loc = e.getLocation(); return "thread=\"" + e.getThread().name() + "\", " + Utils.locationString(loc); } private void setThread(LocatableEventSet e) { if (!e.suspendedNone()) { Thread.yield(); // fetch output script.setPrompt(promptString(e.getThread(), 0)); //### Current thread should be set elsewhere, e.g., //### in ContextManager //### context.setCurrentThread(thread); } } private String promptString(ThreadReference thread, int frameIndex) { if (thread == null) { return DEFAULT_CMD_PROMPT; } else { // Frame indices are presented to user as indexed from 1. return (thread.name() + "[" + (frameIndex + 1) + "]:"); } } }