 |
Dealing with Command Line Parameters
Posted by tchangu on December 19, 2005 at 09:43 AM | Comments (5)
One of the things that keep popping up often is a need to write batch programs that is started from command line. Every single time its always been either reinvent the wheel or copy/paste from old code. So recently decided to put an end to this practice by looking at CLI solution from Apache.
CLI is a really nice utility and could be a potential enterprise reusable component. However while dealing with CLI, one will soon discover the verbosity especially while dealing with OptionBuilder
class. This means we are reverting back to old manner of programming (cut/paste) but in style.
But one could externalize this in a XML by hiding the plumbing of CLI that deals with verbosity. A simple framework around CLI framework would do this trick and this means a developer who wants to use CLI would write this simple XML
<cli-map>
<cli-parser>org.apache.commons.cli.GnuParser</cli-parser>
<cli-domain-obj>com.util.cli.domain.CommandObj</cli-domain-obj>
<help>
<help-formatter>org.apache.commons.cli.HelpFormatter</help-formatter>
<print-help>true</print-help>
<syntax-tip>java com.util.cli.TestDrive blah blah </syntax-tip>
</help>
<options>
<option optName="file" withArgName="file"
hasArgs="true" withDescription="use given file for log" />
<option optName="logger" withArgName="classname"
hasArgs="true" withDescription="the class which it to perform logging" />
<option optName="listener" withArgName="classname"
hasArgs="true" withDescription="add an instance of class as a project listener" />
<option optName="buildfile" withArgName="file" hasArgs="true" withDescription ="use given buildfile" />
<option optName="file" withArgName="file"
hasArgs="true" withDescription="search for buildfile towards the root of the filesystem and use it" />
<option optName="D" withArgName="property=value"
hasArgs="true" withValueSeparator="=" withDescription ="use value for given property" />
</options>
</cli-map>
The com.util.cli.domain.CommandObj needs to have instance variables that is same as optName. Then, using reflection and XML processing one could do bulk of the CLI plumbing to figure out what the values are. The outcome of this simple exercise - No more need to go through drudgery of writing code to parse command line arguments.
Write a simple XML, create a POJO, and get values populated in the POJO that is needed for the batch program with just three lines of code.
String fileName = "cli-map.xml";
CommandProcessorExt cmdProcessor = new CommandProcessorExt(fileName);
CommandObj obj = (CommandObj)cmdProcessor.process(args);
Better yet, Commons Configuration could be used to implement something similar! too...
Of course if some one is interested in the rudimentary, but working, source code, please feel free to ping!
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Writing XML configuration file to read configuration parameters for the program? Next logical step would be the configuration DB table for the XML configuration file and the XML-declared UI to edit the configuration DB table... :)
Posted by: kirillcool on December 19, 2005 at 12:55 PM
-
I'd prefer to use annotations for this. For simple options just annotate a field and the command processor will fill in the relevant value, more complex options would call a method. If you extend such a command line class the annotations are naturally inherited.
Posted by: mthornton on December 20, 2005 at 09:12 AM
-
Have you taken a look at the args4j project here on java.net? It works very well.
Posted by: evickroy on December 20, 2005 at 09:34 AM
-
kirillcool, I have a solution for managing and auto-generation DB schemas designed for XML-based argument parsing solutions. It's an enterprise product serving B2B initiatives, reducing development time, and tripling a companies ROI. Machine-based licenses start at $1000 per box, lol.
Please Java.net, stop giving people a reason to reinforce classic Java stereotypes!
Posted by: ilazarte on December 20, 2005 at 12:24 PM
-
Well said Kiril. This seems a perfect example of using a framework for the sake of using a framework.
Not that I've not seen things like you describe. In one case we indeed (no, I didn't think it up) had a database containing configuration information for a file system, with the database configuration being contained in configuration files which were on that same filesystem (with no intent to ever use a distributed system (the thing wasn't even programmed to allow for files on UNC paths), but you never know...).
Most programs have a fixed set of commandline parameters that never change (though some may be optional).
Nothing wrong with hardwiring things like that.At most you could make the actual names configurable if you want to make it possible to i18n the command line (not a good idea if you ask me, makes scriptable access to your application a nightmare).
Posted by: jwenting on December 22, 2005 at 03:00 AM
|