29 * However, the following notice accompanied the original version of this |
29 * However, the following notice accompanied the original version of this |
30 * file: |
30 * file: |
31 * |
31 * |
32 * The MIT License |
32 * The MIT License |
33 * |
33 * |
34 * Copyright (c) 2004-2014 Paul R. Holser, Jr. |
34 * Copyright (c) 2004-2015 Paul R. Holser, Jr. |
35 * |
35 * |
36 * Permission is hereby granted, free of charge, to any person obtaining |
36 * Permission is hereby granted, free of charge, to any person obtaining |
37 * a copy of this software and associated documentation files (the |
37 * a copy of this software and associated documentation files (the |
38 * "Software"), to deal in the Software without restriction, including |
38 * "Software"), to deal in the Software without restriction, including |
39 * without limitation the rights to use, copy, modify, merge, publish, |
39 * without limitation the rights to use, copy, modify, merge, publish, |
54 */ |
54 */ |
55 |
55 |
56 package jdk.internal.joptsimple; |
56 package jdk.internal.joptsimple; |
57 |
57 |
58 import java.util.ArrayList; |
58 import java.util.ArrayList; |
59 import java.util.Collection; |
|
60 import java.util.List; |
59 import java.util.List; |
61 import java.util.StringTokenizer; |
60 import java.util.StringTokenizer; |
62 |
61 |
63 import static java.util.Collections.*; |
62 import static java.util.Collections.*; |
64 |
63 import static java.util.Objects.*; |
65 import static jdk.internal.joptsimple.internal.Objects.*; |
64 |
66 import static jdk.internal.joptsimple.internal.Reflection.*; |
65 import static jdk.internal.joptsimple.internal.Reflection.*; |
67 import static jdk.internal.joptsimple.internal.Strings.*; |
66 import static jdk.internal.joptsimple.internal.Strings.*; |
68 |
67 |
69 /** |
68 /** |
70 * <p>Specification of an option that accepts an argument.</p> |
69 * <p>Specification of an option that accepts an argument.</p> |
86 * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a> |
85 * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a> |
87 */ |
86 */ |
88 public abstract class ArgumentAcceptingOptionSpec<V> extends AbstractOptionSpec<V> { |
87 public abstract class ArgumentAcceptingOptionSpec<V> extends AbstractOptionSpec<V> { |
89 private static final char NIL_VALUE_SEPARATOR = '\u0000'; |
88 private static final char NIL_VALUE_SEPARATOR = '\u0000'; |
90 |
89 |
|
90 private final boolean argumentRequired; |
|
91 private final List<V> defaultValues = new ArrayList<>(); |
|
92 |
91 private boolean optionRequired; |
93 private boolean optionRequired; |
92 private final boolean argumentRequired; |
|
93 private ValueConverter<V> converter; |
94 private ValueConverter<V> converter; |
94 private String argumentDescription = ""; |
95 private String argumentDescription = ""; |
95 private String valueSeparator = String.valueOf( NIL_VALUE_SEPARATOR ); |
96 private String valueSeparator = String.valueOf( NIL_VALUE_SEPARATOR ); |
96 private final List<V> defaultValues = new ArrayList<V>(); |
|
97 |
97 |
98 ArgumentAcceptingOptionSpec( String option, boolean argumentRequired ) { |
98 ArgumentAcceptingOptionSpec( String option, boolean argumentRequired ) { |
99 super( option ); |
99 super( option ); |
100 |
100 |
101 this.argumentRequired = argumentRequired; |
101 this.argumentRequired = argumentRequired; |
102 } |
102 } |
103 |
103 |
104 ArgumentAcceptingOptionSpec( Collection<String> options, boolean argumentRequired, String description ) { |
104 ArgumentAcceptingOptionSpec( List<String> options, boolean argumentRequired, String description ) { |
105 super( options, description ); |
105 super( options, description ); |
106 |
106 |
107 this.argumentRequired = argumentRequired; |
107 this.argumentRequired = argumentRequired; |
108 } |
108 } |
109 |
109 |
180 * OptionSet options = parser.parse( new String[] { "-z", "foo,bar,baz", "-z", |
180 * OptionSet options = parser.parse( new String[] { "-z", "foo,bar,baz", "-z", |
181 * "fizz", "-z", "buzz" } ); |
181 * "fizz", "-z", "buzz" } ); |
182 * </code> |
182 * </code> |
183 * </pre> |
183 * </pre> |
184 * |
184 * |
185 * <p>Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p> |
185 * <p>Then <code>options.valuesOf( "z" )</code> would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p> |
186 * |
186 * |
187 * <p>You cannot use Unicode U+0000 as the separator.</p> |
187 * <p>You cannot use Unicode U+0000 as the separator.</p> |
188 * |
188 * |
189 * @param separator a character separator |
189 * @param separator a character separator |
190 * @return self, so that the caller can add clauses to the fluent interface sentence |
190 * @return self, so that the caller can add clauses to the fluent interface sentence |
209 * OptionSet options = parser.parse( new String[] { "-z", "foo:::bar:::baz", "-z", |
209 * OptionSet options = parser.parse( new String[] { "-z", "foo:::bar:::baz", "-z", |
210 * "fizz", "-z", "buzz" } ); |
210 * "fizz", "-z", "buzz" } ); |
211 * </code> |
211 * </code> |
212 * </pre> |
212 * </pre> |
213 * |
213 * |
214 * <p>Then {@code options.valuesOf( "z" )} would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p> |
214 * <p>Then <code>options.valuesOf( "z" )</code> would yield the list {@code [foo, bar, baz, fizz, buzz]}.</p> |
215 * |
215 * |
216 * <p>You cannot use Unicode U+0000 in the separator.</p> |
216 * <p>You cannot use Unicode U+0000 in the separator.</p> |
217 * |
217 * |
218 * @param separator a string separator |
218 * @param separator a string separator |
219 * @return self, so that the caller can add clauses to the fluent interface sentence |
219 * @return self, so that the caller can add clauses to the fluent interface sentence |
234 * @param values the (optional) remainder of the set of default argument values for this spec's option |
234 * @param values the (optional) remainder of the set of default argument values for this spec's option |
235 * @return self, so that the caller can add clauses to the fluent interface sentence |
235 * @return self, so that the caller can add clauses to the fluent interface sentence |
236 * @throws NullPointerException if {@code value}, {@code values}, or any elements of {@code values} are |
236 * @throws NullPointerException if {@code value}, {@code values}, or any elements of {@code values} are |
237 * {@code null} |
237 * {@code null} |
238 */ |
238 */ |
239 @SuppressWarnings("unchecked") |
239 @SafeVarargs |
240 public ArgumentAcceptingOptionSpec<V> defaultsTo( V value, V... values ) { |
240 @SuppressWarnings("varargs") |
|
241 public final ArgumentAcceptingOptionSpec<V> defaultsTo( V value, V... values ) { |
241 addDefaultValue( value ); |
242 addDefaultValue( value ); |
242 defaultsTo( values ); |
243 defaultsTo( values ); |
243 |
244 |
244 return this; |
245 return this; |
245 } |
246 } |
273 public boolean isRequired() { |
274 public boolean isRequired() { |
274 return optionRequired; |
275 return optionRequired; |
275 } |
276 } |
276 |
277 |
277 private void addDefaultValue( V value ) { |
278 private void addDefaultValue( V value ) { |
278 ensureNotNull( value ); |
279 requireNonNull( value ); |
279 defaultValues.add( value ); |
280 defaultValues.add( value ); |
280 } |
281 } |
281 |
282 |
282 @Override |
283 @Override |
283 final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, |
284 final void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, |
284 String detectedArgument ) { |
285 String detectedArgument ) { |
285 |
286 |
286 if ( isNullOrEmpty( detectedArgument ) ) |
287 if ( detectedArgument == null ) |
287 detectOptionArgument( parser, arguments, detectedOptions ); |
288 detectOptionArgument( parser, arguments, detectedOptions ); |
288 else |
289 else |
289 addArguments( detectedOptions, detectedArgument ); |
290 addArguments( detectedOptions, detectedArgument ); |
290 } |
291 } |
291 |
292 |