001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.cli;
019
020 /**
021 * OptionBuilder allows the user to create Options using descriptive methods.
022 *
023 * <p>Details on the Builder pattern can be found at
024 * <a href="http://c2.com/cgi-bin/wiki?BuilderPattern">
025 * http://c2.com/cgi-bin/wiki?BuilderPattern</a>.</p>
026 *
027 * @author John Keyes (john at integralsource.com)
028 * @version $Revision: 754830 $, $Date: 2009-03-16 00:26:44 -0700 (Mon, 16 Mar 2009) $
029 * @since 1.0
030 */
031 public final class OptionBuilder
032 {
033 /** long option */
034 private static String longopt;
035
036 /** option description */
037 private static String description;
038
039 /** argument name */
040 private static String argName;
041
042 /** is required? */
043 private static boolean required;
044
045 /** the number of arguments */
046 private static int numberOfArgs = Option.UNINITIALIZED;
047
048 /** option type */
049 private static Object type;
050
051 /** option can have an optional argument value */
052 private static boolean optionalArg;
053
054 /** value separator for argument value */
055 private static char valuesep;
056
057 /** option builder instance */
058 private static OptionBuilder instance = new OptionBuilder();
059
060 /**
061 * private constructor to prevent instances being created
062 */
063 private OptionBuilder()
064 {
065 // hide the constructor
066 }
067
068 /**
069 * Resets the member variables to their default values.
070 */
071 private static void reset()
072 {
073 description = null;
074 argName = "arg";
075 longopt = null;
076 type = null;
077 required = false;
078 numberOfArgs = Option.UNINITIALIZED;
079
080
081 // PMM 9/6/02 - these were missing
082 optionalArg = false;
083 valuesep = (char) 0;
084 }
085
086 /**
087 * The next Option created will have the following long option value.
088 *
089 * @param newLongopt the long option value
090 * @return the OptionBuilder instance
091 */
092 public static OptionBuilder withLongOpt(String newLongopt)
093 {
094 OptionBuilder.longopt = newLongopt;
095
096 return instance;
097 }
098
099 /**
100 * The next Option created will require an argument value.
101 *
102 * @return the OptionBuilder instance
103 */
104 public static OptionBuilder hasArg()
105 {
106 OptionBuilder.numberOfArgs = 1;
107
108 return instance;
109 }
110
111 /**
112 * The next Option created will require an argument value if
113 * <code>hasArg</code> is true.
114 *
115 * @param hasArg if true then the Option has an argument value
116 * @return the OptionBuilder instance
117 */
118 public static OptionBuilder hasArg(boolean hasArg)
119 {
120 OptionBuilder.numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
121
122 return instance;
123 }
124
125 /**
126 * The next Option created will have the specified argument value name.
127 *
128 * @param name the name for the argument value
129 * @return the OptionBuilder instance
130 */
131 public static OptionBuilder withArgName(String name)
132 {
133 OptionBuilder.argName = name;
134
135 return instance;
136 }
137
138 /**
139 * The next Option created will be required.
140 *
141 * @return the OptionBuilder instance
142 */
143 public static OptionBuilder isRequired()
144 {
145 OptionBuilder.required = true;
146
147 return instance;
148 }
149
150 /**
151 * The next Option created uses <code>sep</code> as a means to
152 * separate argument values.
153 *
154 * <b>Example:</b>
155 * <pre>
156 * Option opt = OptionBuilder.withValueSeparator(':')
157 * .create('D');
158 *
159 * CommandLine line = parser.parse(args);
160 * String propertyName = opt.getValue(0);
161 * String propertyValue = opt.getValue(1);
162 * </pre>
163 *
164 * @param sep The value separator to be used for the argument values.
165 *
166 * @return the OptionBuilder instance
167 */
168 public static OptionBuilder withValueSeparator(char sep)
169 {
170 OptionBuilder.valuesep = sep;
171
172 return instance;
173 }
174
175 /**
176 * The next Option created uses '<code>=</code>' as a means to
177 * separate argument values.
178 *
179 * <b>Example:</b>
180 * <pre>
181 * Option opt = OptionBuilder.withValueSeparator()
182 * .create('D');
183 *
184 * CommandLine line = parser.parse(args);
185 * String propertyName = opt.getValue(0);
186 * String propertyValue = opt.getValue(1);
187 * </pre>
188 *
189 * @return the OptionBuilder instance
190 */
191 public static OptionBuilder withValueSeparator()
192 {
193 OptionBuilder.valuesep = '=';
194
195 return instance;
196 }
197
198 /**
199 * The next Option created will be required if <code>required</code>
200 * is true.
201 *
202 * @param newRequired if true then the Option is required
203 * @return the OptionBuilder instance
204 */
205 public static OptionBuilder isRequired(boolean newRequired)
206 {
207 OptionBuilder.required = newRequired;
208
209 return instance;
210 }
211
212 /**
213 * The next Option created can have unlimited argument values.
214 *
215 * @return the OptionBuilder instance
216 */
217 public static OptionBuilder hasArgs()
218 {
219 OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
220
221 return instance;
222 }
223
224 /**
225 * The next Option created can have <code>num</code> argument values.
226 *
227 * @param num the number of args that the option can have
228 * @return the OptionBuilder instance
229 */
230 public static OptionBuilder hasArgs(int num)
231 {
232 OptionBuilder.numberOfArgs = num;
233
234 return instance;
235 }
236
237 /**
238 * The next Option can have an optional argument.
239 *
240 * @return the OptionBuilder instance
241 */
242 public static OptionBuilder hasOptionalArg()
243 {
244 OptionBuilder.numberOfArgs = 1;
245 OptionBuilder.optionalArg = true;
246
247 return instance;
248 }
249
250 /**
251 * The next Option can have an unlimited number of optional arguments.
252 *
253 * @return the OptionBuilder instance
254 */
255 public static OptionBuilder hasOptionalArgs()
256 {
257 OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
258 OptionBuilder.optionalArg = true;
259
260 return instance;
261 }
262
263 /**
264 * The next Option can have the specified number of optional arguments.
265 *
266 * @param numArgs - the maximum number of optional arguments
267 * the next Option created can have.
268 * @return the OptionBuilder instance
269 */
270 public static OptionBuilder hasOptionalArgs(int numArgs)
271 {
272 OptionBuilder.numberOfArgs = numArgs;
273 OptionBuilder.optionalArg = true;
274
275 return instance;
276 }
277
278 /**
279 * The next Option created will have a value that will be an instance
280 * of <code>type</code>.
281 *
282 * @param newType the type of the Options argument value
283 * @return the OptionBuilder instance
284 */
285 public static OptionBuilder withType(Object newType)
286 {
287 OptionBuilder.type = newType;
288
289 return instance;
290 }
291
292 /**
293 * The next Option created will have the specified description
294 *
295 * @param newDescription a description of the Option's purpose
296 * @return the OptionBuilder instance
297 */
298 public static OptionBuilder withDescription(String newDescription)
299 {
300 OptionBuilder.description = newDescription;
301
302 return instance;
303 }
304
305 /**
306 * Create an Option using the current settings and with
307 * the specified Option <code>char</code>.
308 *
309 * @param opt the character representation of the Option
310 * @return the Option instance
311 * @throws IllegalArgumentException if <code>opt</code> is not
312 * a valid character. See Option.
313 */
314 public static Option create(char opt) throws IllegalArgumentException
315 {
316 return create(String.valueOf(opt));
317 }
318
319 /**
320 * Create an Option using the current settings
321 *
322 * @return the Option instance
323 * @throws IllegalArgumentException if <code>longOpt</code> has not been set.
324 */
325 public static Option create() throws IllegalArgumentException
326 {
327 if (longopt == null)
328 {
329 OptionBuilder.reset();
330 throw new IllegalArgumentException("must specify longopt");
331 }
332
333 return create(null);
334 }
335
336 /**
337 * Create an Option using the current settings and with
338 * the specified Option <code>char</code>.
339 *
340 * @param opt the <code>java.lang.String</code> representation
341 * of the Option
342 * @return the Option instance
343 * @throws IllegalArgumentException if <code>opt</code> is not
344 * a valid character. See Option.
345 */
346 public static Option create(String opt) throws IllegalArgumentException
347 {
348 Option option = null;
349 try {
350 // create the option
351 option = new Option(opt, description);
352
353 // set the option properties
354 option.setLongOpt(longopt);
355 option.setRequired(required);
356 option.setOptionalArg(optionalArg);
357 option.setArgs(numberOfArgs);
358 option.setType(type);
359 option.setValueSeparator(valuesep);
360 option.setArgName(argName);
361 } finally {
362 // reset the OptionBuilder properties
363 OptionBuilder.reset();
364 }
365
366 // return the Option instance
367 return option;
368 }
369 }