blob: 5a87772f87cd00cee1ad03a296ce40f1d7d72f1b [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004-2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.tools.jconsole.inspector;
27
28import java.awt.BorderLayout;
29import java.awt.Color;
30import java.awt.Component;
31import java.awt.GridLayout;
32import java.util.*;
33import javax.management.*;
34import javax.swing.*;
35import javax.swing.border.TitledBorder;
36import javax.swing.event.*;
37import javax.swing.table.*;
38import javax.swing.tree.*;
39import sun.tools.jconsole.JConsole;
40import sun.tools.jconsole.Resources;
41import sun.tools.jconsole.inspector.XNodeInfo.Type;
42
43import static sun.tools.jconsole.Utilities.*;
44
45@SuppressWarnings("serial")
46public class XMBeanInfo extends JPanel {
47
48 private static final Color lightYellow = new Color(255, 255, 128);
49
50 private final int NAME_COLUMN = 0;
51 private final int VALUE_COLUMN = 1;
52
53 private final String[] columnNames = {
54 Resources.getText("Name"),
55 Resources.getText("Value")
56 };
57
58 private JTable infoTable = new JTable();
59 private JTable descTable = new JTable();
60 private JPanel infoBorderPanel = new JPanel(new BorderLayout());
61 private JPanel descBorderPanel = new JPanel(new BorderLayout());
62
63 private static class ReadOnlyDefaultTableModel extends DefaultTableModel {
64 public void setValueAt(Object value, int row, int col) {
65 }
66 }
67
68 private static class TableRowDivider {
69
70 private String tableRowDividerText;
71
72 public TableRowDivider(String tableRowDividerText) {
73 this.tableRowDividerText = tableRowDividerText;
74 }
75
76 public String toString() {
77 return tableRowDividerText;
78 }
79 }
80
81 private static MBeanInfoTableCellRenderer renderer =
82 new MBeanInfoTableCellRenderer();
83
84 private static class MBeanInfoTableCellRenderer
85 extends DefaultTableCellRenderer {
86
87 public Component getTableCellRendererComponent(
88 JTable table, Object value, boolean isSelected,
89 boolean hasFocus, int row, int column) {
90 Component comp = super.getTableCellRendererComponent(
91 table, value, isSelected, hasFocus, row, column);
92 if (value instanceof TableRowDivider) {
93 JLabel label = new JLabel(value.toString());
94 label.setBackground(ensureContrast(lightYellow,
95 label.getForeground()));
96 label.setOpaque(true);
97 return label;
98 }
99 return comp;
100 }
101 }
102
103 private static TableCellEditor editor =
104 new MBeanInfoTableCellEditor(new JTextField());
105
106 private static class MBeanInfoTableCellEditor
107 extends Utils.ReadOnlyTableCellEditor {
108 public MBeanInfoTableCellEditor(JTextField tf) {
109 super(tf);
110 }
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(Resources.getText("Descriptor")));
168 descBorderPanel.add(descTableScrollPane);
169 // Add the two tables to the grid
170 //
171 add(infoBorderPanel);
172 add(descBorderPanel);
173 }
174
175 public void emptyInfoTable() {
176 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
177 while (tableModel.getRowCount() > 0) {
178 tableModel.removeRow(0);
179 }
180 }
181
182 public void emptyDescTable() {
183 DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
184 while (tableModel.getRowCount() > 0) {
185 tableModel.removeRow(0);
186 }
187 }
188
189 private void addDescriptor(Descriptor desc, String text) {
190 if (desc != null && desc.getFieldNames().length > 0) {
191 DefaultTableModel tableModel = (DefaultTableModel) descTable.getModel();
192 Object rowData[] = new Object[2];
193 rowData[0] = new TableRowDivider(text);
194 rowData[1] = new TableRowDivider("");
195 tableModel.addRow(rowData);
196 for (String fieldName : desc.getFieldNames()) {
197 rowData[0] = fieldName;
198 Object fieldValue = desc.getFieldValue(fieldName);
199 if (fieldValue instanceof boolean[]) {
200 rowData[1] = Arrays.toString((boolean[]) fieldValue);
201 } else if (fieldValue instanceof byte[]) {
202 rowData[1] = Arrays.toString((byte[]) fieldValue);
203 } else if (fieldValue instanceof char[]) {
204 rowData[1] = Arrays.toString((char[]) fieldValue);
205 } else if (fieldValue instanceof double[]) {
206 rowData[1] = Arrays.toString((double[]) fieldValue);
207 } else if (fieldValue instanceof float[]) {
208 rowData[1] = Arrays.toString((float[]) fieldValue);
209 } else if (fieldValue instanceof int[]) {
210 rowData[1] = Arrays.toString((int[]) fieldValue);
211 } else if (fieldValue instanceof long[]) {
212 rowData[1] = Arrays.toString((long[]) fieldValue);
213 } else if (fieldValue instanceof short[]) {
214 rowData[1] = Arrays.toString((short[]) fieldValue);
215 } else if (fieldValue instanceof Object[]) {
216 rowData[1] = Arrays.toString((Object[]) fieldValue);
217 } else {
218 rowData[1] = fieldValue;
219 }
220 tableModel.addRow(rowData);
221 }
222 tableModel.newDataAvailable(new TableModelEvent(tableModel));
223 }
224 }
225
226 public void addMBeanInfo(XMBean mbean, MBeanInfo mbeanInfo) {
227 emptyInfoTable();
228 emptyDescTable();
229 ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
230 Resources.getText("MBeanInfo"));
231 String text = Resources.getText("Info") + ":";
232 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
233 Object rowData[] = new Object[2];
234 rowData[0] = new TableRowDivider(text);
235 rowData[1] = new TableRowDivider("");
236 tableModel.addRow(rowData);
237 rowData[0] = Resources.getText("ObjectName");
238 rowData[1] = mbean.getObjectName();
239 tableModel.addRow(rowData);
240 rowData[0] = Resources.getText("ClassName");
241 rowData[1] = mbeanInfo.getClassName();
242 tableModel.addRow(rowData);
243 rowData[0] = Resources.getText("Description");
244 rowData[1] = mbeanInfo.getDescription();
245 tableModel.addRow(rowData);
246 addDescriptor(mbeanInfo.getDescriptor(), text);
247 // MBeanConstructorInfo
248 //
249 int i = 0;
250 for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) {
251 addMBeanConstructorInfo(mbci,
252 Resources.getText("Constructor") + "-" + i + ":");
253 // MBeanParameterInfo
254 //
255 int j = 0;
256 for (MBeanParameterInfo mbpi : mbci.getSignature()) {
257 addMBeanParameterInfo(mbpi,
258 Resources.getText("Parameter") + "-" + i + "-" + j + ":");
259 j++;
260 }
261 i++;
262 }
263 tableModel.newDataAvailable(new TableModelEvent(tableModel));
264 }
265
266 public void addMBeanAttributeInfo(MBeanAttributeInfo mbai) {
267 emptyInfoTable();
268 emptyDescTable();
269 ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
270 Resources.getText("MBeanAttributeInfo"));
271 String text = Resources.getText("Attribute") + ":";
272 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
273 Object rowData[] = new Object[2];
274 rowData[0] = new TableRowDivider(text);
275 rowData[1] = new TableRowDivider("");
276 tableModel.addRow(rowData);
277 rowData[0] = Resources.getText("Name");
278 rowData[1] = mbai.getName();
279 tableModel.addRow(rowData);
280 rowData[0] = Resources.getText("Description");
281 rowData[1] = mbai.getDescription();
282 tableModel.addRow(rowData);
283 rowData[0] = Resources.getText("Readable");
284 rowData[1] = mbai.isReadable();
285 tableModel.addRow(rowData);
286 rowData[0] = Resources.getText("Writable");
287 rowData[1] = mbai.isWritable();
288 tableModel.addRow(rowData);
289 rowData[0] = Resources.getText("Is");
290 rowData[1] = mbai.isIs();
291 tableModel.addRow(rowData);
292 rowData[0] = Resources.getText("Type");
293 rowData[1] = mbai.getType();
294 tableModel.addRow(rowData);
295 addDescriptor(mbai.getDescriptor(), text);
296 tableModel.newDataAvailable(new TableModelEvent(tableModel));
297 }
298
299 public void addMBeanOperationInfo(MBeanOperationInfo mboi) {
300 emptyInfoTable();
301 emptyDescTable();
302 ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
303 Resources.getText("MBeanOperationInfo"));
304 String text = Resources.getText("Operation") + ":";
305 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
306 Object rowData[] = new Object[2];
307 rowData[0] = new TableRowDivider(text);
308 rowData[1] = new TableRowDivider("");
309 tableModel.addRow(rowData);
310 rowData[0] = Resources.getText("Name");
311 rowData[1] = mboi.getName();
312 tableModel.addRow(rowData);
313 rowData[0] = Resources.getText("Description");
314 rowData[1] = mboi.getDescription();
315 tableModel.addRow(rowData);
316 rowData[0] = Resources.getText("Impact");
317 switch (mboi.getImpact()) {
318 case MBeanOperationInfo.INFO:
319 rowData[1] = Resources.getText("INFO");
320 break;
321 case MBeanOperationInfo.ACTION:
322 rowData[1] = Resources.getText("ACTION");
323 break;
324 case MBeanOperationInfo.ACTION_INFO:
325 rowData[1] = Resources.getText("ACTION_INFO");
326 break;
327 case MBeanOperationInfo.UNKNOWN:
328 rowData[1] = Resources.getText("UNKNOWN");
329 break;
330 }
331 tableModel.addRow(rowData);
332 rowData[0] = Resources.getText("ReturnType");
333 rowData[1] = mboi.getReturnType();
334 tableModel.addRow(rowData);
335 addDescriptor(mboi.getDescriptor(), text);
336 // MBeanParameterInfo
337 //
338 int i = 0;
339 for (MBeanParameterInfo mbpi : mboi.getSignature()) {
340 addMBeanParameterInfo(mbpi,
341 Resources.getText("Parameter") + "-" + i++ + ":");
342 }
343 tableModel.newDataAvailable(new TableModelEvent(tableModel));
344 }
345
346 public void addMBeanNotificationInfo(MBeanNotificationInfo mbni) {
347 emptyInfoTable();
348 emptyDescTable();
349 ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
350 Resources.getText("MBeanNotificationInfo"));
351 String text = Resources.getText("Notification") + ":";
352 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
353 Object rowData[] = new Object[2];
354 rowData[0] = new TableRowDivider(text);
355 rowData[1] = new TableRowDivider("");
356 tableModel.addRow(rowData);
357 rowData[0] = Resources.getText("Name");
358 rowData[1] = mbni.getName();
359 tableModel.addRow(rowData);
360 rowData[0] = Resources.getText("Description");
361 rowData[1] = mbni.getDescription();
362 tableModel.addRow(rowData);
363 rowData[0] = Resources.getText("NotifTypes");
364 rowData[1] = Arrays.toString(mbni.getNotifTypes());
365 tableModel.addRow(rowData);
366 addDescriptor(mbni.getDescriptor(), text);
367 tableModel.newDataAvailable(new TableModelEvent(tableModel));
368 }
369
370 private void addMBeanConstructorInfo(MBeanConstructorInfo mbci, String text) {
371 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
372 Object rowData[] = new Object[2];
373 rowData[0] = new TableRowDivider(text);
374 rowData[1] = new TableRowDivider("");
375 tableModel.addRow(rowData);
376 rowData[0] = Resources.getText("Name");
377 rowData[1] = mbci.getName();
378 tableModel.addRow(rowData);
379 rowData[0] = Resources.getText("Description");
380 rowData[1] = mbci.getDescription();
381 tableModel.addRow(rowData);
382 addDescriptor(mbci.getDescriptor(), text);
383 tableModel.newDataAvailable(new TableModelEvent(tableModel));
384 }
385
386 private void addMBeanParameterInfo(MBeanParameterInfo mbpi, String text) {
387 DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
388 Object rowData[] = new Object[2];
389 rowData[0] = new TableRowDivider(text);
390 rowData[1] = new TableRowDivider("");
391 tableModel.addRow(rowData);
392 rowData[0] = Resources.getText("Name");
393 rowData[1] = mbpi.getName();
394 tableModel.addRow(rowData);
395 rowData[0] = Resources.getText("Description");
396 rowData[1] = mbpi.getDescription();
397 tableModel.addRow(rowData);
398 rowData[0] = Resources.getText("Type");
399 rowData[1] = mbpi.getType();
400 tableModel.addRow(rowData);
401 addDescriptor(mbpi.getDescriptor(), text);
402 tableModel.newDataAvailable(new TableModelEvent(tableModel));
403 }
404
405 public static void loadInfo(DefaultMutableTreeNode root) {
406 // Retrieve XMBean from XNodeInfo
407 //
408 XMBean mbean = (XMBean) ((XNodeInfo) root.getUserObject()).getData();
409 // Initialize MBean*Info
410 //
411 final MBeanInfo mbeanInfo;
412 try {
413 mbeanInfo = mbean.getMBeanInfo();
414 } catch (Exception e) {
415 if (JConsole.isDebug()) {
416 e.printStackTrace();
417 }
418 return;
419 }
420 MBeanAttributeInfo[] ai = mbeanInfo.getAttributes();
421 MBeanOperationInfo[] oi = mbeanInfo.getOperations();
422 MBeanNotificationInfo[] ni = mbeanInfo.getNotifications();
423 // MBeanAttributeInfo node
424 //
425 if (ai != null && ai.length > 0) {
426 DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
427 XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
428 Resources.getText("Attributes"), null);
429 attributes.setUserObject(attributesUO);
430 root.add(attributes);
431 for (MBeanAttributeInfo mbai : ai) {
432 DefaultMutableTreeNode attribute = new DefaultMutableTreeNode();
433 XNodeInfo attributeUO = new XNodeInfo(Type.ATTRIBUTE,
434 new Object[] {mbean, mbai}, mbai.getName(), null);
435 attribute.setUserObject(attributeUO);
436 attributes.add(attribute);
437 }
438 }
439 // MBeanOperationInfo node
440 //
441 if (oi != null && oi.length > 0) {
442 DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
443 XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
444 Resources.getText("Operations"), null);
445 operations.setUserObject(operationsUO);
446 root.add(operations);
447 for (MBeanOperationInfo mboi : oi) {
448 // Compute the operation's tool tip text:
449 // "operationname(param1type,param2type,...)"
450 //
451 StringBuilder sb = new StringBuilder();
452 for (MBeanParameterInfo mbpi : mboi.getSignature()) {
453 sb.append(mbpi.getType() + ",");
454 }
455 String signature = sb.toString();
456 if (signature.length() > 0) {
457 // Remove the trailing ','
458 //
459 signature = signature.substring(0, signature.length() - 1);
460 }
461 String toolTipText = mboi.getName() + "(" + signature + ")";
462 // Create operation node
463 //
464 DefaultMutableTreeNode operation = new DefaultMutableTreeNode();
465 XNodeInfo operationUO = new XNodeInfo(Type.OPERATION,
466 new Object[] {mbean, mboi}, mboi.getName(), toolTipText);
467 operation.setUserObject(operationUO);
468 operations.add(operation);
469 }
470 }
471 // MBeanNotificationInfo node
472 //
473 if (mbean.isBroadcaster()) {
474 DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
475 XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
476 Resources.getText("Notifications"), null);
477 notifications.setUserObject(notificationsUO);
478 root.add(notifications);
479 if (ni != null && ni.length > 0) {
480 for (MBeanNotificationInfo mbni : ni) {
481 DefaultMutableTreeNode notification =
482 new DefaultMutableTreeNode();
483 XNodeInfo notificationUO = new XNodeInfo(Type.NOTIFICATION,
484 mbni, mbni.getName(), null);
485 notification.setUserObject(notificationUO);
486 notifications.add(notification);
487 }
488 }
489 }
490 }
491}