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
This commit is contained in:
Dave Syer
2013-05-24 10:54:39 +01:00
committed by Chris Beams
parent f9b5b1df53
commit 7860af8624
6 changed files with 34 additions and 12 deletions

View File

@@ -185,7 +185,7 @@ import org.springframework.util.StringUtils;
* @see SimpleCommandLinePropertySource
* @see JOptCommandLinePropertySource
*/
public abstract class CommandLinePropertySource<T> extends PropertySource<T> {
public abstract class CommandLinePropertySource<T> extends EnumerablePropertySource<T> {
/** The default name given to {@link CommandLinePropertySource} instances: {@value} */
public static final String COMMAND_LINE_PROPERTY_SOURCE_NAME = "commandLineArgs";
@@ -218,7 +218,7 @@ public abstract class CommandLinePropertySource<T> extends PropertySource<T> {
public void setNonOptionArgsPropertyName(String nonOptionArgsPropertyName) {
this.nonOptionArgsPropertyName = nonOptionArgsPropertyName;
}
/**
* Return whether this {@code PropertySource} contains a property with the given name.
* <p>This implementation first checks to see if the name specified is the special

View File

@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
/**
* {@link CommandLinePropertySource} implementation backed by a JOpt {@link OptionSet}.
@@ -76,7 +77,20 @@ public class JOptCommandLinePropertySource extends CommandLinePropertySource<Opt
protected boolean containsOption(String name) {
return this.source.has(name);
}
@Override
public String[] getPropertyNames() {
List<String> names = new ArrayList<>();
for (OptionSpec<?> spec : source.specs()) {
List<String> aliases = new ArrayList<>(spec.options());
if (!aliases.isEmpty()) {
// Only the longest name is used for enumerating
names.add(aliases.get(aliases.size()-1));
}
}
return names.toArray(new String[names.size()]);
}
@Override
public List<String> getOptionValues(String name) {
List<?> argValues = this.source.valuesOf(name);

View File

@@ -94,6 +94,14 @@ public class SimpleCommandLinePropertySource extends CommandLinePropertySource<C
public SimpleCommandLinePropertySource(String name, String[] args) {
super(name, new SimpleCommandLineArgsParser().parse(args));
}
/**
* Get the property names for the option arguments.
*/
@Override
public String[] getPropertyNames() {
return source.getOptionNames().toArray(new String[source.getOptionNames().size()]);
}
@Override
protected boolean containsOption(String name) {