KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > console > twiddle > command > InvokeCommand


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.console.twiddle.command;
23
24 import java.io.PrintWriter JavaDoc;
25
26 import java.util.List JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Collections JavaDoc;
31
32 import java.beans.PropertyEditor JavaDoc;
33
34 import javax.management.ObjectName JavaDoc;
35 import javax.management.MBeanInfo JavaDoc;
36 import javax.management.MBeanOperationInfo JavaDoc;
37 import javax.management.MBeanServerConnection JavaDoc;
38 import javax.management.MBeanParameterInfo JavaDoc;
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 /**
47  * Invoke an operation on an MBean.
48  *
49  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
50  * @author Scott.Stark@jboss.org
51  * @version <tt>$Revision: 37459 $</tt>
52  */

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 JavaDoc query;
62
63    private String JavaDoc opName;
64
65    private List JavaDoc opArgs = new ArrayList JavaDoc(5); // probably not more than 5 args
66

67    public InvokeCommand()
68    {
69       super("invoke", "Invoke an operation on an MBean");
70    }
71
72    public void displayHelp()
73    {
74       PrintWriter JavaDoc 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 JavaDoc[] 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 JavaDoc 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                // non-option arguments
124
case 1:
125                {
126                   String JavaDoc 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                // Set the query type
148
case 'q':
149                {
150                   String JavaDoc arg = getopt.getOptarg();
151
152                   //
153
// jason: need a uniqueness mapper, like getopt uses for options...
154
//
155

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 JavaDoc name)
178       throws Exception JavaDoc
179    {
180       log.debug("Invoke " + name);
181
182       MBeanServerConnection JavaDoc server = getMBeanServer();
183       
184       // get mbean info for this mbean
185
MBeanInfo JavaDoc info = server.getMBeanInfo(name);
186       
187       // does it even have an operation of this name?
188
MBeanOperationInfo JavaDoc[] ops = info.getOperations();
189       MBeanOp inputOp = new MBeanOp(opName, opArgs.size());
190       MBeanOp matchOp = null;
191       ArrayList JavaDoc opList = new ArrayList JavaDoc();
192       for (int i = 0; i < ops.length; i++)
193       {
194          MBeanOperationInfo JavaDoc 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          // If there was not explicit match on type, look for a match on arg count
207
OpCountComparator comparator = new OpCountComparator();
208          Collections.sort(opList, comparator);
209          int match = Collections.binarySearch(opList, inputOp, comparator);
210          if( match >= 0 )
211          {
212             // Validate that the match op equates to the input op
213
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       // convert parameters with PropertyEditor
229
int count = matchOp.getArgCount();
230       Object JavaDoc[] params = new Object JavaDoc[count];
231       for (int i = 0; i < count; i++)
232       {
233          String JavaDoc argType = matchOp.getArgType(i);
234          PropertyEditor JavaDoc editor = PropertyEditors.getEditor(argType);
235          editor.setAsText((String JavaDoc) opArgs.get(i));
236          params[i] = editor.getValue();
237       }
238       log.debug("Using params: " + Strings.join(params, ","));
239
240       // invoke the operation
241
Object JavaDoc result = server.invoke(name, opName, params, matchOp.getSignature());
242       log.debug("Raw result: " + result);
243
244       if (!context.isQuiet())
245       {
246          // Translate the result to text
247
String JavaDoc resultText = null;
248
249          if (result != null)
250          {
251             PropertyEditor JavaDoc 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          // render results to out
262
PrintWriter JavaDoc out = context.getWriter();
263          out.println(resultText);
264          out.flush();
265       }
266    }
267
268    public void execute(String JavaDoc[] args) throws Exception JavaDoc
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       // get the list of object names to work with
281
ObjectName JavaDoc[] names = queryMBeans(query);
282       if (type == QUERY_FIRST)
283       {
284          names = new ObjectName JavaDoc[]{names[0]};
285       }
286
287       for (int i = 0; i < names.length; i++)
288       {
289          invoke(names[i]);
290       }
291    }
292 }
293
Popular Tags