View Javadoc
1   /*
2    * (C) Copyright Keith Visco 1998, 1999  All rights reserved.
3    *
4    * The contents of this file are released under an Open Source 
5    * Definition (OSD) compliant license; you may not use this file 
6    * execpt in compliance with the license. Please see license.txt, 
7    * distributed with this file. You may also obtain a copy of the
8    * license at http://www.clc-marketing.com/xslp/license.txt
9    *
10   * The program is provided "as is" without any warranty express or
11   * implied, including the warranty of non-infringement and the implied
12   * warranties of merchantibility and fitness for a particular purpose.
13   * The Copyright owner will not be liable for any damages suffered by
14   * you as a result of using the Program. In no event will the Copyright
15   * owner be liable for any special, indirect or consequential damages or
16   * lost profits even if the Copyright owner has been advised of the
17   * possibility of their occurrence.
18   *
19   * $Id$
20   */
21  
22   
23  package org.exolab.castor.util;
24  
25  import java.io.PrintWriter;
26  import java.util.Hashtable;
27  import java.util.Properties;
28  import java.util.Vector;
29  
30  import org.castor.core.util.Messages;
31  
32  /**
33   * A utility class for generating command line options.
34   *
35   * @author <a href="mailto:kvisco@ziplink.net">Keith Visco</a>
36   * @version $Revision$ $Date: 2006-04-10 16:39:24 -0600 (Mon, 10 Apr 2006) $
37   */
38  public class CommandLineOptions {
39      private Vector _flags = null;
40      private Hashtable _optionInfo = null;
41      private PrintWriter _errorWriter = null;
42      
43      public CommandLineOptions() {
44          _flags = new Vector();
45          _optionInfo = new Hashtable();
46          _errorWriter = new PrintWriter(System.out);
47      }
48      
49      /**
50       * Adds the flag to list of available command line options.
51       * 
52       * @param flag the flag to add as an available command line option.
53       */
54      public void addFlag(final String flag) {
55          addFlag(flag, null, null);
56      }
57      
58      /**
59       * Adds the flag to list of available command line options.
60       * 
61       * @param flag the flag to add as an available command line option.
62       * @param comment a comment for the flag.
63       */
64      public void addFlag(final String flag, final String comment) {
65          addFlag(flag, null, comment, false);
66      }
67      
68      /**
69       * Adds the flag to list of available command line options.
70       * 
71       * @param flag the flag to add as an available command line option.
72       * @param comment a comment for the flag.
73       * @param usageText the text that appears after the flag in the
74       *        usage string.
75       */
76      public void addFlag(final String flag, final String usageText, final String comment) {
77          addFlag(flag, usageText, comment, false);
78      } //-- addFlag
79  
80      /**
81       * Adds the flag to list of available command line options.
82       * 
83       * @param flag The flag to add as an available command line option.
84       * @param comment A comment for the flag.
85       * @param usageText The text that appears after the flag in the usage string.
86       * @param optional When true, indicates that this flag is optional.
87       */
88      public void addFlag(final String flag, final String usageText, final String comment,
89              final boolean optional) {
90          if (flag == null) { return; }
91          _flags.addElement(flag);
92          
93          CmdLineOption opt = new CmdLineOption(flag);
94          opt.setComment(comment);
95          opt.setUsageText(usageText);
96          opt.setOptional(optional);
97          _optionInfo.put(flag, opt);
98      }
99      
100     /**
101      * Parses the arguments into a hashtable with the proper flag as the key.
102      */
103     public Properties getOptions(final String[] args) {
104         Properties options = new Properties();
105         String flag = null;
106         for (int i = 0; i < args.length; i++) {
107             
108             if (args[i].startsWith("-")) {
109                     
110                 // clean up previous flag
111                 if (flag != null) {
112                     options.put(flag, args[i]);
113                     options.put(new Integer(i), args[i]);
114                 }
115                 // get next flag
116                 flag = args[i].substring(1);
117                 
118                 //-- check full flag, otherwise try to find
119                 //-- flag within string
120                 if (!_flags.contains(flag)) {
121                     int idx = 1;
122                     while (idx <= flag.length()) {
123                         if (_flags.contains(flag.substring(0, idx))) {
124                             if (idx < flag.length()) {
125                                 options.put(flag.substring(0, idx),
126                                     flag.substring(idx));
127                                 break;
128                             }
129                         }
130                         else if (idx == flag.length()) {
131                             _errorWriter.println(Messages.format("misc.invalidCLIOption",
132                                     "-" + flag));
133                             printUsage(_errorWriter);
134                         }
135                         ++idx;
136                     }
137                 }
138             } else {
139                 // Store both flag key and number key
140                 if (flag != null) { options.put(flag, args[i]); }
141                 options.put(new Integer(i), args[i]);
142                 flag = null;
143             }
144             
145         }
146         if (flag != null) { options.put(flag, "no value"); }
147         return options;
148     }
149 
150     /**
151      * Sets a comment for the flag.
152      * 
153      * @param flag the flag to set the comment for.
154      * @param comment the comment to use when printing help for the given flag.
155      */
156     public void setComment(final String flag, final String comment) {
157         if (flag == null) { return; }
158         CmdLineOption opt = (CmdLineOption) _optionInfo.get(flag);
159         if (opt != null) { opt.setComment(comment); }
160     }
161     
162     /**
163      * Sets whether or not a given flag is optional.
164      * 
165      * @param flag the flag to set optionality for.
166      * @param optional the boolean indicating the optionality for the given flag.
167      */
168     public void setOptional(final String flag, final boolean optional) {
169         if (flag == null) { return; }
170         CmdLineOption opt = (CmdLineOption) _optionInfo.get(flag);
171         if (opt != null) { opt.setOptional(optional); }
172     }
173     
174     /**
175      * Sets the text to print after the flag when printing the usage line.
176      * 
177      * @param flag the flag to set the usage info for.
178      * @param usage the usage text.
179      */
180     public void setUsageInfo(final String flag, final String usage) {
181         if (flag == null) { return; }
182         CmdLineOption opt = (CmdLineOption) _optionInfo.get(flag);
183         if (opt != null) { opt.setUsageText(usage); }
184     }
185 
186     public void printUsage(final PrintWriter pw) {
187         pw.println();
188         pw.print(Messages.message("misc.CLIUsage"));
189         for (int i = 0; i < _flags.size(); i++) {
190             String flag = (String) _flags.elementAt(i);
191             CmdLineOption opt = (CmdLineOption) _optionInfo.get(flag);
192             if (opt.getOptional()) {
193                 pw.print(" [-");
194             } else {
195                 pw.print(" -");
196             }
197             pw.print(flag);
198             String usage = opt.getUsageText();
199             if (usage != null) {
200                 pw.print(' ');
201                 pw.print(usage);
202             }
203             if (opt.getOptional()) {
204                 pw.print(']');
205             }
206         }
207         pw.println();
208         pw.flush();
209     }
210     
211     public void printHelp(final PrintWriter pw) {
212         printUsage(pw);
213         pw.println();
214         
215         if (_flags.size() > 0) {
216             pw.println("Flag               Description");
217             pw.println("----------------------------------------------");
218         }
219         for (int i = 0; i < _flags.size(); i++) {
220             String flag = (String) _flags.elementAt(i);
221             CmdLineOption opt = (CmdLineOption) _optionInfo.get(flag);
222             
223             pw.print('-');
224             pw.print(flag);
225             
226             pw.print(' ');
227             //-- adjust spacing
228             int spaces = 17 - flag.length();
229             while (spaces > 0) { 
230                 pw.print(' ');
231                 --spaces;
232             }
233             
234             pw.print(opt.getComment());
235             
236             //String usage = opt.getUsageText();
237             //if (usage != null) {
238             //    pw.print(' ');
239             //    pw.print(usage);
240             //}
241             //if (opt.getOptional()) pw.print(']');
242             pw.println();
243         }
244         pw.println();
245         pw.flush();
246     }
247 }
248 
249 class CmdLineOption {
250     private boolean _optional = false;
251     private String _usageText = null;
252     private String _comment = null;
253     private String _flag = null;
254     
255     /**
256      * Creates a new CmdLineOption.
257      * 
258      * @param flag The flag associated with this command line option.
259      */
260     CmdLineOption(final String flag) {
261         super();
262         _flag = flag;
263     }
264     
265     /**
266      * Returns the flag associated with this command line option.
267      * 
268      * @return the flag associated with this command line option.
269      */
270     public String getFlag() {
271         return _flag;
272     }
273     
274     /**
275      * Returns whether or not this CmdLineOption is optional or not.
276      * 
277      * @return true if this CmdLineOption is optional, otherwise false.
278     */
279     public boolean getOptional() {
280         return _optional;
281     }
282     
283     /**
284      * Returns the comment for this option.
285      * 
286      * @return the comment for this command line option.
287      */
288     public String getComment() {
289         return _comment;
290     }
291     
292     /**
293      * Returns the text to print after the flag when printing the usage line.
294      * 
295      * @return the text to print after the flag when printing the usage line.
296      */
297     public String getUsageText() {
298         return _usageText;
299     }
300     
301     /**
302      * Sets whether or not this CmdLineOption is optional or not.
303      * 
304      * @param optional the flag indicating whether or not this CmdLineOption
305      *        is optional.
306      */
307     public void setOptional(final boolean optional) {
308         _optional = optional;
309     }
310     
311     /**
312      * Sets a comment for the flag.
313      * 
314      * @param comment the comment to use when printing help for the given flag.
315      */
316     public void setComment(final String comment) {
317         _comment = comment;
318     }
319     
320     /**
321      * Sets the text to print after the flag when printing the usage line.
322      * 
323      * @param usageText the usage text.
324      */
325     public void setUsageText(final String usageText) {
326         _usageText = usageText;
327     }
328 }
329