Skip to content

Commit 269eae1

Browse files
committed
CLI-271: CommandLine.getXXX and CommandLine.hasXXX should accept an Option as a
parameter. Thanks to Christoph Läubrich. This also fixes apache#9 from GitHub git-svn-id: https://svn.apache.org/repos/asf/commons/proper/cli/trunk@1788678 13f79535-47bb-0310-9956-ffa450edef68
1 parent 73d649b commit 269eae1

6 files changed

Lines changed: 361 additions & 24 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
<body>
2424

2525
<release version="1.5" date="tba" description="tba">
26+
<action type="add" dev="britter" due-to="Christoph Läubrich" issue="CLI-271">
27+
CommandLine.getXXX and CommandLine.hasXXX should accept an Option as a parameter
28+
</action>
2629
</release>
2730

2831
<release version="1.4" date="2017-03-09" description="New features and bug fixes">

src/main/java/org/apache/commons/cli/CommandLine.java

Lines changed: 146 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ protected CommandLine()
5555
{
5656
// nothing to do
5757
}
58+
59+
/**
60+
* Query to see if an option has been set.
61+
*
62+
* @param opt the option to check
63+
* @return true if set, false if not
64+
* @since 1.4
65+
*/
66+
public boolean hasOption(Option opt)
67+
{
68+
return options.contains(opt);
69+
}
5870

5971
/**
6072
* Query to see if an option has been set.
@@ -64,9 +76,9 @@ protected CommandLine()
6476
*/
6577
public boolean hasOption(String opt)
6678
{
67-
return options.contains(resolveOption(opt));
79+
return hasOption(resolveOption(opt));
6880
}
69-
81+
7082
/**
7183
* Query to see if an option has been set.
7284
*
@@ -98,39 +110,87 @@ public Object getOptionObject(String opt)
98110
return null;
99111
}
100112
}
101-
113+
102114
/**
103115
* Return a version of this <code>Option</code> converted to a particular type.
104116
*
105-
* @param opt the name of the option
117+
* @param option the name of the option
106118
* @return the value parsed into a particular object
107119
* @throws ParseException if there are problems turning the option value into the desired type
108120
* @see PatternOptionBuilder
109-
* @since 1.2
121+
* @since 1.4
110122
*/
111-
public Object getParsedOptionValue(String opt) throws ParseException
123+
public Object getParsedOptionValue(Option option) throws ParseException
112124
{
113-
String res = getOptionValue(opt);
114-
Option option = resolveOption(opt);
115-
116-
if (option == null || res == null)
125+
if (option == null)
126+
{
127+
return null;
128+
}
129+
String res = getOptionValue(option);
130+
if (res == null)
117131
{
118132
return null;
119133
}
120-
121134
return TypeHandler.createValue(res, option.getType());
122135
}
123136

137+
/**
138+
* Return a version of this <code>Option</code> converted to a particular type.
139+
*
140+
* @param opt the name of the option
141+
* @return the value parsed into a particular object
142+
* @throws ParseException if there are problems turning the option value into the desired type
143+
* @see PatternOptionBuilder
144+
* @since 1.2
145+
*/
146+
public Object getParsedOptionValue(String opt) throws ParseException
147+
{
148+
return getParsedOptionValue(resolveOption(opt));
149+
}
150+
151+
/**
152+
* Return a version of this <code>Option</code> converted to a particular type.
153+
*
154+
* @param opt the name of the option
155+
* @return the value parsed into a particular object
156+
* @throws ParseException if there are problems turning the option value into the desired type
157+
* @see PatternOptionBuilder
158+
* @since 1.2
159+
*/
160+
public Object getParsedOptionValue(char opt) throws ParseException
161+
{
162+
return getParsedOptionValue(String.valueOf(opt));
163+
}
164+
124165
/**
125166
* Return the <code>Object</code> type of this <code>Option</code>.
126167
*
168+
* @deprecated due to System.err message. Instead use getParsedOptionValue(char)
127169
* @param opt the name of the option
128170
* @return the type of opt
129171
*/
130172
public Object getOptionObject(char opt)
131173
{
132174
return getOptionObject(String.valueOf(opt));
133175
}
176+
177+
/**
178+
* Retrieve the first argument, if any, of this option.
179+
*
180+
* @param option the name of the option
181+
* @return Value of the argument if option is set, and has an argument,
182+
* otherwise null.
183+
* @since 1.4
184+
*/
185+
public String getOptionValue(Option option)
186+
{
187+
if (option == null)
188+
{
189+
return null;
190+
}
191+
String[] values = getOptionValues(option);
192+
return (values == null) ? null : values[0];
193+
}
134194

135195
/**
136196
* Retrieve the first argument, if any, of this option.
@@ -141,9 +201,7 @@ public Object getOptionObject(char opt)
141201
*/
142202
public String getOptionValue(String opt)
143203
{
144-
String[] values = getOptionValues(opt);
145-
146-
return (values == null) ? null : values[0];
204+
return getOptionValue(resolveOption(opt));
147205
}
148206

149207
/**
@@ -157,29 +215,42 @@ public String getOptionValue(char opt)
157215
{
158216
return getOptionValue(String.valueOf(opt));
159217
}
160-
218+
161219
/**
162220
* Retrieves the array of values, if any, of an option.
163221
*
164-
* @param opt string name of the option
222+
* @param option string name of the option
165223
* @return Values of the argument if option is set, and has an argument,
166224
* otherwise null.
225+
* @since 1.4
167226
*/
168-
public String[] getOptionValues(String opt)
227+
public String[] getOptionValues(Option option)
169228
{
170229
List<String> values = new ArrayList<String>();
171230

172-
for (Option option : options)
231+
for (Option processedOption : options)
173232
{
174-
if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt()))
233+
if (processedOption.equals(option))
175234
{
176-
values.addAll(option.getValuesList());
235+
values.addAll(processedOption.getValuesList());
177236
}
178237
}
179238

180239
return values.isEmpty() ? null : values.toArray(new String[values.size()]);
181240
}
182241

242+
/**
243+
* Retrieves the array of values, if any, of an option.
244+
*
245+
* @param opt string name of the option
246+
* @return Values of the argument if option is set, and has an argument,
247+
* otherwise null.
248+
*/
249+
public String[] getOptionValues(String opt)
250+
{
251+
return getOptionValues(resolveOption(opt));
252+
}
253+
183254
/**
184255
* Retrieves the option object given the long or short option as a String
185256
*
@@ -216,6 +287,22 @@ public String[] getOptionValues(char opt)
216287
{
217288
return getOptionValues(String.valueOf(opt));
218289
}
290+
291+
/**
292+
* Retrieve the first argument, if any, of an option.
293+
*
294+
* @param option name of the option
295+
* @param defaultValue is the default value to be returned if the option
296+
* is not specified
297+
* @return Value of the argument if option is set, and has an argument,
298+
* otherwise <code>defaultValue</code>.
299+
* @since 1.4
300+
*/
301+
public String getOptionValue(Option option, String defaultValue)
302+
{
303+
String answer = getOptionValue(option);
304+
return (answer != null) ? answer : defaultValue;
305+
}
219306

220307
/**
221308
* Retrieve the first argument, if any, of an option.
@@ -228,9 +315,7 @@ public String[] getOptionValues(char opt)
228315
*/
229316
public String getOptionValue(String opt, String defaultValue)
230317
{
231-
String answer = getOptionValue(opt);
232-
233-
return (answer != null) ? answer : defaultValue;
318+
return getOptionValue(resolveOption(opt), defaultValue);
234319
}
235320

236321
/**
@@ -246,6 +331,44 @@ public String getOptionValue(char opt, String defaultValue)
246331
{
247332
return getOptionValue(String.valueOf(opt), defaultValue);
248333
}
334+
335+
/**
336+
* Retrieve the map of values associated to the option. This is convenient
337+
* for options specifying Java properties like <tt>-Dparam1=value1
338+
* -Dparam2=value2</tt>. The first argument of the option is the key, and
339+
* the 2nd argument is the value. If the option has only one argument
340+
* (<tt>-Dfoo</tt>) it is considered as a boolean flag and the value is
341+
* <tt>"true"</tt>.
342+
*
343+
* @param option name of the option
344+
* @return The Properties mapped by the option, never <tt>null</tt>
345+
* even if the option doesn't exists
346+
* @since 1.4
347+
*/
348+
public Properties getOptionProperties(Option option)
349+
{
350+
Properties props = new Properties();
351+
352+
for (Option processedOption : options)
353+
{
354+
if (processedOption.equals(option))
355+
{
356+
List<String> values = processedOption.getValuesList();
357+
if (values.size() >= 2)
358+
{
359+
// use the first 2 arguments as the key/value pair
360+
props.put(values.get(0), values.get(1));
361+
}
362+
else if (values.size() == 1)
363+
{
364+
// no explicit value, handle it as a boolean
365+
props.put(values.get(0), "true");
366+
}
367+
}
368+
}
369+
370+
return props;
371+
}
249372

250373
/**
251374
* Retrieve the map of values associated to the option. This is convenient

src/test/java/org/apache/commons/cli/CommandLineTest.java

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertNotNull;
22+
import static org.junit.Assert.assertNull;
2223

2324
import java.util.Properties;
2425

@@ -49,6 +50,31 @@ public void testGetOptionProperties() throws Exception
4950

5051
assertEquals("property with long format", "bar", cl.getOptionProperties("property").getProperty("foo"));
5152
}
53+
54+
@Test
55+
public void testGetOptionPropertiesWithOption() throws Exception
56+
{
57+
String[] args = new String[] { "-Dparam1=value1", "-Dparam2=value2", "-Dparam3", "-Dparam4=value4", "-D", "--property", "foo=bar" };
58+
59+
Options options = new Options();
60+
Option option_D = OptionBuilder.withValueSeparator().hasOptionalArgs(2).create('D');
61+
Option option_property = OptionBuilder.withValueSeparator().hasArgs(2).withLongOpt("property").create();
62+
options.addOption(option_D);
63+
options.addOption(option_property);
64+
65+
Parser parser = new GnuParser();
66+
CommandLine cl = parser.parse(options, args);
67+
68+
Properties props = cl.getOptionProperties(option_D);
69+
assertNotNull("null properties", props);
70+
assertEquals("number of properties in " + props, 4, props.size());
71+
assertEquals("property 1", "value1", props.getProperty("param1"));
72+
assertEquals("property 2", "value2", props.getProperty("param2"));
73+
assertEquals("property 3", "true", props.getProperty("param3"));
74+
assertEquals("property 4", "value4", props.getProperty("param4"));
75+
76+
assertEquals("property with long format", "bar", cl.getOptionProperties(option_property).getProperty("foo"));
77+
}
5278

5379
@Test
5480
public void testGetOptions()
@@ -76,6 +102,47 @@ public void testGetParsedOptionValue() throws Exception {
76102
assertEquals(123, ((Number) cmd.getParsedOptionValue("i")).intValue());
77103
assertEquals("foo", cmd.getParsedOptionValue("f"));
78104
}
105+
106+
@Test
107+
public void testGetParsedOptionValueWithChar() throws Exception {
108+
Options options = new Options();
109+
options.addOption(Option.builder("i").hasArg().type(Number.class).build());
110+
options.addOption(Option.builder("f").hasArg().build());
111+
112+
CommandLineParser parser = new DefaultParser();
113+
CommandLine cmd = parser.parse(options, new String[] { "-i", "123", "-f", "foo" });
114+
115+
assertEquals(123, ((Number) cmd.getParsedOptionValue('i')).intValue());
116+
assertEquals("foo", cmd.getParsedOptionValue('f'));
117+
}
118+
119+
@Test
120+
public void testGetParsedOptionValueWithOption() throws Exception {
121+
Options options = new Options();
122+
Option opt_i = Option.builder("i").hasArg().type(Number.class).build();
123+
Option opt_f = Option.builder("f").hasArg().build();
124+
options.addOption(opt_i);
125+
options.addOption(opt_f);
126+
127+
CommandLineParser parser = new DefaultParser();
128+
CommandLine cmd = parser.parse(options, new String[] { "-i", "123", "-f", "foo" });
129+
130+
assertEquals(123, ((Number) cmd.getParsedOptionValue(opt_i)).intValue());
131+
assertEquals("foo", cmd.getParsedOptionValue(opt_f));
132+
}
133+
134+
@Test
135+
public void testNullhOption() throws Exception {
136+
Options options = new Options();
137+
Option opt_i = Option.builder("i").hasArg().type(Number.class).build();
138+
Option opt_f = Option.builder("f").hasArg().build();
139+
options.addOption(opt_i);
140+
options.addOption(opt_f);
141+
CommandLineParser parser = new DefaultParser();
142+
CommandLine cmd = parser.parse(options, new String[] { "-i", "123", "-f", "foo" });
143+
assertNull(cmd.getOptionValue((Option)null));
144+
assertNull(cmd.getParsedOptionValue((Option)null));
145+
}
79146

80147
@Test
81148
public void testBuilder()

src/test/java/org/apache/commons/cli/OptionTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertFalse;
22+
import static org.junit.Assert.assertNotEquals;
2223
import static org.junit.Assert.assertNotSame;
2324
import static org.junit.Assert.assertTrue;
2425

@@ -71,6 +72,13 @@ public void testClone()
7172
assertEquals(0, a.getValuesList().size());
7273
assertEquals(2, b.getValues().length);
7374
}
75+
76+
@Test
77+
public void testHashCode() {
78+
assertNotEquals(Option.builder("test").build().hashCode(), Option.builder("test2").build().hashCode()) ;
79+
assertNotEquals(Option.builder("test").build().hashCode(), Option.builder().longOpt("test").build().hashCode()) ;
80+
assertNotEquals(Option.builder("test").build().hashCode(), Option.builder("test").longOpt("long test").build().hashCode()) ;
81+
}
7482

7583
private static class DefaultOption extends Option
7684
{

0 commit comments

Comments
 (0)