KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > demo > CmdLineParser


1 package org.jdesktop.demo;
2
3 import java.text.NumberFormat JavaDoc;
4 import java.text.ParseException JavaDoc;
5 import java.util.Hashtable JavaDoc;
6 import java.util.Vector JavaDoc;
7 import java.util.Enumeration JavaDoc;
8 import java.util.Locale JavaDoc;
9
10 /**
11  * Largely GNU-compatible command-line options parser. Has short (-v) and
12  * long-form (--verbose) option support, and also allows options with
13  * associated values (-d 2, --debug 2, --debug=2). Option processing
14  * can be explicitly terminated by the argument '--'.
15  * <p/>
16  * <b>Note from Richard Bair:</b> This file was taken from the jargs project
17  * which can be found at http://sourceforge.net/projects/jargs. The project is
18  * BSD licensed, so I'm ok in doing this.
19  *
20  * @author Steve Purcell
21  * @version $Revision: 1.1 $
22  */

23 public class CmdLineParser {
24
25     /**
26      * Base class for exceptions that may be thrown when options are parsed
27      */

28     public static abstract class OptionException extends Exception JavaDoc {
29         OptionException(String JavaDoc msg) { super(msg); }
30     }
31
32     /**
33      * Thrown when the parsed command-line contains an option that is not
34      * recognised. <code>getMessage()</code> returns
35      * an error string suitable for reporting the error to the user (in
36      * English).
37      */

38     public static class UnknownOptionException extends OptionException {
39         UnknownOptionException( String JavaDoc optionName ) {
40             super("unknown option '" + optionName + "'");
41             this.optionName = optionName;
42         }
43
44         /**
45          * @return the name of the option that was unknown (e.g. "-u")
46          */

47         public String JavaDoc getOptionName() { return this.optionName; }
48         private String JavaDoc optionName = null;
49     }
50
51     /**
52      * Thrown when an illegal or missing value is given by the user for
53      * an option that takes a value. <code>getMessage()</code> returns
54      * an error string suitable for reporting the error to the user (in
55      * English).
56      */

57     public static class IllegalOptionValueException extends OptionException {
58         public IllegalOptionValueException( Option opt, String JavaDoc value ) {
59             super("illegal value '" + value + "' for option -" +
60                   opt.shortForm() + "/--" + opt.longForm());
61             this.option = opt;
62             this.value = value;
63         }
64
65         /**
66          * @return the name of the option whose value was illegal (e.g. "-u")
67          */

68         public Option getOption() { return this.option; }
69
70         /**
71          * @return the illegal value
72          */

73         public String JavaDoc getValue() { return this.value; }
74         private Option option;
75         private String JavaDoc value;
76     }
77
78     /**
79      * Representation of a command-line option
80      */

81     public static abstract class Option {
82
83         protected Option( char shortForm, String JavaDoc longForm,
84                           boolean wantsValue ) {
85             if ( longForm == null )
86                 throw new IllegalArgumentException JavaDoc("null arg forms not allowed");
87             this.shortForm = new String JavaDoc(new char[]{shortForm});
88             this.longForm = longForm;
89             this.wantsValue = wantsValue;
90         }
91
92         public String JavaDoc shortForm() { return this.shortForm; }
93
94         public String JavaDoc longForm() { return this.longForm; }
95
96         /**
97          * Tells whether or not this option wants a value
98          */

99         public boolean wantsValue() { return this.wantsValue; }
100
101         public final Object JavaDoc getValue( String JavaDoc arg, Locale JavaDoc locale )
102             throws IllegalOptionValueException {
103             if ( this.wantsValue ) {
104                 if ( arg == null ) {
105                     throw new IllegalOptionValueException(this, "");
106                 }
107                 return this.parseValue(arg, locale);
108             }
109             else {
110                 return Boolean.TRUE;
111             }
112         }
113
114         /**
115          * Override to extract and convert an option value passed on the
116          * command-line
117          */

118         protected Object JavaDoc parseValue( String JavaDoc arg, Locale JavaDoc locale )
119             throws IllegalOptionValueException {
120             return null;
121         }
122
123         private String JavaDoc shortForm = null;
124         private String JavaDoc longForm = null;
125         private boolean wantsValue = false;
126
127         public static class BooleanOption extends Option {
128             public BooleanOption( char shortForm, String JavaDoc longForm ) {
129                 super(shortForm, longForm, false);
130             }
131         }
132
133         /**
134          * An option that expects an integer value
135          */

136         public static class IntegerOption extends Option {
137             public IntegerOption( char shortForm, String JavaDoc longForm ) {
138                 super(shortForm, longForm, true);
139             }
140             protected Object JavaDoc parseValue( String JavaDoc arg, Locale JavaDoc locale )
141                 throws IllegalOptionValueException {
142                 try {
143                     return new Integer JavaDoc(arg);
144                 }
145                 catch (NumberFormatException JavaDoc e) {
146                     throw new IllegalOptionValueException(this, arg);
147                 }
148             }
149         }
150
151         /**
152          * An option that expects a floating-point value
153          */

154         public static class DoubleOption extends Option {
155             public DoubleOption( char shortForm, String JavaDoc longForm ) {
156                 super(shortForm, longForm, true);
157             }
158             protected Object JavaDoc parseValue( String JavaDoc arg, Locale JavaDoc locale )
159                 throws IllegalOptionValueException {
160                 try {
161                     NumberFormat JavaDoc format = NumberFormat.getNumberInstance(locale);
162                     Number JavaDoc num = (Number JavaDoc)format.parse(arg);
163                     return new Double JavaDoc(num.doubleValue());
164                 }
165                 catch (ParseException JavaDoc e) {
166                     throw new IllegalOptionValueException(this, arg);
167                 }
168             }
169         }
170
171         /**
172          * An option that expects a string value
173          */

174         public static class StringOption extends Option {
175             public StringOption( char shortForm, String JavaDoc longForm ) {
176                 super(shortForm, longForm, true);
177             }
178             protected Object JavaDoc parseValue( String JavaDoc arg, Locale JavaDoc locale ) {
179                 return arg;
180             }
181         }
182     }
183
184     /**
185      * Add the specified Option to the list of accepted options
186      */

187     public final Option addOption( Option opt ) {
188         this.options.put("-" + opt.shortForm(), opt);
189         this.options.put("--" + opt.longForm(), opt);
190         return opt;
191     }
192
193     /**
194      * Convenience method for adding a string option.
195      * @return the new Option
196      */

197     public final Option addStringOption( char shortForm, String JavaDoc longForm ) {
198         Option opt = new Option.StringOption(shortForm, longForm);
199         addOption(opt);
200         return opt;
201     }
202
203     /**
204      * Convenience method for adding an integer option.
205      * @return the new Option
206      */

207     public final Option addIntegerOption( char shortForm, String JavaDoc longForm ) {
208         Option opt = new Option.IntegerOption(shortForm, longForm);
209         addOption(opt);
210         return opt;
211     }
212
213     /**
214      * Convenience method for adding a double option.
215      * @return the new Option
216      */

217     public final Option addDoubleOption( char shortForm, String JavaDoc longForm ) {
218         Option opt = new Option.DoubleOption(shortForm, longForm);
219         addOption(opt);
220         return opt;
221     }
222
223     /**
224      * Convenience method for adding a boolean option.
225      * @return the new Option
226      */

227     public final Option addBooleanOption( char shortForm, String JavaDoc longForm ) {
228         Option opt = new Option.BooleanOption(shortForm, longForm);
229         addOption(opt);
230         return opt;
231     }
232
233     /**
234      * @return the parsed value of the given Option, or null if the
235      * option was not set
236      */

237     public final Object JavaDoc getOptionValue( Option o ) {
238         return values.get(o.longForm());
239     }
240
241     /**
242      * @return the parsed value of the given Option, or null if the
243      * option was not set
244      */

245     public final Object JavaDoc getOptionValue( Option o, Object JavaDoc defaultValue ) {
246         Object JavaDoc val = values.get(o.longForm());
247         return val == null ? defaultValue : val;
248     }
249
250     /**
251      * @return the non-option arguments
252      */

253     public final String JavaDoc[] getRemainingArgs() {
254         return this.remainingArgs;
255     }
256
257     /**
258      * Extract the options and non-option arguments from the given
259      * list of command-line arguments. The default locale is used for
260      * parsing options whose values might be locale-specific.
261      */

262     public final void parse( String JavaDoc[] argv )
263         throws IllegalOptionValueException, UnknownOptionException {
264         parse(argv, Locale.getDefault());
265     }
266
267     /**
268      * Extract the options and non-option arguments from the given
269      * list of command-line arguments. The specified locale is used for
270      * parsing options whose values might be locale-specific.
271      */

272     public final void parse( String JavaDoc[] argv, Locale JavaDoc locale )
273         throws IllegalOptionValueException, UnknownOptionException {
274         Vector JavaDoc otherArgs = new Vector JavaDoc();
275         int position = 0;
276         this.values = new Hashtable JavaDoc(10);
277         while ( position < argv.length ) {
278             String JavaDoc curArg = argv[position];
279             if ( curArg.startsWith("-") ) {
280                 if ( curArg.equals("--") ) { // end of options
281
position += 1;
282                     break;
283                 }
284                 String JavaDoc valueArg = null;
285                 if ( curArg.startsWith("--") ) { // handle --arg=value
286
int equalsPos = curArg.indexOf("=");
287                     if ( equalsPos != -1 ) {
288                         valueArg = curArg.substring(equalsPos+1);
289                         curArg = curArg.substring(0,equalsPos);
290                     }
291                 }
292                 Option opt = (Option)this.options.get(curArg);
293                 if ( opt == null ) {
294                     throw new UnknownOptionException(curArg);
295                 }
296                 Object JavaDoc value = null;
297                 if ( opt.wantsValue() ) {
298                     if ( valueArg == null ) {
299                         position += 1;
300                         valueArg = null;
301                         if ( position < argv.length ) {
302                             valueArg = argv[position];
303                         }
304                     }
305                     value = opt.getValue(valueArg, locale);
306                 }
307                 else {
308                     value = opt.getValue(null, locale);
309                 }
310                 this.values.put(opt.longForm(), value);
311                 position += 1;
312             }
313             else {
314                 break;
315             }
316         }
317         for ( ; position < argv.length; ++position ) {
318             otherArgs.addElement(argv[position]);
319         }
320
321         this.remainingArgs = new String JavaDoc[otherArgs.size()];
322         int i = 0;
323         for (Enumeration JavaDoc e = otherArgs.elements(); e.hasMoreElements(); ++i) {
324             this.remainingArgs[i] = (String JavaDoc)e.nextElement();
325         }
326     }
327
328     private String JavaDoc[] remainingArgs = null;
329     private Hashtable JavaDoc options = new Hashtable JavaDoc(10);
330     private Hashtable JavaDoc values = new Hashtable JavaDoc(10);
331 }
332
Popular Tags