Repository navigation
Expand file tree
/
Copy pathOptionSet.java
More file actions
746 lines (680 loc) · 31.7 KB
/
Copy pathOptionSet.java
File metadata and controls
746 lines (680 loc) · 31.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
/*
* Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
*
* Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product
* that is described in this document. In particular, and without limitation, these intellectual property
* rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or
* more additional patents or pending patent applications in the U.S. and in other countries.
*
* U.S. Government Rights - Commercial software. Government users are subject to the Sun
* Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its
* supplements.
*
* Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or
* registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks
* are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the
* U.S. and other countries.
*
* UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open
* Company, Ltd.
*/
package com.sun.max.program.option;
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import com.sun.max.*;
import com.sun.max.lang.*;
import com.sun.max.program.*;
import com.sun.max.program.option.gui.*;
/**
* The {@code OptionSet} class parses and collects options from the command line and
* configuration files.
*
* @author Ben L. Titzer
*/
public class OptionSet {
/**
* The {@code Syntax} enum allows different options to be parsed differently,
* depending on their usage.
*/
public enum Syntax {
REQUIRES_EQUALS {
@Override
public String getUsage(Option option) {
return "-" + option.getName() + "=" + option.getType().getValueFormat();
}
},
EQUALS_OR_BLANK {
@Override
public String getUsage(Option option) {
return "-" + option.getName() + "[=" + option.getType().getValueFormat() + "]";
}
},
REQUIRES_BLANK {
@Override
public String getUsage(Option option) {
return "-" + option.getName();
}
},
CONSUMES_NEXT {
@Override
public String getUsage(Option option) {
return "-" + option.getName() + " " + option.getType().getValueFormat();
}
};
public abstract String getUsage(Option option);
}
protected final Map<String, Option> optionMap;
protected final Map<String, Syntax> optionSyntax;
protected final Map<String, String> optionValues;
protected final boolean allowUnrecognizedOptions;
protected static final String[] NO_ARGUMENTS = {};
protected String[] arguments = NO_ARGUMENTS;
/**
* Creates an option set that does not allow unrecognized options to be present when
* {@linkplain #parseArguments(String[]) parsing command line arguments} or
* {@linkplain #loadOptions(OptionSet) loading options from another option set}.
*/
public OptionSet() {
this(false);
}
/**
* Creates an option set.
*
* @param allowUnrecognizedOptions
* specifies if this option set allows unrecognized options to be present when
* {@linkplain #parseArguments(String[]) parsing command line arguments} or
* {@linkplain #loadOptions(OptionSet) loading options from another option set}.
*/
public OptionSet(boolean allowUnrecognizedOptions) {
optionValues = new HashMap<String, String>();
// Using a LinkedHashMap to preserve insertion order when iterating over values
optionMap = new LinkedHashMap<String, Option>();
optionSyntax = new HashMap<String, Syntax>();
this.allowUnrecognizedOptions = allowUnrecognizedOptions;
}
/**
* Converts this option set into a list of command line arguments, to be used, for example, to pass to an external
* tool. For each option in this set that has been explicitly set this method will prepend an appropriate option
* string of appropriate syntactic form (e.g. "-name=value") to the array of arguments passed.
*
* @return a new array of program arguments that includes these options
*/
public String[] asArguments() {
String[] newArgs = Arrays.copyOf(arguments, arguments.length + optionValues.size());
int i = 0;
for (String name : optionValues.keySet()) {
final String value = optionValues.get(name);
final Syntax syntax = optionSyntax.get(name);
if (syntax == Syntax.REQUIRES_BLANK) {
newArgs[i++] = "-" + name;
} else if (syntax == Syntax.CONSUMES_NEXT) {
newArgs = Arrays.copyOf(newArgs, newArgs.length + 1);
newArgs[i++] = "-" + name;
newArgs[i++] = value;
} else {
newArgs[i++] = "-" + name + "=" + value;
}
}
return newArgs;
}
/**
* Gets an option set derived from this option set that contains all the unrecognized options that have been loaded
* or parsed into this option set. The returned option set also includes a copy of the
* {@linkplain #getArguments() non-option arguments} from this option set.
* @return a new option set encapsulating all the arguments and options
*/
public OptionSet getArgumentsAndUnrecognizedOptions() {
final OptionSet argumentsAndUnrecognizedOptions = new OptionSet(true);
for (Map.Entry<String, String> entry : optionValues.entrySet()) {
if (!optionMap.containsKey(entry.getKey())) {
argumentsAndUnrecognizedOptions.optionValues.put(entry.getKey(), entry.getValue());
}
}
argumentsAndUnrecognizedOptions.arguments = arguments;
return argumentsAndUnrecognizedOptions;
}
/**
* Handles an Option.Error raised while loading or parsing values into this option set.
* <p>
* This default implementation is to print a usage message and the call {@link System#exit(int)}.
* @param error the error that occurred
* @param optionName the name of the option being parsed
*/
protected void handleErrorDuringParseOrLoad(Option.Error error, String optionName) {
System.out.println("Error parsing option -" + optionName + ": " + error.getMessage());
printHelp(System.out, 78);
System.exit(1);
}
/**
* Parses a list of command line arguments, processing the leading options (i.e. arguments that start with '-')
* and returning the "leftover" arguments to the caller. The longest tail of {@code arguments} that starts with a non-option argument can be retrieved after parsing with {@link #getArguments()}.
*
* @param args
* the arguments
* @return this option set
*/
public OptionSet parseArguments(String[] args) {
// parse the options
int i = 0;
for (; i < args.length; i++) {
final String argument = args[i];
if (argument.charAt(0) == '-') {
// is the beginning of a valid option.
final int index = argument.indexOf('=');
final String optionName = getOptionName(argument, index);
String value = getOptionValue(argument, index);
final Syntax syntax = optionSyntax.get(optionName);
// check the syntax of this option
try {
checkSyntax(optionName, syntax, value);
if (syntax == Syntax.CONSUMES_NEXT) {
value = args[++i];
}
setValue(optionName, value);
} catch (Option.Error error) {
handleErrorDuringParseOrLoad(error, optionName);
}
} else {
// is not an option, therefore the start of arguments
break;
}
}
final int left = args.length - i;
arguments = new String[left];
System.arraycopy(args, i, arguments, 0, left);
if (System.getProperty("useProgramOptionDialog") != null) {
OptionsDialog.show(null, this);
}
return this;
}
/**
* The {@code getArguments()} method gets the leftover command line options
* from the last call to {@code parseArguments}.
*
* @return the leftover command line options
*/
public String[] getArguments() {
if (arguments.length == 0) {
return arguments;
}
return Arrays.copyOf(arguments, arguments.length);
}
/**
* Determines if this option set allows parsing or loading of unrecognized options.
* @return {@code true} if this option set allows unrecognized options
*/
public boolean allowsUnrecognizedOptions() {
return allowUnrecognizedOptions;
}
/**
* The {@code loadSystemProperties()} method loads the value of the valid
* options from the systems properties with the specified prefix.
*
* @param prefix the prefix of each system property, used to disambiguate
* these options from other system properties.
* @return this option set
*/
public OptionSet loadSystemProperties(String prefix) {
final Properties systemProperties = System.getProperties();
final Properties properties = new Properties();
for (String key : systemProperties.stringPropertyNames()) {
if (key.startsWith(prefix)) {
properties.setProperty(key.substring(prefix.length()), systemProperties.getProperty(key));
}
}
return loadProperties(properties, true);
}
/**
* The {@code storeSystemProperties()} method stores these option values
* into the system properties.
*
* @param prefix the prefix to append to all option names when inserting them
* into the systems properties
*/
public void storeSystemProperties(String prefix) {
for (Map.Entry<String, String> entry : optionValues.entrySet()) {
System.setProperty(prefix + entry.getKey(), entry.getValue());
}
}
/**
* Loads the specified properties into this set of options.
*
* @param p
* the properties set to load into this set of options
* @param loadall
* true if this method should load all properties in the property set into this option set; false if this
* method should only load properties for options already in this option set
* @return this option set
*/
public OptionSet loadProperties(Properties p, boolean loadall) {
if (loadall) {
// if loadall is specified, load all properties in the set
for (Object object : p.keySet()) {
final String name = (String) object;
final String val = p.getProperty(name);
try {
setValue(name, val);
} catch (Option.Error error) {
handleErrorDuringParseOrLoad(error, name);
}
}
} else {
// if loadall is not specified, only load options that are in this option set.
for (Object o : p.keySet()) {
final String name = (String) o;
if (optionMap.containsKey(name)) {
final String val = p.getProperty(name);
try {
setValue(name, val);
} catch (Option.Error error) {
handleErrorDuringParseOrLoad(error, name);
}
}
}
}
if (System.getProperty("useProgramOptionDialog") != null) {
OptionsDialog.show(null, this);
}
return this;
}
/**
* The {@code loadFile()} method parses properties from a file and loads them into this set of options.
*
* @param fname
* the filename from while to load the properties
* @param loadall
* true if this method should load all properties in the property set into this option set; false if this
* method should only load properties for options already in this option set
* @return this option set
* @throws java.io.IOException
* if there is a problem opening or reading the file
* @throws Option.Error
* if there is a problem parsing an option
*/
public OptionSet loadFile(String fname, boolean loadall) throws IOException, Option.Error {
final Properties defs = new Properties();
final FileInputStream stream = new FileInputStream(new File(fname));
defs.load(stream);
stream.close();
return loadProperties(defs, loadall);
}
/**
* Loads a set of options and {@linkplain #getArguments() arguments} from another option set.
*
* @param options the option set from which to load the option values
* @return this option set
*/
public OptionSet loadOptions(OptionSet options) {
for (Map.Entry<String, String> entry : options.optionValues.entrySet()) {
try {
setValue(entry.getKey(), entry.getValue());
} catch (Option.Error error) {
handleErrorDuringParseOrLoad(error, entry.getKey());
}
}
arguments = options.arguments;
if (System.getProperty("useProgramOptionDialog") != null) {
OptionsDialog.show(null, this);
}
return this;
}
protected void checkSyntax(String optname, Syntax syntax, String value) {
if (syntax == Syntax.REQUIRES_BLANK && value != null) {
throw new Option.Error("syntax error: \"-" + optname + "\" required");
}
if (syntax == Syntax.REQUIRES_EQUALS && value == null) {
throw new Option.Error("syntax error: \"-" + optname + "=value\" required");
}
if (syntax == Syntax.CONSUMES_NEXT && value != null) {
throw new Option.Error("syntax error: \"-" + optname + " value\" required");
}
}
protected String getOptionName(String argument, int equalIndex) {
if (equalIndex < 0) { // naked option
return argument.substring(1, argument.length());
}
return argument.substring(1, equalIndex);
}
protected String getOptionValue(String argument, int equalIndex) {
if (equalIndex < 0) { // naked option
return null;
}
return argument.substring(equalIndex + 1);
}
/**
* Adds the options of an {@link OptionSet} to this set.
* @param optionSet the set of options to add
*/
public void addOptions(OptionSet optionSet) {
for (Option<?> option : optionSet.getOptions()) {
final Syntax syntax = optionSet.optionSyntax.get(option.getName());
addOption(option, syntax);
}
}
/**
* The {@code addOption()} method adds an option with the {@link Syntax#REQUIRES_EQUALS} syntax to this option set.
*
* @param option the new option to add to this set
* @return the option passed as the argument, after it has been added to this option set
*/
public <T> Option<T> addOption(Option<T> option) {
return addOption(option, Syntax.REQUIRES_EQUALS);
}
/**
* The {@code addOption()} method adds an option to this option set.
*
* @param option the new option to add to this set
* @param syntax the syntax of the option, which specifies how to parse the option
* from command line parameters
* @return the option passed as the argument, after it has been added to this option set
*/
public <T> Option<T> addOption(Option<T> option, Syntax syntax) {
final String name = option.getName();
final Option existingOption = optionMap.put(name, option);
if (existingOption != null) {
throw ProgramError.unexpected("Cannot register more than one option under the same name: " + option.getName());
}
optionSyntax.put(name, syntax);
return option;
}
/**
* The {@code setSyntax()} method sets the syntax of a particular option.
*
* @param option the option for which to change the syntax
* @param syntax the new syntax for the instruction
*/
public void setSyntax(Option option, Syntax syntax) {
optionSyntax.put(option.getName(), syntax);
}
/**
* The {@code setValue()} method sets the value of the specified option in
* this option set. If there is no option by the specified name, the name/value
* pair will simply be remembered.
*
* @param name the name of the option
* @param value the new value of the option as a string
* @throws Option.Error if {@code name} denotes an unrecognized option and this
*/
public void setValue(String name, String value) {
final String v = value == null ? "" : value;
final Option opt = optionMap.get(name);
if (opt != null) {
opt.setString(v);
} else {
if (!allowUnrecognizedOptions) {
throw new Option.Error("unrecognized option -" + name);
}
}
optionValues.put(name, v);
}
public void setValuesAgain() {
for (String name : optionValues.keySet()) {
final Option opt = optionMap.get(name);
opt.setString(optionValues.get(name));
}
}
public String getStringValue(String name) {
return optionValues.get(name);
}
/**
* The {@code hasOptionSpecified()} method checks whether an option with the specified
* name has been assigned to. An option as been "assigned to" if its value has been set
* by either parsing arguments (the {@code parseArguments() method} or loading properties
* from a file or the system properties.
*
* @param name the name of the option to query
* @return true if an option with the specified name has been set; false otherwise
*/
public boolean hasOptionSpecified(String name) {
return optionValues.containsKey(name);
}
/**
* Retrieves the options from this option
* set, in the order in which they were added.
* @return an iterable collection of {@code Option} instances, sorted according to insertion order
*/
public Iterable<Option<?>> getOptions() {
return Utils.cast(optionMap.values());
}
/**
* The {@code getSortedOptions()} method retrieves the options from this option
* set, sorting all options by their names.
* @return an iterable collection of {@code Option} instances, sorted according to the name of each option
*/
public Iterable<Option<?>> getSortedOptions() {
final List<Option<?>> list = new LinkedList<Option<?>>();
final TreeSet<String> tree = new TreeSet<String>();
for (String string : optionMap.keySet()) {
tree.add(string);
}
for (String string : tree) {
list.add(optionMap.get(string));
}
return list;
}
/**
* Prints the help message header.
*
* @param stream the output stream to which to write the help text
*/
protected void printHelpHeader(PrintStream stream) {
}
/**
* The {@code printHelp()} method prints a textual listing of these options and their syntax
* to the specified output stream.
* @param stream the output stream to which to write the help text
* @param width the length of the line to truncate
*/
public void printHelp(PrintStream stream, int width) {
printHelpHeader(stream);
for (Option<?> option : getSortedOptions()) {
if (option.type == OptionTypes.BLANK_BOOLEAN_TYPE && option instanceof FieldOption) {
FieldOption fopt = (FieldOption) option;
try {
if (!fopt.nullValue.equals(fopt.field.getBoolean(null))) {
// Don't show message for "-XX:+<opt>" option if the default is represented by the
// "-XX:-<opt>" option instead (and vice versa).
continue;
}
} catch (Exception e) {
}
}
final Option<Object> opt = Utils.cast(option);
stream.print(" " + getUsage(opt));
final Object defaultValue = opt.getDefaultValue();
if (defaultValue != null) {
stream.println(" (default: " + opt.getType().unparseValue(defaultValue) + ")");
} else {
stream.println();
}
final String help = opt.getHelp();
if (help.length() > 0) {
stream.print(Strings.formatParagraphs(help, 8, 0, width));
stream.println();
}
}
}
/**
* This method gets a usage string for a particular option that describes
* the range of valid string values that it accepts.
* @param option the option for which to get usage
* @return a string describing the usage syntax for the specified option
*/
public String getUsage(Option option) {
return optionSyntax.get(option.getName()).getUsage(option);
}
/**
* This method adds all public static fields with appropriate types to the
* option set with the specified prefix.
* @param javaClass the java class containing the fields
* @param prefix the prefix to add to the options
* @param helpMap map from option names to the help message for the option (may be {@code null})
*/
public void addFieldOptions(Class<?> javaClass, String prefix, Map<String, String> helpMap) {
for (final Field field : javaClass.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
field.setAccessible(true);
final OptionSettings settings = field.getAnnotation(OptionSettings.class);
String help;
String name;
if (settings != null) {
help = settings.help();
name = settings.name().isEmpty() ? field.getName().replace('_', '-') : settings.name();
} else {
name = field.getName().replace('_', '-');
help = helpMap != null ? helpMap.get(name) : "";
if (help == null) {
help = "";
}
}
addFieldOption(prefix, name, null, field, help);
}
}
}
/**
* Adds a new option whose value is stored in the specified reflection field.
* @param prefix the name of the option
* @param name the name of the option
* @param object the object containing the field (if the field is not static)
* @param field the field to store the value
* @param help the help text for the option @return a new option that will mod?ify the field when parsed
* @return the option created
*/
@SuppressWarnings("unchecked")
public Option<?> addFieldOption(String prefix, String name, Object object, Field field, String help) {
final Class<?> fieldType = field.getType();
final Object defaultValue;
final String optionName = prefix + ":" + name;
try {
defaultValue = field.get(null);
} catch (IllegalAccessException e) {
return null;
}
if (fieldType == boolean.class) {
if (prefix.length() > 0) {
// setup a "-prefix+name" option
String plusName = prefix + ":+" + name;
FieldOption<Boolean> plusOption = new FieldOption<Boolean>(plusName, object, field, (Boolean) defaultValue, OptionTypes.BLANK_BOOLEAN_TYPE, help);
plusOption.nullValue = true;
addOption(plusOption, Syntax.REQUIRES_BLANK);
// setup a "-prefix-name" option
String minusName = prefix + ":-" + name;
FieldOption<Boolean> minusOption = new FieldOption<Boolean>(minusName, object, field, (Boolean) defaultValue, OptionTypes.BLANK_BOOLEAN_TYPE, help);
minusOption.nullValue = false;
return addOption(minusOption, Syntax.REQUIRES_BLANK);
}
return addOption(new FieldOption<Boolean>(optionName, object, field, (Boolean) defaultValue, OptionTypes.BOOLEAN_TYPE, help));
} else if (fieldType == int.class) {
return addOption(new FieldOption<Integer>(optionName, object, field, (Integer) defaultValue, OptionTypes.INT_TYPE, help));
} else if (fieldType == float.class) {
return addOption(new FieldOption<Float>(optionName, object, field, (Float) defaultValue, OptionTypes.FLOAT_TYPE, help));
} else if (fieldType == long.class) {
return addOption(new FieldOption<Long>(optionName, object, field, (Long) defaultValue, OptionTypes.LONG_TYPE, help));
} else if (fieldType == double.class) {
return addOption(new FieldOption<Double>(optionName, object, field, (Double) defaultValue, OptionTypes.DOUBLE_TYPE, help));
} else if (fieldType == String.class) {
return addOption(new FieldOption<String>(optionName, object, field, (String) defaultValue, OptionTypes.STRING_TYPE, help));
} else if (fieldType == File.class) {
return addOption(new FieldOption<File>(optionName, object, field, (File) defaultValue, OptionTypes.FILE_TYPE, help));
} else if (fieldType.isEnum()) {
final Class<? extends Enum> enumClass = Utils.cast(fieldType);
return addOption(makeEnumFieldOption(optionName, object, field, defaultValue, enumClass, help));
}
return null;
}
private <T extends Enum<T>> FieldOption<T> makeEnumFieldOption(String name, Object object, Field field, Object defaultValue, Class<T> enumClass, String help) {
final OptionTypes.EnumType<T> optionType = new OptionTypes.EnumType<T>(enumClass);
final T defaultV = Utils.<T>cast(defaultValue);
return new FieldOption<T>(name, object, field, defaultV, optionType, help);
}
public Option<String> newStringOption(String name, String defaultValue, String help) {
return addOption(new Option<String>(name, defaultValue, OptionTypes.STRING_TYPE, help));
}
public Option<Integer> newIntegerOption(String name, Integer defaultValue, String help) {
return addOption(new Option<Integer>(name, defaultValue, OptionTypes.INT_TYPE, help));
}
public Option<Long> newLongOption(String name, Long defaultValue, String help) {
return addOption(new Option<Long>(name, defaultValue, OptionTypes.LONG_TYPE, help));
}
public Option<Float> newFloatOption(String name, Float defaultValue, String help) {
return addOption(new Option<Float>(name, defaultValue, OptionTypes.FLOAT_TYPE, help));
}
public Option<Double> newDoubleOption(String name, Double defaultValue, String help) {
return addOption(new Option<Double>(name, defaultValue, OptionTypes.DOUBLE_TYPE, help));
}
public Option<List<String>> newStringListOption(String name, String defaultValue, String help) {
return addOption(new Option<List<String>>(name, defaultValue == null ? null : OptionTypes.COMMA_SEPARATED_STRING_LIST_TYPE.parseValue(defaultValue), OptionTypes.COMMA_SEPARATED_STRING_LIST_TYPE, help));
}
public Option<List<String>> newStringListOption(String name, String[] defaultValue, String help) {
List<String> list = null;
if (defaultValue != null) {
list = new ArrayList<String>(defaultValue.length);
list.addAll(Arrays.asList(defaultValue));
}
return addOption(new Option<List<String>>(name, list, OptionTypes.COMMA_SEPARATED_STRING_LIST_TYPE, help));
}
public Option<List<String>> newStringListOption(String name, String defaultValue, char separator, String help) {
final OptionTypes.StringListType type = new OptionTypes.StringListType(separator);
return addOption(new Option<List<String>>(name, defaultValue == null ? null : type.parseValue(defaultValue), type, help));
}
public <T> Option<List<T>> newListOption(String name, String defaultValue, Option.Type<T> elementOptionType, char separator, String help) {
final OptionTypes.ListType<T> type = new OptionTypes.ListType<T>(separator, elementOptionType);
return addOption(new Option<List<T>>(name, defaultValue == null ? null : type.parseValue(defaultValue), type, help));
}
public Option<File> newFileOption(String name, String defaultValue, String help) {
return newFileOption(name, OptionTypes.FILE_TYPE.parseValue(defaultValue), help);
}
public Option<File> newFileOption(String name, File defaultValue, String help) {
return addOption(new Option<File>(name, defaultValue, OptionTypes.FILE_TYPE, help));
}
public Option<URL> newURLOption(String name, URL defaultValue, String help) {
return addOption(new Option<URL>(name, defaultValue, OptionTypes.URL_TYPE, help));
}
public <T> Option<T> newInstanceOption(String name, Class<T> klass, T defaultValue, String help) {
return addOption(new Option<T>(name, defaultValue, OptionTypes.createInstanceOptionType(klass), help));
}
public <T> Option<List<T>> newListInstanceOption(String name, String defaultValue, Class<T> klass, char separator, String help) {
final OptionTypes.ListType<T> type = OptionTypes.createInstanceListOptionType(klass, separator);
return addOption(new Option<List<T>>(name, (defaultValue == null) ? null : type.parseValue(defaultValue), type, help));
}
public Option<Boolean> newBooleanOption(String name, Boolean defaultValue, String help) {
if (defaultValue != null && !defaultValue) {
return addOption(new Option<Boolean>(name, defaultValue, OptionTypes.BOOLEAN_TYPE, help), Syntax.EQUALS_OR_BLANK);
}
return addOption(new Option<Boolean>(name, defaultValue, OptionTypes.BOOLEAN_TYPE, help));
}
public <T> Option<T> newOption(String name, String defaultValue, Option.Type<T> type, String help) {
return newOption(name, type.parseValue(defaultValue), type, Syntax.REQUIRES_EQUALS, help);
}
public <T> Option<T> newOption(String name, T defaultValue, Option.Type<T> type, Syntax syntax, String help) {
return addOption(new Option<T>(name, defaultValue, type, help), syntax);
}
public <E extends Enum<E>> Option<E> newEnumOption(String name, E defaultValue, Class<E> enumClass, String help) {
return addOption(new Option<E>(name, defaultValue, new OptionTypes.EnumType<E>(enumClass), help));
}
public <E extends Enum<E>> Option<List<E>> newEnumListOption(String name, Iterable<E> defaultValue, Class<E> enumClass, String help) {
final List<E> list;
if (defaultValue == null) {
list = null;
} else if (defaultValue instanceof List) {
list = Utils.cast(defaultValue);
} else if (defaultValue instanceof Collection) {
final Collection<E> collection = Utils.cast(defaultValue);
list = new ArrayList<E>(collection);
} else {
list = new ArrayList<E>();
for (E value : defaultValue) {
list.add(value);
}
}
final Option<List<E>> option = new Option<List<E>>(name, list, new OptionTypes.EnumListType<E>(enumClass, ','), help);
return addOption(option);
}
public Option<File> newConfigOption(String name, File defaultFile, String help) {
return addOption(new Option<File>(name, defaultFile, new OptionTypes.ConfigFile(this), help));
}
}