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 javax.swing.*; 29 import java.awt.BorderLayout; 30 import java.awt.GridLayout; 31 import java.awt.FlowLayout; 32 import java.awt.Component; 33 import java.awt.event.*; 34 import java.util.*; 35 36 import javax.management.*; 37 38 import sun.tools.jconsole.MBeansTab; 39 import sun.tools.jconsole.JConsole; 40 import sun.tools.jconsole.resources.Messages; 41 42 @SuppressWarnings("serial") 43 public abstract class XOperations extends JPanel implements ActionListener { 44 45 public final static String OPERATION_INVOCATION_EVENT = 46 "jam.xoperations.invoke.result"; 47 private java.util.List<NotificationListener> notificationListenersList; 48 private Hashtable<JButton, OperationEntry> operationEntryTable; 49 private XMBean mbean; 50 private MBeanInfo mbeanInfo; 51 private MBeansTab mbeansTab; 52 53 public XOperations(MBeansTab mbeansTab) { 54 super(new GridLayout(1, 1)); 55 this.mbeansTab = mbeansTab; 56 operationEntryTable = new Hashtable<JButton, OperationEntry>(); 57 ArrayList<NotificationListener> l = 58 new ArrayList<NotificationListener>(1); 59 notificationListenersList = 60 Collections.synchronizedList(l); 61 } 62 63 // Call on EDT 64 public void removeOperations() { 65 removeAll(); 66 } 67 68 // Call on EDT 69 public void loadOperations(XMBean mbean, MBeanInfo mbeanInfo) { 70 this.mbean = mbean; 71 this.mbeanInfo = mbeanInfo; 72 // add operations information 73 MBeanOperationInfo operations[] = mbeanInfo.getOperations(); 74 invalidate(); 75 76 // remove listeners, if any 77 Component listeners[] = getComponents(); 78 for (int i = 0; i < listeners.length; i++) { 79 if (listeners[i] instanceof JButton) { 80 ((JButton) listeners[i]).removeActionListener(this); 81 } 82 } 83 84 removeAll(); 85 setLayout(new BorderLayout()); 86 87 JButton methodButton; 88 JLabel methodLabel; 89 JPanel innerPanelLeft, innerPanelRight; 90 JPanel outerPanelLeft, outerPanelRight; 91 outerPanelLeft = new JPanel(new GridLayout(operations.length, 1)); 92 outerPanelRight = new JPanel(new GridLayout(operations.length, 1)); 93 94 for (int i = 0; i < operations.length; i++) { 95 innerPanelLeft = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 96 innerPanelRight = new JPanel(new FlowLayout(FlowLayout.LEFT)); 97 String returnType = operations[i].getReturnType(); 98 if (returnType == null) { 99 methodLabel = new JLabel("null", JLabel.RIGHT); 100 if (JConsole.isDebug()) { 101 System.err.println( 102 "WARNING: The operation's return type " + 103 "shouldn't be \"null\". Check how the " + 104 "MBeanOperationInfo for the \"" + 105 operations[i].getName() + "\" operation has " + 106 "been defined in the MBean's implementation code."); 107 } 108 } else { 109 methodLabel = new JLabel( 110 Utils.getReadableClassName(returnType), JLabel.RIGHT); 111 } 112 innerPanelLeft.add(methodLabel); 113 if (methodLabel.getText().length() > 20) { 114 methodLabel.setText(methodLabel.getText(). 115 substring(methodLabel.getText(). 116 lastIndexOf(".") + 1, 117 methodLabel.getText().length())); 118 } 119 120 methodButton = new JButton(operations[i].getName()); 121 methodButton.setToolTipText(operations[i].getDescription()); 122 boolean callable = isCallable(operations[i].getSignature()); 123 if (callable) { 124 methodButton.addActionListener(this); 125 } else { 126 methodButton.setEnabled(false); 127 } 128 129 MBeanParameterInfo[] signature = operations[i].getSignature(); 130 OperationEntry paramEntry = new OperationEntry(operations[i], 131 callable, 132 methodButton, 133 this); 134 operationEntryTable.put(methodButton, paramEntry); 135 innerPanelRight.add(methodButton); 136 if (signature.length == 0) { 137 innerPanelRight.add(new JLabel("( )", JLabel.CENTER)); 138 } else { 139 innerPanelRight.add(paramEntry); 140 } 141 142 outerPanelLeft.add(innerPanelLeft, BorderLayout.WEST); 143 outerPanelRight.add(innerPanelRight, BorderLayout.CENTER); 144 } 145 add(outerPanelLeft, BorderLayout.WEST); 146 add(outerPanelRight, BorderLayout.CENTER); 147 validate(); 148 } 149 150 private boolean isCallable(MBeanParameterInfo[] signature) { 151 for (int i = 0; i < signature.length; i++) { 152 if (!Utils.isEditableType(signature[i].getType())) { 153 return false; 154 } 155 } 156 return true; 157 } 158 159 // Call on EDT 160 public void actionPerformed(final ActionEvent e) { 161 performInvokeRequest((JButton) e.getSource()); 162 } 163 164 void performInvokeRequest(final JButton button) { 165 final OperationEntry entryIf = operationEntryTable.get(button); 166 new SwingWorker<Object, Void>() { 167 @Override 168 public Object doInBackground() throws Exception { 169 return mbean.invoke(button.getText(), 170 entryIf.getParameters(), entryIf.getSignature()); 171 } 172 @Override 173 protected void done() { 174 try { 175 Object result = get(); 176 // sends result notification to upper level if 177 // there is a return value 178 if (entryIf.getReturnType() != null && 179 !entryIf.getReturnType().equals(Void.TYPE.getName()) && 180 !entryIf.getReturnType().equals(Void.class.getName())) { 181 fireChangedNotification(OPERATION_INVOCATION_EVENT, button, result); 182 } else { 183 new ThreadDialog( 184 button, 185 Messages.METHOD_SUCCESSFULLY_INVOKED, 186 Messages.INFO, 187 JOptionPane.INFORMATION_MESSAGE).run(); 188 } 189 } catch (Throwable t) { 190 t = Utils.getActualException(t); 191 if (JConsole.isDebug()) { 192 t.printStackTrace(); 193 } 194 new ThreadDialog( 195 button, 196 Messages.PROBLEM_INVOKING + " " + 197 button.getText() + " : " + t.toString(), 198 Messages.ERROR, 199 JOptionPane.ERROR_MESSAGE).run(); 200 } 201 } 202 }.execute(); 203 } 204 205 public void addOperationsListener(NotificationListener nl) { 206 notificationListenersList.add(nl); 207 } 208 209 public void removeOperationsListener(NotificationListener nl) { 210 notificationListenersList.remove(nl); 211 } 212 213 // Call on EDT 214 private void fireChangedNotification( 215 String type, Object source, Object handback) { 216 Notification n = new Notification(type, source, 0); 217 for (NotificationListener nl : notificationListenersList) { 218 nl.handleNotification(n, handback); 219 } 220 } 221 222 protected abstract MBeanOperationInfo[] updateOperations(MBeanOperationInfo[] operations); 223 }