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.inspector;
  27 
  28 import java.awt.BorderLayout;
  29 import java.awt.Color;
  30 import java.awt.Component;
  31 import java.awt.GridLayout;
  32 import java.util.*;
  33 import javax.management.*;
  34 import javax.swing.*;
  35 import javax.swing.border.TitledBorder;
  36 import javax.swing.event.*;
  37 import javax.swing.table.*;
  38 import sun.tools.jconsole.Resources;
  39 
  40 import static sun.tools.jconsole.Utilities.*;
  41 
  42 @SuppressWarnings("serial")
  43 public class XMBeanInfo extends JPanel {
  44 
  45     private static final Color lightYellow = new Color(255, 255, 128);
  46     private final int NAME_COLUMN = 0;
  47     private final int VALUE_COLUMN = 1;
  48     private final String[] columnNames = {
  49         Resources.getText("Name"),
  50         Resources.getText("Value")
  51     };
  52     private JTable infoTable = new JTable();
  53     private JTable descTable = new JTable();
  54     private JPanel infoBorderPanel = new JPanel(new BorderLayout());
  55     private JPanel descBorderPanel = new JPanel(new BorderLayout());
  56 
  57     private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
  58 
  59         @Override
  60         public void setValueAt(Object value, int row, int col) {
  61         }
  62     }
  63 
  64     private static class TableRowDivider {
  65 
  66         private String tableRowDividerText;
  67 
  68         public TableRowDivider(String tableRowDividerText) {
  69             this.tableRowDividerText = tableRowDividerText;
  70         }
  71 
  72         @Override
  73         public String toString() {
  74             return tableRowDividerText;
  75         }
  76     }
  77     private static MBeanInfoTableCellRenderer renderer =
  78             new MBeanInfoTableCellRenderer();
  79 
  80     private static class MBeanInfoTableCellRenderer
  81             extends DefaultTableCellRenderer {
  82 
  83         @Override
  84         public Component getTableCellRendererComponent(
  85                 JTable table, Object value, boolean isSelected,
  86                 boolean hasFocus, int row, int column) {
  87             Component comp = super.getTableCellRendererComponent(
  88                     table, value, isSelected, hasFocus, row, column);
  89             if (value instanceof TableRowDivider) {
  90                 JLabel label = new JLabel(value.toString());
  91                 label.setBackground(ensureContrast(lightYellow,
  92                         label.getForeground()));
  93                 label.setOpaque(true);
  94                 return label;
  95             }
  96             return comp;
  97         }
  98     }
  99     private static TableCellEditor editor =
 100             new MBeanInfoTableCellEditor(new JTextField());
 101 
 102     private static class MBeanInfoTableCellEditor
 103             extends Utils.ReadOnlyTableCellEditor {
 104 
 105         public MBeanInfoTableCellEditor(JTextField tf) {
 106             super(tf);
 107         }
 108 
 109         @Override
 110         public Component getTableCellEditorComponent(
 111                 JTable table, Object value, boolean isSelected,
 112                 int row, int column) {
 113             Component comp = super.getTableCellEditorComponent(
 114                     table, value, isSelected, row, column);
 115             if (value instanceof TableRowDivider) {
 116                 JLabel label = new JLabel(value.toString());
 117                 label.setBackground(ensureContrast(lightYellow,
 118                         label.getForeground()));
 119                 label.setOpaque(true);
 120                 return label;
 121             }
 122             return comp;
 123         }
 124     }
 125 
 126     public XMBeanInfo() {
 127         // Use the grid layout to display the two tables
 128         //
 129         super(new GridLayout(2, 1));
 130         // MBean*Info table
 131         //
 132         infoTable.setModel(new ReadOnlyDefaultTableModel());
 133         infoTable.setRowSelectionAllowed(false);
 134         infoTable.setColumnSelectionAllowed(false);
 135         infoTable.getTableHeader().setReorderingAllowed(false);
 136         ((DefaultTableModel) infoTable.getModel()).setColumnIdentifiers(columnNames);
 137         infoTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140);
 138         infoTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140);
 139         infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer);
 140         infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer);
 141         infoTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor);
 142         infoTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor);
 143         infoTable.addKeyListener(new Utils.CopyKeyAdapter());
 144         infoTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
 145         JScrollPane infoTableScrollPane = new JScrollPane(infoTable);
 146         infoBorderPanel.setBorder(
 147                 BorderFactory.createTitledBorder("MBeanInfoPlaceHolder"));
 148         infoBorderPanel.add(infoTableScrollPane);
 149         // Descriptor table
 150         //
 151         descTable.setModel(new ReadOnlyDefaultTableModel());
 152         descTable.setRowSelectionAllowed(false);
 153         descTable.setColumnSelectionAllowed(false);
 154         descTable.getTableHeader().setReorderingAllowed(false);
 155         ((DefaultTableModel) descTable.getModel()).setColumnIdentifiers(columnNames);
 156         descTable.getColumnModel().getColumn(NAME_COLUMN).setPreferredWidth(140);
 157         descTable.getColumnModel().getColumn(NAME_COLUMN).setMaxWidth(140);
 158         descTable.getColumnModel().getColumn(NAME_COLUMN).setCellRenderer(renderer);
 159         descTable.getColumnModel().getColumn(VALUE_COLUMN).setCellRenderer(renderer);
 160         descTable.getColumnModel().getColumn(NAME_COLUMN).setCellEditor(editor);
 161         descTable.getColumnModel().getColumn(VALUE_COLUMN).setCellEditor(editor);
 162         descTable.addKeyListener(new Utils.CopyKeyAdapter());
 163         descTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
 164         JScrollPane descTableScrollPane = new JScrollPane(descTable);
 165         descBorderPanel.setBorder(
 166                 BorderFactory.createTitledBorder(Resources.getText("Descriptor")));
 167         descBorderPanel.add(descTableScrollPane);
 168         // Add the two tables to the grid
 169         //
 170         add(infoBorderPanel);
 171         add(descBorderPanel);
 172     }
 173 
 174     // Call on EDT
 175     public void emptyInfoTable() {
 176         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 177         while (tableModel.getRowCount() > 0) {
 178             tableModel.removeRow(0);
 179         }
 180     }
 181 
 182     // Call on EDT
 183     public void emptyDescTable() {
 184         DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
 185         while (tableModel.getRowCount() > 0) {
 186             tableModel.removeRow(0);
 187         }
 188     }
 189 
 190     // Call on EDT
 191     private void addDescriptor(Descriptor desc, String text) {
 192         if (desc != null && desc.getFieldNames().length > 0) {
 193             DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
 194             Object rowData[] = new Object[2];
 195             rowData[0] = new TableRowDivider(text);
 196             rowData[1] = new TableRowDivider("");
 197             tableModel.addRow(rowData);
 198             for (String fieldName : desc.getFieldNames()) {
 199                 rowData[0] = fieldName;
 200                 Object fieldValue = desc.getFieldValue(fieldName);
 201                 if (fieldValue instanceof boolean[]) {
 202                     rowData[1] = Arrays.toString((boolean[]) fieldValue);
 203                 } else if (fieldValue instanceof byte[]) {
 204                     rowData[1] = Arrays.toString((byte[]) fieldValue);
 205                 } else if (fieldValue instanceof char[]) {
 206                     rowData[1] = Arrays.toString((char[]) fieldValue);
 207                 } else if (fieldValue instanceof double[]) {
 208                     rowData[1] = Arrays.toString((double[]) fieldValue);
 209                 } else if (fieldValue instanceof float[]) {
 210                     rowData[1] = Arrays.toString((float[]) fieldValue);
 211                 } else if (fieldValue instanceof int[]) {
 212                     rowData[1] = Arrays.toString((int[]) fieldValue);
 213                 } else if (fieldValue instanceof long[]) {
 214                     rowData[1] = Arrays.toString((long[]) fieldValue);
 215                 } else if (fieldValue instanceof short[]) {
 216                     rowData[1] = Arrays.toString((short[]) fieldValue);
 217                 } else if (fieldValue instanceof Object[]) {
 218                     rowData[1] = Arrays.toString((Object[]) fieldValue);
 219                 } else {
 220                     rowData[1] = fieldValue;
 221                 }
 222                 tableModel.addRow(rowData);
 223             }
 224             tableModel.newDataAvailable(new TableModelEvent(tableModel));
 225         }
 226     }
 227 
 228     // Call on EDT
 229     public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
 230         emptyInfoTable();
 231         emptyDescTable();
 232         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
 233                 Resources.getText("MBeanInfo"));
 234         String text = Resources.getText("Info") + ":";
 235         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 236         Object rowData[] = new Object[2];
 237         rowData[0] = new TableRowDivider(text);
 238         rowData[1] = new TableRowDivider("");
 239         tableModel.addRow(rowData);
 240         rowData[0] = Resources.getText("ObjectName");
 241         rowData[1] = mbean.getObjectName();
 242         tableModel.addRow(rowData);
 243         rowData[0] = Resources.getText("ClassName");
 244         rowData[1] = mbeanInfo.getClassName();
 245         tableModel.addRow(rowData);
 246         rowData[0] = Resources.getText("Description");
 247         rowData[1] = mbeanInfo.getDescription();
 248         tableModel.addRow(rowData);
 249         addDescriptor(mbeanInfo.getDescriptor(), text);
 250         // MBeanConstructorInfo
 251         //
 252         int i = 0;
 253         for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) {
 254             addMBeanConstructorInfo(mbci,
 255                     Resources.getText("Constructor") + "-" + i + ":");
 256             // MBeanParameterInfo
 257             //
 258             int j = 0;
 259             for (MBeanParameterInfo mbpi : mbci.getSignature()) {
 260                 addMBeanParameterInfo(mbpi,
 261                         Resources.getText("Parameter") + "-" + i + "-" + j + ":");
 262                 j++;
 263             }
 264             i++;
 265         }
 266         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 267     }
 268 
 269     // Call on EDT
 270     public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
 271         emptyInfoTable();
 272         emptyDescTable();
 273         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
 274                 Resources.getText("MBeanAttributeInfo"));
 275         String text = Resources.getText("Attribute") + ":";
 276         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 277         Object rowData[] = new Object[2];
 278         rowData[0] = new TableRowDivider(text);
 279         rowData[1] = new TableRowDivider("");
 280         tableModel.addRow(rowData);
 281         rowData[0] = Resources.getText("Name");
 282         rowData[1] = mbai.getName();
 283         tableModel.addRow(rowData);
 284         rowData[0] = Resources.getText("Description");
 285         rowData[1] = mbai.getDescription();
 286         tableModel.addRow(rowData);
 287         rowData[0] = Resources.getText("Readable");
 288         rowData[1] = mbai.isReadable();
 289         tableModel.addRow(rowData);
 290         rowData[0] = Resources.getText("Writable");
 291         rowData[1] = mbai.isWritable();
 292         tableModel.addRow(rowData);
 293         rowData[0] = Resources.getText("Is");
 294         rowData[1] = mbai.isIs();
 295         tableModel.addRow(rowData);
 296         rowData[0] = Resources.getText("Type");
 297         rowData[1] = mbai.getType();
 298         tableModel.addRow(rowData);
 299         addDescriptor(mbai.getDescriptor(), text);
 300         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 301     }
 302 
 303     // Call on EDT
 304     public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
 305         emptyInfoTable();
 306         emptyDescTable();
 307         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
 308                 Resources.getText("MBeanOperationInfo"));
 309         String text = Resources.getText("Operation") + ":";
 310         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 311         Object rowData[] = new Object[2];
 312         rowData[0] = new TableRowDivider(text);
 313         rowData[1] = new TableRowDivider("");
 314         tableModel.addRow(rowData);
 315         rowData[0] = Resources.getText("Name");
 316         rowData[1] = mboi.getName();
 317         tableModel.addRow(rowData);
 318         rowData[0] = Resources.getText("Description");
 319         rowData[1] = mboi.getDescription();
 320         tableModel.addRow(rowData);
 321         rowData[0] = Resources.getText("Impact");
 322         switch (mboi.getImpact()) {
 323             case MBeanOperationInfo.INFO:
 324                 rowData[1] = Resources.getText("INFO");
 325                 break;
 326             case MBeanOperationInfo.ACTION:
 327                 rowData[1] = Resources.getText("ACTION");
 328                 break;
 329             case MBeanOperationInfo.ACTION_INFO:
 330                 rowData[1] = Resources.getText("ACTION_INFO");
 331                 break;
 332             case MBeanOperationInfo.UNKNOWN:
 333                 rowData[1] = Resources.getText("UNKNOWN");
 334                 break;
 335         }
 336         tableModel.addRow(rowData);
 337         rowData[0] = Resources.getText("ReturnType");
 338         rowData[1] = mboi.getReturnType();
 339         tableModel.addRow(rowData);
 340         addDescriptor(mboi.getDescriptor(), text);
 341         // MBeanParameterInfo
 342         //
 343         int i = 0;
 344         for (MBeanParameterInfo mbpi : mboi.getSignature()) {
 345             addMBeanParameterInfo(mbpi,
 346                     Resources.getText("Parameter") + "-" + i++ + ":");
 347         }
 348         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 349     }
 350 
 351     // Call on EDT
 352     public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
 353         emptyInfoTable();
 354         emptyDescTable();
 355         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
 356                 Resources.getText("MBeanNotificationInfo"));
 357         String text = Resources.getText("Notification") + ":";
 358         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 359         Object rowData[] = new Object[2];
 360         rowData[0] = new TableRowDivider(text);
 361         rowData[1] = new TableRowDivider("");
 362         tableModel.addRow(rowData);
 363         rowData[0] = Resources.getText("Name");
 364         rowData[1] = mbni.getName();
 365         tableModel.addRow(rowData);
 366         rowData[0] = Resources.getText("Description");
 367         rowData[1] = mbni.getDescription();
 368         tableModel.addRow(rowData);
 369         rowData[0] = Resources.getText("NotifTypes");
 370         rowData[1] = Arrays.toString(mbni.getNotifTypes());
 371         tableModel.addRow(rowData);
 372         addDescriptor(mbni.getDescriptor(), text);
 373         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 374     }
 375 
 376     // Call on EDT
 377     private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
 378         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 379         Object rowData[] = new Object[2];
 380         rowData[0] = new TableRowDivider(text);
 381         rowData[1] = new TableRowDivider("");
 382         tableModel.addRow(rowData);
 383         rowData[0] = Resources.getText("Name");
 384         rowData[1] = mbci.getName();
 385         tableModel.addRow(rowData);
 386         rowData[0] = Resources.getText("Description");
 387         rowData[1] = mbci.getDescription();
 388         tableModel.addRow(rowData);
 389         addDescriptor(mbci.getDescriptor(), text);
 390         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 391     }
 392 
 393     // Call on EDT
 394     private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
 395         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
 396         Object rowData[] = new Object[2];
 397         rowData[0] = new TableRowDivider(text);
 398         rowData[1] = new TableRowDivider("");
 399         tableModel.addRow(rowData);
 400         rowData[0] = Resources.getText("Name");
 401         rowData[1] = mbpi.getName();
 402         tableModel.addRow(rowData);
 403         rowData[0] = Resources.getText("Description");
 404         rowData[1] = mbpi.getDescription();
 405         tableModel.addRow(rowData);
 406         rowData[0] = Resources.getText("Type");
 407         rowData[1] = mbpi.getType();
 408         tableModel.addRow(rowData);
 409         addDescriptor(mbpi.getDescriptor(), text);
 410         tableModel.newDataAvailable(new TableModelEvent(tableModel));
 411     }
 412 }