1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.cli;
19
20 /**
21 * OptionBuilder allows the user to create Options using descriptive methods.
22 * <p>
23 * Details on the Builder pattern can be found at
24 * <a href="http://c2.com/cgi-bin/wiki?BuilderPattern">http://c2.com/cgi-bin/wiki?BuilderPattern</a>.
25 * <p>
26 * This class is NOT thread safe. See <a href="https://issues.apache.org/jira/browse/CLI-209">CLI-209</a>
27 *
28 * @version $Id: OptionBuilder.java 1447094 2013-02-17 22:32:21Z tn $
29 * @since 1.0
30 * @deprecated since 1.3, use {@link Option.builder(String)} instead
31 */
32 @Deprecated
33 public final class OptionBuilder
34 {
35 /** long option */
36 private static String longopt;
37
38 /** option description */
39 private static String description;
40
41 /** argument name */
42 private static String argName;
43
44 /** is required? */
45 private static boolean required;
46
47 /** the number of arguments */
48 private static int numberOfArgs = Option.UNINITIALIZED;
49
50 /** option type */
51 private static Class<?> type;
52
53 /** option can have an optional argument value */
54 private static boolean optionalArg;
55
56 /** value separator for argument value */
57 private static char valuesep;
58
59 /** option builder instance */
60 private static OptionBuilder instance = new OptionBuilder();
61
62 static
63 {
64 // ensure the consistency of the initial values
65 reset();
66 }
67
68 /**
69 * private constructor to prevent instances being created
70 */
71 private OptionBuilder()
72 {
73 // hide the constructor
74 }
75
76 /**
77 * Resets the member variables to their default values.
78 */
79 private static void reset()
80 {
81 description = null;
82 argName = null;
83 longopt = null;
84 type = String.class;
85 required = false;
86 numberOfArgs = Option.UNINITIALIZED;
87 optionalArg = false;
88 valuesep = (char) 0;
89 }
90
91 /**
92 * The next Option created will have the following long option value.
93 *
94 * @param newLongopt the long option value
95 * @return the OptionBuilder instance
96 */
97 public static OptionBuilder withLongOpt(String newLongopt)
98 {
99 OptionBuilder.longopt = newLongopt;
100
101 return instance;
102 }
103
104 /**
105 * The next Option created will require an argument value.
106 *
107 * @return the OptionBuilder instance
108 */
109 public static OptionBuilder hasArg()
110 {
111 OptionBuilder.numberOfArgs = 1;
112
113 return instance;
114 }
115
116 /**
117 * The next Option created will require an argument value if
118 * <code>hasArg</code> is true.
119 *
120 * @param hasArg if true then the Option has an argument value
121 * @return the OptionBuilder instance
122 */
123 public static OptionBuilder hasArg(boolean hasArg)
124 {
125 OptionBuilder.numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
126
127 return instance;
128 }
129
130 /**
131 * The next Option created will have the specified argument value name.
132 *
133 * @param name the name for the argument value
134 * @return the OptionBuilder instance
135 */
136 public static OptionBuilder withArgName(String name)
137 {
138 OptionBuilder.argName = name;
139
140 return instance;
141 }
142
143 /**
144 * The next Option created will be required.
145 *
146 * @return the OptionBuilder instance
147 */
148 public static OptionBuilder isRequired()
149 {
150 OptionBuilder.required = true;
151
152 return instance;
153 }
154
155 /**
156 * The next Option created uses <code>sep</code> as a means to
157 * separate argument values.
158 * <p>
159 * <b>Example:</b>
160 * <pre>
161 * Option opt = OptionBuilder.withValueSeparator('=')
162 * .create('D');
163 *
164 * String args = "-Dkey=value";
165 * CommandLine line = parser.parse(args);
166 * String propertyName = opt.getValue(0); // will be "key"
167 * String propertyValue = opt.getValue(1); // will be "value"
168 * </pre>
169 *
170 * @param sep The value separator to be used for the argument values.
171 *
172 * @return the OptionBuilder instance
173 */
174 public static OptionBuilder withValueSeparator(char sep)
175 {
176 OptionBuilder.valuesep = sep;
177
178 return instance;
179 }
180
181 /**
182 * The next Option created uses '<code>=</code>' as a means to
183 * separate argument values.
184 *
185 * <b>Example:</b>
186 * <pre>
187 * Option opt = OptionBuilder.withValueSeparator()
188 * .create('D');
189 *
190 * CommandLine line = parser.parse(args);
191 * String propertyName = opt.getValue(0);
192 * String propertyValue = opt.getValue(1);
193 * </pre>
194 *
195 * @return the OptionBuilder instance
196 */
197 public static OptionBuilder withValueSeparator()
198 {
199 OptionBuilder.valuesep = '=';
200
201 return instance;
202 }
203
204 /**
205 * The next Option created will be required if <code>required</code>
206 * is true.
207 *
208 * @param newRequired if true then the Option is required
209 * @return the OptionBuilder instance
210 */
211 public static OptionBuilder isRequired(boolean newRequired)
212 {
213 OptionBuilder.required = newRequired;
214
215 return instance;
216 }
217
218 /**
219 * The next Option created can have unlimited argument values.
220 *
221 * @return the OptionBuilder instance
222 */
223 public static OptionBuilder hasArgs()
224 {
225 OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
226
227 return instance;
228 }
229
230 /**
231 * The next Option created can have <code>num</code> argument values.
232 *
233 * @param num the number of args that the option can have
234 * @return the OptionBuilder instance
235 */
236 public static OptionBuilder hasArgs(int num)
237 {
238 OptionBuilder.numberOfArgs = num;
239
240 return instance;
241 }
242
243 /**
244 * The next Option can have an optional argument.
245 *
246 * @return the OptionBuilder instance
247 */
248 public static OptionBuilder hasOptionalArg()
249 {
250 OptionBuilder.numberOfArgs = 1;
251 OptionBuilder.optionalArg = true;
252
253 return instance;
254 }
255
256 /**
257 * The next Option can have an unlimited number of optional arguments.
258 *
259 * @return the OptionBuilder instance
260 */
261 public static OptionBuilder hasOptionalArgs()
262 {
263 OptionBuilder.numberOfArgs = Option.UNLIMITED_VALUES;
264 OptionBuilder.optionalArg = true;
265
266 return instance;
267 }
268
269 /**
270 * The next Option can have the specified number of optional arguments.
271 *
272 * @param numArgs - the maximum number of optional arguments
273 * the next Option created can have.
274 * @return the OptionBuilder instance
275 */
276 public static OptionBuilder hasOptionalArgs(int numArgs)
277 {
278 OptionBuilder.numberOfArgs = numArgs;
279 OptionBuilder.optionalArg = true;
280
281 return instance;
282 }
283
284 /**
285 * The next Option created will have a value that will be an instance
286 * of <code>type</code>.
287 * <p>
288 * <b>Note:</b> this method is kept for binary compatibility and the
289 * input type is supposed to be a {@link Class} object.
290 *
291 * @param newType the type of the Options argument value
292 * @return the OptionBuilder instance
293 * @deprecated since 1.3, use {@link #withType(Class)} instead
294 */
295 @Deprecated
296 public static OptionBuilder withType(Object newType)
297 {
298 return withType((Class<?>) newType);
299 }
300
301 /**
302 * The next Option created will have a value that will be an instance
303 * of <code>type</code>.
304 *
305 * @param newType the type of the Options argument value
306 * @return the OptionBuilder instance
307 * @since 1.3
308 */
309 public static OptionBuilder withType(Class<?> newType)
310 {
311 OptionBuilder.type = newType;
312
313 return instance;
314 }
315
316 /**
317 * The next Option created will have the specified description
318 *
319 * @param newDescription a description of the Option's purpose
320 * @return the OptionBuilder instance
321 */
322 public static OptionBuilder withDescription(String newDescription)
323 {
324 OptionBuilder.description = newDescription;
325
326 return instance;
327 }
328
329 /**
330 * Create an Option using the current settings and with
331 * the specified Option <code>char</code>.
332 *
333 * @param opt the character representation of the Option
334 * @return the Option instance
335 * @throws IllegalArgumentException if <code>opt</code> is not
336 * a valid character. See Option.
337 */
338 public static Option create(char opt) throws IllegalArgumentException
339 {
340 return create(String.valueOf(opt));
341 }
342
343 /**
344 * Create an Option using the current settings
345 *
346 * @return the Option instance
347 * @throws IllegalArgumentException if <code>longOpt</code> has not been set.
348 */
349 public static Option create() throws IllegalArgumentException
350 {
351 if (longopt == null)
352 {
353 OptionBuilder.reset();
354 throw new IllegalArgumentException("must specify longopt");
355 }
356
357 return create(null);
358 }
359
360 /**
361 * Create an Option using the current settings and with
362 * the specified Option <code>char</code>.
363 *
364 * @param opt the <code>java.lang.String</code> representation
365 * of the Option
366 * @return the Option instance
367 * @throws IllegalArgumentException if <code>opt</code> is not
368 * a valid character. See Option.
369 */
370 public static Option create(String opt) throws IllegalArgumentException
371 {
372 Option option = null;
373 try
374 {
375 // create the option
376 option = new Option(opt, description);
377
378 // set the option properties
379 option.setLongOpt(longopt);
380 option.setRequired(required);
381 option.setOptionalArg(optionalArg);
382 option.setArgs(numberOfArgs);
383 option.setType(type);
384 option.setValueSeparator(valuesep);
385 option.setArgName(argName);
386 }
387 finally
388 {
389 // reset the OptionBuilder properties
390 OptionBuilder.reset();
391 }
392
393 // return the Option instance
394 return option;
395 }
396 }