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