commandinterpreter.java
来自「jpda例子文件」· Java 代码 · 共 1,488 行 · 第 1/4 页
JAVA
1,488 行
/* * @(#)CommandInterpreter.java 1.22 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Copyright (c) 1997-1999 by Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */package com.sun.tools.example.debug.gui;import java.io.*;import java.util.*;import com.sun.jdi.*;import com.sun.jdi.request.*;import com.sun.tools.example.debug.bdi.*;public class CommandInterpreter { boolean echo; Environment env; private ContextManager context; private ExecutionManager runtime; private ClassManager classManager; private SourceManager sourceManager; private OutputSink out; //### Hack! Should be local in each method used. private String lastCommand = "help"; public CommandInterpreter(Environment env) { this(env, true); } public CommandInterpreter(Environment env, boolean echo) { this.env = env; this.echo = echo; this.runtime = env.getExecutionManager(); this.context = env.getContextManager(); this.classManager = env.getClassManager(); this.sourceManager = env.getSourceManager(); } private ThreadReference[] threads = null; /* * The numbering of threads is relative to the current set of threads, * and may be affected by the creation and termination of new threads. * Commands issued using such thread ids will only give reliable behavior * relative to what was shown earlier in 'list' commands if the VM is interrupted. * We need a better scheme. */ private ThreadReference[] threads() throws NoSessionException { if (threads == null) { ThreadIterator ti = new ThreadIterator(getDefaultThreadGroup()); List tlist = new ArrayList(); while (ti.hasNext()) { tlist.add(ti.nextThread()); } threads = (ThreadReference[])tlist.toArray(new ThreadReference[tlist.size()]); } return threads; } private ThreadReference findThread(String idToken) throws NoSessionException { String id; ThreadReference thread = null; if (idToken.startsWith("t@")) { id = idToken.substring(2); } else { id = idToken; } try { ThreadReference[] threads = threads(); long threadID = Long.parseLong(id, 16); for (int i = 0; i < threads.length; i++) { if (threads[i].uniqueID() == threadID) { thread = threads[i]; break; } } if (thread == null) { //env.failure("No thread for id \"" + idToken + "\""); env.failure("\"" + idToken + "\" is not a valid thread id."); } } catch (NumberFormatException e) { env.error("Thread id \"" + idToken + "\" is ill-formed."); thread = null; } return thread; } private ThreadIterator allThreads() throws NoSessionException { threads = null; //### Why not use runtime.allThreads().iterator() ? return new ThreadIterator(runtime.topLevelThreadGroups()); } private ThreadIterator currentThreadGroupThreads() throws NoSessionException { threads = null; return new ThreadIterator(getDefaultThreadGroup()); } private ThreadGroupIterator allThreadGroups() throws NoSessionException { threads = null; return new ThreadGroupIterator(runtime.topLevelThreadGroups()); } private ThreadGroupReference defaultThreadGroup; private ThreadGroupReference getDefaultThreadGroup() throws NoSessionException { if (defaultThreadGroup == null) { defaultThreadGroup = runtime.systemThreadGroup(); } return defaultThreadGroup; } private void setDefaultThreadGroup(ThreadGroupReference tg) { defaultThreadGroup = tg; } /* * Command handlers. */ // Command: classes private void commandClasses() throws NoSessionException { List list = runtime.allClasses(); OutputSink out = env.getOutputSink(); //out.println("** classes list **"); for (int i = 0 ; i < list.size() ; i++) { ReferenceType refType = (ReferenceType)list.get(i); out.println(refType.name()); } out.show(); } // Command: methods private void commandMethods(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("No class specified."); return; } String idClass = t.nextToken(); ReferenceType cls = findClass(idClass); if (cls != null) { List methods = cls.allMethods(); OutputSink out = env.getOutputSink(); for (int i = 0; i < methods.size(); i++) { Method method = (Method)methods.get(i); out.print(method.declaringType().name() + " " + method.name() + "("); Iterator it = method.argumentTypeNames().iterator(); if (it.hasNext()) { while (true) { out.print((String)it.next()); if (!it.hasNext()) { break; } out.print(", "); } } out.println(")"); } out.show(); } else { //### Should validate class name syntax. env.failure("\"" + idClass + "\" is not a valid id or class name."); } } private ReferenceType findClass(String pattern) throws NoSessionException { List results = runtime.findClassesMatchingPattern(pattern); if (results.size() > 0) { //### Should handle multiple results sensibly. return (ReferenceType)results.get(0); } return null; } // Command: threads private void commandThreads(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { OutputSink out = env.getOutputSink(); printThreadGroup(out, getDefaultThreadGroup(), 0); out.show(); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { OutputSink out = env.getOutputSink(); printThreadGroup(out, tg, 0); out.show(); } } private ThreadGroupReference findThreadGroup(String name) throws NoSessionException { //### Issue: Uniqueness of thread group names is not enforced. ThreadGroupIterator tgi = allThreadGroups(); while (tgi.hasNext()) { ThreadGroupReference tg = tgi.nextThreadGroup(); if (tg.name().equals(name)) { return tg; } } return null; } private int printThreadGroup(OutputSink out, ThreadGroupReference tg, int iThread) { out.println("Group " + tg.name() + ":"); List tlist = tg.threads(); int maxId = 0; int maxName = 0; for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = (ThreadReference)tlist.get(i); int len = Utils.description(thr).length(); if (len > maxId) maxId = len; String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } if (name.length() > maxName) maxName = name.length(); } String maxNumString = String.valueOf(iThread + tlist.size()); int maxNumDigits = maxNumString.length(); for (int i = 0 ; i < tlist.size() ; i++) { ThreadReference thr = (ThreadReference)tlist.get(i); char buf[] = new char[80]; for (int j = 0; j < 79; j++) { buf[j] = ' '; } buf[79] = '\0'; StringBuffer sbOut = new StringBuffer(); sbOut.append(buf); // Right-justify the thread number at start of output string String numString = String.valueOf(iThread + i + 1); sbOut.insert(maxNumDigits - numString.length(), numString); sbOut.insert(maxNumDigits, "."); int iBuf = maxNumDigits + 2; sbOut.insert(iBuf, Utils.description(thr)); iBuf += maxId + 1; String name = thr.name(); int iDot = name.lastIndexOf('.'); if (iDot >= 0 && name.length() > iDot) { name = name.substring(iDot + 1); } sbOut.insert(iBuf, name); iBuf += maxName + 1; sbOut.insert(iBuf, Utils.getStatus(thr)); sbOut.setLength(79); out.println(sbOut.toString()); } List tglist = tg.threadGroups(); for (int ig = 0; ig < tglist.size(); ig++) { ThreadGroupReference tg0 = (ThreadGroupReference)tglist.get(ig); if (!tg.equals(tg0)) { // TODO ref mgt iThread += printThreadGroup(out, tg0, iThread + tlist.size()); } } return tlist.size(); } // Command: threadgroups private void commandThreadGroups() throws NoSessionException { ThreadGroupIterator it = allThreadGroups(); int cnt = 0; OutputSink out = env.getOutputSink(); while (it.hasNext()) { ThreadGroupReference tg = it.nextThreadGroup(); ++cnt; out.println("" + cnt + ". " + Utils.description(tg) + " " + tg.name()); } out.show(); } // Command: thread private void commandThread(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Thread number not specified."); return; } ThreadReference thread = findThread(t.nextToken()); if (thread != null) { //### Should notify user. context.setCurrentThread(thread); } } // Command: threadgroup private void commandThreadGroup(StringTokenizer t) throws NoSessionException { if (!t.hasMoreTokens()) { env.error("Threadgroup name not specified."); return; } String name = t.nextToken(); ThreadGroupReference tg = findThreadGroup(name); if (tg == null) { env.failure(name + " is not a valid threadgroup name."); } else { //### Should notify user. setDefaultThreadGroup(tg); } } // Command: run private void commandRun(StringTokenizer t) throws NoSessionException { if (doLoad(false, t)) { env.notice("Running ..."); } } // Command: load private void commandLoad(StringTokenizer t) throws NoSessionException { if (doLoad(true, t)) {} } private boolean doLoad(boolean suspended, StringTokenizer t) throws NoSessionException { String clname; if (!t.hasMoreTokens()) { clname = context.getMainClassName(); if (!clname.equals("")) { // Run from prevously-set class name.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?