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