| /* |
| * Copyright (c) 2004, 2012, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package sun.tools.jconsole; |
| |
| import java.awt.BorderLayout; |
| import java.awt.EventQueue; |
| import java.awt.event.MouseAdapter; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.MouseListener; |
| import java.beans.*; |
| import java.io.*; |
| import java.util.Set; |
| import javax.management.*; |
| import javax.swing.*; |
| import javax.swing.event.*; |
| import javax.swing.tree.*; |
| import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection; |
| import sun.tools.jconsole.inspector.*; |
| |
| import com.sun.tools.jconsole.JConsoleContext; |
| |
| @SuppressWarnings("serial") |
| public class MBeansTab extends Tab implements |
| NotificationListener, PropertyChangeListener, |
| TreeSelectionListener, TreeWillExpandListener { |
| |
| private XTree tree; |
| private XSheet sheet; |
| private XDataViewer viewer; |
| |
| public static String getTabName() { |
| return Messages.MBEANS; |
| } |
| |
| public MBeansTab(final VMPanel vmPanel) { |
| super(vmPanel, getTabName()); |
| addPropertyChangeListener(this); |
| setupTab(); |
| } |
| |
| public XDataViewer getDataViewer() { |
| return viewer; |
| } |
| |
| public XTree getTree() { |
| return tree; |
| } |
| |
| public XSheet getSheet() { |
| return sheet; |
| } |
| |
| @Override |
| public void dispose() { |
| super.dispose(); |
| sheet.dispose(); |
| } |
| |
| public int getUpdateInterval() { |
| return vmPanel.getUpdateInterval(); |
| } |
| |
| private void buildMBeanServerView() { |
| new SwingWorker<Set<ObjectName>, Void>() { |
| @Override |
| public Set<ObjectName> doInBackground() { |
| // Register listener for MBean registration/unregistration |
| // |
| try { |
| getMBeanServerConnection().addNotificationListener( |
| MBeanServerDelegate.DELEGATE_NAME, |
| MBeansTab.this, |
| null, |
| null); |
| } catch (InstanceNotFoundException e) { |
| // Should never happen because the MBeanServerDelegate |
| // is always present in any standard MBeanServer |
| // |
| if (JConsole.isDebug()) { |
| e.printStackTrace(); |
| } |
| } catch (IOException e) { |
| if (JConsole.isDebug()) { |
| e.printStackTrace(); |
| } |
| vmPanel.getProxyClient().markAsDead(); |
| return null; |
| } |
| // Retrieve MBeans from MBeanServer |
| // |
| Set<ObjectName> mbeans = null; |
| try { |
| mbeans = getMBeanServerConnection().queryNames(null, null); |
| } catch (IOException e) { |
| if (JConsole.isDebug()) { |
| e.printStackTrace(); |
| } |
| vmPanel.getProxyClient().markAsDead(); |
| return null; |
| } |
| return mbeans; |
| } |
| @Override |
| protected void done() { |
| try { |
| // Wait for mbsc.queryNames() result |
| Set<ObjectName> mbeans = get(); |
| // Do not display anything until the new tree has been built |
| // |
| tree.setVisible(false); |
| // Cleanup current tree |
| // |
| tree.removeAll(); |
| // Add MBeans to tree |
| // |
| tree.addMBeansToView(mbeans); |
| // Display the new tree |
| // |
| tree.setVisible(true); |
| } catch (Exception e) { |
| Throwable t = Utils.getActualException(e); |
| if (JConsole.isDebug()) { |
| System.err.println("Problem at MBean tree construction"); |
| t.printStackTrace(); |
| } |
| } |
| } |
| }.execute(); |
| } |
| |
| public MBeanServerConnection getMBeanServerConnection() { |
| return vmPanel.getProxyClient().getMBeanServerConnection(); |
| } |
| |
| public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() { |
| return vmPanel.getProxyClient().getSnapshotMBeanServerConnection(); |
| } |
| |
| @Override |
| public void update() { |
| // Ping the connection to see if it is still alive. At |
| // some point the ProxyClient class should centralize |
| // the connection aliveness monitoring and no longer |
| // rely on the custom tabs to ping the connections. |
| // |
| try { |
| getMBeanServerConnection().getDefaultDomain(); |
| } catch (IOException ex) { |
| vmPanel.getProxyClient().markAsDead(); |
| } |
| } |
| |
| private void setupTab() { |
| // set up the split pane with the MBean tree and MBean sheet panels |
| setLayout(new BorderLayout()); |
| JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); |
| mainSplit.setDividerLocation(160); |
| mainSplit.setBorder(BorderFactory.createEmptyBorder()); |
| |
| // set up the MBean tree panel (left pane) |
| tree = new XTree(this); |
| tree.setCellRenderer(new XTreeRenderer()); |
| tree.getSelectionModel().setSelectionMode( |
| TreeSelectionModel.SINGLE_TREE_SELECTION); |
| tree.addTreeSelectionListener(this); |
| tree.addTreeWillExpandListener(this); |
| tree.addMouseListener(ml); |
| JScrollPane theScrollPane = new JScrollPane( |
| tree, |
| JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, |
| JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); |
| JPanel treePanel = new JPanel(new BorderLayout()); |
| treePanel.add(theScrollPane, BorderLayout.CENTER); |
| mainSplit.add(treePanel, JSplitPane.LEFT, 0); |
| |
| // set up the MBean sheet panel (right pane) |
| viewer = new XDataViewer(this); |
| sheet = new XSheet(this); |
| mainSplit.add(sheet, JSplitPane.RIGHT, 0); |
| |
| add(mainSplit); |
| } |
| |
| /* notification listener: handleNotification */ |
| public void handleNotification( |
| final Notification notification, Object handback) { |
| EventQueue.invokeLater(new Runnable() { |
| public void run() { |
| if (notification instanceof MBeanServerNotification) { |
| ObjectName mbean = |
| ((MBeanServerNotification) notification).getMBeanName(); |
| if (notification.getType().equals( |
| MBeanServerNotification.REGISTRATION_NOTIFICATION)) { |
| tree.addMBeanToView(mbean); |
| } else if (notification.getType().equals( |
| MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { |
| tree.removeMBeanFromView(mbean); |
| } |
| } |
| } |
| }); |
| } |
| |
| /* property change listener: propertyChange */ |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) { |
| boolean connected = (Boolean) evt.getNewValue(); |
| if (connected) { |
| buildMBeanServerView(); |
| } else { |
| sheet.dispose(); |
| } |
| } |
| } |
| |
| /* tree selection listener: valueChanged */ |
| public void valueChanged(TreeSelectionEvent e) { |
| DefaultMutableTreeNode node = |
| (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); |
| sheet.displayNode(node); |
| } |
| /* tree mouse listener: mousePressed */ |
| private MouseListener ml = new MouseAdapter() { |
| @Override |
| public void mousePressed(MouseEvent e) { |
| if (e.getClickCount() == 1) { |
| int selRow = tree.getRowForLocation(e.getX(), e.getY()); |
| if (selRow != -1) { |
| TreePath selPath = |
| tree.getPathForLocation(e.getX(), e.getY()); |
| DefaultMutableTreeNode node = |
| (DefaultMutableTreeNode) selPath.getLastPathComponent(); |
| if (sheet.isMBeanNode(node)) { |
| tree.expandPath(selPath); |
| } |
| } |
| } |
| } |
| }; |
| |
| /* tree will expand listener: treeWillExpand */ |
| public void treeWillExpand(TreeExpansionEvent e) |
| throws ExpandVetoException { |
| TreePath path = e.getPath(); |
| if (!tree.hasBeenExpanded(path)) { |
| DefaultMutableTreeNode node = |
| (DefaultMutableTreeNode) path.getLastPathComponent(); |
| if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) { |
| tree.addMetadataNodes(node); |
| } |
| } |
| } |
| |
| /* tree will expand listener: treeWillCollapse */ |
| public void treeWillCollapse(TreeExpansionEvent e) |
| throws ExpandVetoException { |
| } |
| } |