1 22 package org.jboss.console.twiddle.command; 23 24 import java.io.PrintWriter ; 25 26 import java.util.List ; 27 import java.util.ArrayList ; 28 import java.util.HashMap ; 29 import java.util.HashSet ; 30 import java.util.Collections ; 31 32 import java.beans.PropertyEditor ; 33 34 import javax.management.ObjectName ; 35 import javax.management.MBeanInfo ; 36 import javax.management.MBeanOperationInfo ; 37 import javax.management.MBeanServerConnection ; 38 import javax.management.MBeanParameterInfo ; 39 40 import gnu.getopt.Getopt; 41 import gnu.getopt.LongOpt; 42 43 import org.jboss.util.Strings; 44 import org.jboss.util.propertyeditor.PropertyEditors; 45 46 53 public class InvokeCommand 54 extends MBeanServerCommand 55 { 56 public static final int QUERY_FIRST = 0; 57 public static final int QUERY_ALL = 1; 58 59 private int type = QUERY_FIRST; 60 61 private String query; 62 63 private String opName; 64 65 private List opArgs = new ArrayList (5); 67 public InvokeCommand() 68 { 69 super("invoke", "Invoke an operation on an MBean"); 70 } 71 72 public void displayHelp() 73 { 74 PrintWriter out = context.getWriter(); 75 76 out.println(desc); 77 out.println(); 78 out.println("usage: " + name + " [options] <query> <operation> (<arg>)*"); 79 out.println(); 80 out.println("options:"); 81 out.println(" -q, --query-type[=<type>] Treat object name as a query"); 82 out.println(" -- Stop processing options"); 83 out.println(); 84 out.println("query type:"); 85 out.println(" f[irst] Only invoke on the first matching name [default]"); 86 out.println(" a[ll] Invoke on all matching names"); 87 } 88 89 private void processArguments(final String [] args) 90 throws CommandException 91 { 92 log.debug("processing arguments: " + Strings.join(args, ",")); 93 94 if (args.length == 0) 95 { 96 throw new CommandException("Command requires arguments"); 97 } 98 99 String sopts = "-:q:"; 100 LongOpt[] lopts = 101 { 102 new LongOpt("query-type", LongOpt.OPTIONAL_ARGUMENT, null, 'q'), 103 }; 104 105 Getopt getopt = new Getopt(null, args, sopts, lopts); 106 getopt.setOpterr(false); 107 108 int code; 109 int argidx = 0; 110 111 while ((code = getopt.getopt()) != -1) 112 { 113 switch (code) 114 { 115 case ':': 116 throw new CommandException 117 ("Option requires an argument: " + args[getopt.getOptind() - 1]); 118 119 case '?': 120 throw new CommandException 121 ("Invalid (or ambiguous) option: " + args[getopt.getOptind() - 1]); 122 123 case 1: 125 { 126 String arg = getopt.getOptarg(); 127 128 switch (argidx++) 129 { 130 case 0: 131 query = arg; 132 log.debug("query: " + query); 133 break; 134 135 case 1: 136 opName = arg; 137 log.debug("operation name: " + opName); 138 break; 139 140 default: 141 opArgs.add(arg); 142 break; 143 } 144 break; 145 } 146 147 case 'q': 149 { 150 String arg = getopt.getOptarg(); 151 152 156 if (arg.equals("f") || arg.equals("first")) 157 { 158 type = QUERY_FIRST; 159 } 160 else if (arg.equals("a") || arg.equals("all")) 161 { 162 type = QUERY_ALL; 163 } 164 else 165 { 166 throw new CommandException("Invalid query type: " + arg); 167 } 168 169 log.debug("Query type: " + type); 170 171 break; 172 } 173 } 174 } 175 } 176 177 private void invoke(final ObjectName name) 178 throws Exception 179 { 180 log.debug("Invoke " + name); 181 182 MBeanServerConnection server = getMBeanServer(); 183 184 MBeanInfo info = server.getMBeanInfo(name); 186 187 MBeanOperationInfo [] ops = info.getOperations(); 189 MBeanOp inputOp = new MBeanOp(opName, opArgs.size()); 190 MBeanOp matchOp = null; 191 ArrayList opList = new ArrayList (); 192 for (int i = 0; i < ops.length; i++) 193 { 194 MBeanOperationInfo opInfo = ops[i]; 195 MBeanOp op = new MBeanOp(opInfo.getName(), opInfo.getSignature()); 196 if( inputOp.equals(op) == true ) 197 { 198 matchOp = op; 199 break; 200 } 201 opList.add(op); 202 } 203 204 if (matchOp == null) 205 { 206 OpCountComparator comparator = new OpCountComparator(); 208 Collections.sort(opList, comparator); 209 int match = Collections.binarySearch(opList, inputOp, comparator); 210 if( match >= 0 ) 211 { 212 matchOp = (MBeanOp) opList.get(match); 214 match = comparator.compare(matchOp, inputOp); 215 if( match != 0 ) 216 { 217 throw new CommandException("MBean has no such operation named '" + 218 opName + "' with signature compatible with: "+opArgs); 219 } 220 } 221 else 222 { 223 throw new CommandException("MBean has no such operation named '" + 224 opName + "' with signature compatible with: "+opArgs); 225 } 226 } 227 228 int count = matchOp.getArgCount(); 230 Object [] params = new Object [count]; 231 for (int i = 0; i < count; i++) 232 { 233 String argType = matchOp.getArgType(i); 234 PropertyEditor editor = PropertyEditors.getEditor(argType); 235 editor.setAsText((String ) opArgs.get(i)); 236 params[i] = editor.getValue(); 237 } 238 log.debug("Using params: " + Strings.join(params, ",")); 239 240 Object result = server.invoke(name, opName, params, matchOp.getSignature()); 242 log.debug("Raw result: " + result); 243 244 if (!context.isQuiet()) 245 { 246 String resultText = null; 248 249 if (result != null) 250 { 251 PropertyEditor editor = PropertyEditors.getEditor(result.getClass()); 252 editor.setValue(result); 253 resultText = editor.getAsText(); 254 log.debug("Converted result: " + resultText); 255 } 256 else 257 { 258 resultText = "'null'"; 259 } 260 261 PrintWriter out = context.getWriter(); 263 out.println(resultText); 264 out.flush(); 265 } 266 } 267 268 public void execute(String [] args) throws Exception 269 { 270 processArguments(args); 271 272 if (query == null) 273 throw new CommandException("Missing MBean query"); 274 275 if (opName == null) 276 throw new CommandException("Missing operation name"); 277 278 log.debug("operation arguments: " + opArgs); 279 280 ObjectName [] names = queryMBeans(query); 282 if (type == QUERY_FIRST) 283 { 284 names = new ObjectName []{names[0]}; 285 } 286 287 for (int i = 0; i < names.length; i++) 288 { 289 invoke(names[i]); 290 } 291 } 292 } 293 | Popular Tags |