1 /* 2 * Copyright (c) 2004, 2008, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.BorderLayout; 29 import java.awt.EventQueue; 30 import java.awt.event.MouseAdapter; 31 import java.awt.event.MouseEvent; 32 import java.awt.event.MouseListener; 33 import java.beans.*; 34 import java.io.*; 35 import java.util.Set; 36 import javax.management.*; 37 import javax.swing.*; 38 import javax.swing.event.*; 39 import javax.swing.tree.*; 40 import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection; 41 import sun.tools.jconsole.inspector.*; 42 43 import com.sun.tools.jconsole.JConsoleContext; 44 45 @SuppressWarnings("serial") 46 public class MBeansTab extends Tab implements 47 NotificationListener, PropertyChangeListener, 48 TreeSelectionListener, TreeWillExpandListener { 49 50 private XTree tree; 51 private XSheet sheet; 52 private XDataViewer viewer; 53 54 public static String getTabName() { 55 return Resources.getText("MBeans"); 56 } 57 58 public MBeansTab(final VMPanel vmPanel) { 59 super(vmPanel, getTabName()); 60 addPropertyChangeListener(this); 61 setupTab(); 62 } 63 64 public XDataViewer getDataViewer() { 65 return viewer; 66 } 67 68 public XTree getTree() { 69 return tree; 70 } 71 72 public XSheet getSheet() { 73 return sheet; 74 } 75 76 @Override 77 public void dispose() { 78 super.dispose(); 79 sheet.dispose(); 80 } 81 82 public int getUpdateInterval() { 83 return vmPanel.getUpdateInterval(); 84 } 85 86 private void buildMBeanServerView() { 87 new SwingWorker<Set<ObjectName>, Void>() { 88 @Override 89 public Set<ObjectName> doInBackground() { 90 // Register listener for MBean registration/unregistration 91 // 92 try { 93 getMBeanServerConnection().addNotificationListener( 94 MBeanServerDelegate.DELEGATE_NAME, 95 MBeansTab.this, 96 null, 97 null); 98 } catch (InstanceNotFoundException e) { 99 // Should never happen because the MBeanServerDelegate 100 // is always present in any standard MBeanServer 101 // 102 if (JConsole.isDebug()) { 103 e.printStackTrace(); 104 } 105 } catch (IOException e) { 106 if (JConsole.isDebug()) { 107 e.printStackTrace(); 108 } 109 vmPanel.getProxyClient().markAsDead(); 110 return null; 111 } 112 // Retrieve MBeans from MBeanServer 113 // 114 Set<ObjectName> mbeans = null; 115 try { 116 mbeans = getMBeanServerConnection().queryNames(null, null); 117 } catch (IOException e) { 118 if (JConsole.isDebug()) { 119 e.printStackTrace(); 120 } 121 vmPanel.getProxyClient().markAsDead(); 122 return null; 123 } 124 return mbeans; 125 } 126 @Override 127 protected void done() { 128 try { 129 // Wait for mbsc.queryNames() result 130 Set<ObjectName> mbeans = get(); 131 // Do not display anything until the new tree has been built 132 // 133 tree.setVisible(false); 134 // Cleanup current tree 135 // 136 tree.removeAll(); 137 // Add MBeans to tree 138 // 139 tree.addMBeansToView(mbeans); 140 // Display the new tree 141 // 142 tree.setVisible(true); 143 } catch (Exception e) { 144 Throwable t = Utils.getActualException(e); 145 if (JConsole.isDebug()) { 146 System.err.println("Problem at MBean tree construction"); 147 t.printStackTrace(); 148 } 149 } 150 } 151 }.execute(); 152 } 153 154 public MBeanServerConnection getMBeanServerConnection() { 155 return vmPanel.getProxyClient().getMBeanServerConnection(); 156 } 157 158 public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() { 159 return vmPanel.getProxyClient().getSnapshotMBeanServerConnection(); 160 } 161 162 @Override 163 public void update() { 164 // Ping the connection to see if it is still alive. At 165 // some point the ProxyClient class should centralize 166 // the connection aliveness monitoring and no longer 167 // rely on the custom tabs to ping the connections. 168 // 169 try { 170 getMBeanServerConnection().getDefaultDomain(); 171 } catch (IOException ex) { 172 vmPanel.getProxyClient().markAsDead(); 173 } 174 } 175 176 private void setupTab() { 177 // set up the split pane with the MBean tree and MBean sheet panels 178 setLayout(new BorderLayout()); 179 JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 180 mainSplit.setDividerLocation(160); 181 mainSplit.setBorder(BorderFactory.createEmptyBorder()); 182 183 // set up the MBean tree panel (left pane) 184 tree = new XTree(this); 185 tree.setCellRenderer(new XTreeRenderer()); 186 tree.getSelectionModel().setSelectionMode( 187 TreeSelectionModel.SINGLE_TREE_SELECTION); 188 tree.addTreeSelectionListener(this); 189 tree.addTreeWillExpandListener(this); 190 tree.addMouseListener(ml); 191 JScrollPane theScrollPane = new JScrollPane( 192 tree, 193 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 194 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 195 JPanel treePanel = new JPanel(new BorderLayout()); 196 treePanel.add(theScrollPane, BorderLayout.CENTER); 197 mainSplit.add(treePanel, JSplitPane.LEFT, 0); 198 199 // set up the MBean sheet panel (right pane) 200 viewer = new XDataViewer(this); 201 sheet = new XSheet(this); 202 mainSplit.add(sheet, JSplitPane.RIGHT, 0); 203 204 add(mainSplit); 205 } 206 207 /* notification listener: handleNotification */ 208 public void handleNotification( 209 final Notification notification, Object handback) { 210 EventQueue.invokeLater(new Runnable() { 211 public void run() { 212 if (notification instanceof MBeanServerNotification) { 213 ObjectName mbean = 214 ((MBeanServerNotification) notification).getMBeanName(); 215 if (notification.getType().equals( 216 MBeanServerNotification.REGISTRATION_NOTIFICATION)) { 217 tree.addMBeanToView(mbean); 218 } else if (notification.getType().equals( 219 MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { 220 tree.removeMBeanFromView(mbean); 221 } 222 } 223 } 224 }); 225 } 226 227 /* property change listener: propertyChange */ 228 public void propertyChange(PropertyChangeEvent evt) { 229 if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { 230 boolean connected = (Boolean) evt.getNewValue(); 231 if (connected) { 232 buildMBeanServerView(); 233 } else { 234 sheet.dispose(); 235 } 236 } 237 } 238 239 /* tree selection listener: valueChanged */ 240 public void valueChanged(TreeSelectionEvent e) { 241 DefaultMutableTreeNode node = 242 (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); 243 sheet.displayNode(node); 244 } 245 /* tree mouse listener: mousePressed */ 246 private MouseListener ml = new MouseAdapter() { 247 @Override 248 public void mousePressed(MouseEvent e) { 249 if (e.getClickCount() == 1) { 250 int selRow = tree.getRowForLocation(e.getX(), e.getY()); 251 if (selRow != -1) { 252 TreePath selPath = 253 tree.getPathForLocation(e.getX(), e.getY()); 254 DefaultMutableTreeNode node = 255 (DefaultMutableTreeNode) selPath.getLastPathComponent(); 256 if (sheet.isMBeanNode(node)) { 257 tree.expandPath(selPath); 258 } 259 } 260 } 261 } 262 }; 263 264 /* tree will expand listener: treeWillExpand */ 265 public void treeWillExpand(TreeExpansionEvent e) 266 throws ExpandVetoException { 267 TreePath path = e.getPath(); 268 if (!tree.hasBeenExpanded(path)) { 269 DefaultMutableTreeNode node = 270 (DefaultMutableTreeNode) path.getLastPathComponent(); 271 if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) { 272 tree.addMetadataNodes(node); 273 } 274 } 275 } 276 277 /* tree will expand listener: treeWillCollapse */ 278 public void treeWillCollapse(TreeExpansionEvent e) 279 throws ExpandVetoException { 280 } 281 }