0N/A/*
2362N/A * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.tools.jconsole;
0N/A
0N/Aimport java.awt.BorderLayout;
32N/Aimport java.awt.EventQueue;
0N/Aimport java.awt.event.MouseAdapter;
0N/Aimport java.awt.event.MouseEvent;
0N/Aimport java.awt.event.MouseListener;
0N/Aimport java.beans.*;
0N/Aimport java.io.*;
0N/Aimport java.util.Set;
0N/Aimport javax.management.*;
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.event.*;
0N/Aimport javax.swing.tree.*;
363N/Aimport sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection;
0N/Aimport sun.tools.jconsole.inspector.*;
0N/A
0N/Aimport com.sun.tools.jconsole.JConsoleContext;
0N/A
0N/A@SuppressWarnings("serial")
0N/Apublic class MBeansTab extends Tab implements
32N/A NotificationListener, PropertyChangeListener,
32N/A TreeSelectionListener, TreeWillExpandListener {
0N/A
0N/A private XTree tree;
0N/A private XSheet sheet;
0N/A private XDataViewer viewer;
0N/A
0N/A public static String getTabName() {
5335N/A return Messages.MBEANS;
0N/A }
0N/A
0N/A public MBeansTab(final VMPanel vmPanel) {
0N/A super(vmPanel, getTabName());
0N/A addPropertyChangeListener(this);
0N/A setupTab();
0N/A }
0N/A
0N/A public XDataViewer getDataViewer() {
0N/A return viewer;
0N/A }
0N/A
0N/A public XTree getTree() {
0N/A return tree;
0N/A }
0N/A
0N/A public XSheet getSheet() {
0N/A return sheet;
0N/A }
0N/A
32N/A @Override
0N/A public void dispose() {
0N/A super.dispose();
0N/A sheet.dispose();
0N/A }
0N/A
0N/A public int getUpdateInterval() {
0N/A return vmPanel.getUpdateInterval();
0N/A }
0N/A
32N/A private void buildMBeanServerView() {
32N/A new SwingWorker<Set<ObjectName>, Void>() {
32N/A @Override
32N/A public Set<ObjectName> doInBackground() {
32N/A // Register listener for MBean registration/unregistration
32N/A //
32N/A try {
32N/A getMBeanServerConnection().addNotificationListener(
32N/A MBeanServerDelegate.DELEGATE_NAME,
32N/A MBeansTab.this,
32N/A null,
32N/A null);
32N/A } catch (InstanceNotFoundException e) {
32N/A // Should never happen because the MBeanServerDelegate
32N/A // is always present in any standard MBeanServer
32N/A //
32N/A if (JConsole.isDebug()) {
32N/A e.printStackTrace();
32N/A }
32N/A } catch (IOException e) {
32N/A if (JConsole.isDebug()) {
32N/A e.printStackTrace();
32N/A }
32N/A vmPanel.getProxyClient().markAsDead();
32N/A return null;
32N/A }
32N/A // Retrieve MBeans from MBeanServer
32N/A //
32N/A Set<ObjectName> mbeans = null;
32N/A try {
32N/A mbeans = getMBeanServerConnection().queryNames(null, null);
32N/A } catch (IOException e) {
32N/A if (JConsole.isDebug()) {
32N/A e.printStackTrace();
32N/A }
32N/A vmPanel.getProxyClient().markAsDead();
32N/A return null;
32N/A }
32N/A return mbeans;
0N/A }
32N/A @Override
32N/A protected void done() {
32N/A try {
32N/A // Wait for mbsc.queryNames() result
32N/A Set<ObjectName> mbeans = get();
32N/A // Do not display anything until the new tree has been built
32N/A //
32N/A tree.setVisible(false);
32N/A // Cleanup current tree
32N/A //
32N/A tree.removeAll();
32N/A // Add MBeans to tree
32N/A //
32N/A tree.addMBeansToView(mbeans);
32N/A // Display the new tree
32N/A //
32N/A tree.setVisible(true);
32N/A } catch (Exception e) {
32N/A Throwable t = Utils.getActualException(e);
32N/A if (JConsole.isDebug()) {
32N/A System.err.println("Problem at MBean tree construction");
32N/A t.printStackTrace();
32N/A }
32N/A }
0N/A }
32N/A }.execute();
0N/A }
0N/A
0N/A public MBeanServerConnection getMBeanServerConnection() {
0N/A return vmPanel.getProxyClient().getMBeanServerConnection();
0N/A }
0N/A
363N/A public SnapshotMBeanServerConnection getSnapshotMBeanServerConnection() {
363N/A return vmPanel.getProxyClient().getSnapshotMBeanServerConnection();
363N/A }
363N/A
32N/A @Override
0N/A public void update() {
0N/A // Ping the connection to see if it is still alive. At
0N/A // some point the ProxyClient class should centralize
0N/A // the connection aliveness monitoring and no longer
0N/A // rely on the custom tabs to ping the connections.
0N/A //
0N/A try {
0N/A getMBeanServerConnection().getDefaultDomain();
0N/A } catch (IOException ex) {
0N/A vmPanel.getProxyClient().markAsDead();
0N/A }
0N/A }
0N/A
0N/A private void setupTab() {
0N/A // set up the split pane with the MBean tree and MBean sheet panels
0N/A setLayout(new BorderLayout());
0N/A JSplitPane mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
0N/A mainSplit.setDividerLocation(160);
0N/A mainSplit.setBorder(BorderFactory.createEmptyBorder());
0N/A
0N/A // set up the MBean tree panel (left pane)
0N/A tree = new XTree(this);
0N/A tree.setCellRenderer(new XTreeRenderer());
0N/A tree.getSelectionModel().setSelectionMode(
0N/A TreeSelectionModel.SINGLE_TREE_SELECTION);
0N/A tree.addTreeSelectionListener(this);
32N/A tree.addTreeWillExpandListener(this);
0N/A tree.addMouseListener(ml);
0N/A JScrollPane theScrollPane = new JScrollPane(
0N/A tree,
0N/A JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
0N/A JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
0N/A JPanel treePanel = new JPanel(new BorderLayout());
0N/A treePanel.add(theScrollPane, BorderLayout.CENTER);
0N/A mainSplit.add(treePanel, JSplitPane.LEFT, 0);
0N/A
0N/A // set up the MBean sheet panel (right pane)
0N/A viewer = new XDataViewer(this);
0N/A sheet = new XSheet(this);
0N/A mainSplit.add(sheet, JSplitPane.RIGHT, 0);
0N/A
0N/A add(mainSplit);
0N/A }
0N/A
32N/A /* notification listener: handleNotification */
32N/A public void handleNotification(
32N/A final Notification notification, Object handback) {
32N/A EventQueue.invokeLater(new Runnable() {
32N/A public void run() {
32N/A if (notification instanceof MBeanServerNotification) {
32N/A ObjectName mbean =
32N/A ((MBeanServerNotification) notification).getMBeanName();
32N/A if (notification.getType().equals(
32N/A MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
32N/A tree.addMBeanToView(mbean);
32N/A } else if (notification.getType().equals(
32N/A MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
32N/A tree.removeMBeanFromView(mbean);
32N/A }
32N/A }
32N/A }
32N/A });
32N/A }
32N/A
32N/A /* property change listener: propertyChange */
32N/A public void propertyChange(PropertyChangeEvent evt) {
32N/A if (JConsoleContext.CONNECTION_STATE_PROPERTY.equals(evt.getPropertyName())) {
32N/A boolean connected = (Boolean) evt.getNewValue();
32N/A if (connected) {
32N/A buildMBeanServerView();
32N/A } else {
32N/A sheet.dispose();
0N/A }
0N/A }
0N/A }
0N/A
32N/A /* tree selection listener: valueChanged */
0N/A public void valueChanged(TreeSelectionEvent e) {
0N/A DefaultMutableTreeNode node =
0N/A (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
0N/A sheet.displayNode(node);
0N/A }
32N/A /* tree mouse listener: mousePressed */
0N/A private MouseListener ml = new MouseAdapter() {
32N/A @Override
0N/A public void mousePressed(MouseEvent e) {
0N/A if (e.getClickCount() == 1) {
0N/A int selRow = tree.getRowForLocation(e.getX(), e.getY());
0N/A if (selRow != -1) {
0N/A TreePath selPath =
0N/A tree.getPathForLocation(e.getX(), e.getY());
32N/A DefaultMutableTreeNode node =
32N/A (DefaultMutableTreeNode) selPath.getLastPathComponent();
0N/A if (sheet.isMBeanNode(node)) {
0N/A tree.expandPath(selPath);
0N/A }
0N/A }
0N/A }
0N/A }
0N/A };
32N/A
32N/A /* tree will expand listener: treeWillExpand */
32N/A public void treeWillExpand(TreeExpansionEvent e)
32N/A throws ExpandVetoException {
32N/A TreePath path = e.getPath();
32N/A if (!tree.hasBeenExpanded(path)) {
32N/A DefaultMutableTreeNode node =
32N/A (DefaultMutableTreeNode) path.getLastPathComponent();
32N/A if (sheet.isMBeanNode(node) && !tree.hasMetadataNodes(node)) {
32N/A tree.addMetadataNodes(node);
32N/A }
32N/A }
32N/A }
32N/A
32N/A /* tree will expand listener: treeWillCollapse */
32N/A public void treeWillCollapse(TreeExpansionEvent e)
32N/A throws ExpandVetoException {
32N/A }
0N/A}