KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > console > twiddle > Twiddle


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;
23
24 import gnu.getopt.Getopt;
25 import gnu.getopt.LongOpt;
26
27 import java.io.File JavaDoc;
28 import java.io.InputStream JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.net.MalformedURLException JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Map JavaDoc;
37 import java.util.Properties JavaDoc;
38
39 import javax.management.MBeanServerConnection JavaDoc;
40 import javax.naming.Context JavaDoc;
41 import javax.naming.InitialContext JavaDoc;
42 import javax.naming.NamingException JavaDoc;
43
44 import org.jboss.console.twiddle.command.Command;
45 import org.jboss.console.twiddle.command.CommandContext;
46 import org.jboss.console.twiddle.command.CommandException;
47 import org.jboss.console.twiddle.command.NoSuchCommandException;
48 import org.jboss.jmx.adaptor.rmi.RMIAdaptor;
49 import org.jboss.logging.Logger;
50 import org.jboss.security.SecurityAssociation;
51 import org.jboss.security.SimplePrincipal;
52 import org.jboss.util.Strings;
53
54 /**
55  * A command to invoke an operation on an MBean (or MBeans).
56  *
57  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
58  * @author Scott.Stark@jboss.org
59  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
60  * @version $Revision: 37459 $
61  */

62 public class Twiddle
63 {
64    public static final String JavaDoc PROGRAM_NAME = System.getProperty("program.name", "twiddle");
65    public static final String JavaDoc CMD_PROPERTIES = "/org/jboss/console/twiddle/commands.properties";
66    public static final String JavaDoc DEFAULT_JNDI_NAME = "jmx/invoker/RMIAdaptor";
67    private static final Logger log = Logger.getLogger(Twiddle.class);
68    // Command Line Support
69
private static Twiddle twiddle = new Twiddle(new PrintWriter JavaDoc(System.out, true),
70       new PrintWriter JavaDoc(System.err, true));
71    private static String JavaDoc commandName;
72    private static String JavaDoc[] commandArgs;
73    private static boolean commandHelp;
74    private static URL JavaDoc cmdProps;
75
76    private List JavaDoc commandProtoList = new ArrayList JavaDoc();
77    private Map JavaDoc commandProtoMap = new HashMap JavaDoc();
78    private PrintWriter JavaDoc out;
79    private PrintWriter JavaDoc err;
80    private String JavaDoc serverURL;
81    private String JavaDoc adapterName;
82    private boolean quiet;
83    private MBeanServerConnection JavaDoc server;
84
85    public Twiddle(final PrintWriter JavaDoc out, final PrintWriter JavaDoc err)
86    {
87       this.out = out;
88       this.err = err;
89    }
90
91    public void setServerURL(final String JavaDoc url)
92    {
93       this.serverURL = url;
94    }
95
96    public void setAdapterName(final String JavaDoc name)
97    {
98       this.adapterName = name;
99    }
100
101    public void setQuiet(final boolean flag)
102    {
103       this.quiet = flag;
104    }
105
106    public void addCommandPrototype(final Command proto)
107    {
108       String JavaDoc name = proto.getName();
109
110       log.debug("Adding command '" + name + "'; proto: " + proto);
111
112       commandProtoList.add(proto);
113       commandProtoMap.put(name, proto);
114    }
115
116    private CommandContext createCommandContext()
117    {
118       return new CommandContext()
119       {
120          public boolean isQuiet()
121          {
122             return quiet;
123          }
124
125          public PrintWriter JavaDoc getWriter()
126          {
127             return out;
128          }
129
130          public PrintWriter JavaDoc getErrorWriter()
131          {
132             return err;
133          }
134
135          public MBeanServerConnection JavaDoc getServer()
136          {
137             try
138             {
139                connect();
140             }
141             catch (Exception JavaDoc e)
142             {
143                throw new org.jboss.util.NestedRuntimeException(e);
144             }
145
146             return server;
147          }
148       };
149    }
150
151    public Command createCommand(final String JavaDoc name)
152       throws NoSuchCommandException, Exception JavaDoc
153    {
154       //
155
// jason: need to change this to accept unique substrings on command names
156
//
157

158       Command proto = (Command) commandProtoMap.get(name);
159       if (proto == null)
160       {
161          throw new NoSuchCommandException(name);
162       }
163
164       Command command = (Command) proto.clone();
165       command.setCommandContext(createCommandContext());
166
167       return command;
168    }
169
170    private int getMaxCommandNameLength()
171    {
172       int max = 0;
173
174       Iterator JavaDoc iter = commandProtoList.iterator();
175       while (iter.hasNext())
176       {
177          Command command = (Command) iter.next();
178          String JavaDoc name = command.getName();
179          if (name.length() > max)
180          {
181             max = name.length();
182          }
183       }
184
185       return max;
186    }
187
188    public void displayCommandList()
189    {
190       if( commandProtoList.size() == 0 )
191       {
192          try
193          {
194             loadCommands();
195          }
196          catch(Exception JavaDoc e)
197          {
198             System.err.println("Failed to load commnads from: "+cmdProps);
199             e.printStackTrace();
200          }
201       }
202       Iterator JavaDoc iter = commandProtoList.iterator();
203
204       out.println(PROGRAM_NAME + " commands: ");
205
206       int maxNameLength = getMaxCommandNameLength();
207       log.debug("max command name length: " + maxNameLength);
208
209       while (iter.hasNext())
210       {
211          Command proto = (Command) iter.next();
212          String JavaDoc name = proto.getName();
213          String JavaDoc desc = proto.getDescription();
214
215          out.print(" ");
216          out.print(name);
217
218          // an even pad, so things line up correctly
219
out.print(Strings.pad(" ", maxNameLength - name.length()));
220          out.print(" ");
221
222          out.println(desc);
223       }
224
225       out.flush();
226    }
227
228    private MBeanServerConnection JavaDoc createMBeanServerConnection()
229       throws NamingException JavaDoc
230    {
231       InitialContext JavaDoc ctx;
232
233       if (serverURL == null)
234       {
235          ctx = new InitialContext JavaDoc();
236       }
237       else
238       {
239          Properties JavaDoc props = new Properties JavaDoc(System.getProperties());
240          props.put(Context.PROVIDER_URL, serverURL);
241          ctx = new InitialContext JavaDoc(props);
242       }
243
244       // if adapter is null, the use the default
245
if (adapterName == null)
246       {
247          adapterName = DEFAULT_JNDI_NAME;
248       }
249
250       Object JavaDoc obj = ctx.lookup(adapterName);
251       ctx.close();
252
253       if (!(obj instanceof RMIAdaptor))
254       {
255          throw new ClassCastException JavaDoc
256             ("Object not of type: RMIAdaptorImpl, but: " +
257             (obj == null ? "not found" : obj.getClass().getName()));
258       }
259
260       return (MBeanServerConnection JavaDoc) obj;
261    }
262
263    private void connect()
264       throws NamingException JavaDoc
265    {
266       if (server == null)
267       {
268          server = createMBeanServerConnection();
269       }
270    }
271
272    public static void main(final String JavaDoc[] args)
273    {
274       Command command = null;
275
276       try
277       {
278          // initialize java.protocol.handler.pkgs
279
initProtocolHandlers();
280          
281          // Prosess global options
282
processArguments(args);
283          loadCommands();
284
285          // Now execute the command
286
if (commandName == null)
287          {
288             // Display program help
289
displayHelp();
290          }
291          else
292          {
293             command = twiddle.createCommand(commandName);
294
295             if (commandHelp)
296             {
297                System.out.println("Help for command: '" + command.getName() + "'");
298                System.out.println();
299                
300                command.displayHelp();
301             }
302             else
303             {
304                // Execute the command
305
command.execute(commandArgs);
306             }
307          }
308
309          System.exit(0);
310       }
311       catch (CommandException e)
312       {
313          log.error("Command failure", e);
314          System.err.println();
315          
316          if (e instanceof NoSuchCommandException)
317          {
318             twiddle.displayCommandList();
319          }
320          else
321          {
322
323             if (command != null)
324             {
325                System.err.println("Help for command: '" + command.getName() + "'");
326                System.err.println();
327                
328                command.displayHelp();
329             }
330          }
331          System.exit(1);
332       }
333       catch (Exception JavaDoc e)
334       {
335          log.error("Exec failed", e);
336          System.exit(1);
337       }
338    }
339
340    private static void initProtocolHandlers()
341    {
342       // Include the default JBoss protocol handler package
343
String JavaDoc handlerPkgs = System.getProperty("java.protocol.handler.pkgs");
344       if (handlerPkgs != null)
345       {
346          handlerPkgs += "|org.jboss.net.protocol";
347       }
348       else
349       {
350          handlerPkgs = "org.jboss.net.protocol";
351       }
352       System.setProperty("java.protocol.handler.pkgs", handlerPkgs);
353    }
354    
355    private static void loadCommands() throws Exception JavaDoc
356    {
357       // load command protos from property definitions
358
if( cmdProps == null )
359          cmdProps = Twiddle.class.getResource(CMD_PROPERTIES);
360       if (cmdProps == null)
361          throw new IllegalStateException JavaDoc("Failed to find: " + CMD_PROPERTIES);
362       InputStream JavaDoc input = cmdProps.openStream();
363       log.debug("command proto type properties: " + cmdProps);
364       Properties JavaDoc props = new Properties JavaDoc();
365       props.load(input);
366       input.close();
367
368       Iterator JavaDoc iter = props.keySet().iterator();
369       while (iter.hasNext())
370       {
371          String JavaDoc name = (String JavaDoc) iter.next();
372          String JavaDoc typeName = props.getProperty(name);
373          Class JavaDoc type = Class.forName(typeName);
374
375          twiddle.addCommandPrototype((Command) type.newInstance());
376       }
377    }
378
379    private static void displayHelp()
380    {
381       java.io.PrintStream JavaDoc out = System.out;
382
383       out.println("A JMX client to 'twiddle' with a remote JBoss server.");
384       out.println();
385       out.println("usage: " + PROGRAM_NAME + " [options] <command> [command_arguments]");
386       out.println();
387       out.println("options:");
388       out.println(" -h, --help Show this help message");
389       out.println(" --help-commands Show a list of commands");
390       out.println(" -H=<command> Show command specific help");
391       out.println(" -c=command.properties Specify the command.properties file to use");
392       out.println(" -D<name>[=<value>] Set a system property");
393       out.println(" -- Stop processing options");
394       out.println(" -s, --server=<url> The JNDI URL of the remote server");
395       out.println(" -a, --adapter=<name> The JNDI name of the RMI adapter to use");
396       out.println(" -u, --user=<name> Specify the username for authentication");
397       out.println(" -p, --password=<name> Specify the password for authentication");
398       out.println(" -q, --quiet Be somewhat more quiet");
399       out.flush();
400    }
401
402    private static void processArguments(final String JavaDoc[] args) throws Exception JavaDoc
403    {
404       for(int a = 0; a < args.length; a ++)
405       {
406          log.debug("args["+a+"]="+args[a]);
407       }
408       String JavaDoc sopts = "-:hH:u:p:c:D:s:a:q";
409       LongOpt[] lopts =
410          {
411             new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
412             new LongOpt("help-commands", LongOpt.NO_ARGUMENT, null, 0x1000),
413             new LongOpt("server", LongOpt.REQUIRED_ARGUMENT, null, 's'),
414             new LongOpt("adapter", LongOpt.REQUIRED_ARGUMENT, null, 'a'),
415             new LongOpt("quiet", LongOpt.NO_ARGUMENT, null, 'q'),
416             new LongOpt("user", LongOpt.REQUIRED_ARGUMENT, null, 'u'),
417             new LongOpt("password", LongOpt.REQUIRED_ARGUMENT, null, 'p'),
418          };
419
420       Getopt getopt = new Getopt(PROGRAM_NAME, args, sopts, lopts);
421       int code;
422
423       PROCESS_ARGUMENTS:
424
425         while ((code = getopt.getopt()) != -1)
426         {
427            switch (code)
428            {
429               case ':':
430               case '?':
431                  // for now both of these should exit with error status
432
System.exit(1);
433                  break; // for completeness
434

435                  // non-option arguments
436
case 1:
437                  {
438                     // create the command
439
commandName = getopt.getOptarg();
440                     log.debug("Command name: " + commandName);
441
442                     // pass the remaining arguments (if any) to the command for processing
443
int i = getopt.getOptind();
444
445                     if (args.length > i)
446                     {
447                        commandArgs = new String JavaDoc[args.length - i];
448                        System.arraycopy(args, i, commandArgs, 0, args.length - i);
449                     }
450                     else
451                     {
452                        commandArgs = new String JavaDoc[0];
453                     }
454                     // Log the command options
455
log.debug("Command arguments: " + Strings.join(commandArgs, ","));
456
457                     // We are done, execute the command
458
break PROCESS_ARGUMENTS;
459                  }
460
461                  // show command line help
462
case 'h':
463                  displayHelp();
464                  System.exit(0);
465                  break; // for completeness
466

467                  // Show command help
468
case 'H':
469                  commandName = getopt.getOptarg();
470                  commandHelp = true;
471                  break PROCESS_ARGUMENTS;
472
473                  // help-commands
474
case 0x1000:
475                  twiddle.displayCommandList();
476                  System.exit(0);
477                  break; // for completeness
478

479               case 'c':
480                  // Try value as a URL
481
String JavaDoc props = getopt.getOptarg();
482                  try
483                  {
484                     cmdProps = new URL JavaDoc(props);
485                  }
486                  catch (MalformedURLException JavaDoc e)
487                  {
488                     log.debug("Failed to use cmd props as url", e);
489                     File JavaDoc path = new File JavaDoc(props);
490                     if( path.exists() == false )
491                     {
492                        String JavaDoc msg = "Failed to locate command props: " + props
493                           + " as URL or file";
494                        throw new IllegalArgumentException JavaDoc(msg);
495                     }
496                     cmdProps = path.toURL();
497                  }
498                  break;
499                  // set a system property
500
case 'D':
501                  {
502                     String JavaDoc arg = getopt.getOptarg();
503                     String JavaDoc name, value;
504                     int i = arg.indexOf("=");
505                     if (i == -1)
506                     {
507                        name = arg;
508                        value = "true";
509                     }
510                     else
511                     {
512                        name = arg.substring(0, i);
513                        value = arg.substring(i + 1, arg.length());
514                     }
515                     System.setProperty(name, value);
516                     break;
517                  }
518
519                  // Set the JNDI server URL
520
case 's':
521                  twiddle.setServerURL(getopt.getOptarg());
522                  break;
523
524                  // Set the adapter JNDI name
525
case 'a':
526                  twiddle.setAdapterName(getopt.getOptarg());
527                  break;
528               case 'u':
529                  String JavaDoc username = getopt.getOptarg();
530                  SecurityAssociation.setPrincipal(new SimplePrincipal(username));
531                  break;
532               case 'p':
533                  String JavaDoc password = getopt.getOptarg();
534                  SecurityAssociation.setCredential(password);
535                  break;
536
537               // Enable quiet operations
538
case 'q':
539                  twiddle.setQuiet(true);
540                  break;
541            }
542         }
543    }
544 }
545
Popular Tags