1 7 34 35 package com.sun.tools.example.debug.gui; 36 37 import java.io.*; 38 import java.util.*; 39 import java.util.List ; 41 import javax.swing.*; 42 import javax.swing.tree.*; 43 import javax.swing.event.*; 44 import java.awt.*; 45 import java.awt.event.*; 46 47 import com.sun.jdi.*; 48 import com.sun.tools.example.debug.event.*; 49 import com.sun.tools.example.debug.bdi.*; 50 51 55 public class ThreadTreeTool extends JPanel { 56 57 private Environment env; 58 59 private ExecutionManager runtime; 60 private SourceManager sourceManager; 61 private ClassManager classManager; 62 63 private JTree tree; 64 private DefaultTreeModel treeModel; 65 private ThreadTreeNode root; 66 private SearchPath sourcePath; 67 68 private CommandInterpreter interpreter; 69 70 private static String HEADING = "THREADS"; 71 72 public ThreadTreeTool(Environment env) { 73 74 super(new BorderLayout()); 75 76 this.env = env; 77 this.runtime = env.getExecutionManager(); 78 this.sourceManager = env.getSourceManager(); 79 80 this.interpreter = new CommandInterpreter(env); 81 82 root = createThreadTree(HEADING); 83 treeModel = new DefaultTreeModel(root); 84 85 87 tree = new JTree(treeModel); 88 tree.setSelectionModel(new SingleLeafTreeSelectionModel()); 89 90 MouseListener ml = new MouseAdapter() { 91 public void mouseClicked(MouseEvent e) { 92 int selRow = tree.getRowForLocation(e.getX(), e.getY()); 93 TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); 94 if(selRow != -1) { 95 if(e.getClickCount() == 1) { 96 ThreadTreeNode node = 97 (ThreadTreeNode)selPath.getLastPathComponent(); 98 if (node.isLeaf()) { 100 tree.setSelectionPath(selPath); 101 interpreter.executeCommand("thread " + 102 node.getThreadId() + 103 " (\"" + 104 node.getName() + "\")"); 105 } 106 } 107 } 108 } 109 }; 110 111 tree.addMouseListener(ml); 112 113 JScrollPane treeView = new JScrollPane(tree); 114 add(treeView); 115 116 ThreadTreeToolListener listener = new ThreadTreeToolListener(); 118 runtime.addJDIListener(listener); 119 runtime.addSessionListener(listener); 120 121 } 123 124 HashMap threadTable = new HashMap(); 125 126 private List threadPath(ThreadReference thread) { 127 List l = new ArrayList(); 129 l.add(0, thread.name()); 130 ThreadGroupReference group = thread.threadGroup(); 131 while (group != null) { 132 l.add(0, group.name()); 133 group = group.parent(); 134 } 135 return l; 136 } 137 138 private class ThreadTreeToolListener extends JDIAdapter 139 implements JDIListener, SessionListener { 140 141 143 public void sessionStart(EventObject e) { 144 try { 145 Iterator iter = runtime.allThreads().iterator(); 146 while (iter.hasNext()) { 147 ThreadReference thread = ((ThreadReference)iter.next()); 148 root.addThread(thread); 149 } 150 } catch (VMDisconnectedException ee) { 151 } catch (NoSessionException ee) { 153 } 155 } 156 157 public void sessionInterrupt(EventObject e) {} 158 public void sessionContinue(EventObject e) {} 159 160 161 163 public void threadStart(ThreadStartEventSet e) { 164 root.addThread(e.getThread()); 165 } 166 167 public void threadDeath(ThreadDeathEventSet e) { 168 root.removeThread(e.getThread()); 169 } 170 171 public void vmDisconnect(VMDisconnectEventSet e) { 172 root = createThreadTree(HEADING); 174 treeModel = new DefaultTreeModel(root); 175 tree.setModel(treeModel); 176 threadTable = new HashMap(); 177 } 178 179 } 180 181 ThreadTreeNode createThreadTree(String label) { 182 return new ThreadTreeNode(label, null); 183 } 184 185 class ThreadTreeNode extends DefaultMutableTreeNode { 186 187 String name; 188 ThreadReference thread; long uid; 190 String description; 191 192 ThreadTreeNode(String name, ThreadReference thread) { 193 if (name == null) { 194 name = "<unnamed>"; 195 } 196 this.name = name; 197 this.thread = thread; 198 if (thread == null) { 199 this.uid = -1; 200 this.description = name; 201 } else { 202 this.uid = thread.uniqueID(); 203 this.description = name + " (t@" + Long.toHexString(uid) + ")"; 204 } 205 } 206 207 public String toString() { 208 return description; 209 } 210 211 public String getName() { 212 return name; 213 } 214 215 public ThreadReference getThread() { 216 return thread; 217 } 218 219 public String getThreadId() { 220 return "t@" + Long.toHexString(uid); 221 } 222 223 private boolean isThreadGroup() { 224 return (thread == null); 225 } 226 227 public boolean isLeaf() { 228 return !isThreadGroup(); 229 } 230 231 public void addThread(ThreadReference thread) { 232 if (threadTable.get(thread) == null) { 237 try { 239 List path = threadPath(thread); 240 try { 244 threadTable.put(thread, path); 245 addThread(path, thread); 246 } catch (Throwable tt) { 247 throw new RuntimeException ("ThreadTree corrupted"); 249 } 250 } catch (VMDisconnectedException ee) { 251 } 253 } 254 } 255 256 private void addThread(List threadPath, ThreadReference thread) { 257 int size = threadPath.size(); 258 if (size == 0) { 259 return; 260 } else if (size == 1) { 261 String name = (String )threadPath.get(0); 262 insertNode(name, thread); 263 } else { 264 String head = (String )threadPath.get(0); 265 List tail = threadPath.subList(1, size); 266 ThreadTreeNode child = insertNode(head, null); 267 child.addThread(tail, thread); 268 } 269 } 270 271 private ThreadTreeNode insertNode(String name, ThreadReference thread) { 272 for (int i = 0; i < getChildCount(); i++) { 273 ThreadTreeNode child = (ThreadTreeNode)getChildAt(i); 274 int cmp = name.compareTo(child.getName()); 275 if (cmp == 0 && thread == null) { 276 return child; 278 } else if (cmp < 0) { 279 ThreadTreeNode newChild = new ThreadTreeNode(name, thread); 281 treeModel.insertNodeInto(newChild, this, i); 282 return newChild; 283 } 284 } 285 ThreadTreeNode newChild = new ThreadTreeNode(name, thread); 287 treeModel.insertNodeInto(newChild, this, getChildCount()); 288 return newChild; 289 } 290 291 public void removeThread(ThreadReference thread) { 292 List threadPath = (List )threadTable.get(thread); 293 if (threadPath != null) { 296 removeThread(threadPath, thread); 297 } 298 } 299 300 private void removeThread(List threadPath, ThreadReference thread) { 301 int size = threadPath.size(); 302 if (size == 0) { 303 return; 304 } else if (size == 1) { 305 String name = (String )threadPath.get(0); 306 ThreadTreeNode child = findLeafNode(thread, name); 307 treeModel.removeNodeFromParent(child); 308 } else { 309 String head = (String )threadPath.get(0); 310 List tail = threadPath.subList(1, size); 311 ThreadTreeNode child = findInternalNode(head); 312 child.removeThread(tail, thread); 313 if (child.isThreadGroup() && child.getChildCount() < 1) { 314 treeModel.removeNodeFromParent(child); 316 } 317 } 318 } 319 320 private ThreadTreeNode findLeafNode(ThreadReference thread, String name) { 321 for (int i = 0; i < getChildCount(); i++) { 322 ThreadTreeNode child = (ThreadTreeNode)getChildAt(i); 323 if (child.getThread() == thread) { 324 if (!name.equals(child.getName())) { 325 throw new RuntimeException ("name mismatch"); 327 } 328 return child; 329 } 330 } 331 throw new RuntimeException ("not found"); 333 } 334 335 private ThreadTreeNode findInternalNode(String name) { 336 for (int i = 0; i < getChildCount(); i++) { 337 ThreadTreeNode child = (ThreadTreeNode)getChildAt(i); 338 if (name.equals(child.getName())) { 339 return child; 340 } 341 } 342 throw new RuntimeException ("not found"); 344 } 345 346 } 347 348 } 349 | Popular Tags |