Skip to content

Commit 7860af8

Browse files
Dave Syercbeams
Dave Syer
authored andcommitted
Make CommandLinePropertySource enumerable
JOpt 4.4 has enumerable options, so this change can be made if we upgrade. The only awkward thing is that JOpt allows aliases for options, so we have to pick one to avoid double counting. This implementation picks the last one in the list which is the alphebtically last of the long options, if there are any (e.g. "o1", "option1" returns "option1"). Most of the time there will only be one or two aliases for each option so it won't matter. Issue: SPR-10579
1 parent f9b5b1d commit 7860af8

File tree

6 files changed

+34
-12
lines changed

6 files changed

+34
-12
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ project("spring-core") {
205205
compile(files(cglibRepackJar))
206206
compile("commons-logging:commons-logging:1.1.1")
207207
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
208-
optional("net.sf.jopt-simple:jopt-simple:3.0")
208+
optional("net.sf.jopt-simple:jopt-simple:4.4")
209209
optional("log4j:log4j:1.2.17")
210210
testCompile("xmlunit:xmlunit:1.3")
211211
testCompile("org.codehaus.woodstox:wstx-asl:3.2.7") {

spring-core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@
185185
* @see SimpleCommandLinePropertySource
186186
* @see JOptCommandLinePropertySource
187187
*/
188-
public abstract class CommandLinePropertySource<T> extends PropertySource<T> {
188+
public abstract class CommandLinePropertySource<T> extends EnumerablePropertySource<T> {
189189

190190
/** The default name given to {@link CommandLinePropertySource} instances: {@value} */
191191
public static final String COMMAND_LINE_PROPERTY_SOURCE_NAME = "commandLineArgs";
@@ -218,7 +218,7 @@ public CommandLinePropertySource(String name, T source) {
218218
public void setNonOptionArgsPropertyName(String nonOptionArgsPropertyName) {
219219
this.nonOptionArgsPropertyName = nonOptionArgsPropertyName;
220220
}
221-
221+
222222
/**
223223
* Return whether this {@code PropertySource} contains a property with the given name.
224224
* <p>This implementation first checks to see if the name specified is the special

spring-core/src/main/java/org/springframework/core/env/JOptCommandLinePropertySource.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.List;
2222

2323
import joptsimple.OptionSet;
24+
import joptsimple.OptionSpec;
2425

2526
/**
2627
* {@link CommandLinePropertySource} implementation backed by a JOpt {@link OptionSet}.
@@ -76,7 +77,20 @@ public JOptCommandLinePropertySource(String name, OptionSet options) {
7677
protected boolean containsOption(String name) {
7778
return this.source.has(name);
7879
}
79-
80+
81+
@Override
82+
public String[] getPropertyNames() {
83+
List<String> names = new ArrayList<>();
84+
for (OptionSpec<?> spec : source.specs()) {
85+
List<String> aliases = new ArrayList<>(spec.options());
86+
if (!aliases.isEmpty()) {
87+
// Only the longest name is used for enumerating
88+
names.add(aliases.get(aliases.size()-1));
89+
}
90+
}
91+
return names.toArray(new String[names.size()]);
92+
}
93+
8094
@Override
8195
public List<String> getOptionValues(String name) {
8296
List<?> argValues = this.source.valuesOf(name);

spring-core/src/main/java/org/springframework/core/env/SimpleCommandLinePropertySource.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ public SimpleCommandLinePropertySource(String... args) {
9494
public SimpleCommandLinePropertySource(String name, String[] args) {
9595
super(name, new SimpleCommandLineArgsParser().parse(args));
9696
}
97+
98+
/**
99+
* Get the property names for the option arguments.
100+
*/
101+
@Override
102+
public String[] getPropertyNames() {
103+
return source.getOptionNames().toArray(new String[source.getOptionNames().size()]);
104+
}
97105

98106
@Override
99107
protected boolean containsOption(String name) {

spring-core/src/test/java/org/springframework/core/env/JOptCommandLinePropertySourceTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,17 +117,18 @@ public void withDottedOptionName() {
117117
@Test
118118
public void withDefaultNonOptionArgsNameAndNoNonOptionArgsPresent() {
119119
OptionParser parser = new OptionParser();
120-
parser.accepts("o1").withRequiredArg();
120+
parser.acceptsAll(Arrays.asList("o1","option1")).withRequiredArg();
121121
parser.accepts("o2");
122122
OptionSet optionSet = parser.parse("--o1=v1", "--o2");
123-
PropertySource<?> ps = new JOptCommandLinePropertySource(optionSet);
123+
EnumerablePropertySource<?> ps = new JOptCommandLinePropertySource(optionSet);
124124

125125
assertThat(ps.containsProperty("nonOptionArgs"), is(false));
126126
assertThat(ps.containsProperty("o1"), is(true));
127127
assertThat(ps.containsProperty("o2"), is(true));
128128

129129
assertThat(ps.containsProperty("nonOptionArgs"), is(false));
130130
assertThat(ps.getProperty("nonOptionArgs"), nullValue());
131+
assertThat(ps.getPropertyNames().length, is(2));
131132
}
132133

133134
@Test

spring-core/src/test/java/org/springframework/core/env/SimpleCommandLinePropertySourceTests.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616

1717
package org.springframework.core.env;
1818

19-
import static org.hamcrest.CoreMatchers.equalTo;
20-
import static org.hamcrest.CoreMatchers.is;
21-
import static org.hamcrest.CoreMatchers.nullValue;
22-
import static org.junit.Assert.assertThat;
23-
2419
import java.util.List;
2520

2621
import org.junit.Test;
2722

23+
import static org.hamcrest.CoreMatchers.*;
24+
import static org.junit.Assert.*;
25+
2826
/**
2927
* Unit tests for {@link SimpleCommandLinePropertySource}.
3028
*
@@ -67,14 +65,15 @@ public void withOptionArgsOnly() {
6765

6866
@Test
6967
public void withDefaultNonOptionArgsNameAndNoNonOptionArgsPresent() {
70-
PropertySource<?> ps = new SimpleCommandLinePropertySource("--o1=v1", "--o2");
68+
EnumerablePropertySource<?> ps = new SimpleCommandLinePropertySource("--o1=v1", "--o2");
7169

7270
assertThat(ps.containsProperty("nonOptionArgs"), is(false));
7371
assertThat(ps.containsProperty("o1"), is(true));
7472
assertThat(ps.containsProperty("o2"), is(true));
7573

7674
assertThat(ps.containsProperty("nonOptionArgs"), is(false));
7775
assertThat(ps.getProperty("nonOptionArgs"), nullValue());
76+
assertThat(ps.getPropertyNames().length, is(2));
7877
}
7978

8079
@Test

0 commit comments

Comments
 (0)