blob: abd5de795d007976914d3c8bf538eebaaf385815 [file] [log] [blame]
/*
* Copyright (c) 2004, 2008, 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 Resources.getText("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 {
}
}