Browse Source
Users may now work with command line arguments as a source of properties for use with the PropertySource and Environment APIs. An implementation based on the jopt library and a "simple" implementation requiring no external libraries are are provided out-of-the box. See Javadoc for CommandLinePropertySource, JOptCommandLinePropertySource and SimpleCommandLinePropertySource for details. Issue: SPR-8482pull/7/head
11 changed files with 1100 additions and 0 deletions
@ -0,0 +1,91 @@
@@ -0,0 +1,91 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* A simple representation of command line arguments, broken into "option arguments" and |
||||
* "non-option arguments". |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see SimpleCommandLineArgsParser |
||||
*/ |
||||
class CommandLineArgs { |
||||
|
||||
private final Map<String, List<String>> optionArgs = new HashMap<String, List<String>>(); |
||||
private final List<String> nonOptionArgs = new ArrayList<String>(); |
||||
|
||||
/** |
||||
* Add an option argument for the given option name and add the given value to the |
||||
* list of values associated with this option (of which there may be zero or more). |
||||
* The given value may be {@code null}, indicating that the option was specified |
||||
* without an associated value (e.g. "--foo" vs. "--foo=bar"). |
||||
*/ |
||||
public void addOptionArg(String optionName, String optionValue) { |
||||
if (!this.optionArgs.containsKey(optionName)) { |
||||
this.optionArgs.put(optionName, new ArrayList<String>()); |
||||
} |
||||
if (optionValue != null) { |
||||
this.optionArgs.get(optionName).add(optionValue); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return the set of all option arguments present on the command line. |
||||
*/ |
||||
public Set<String> getOptionNames() { |
||||
return Collections.unmodifiableSet(this.optionArgs.keySet()); |
||||
} |
||||
|
||||
/** |
||||
* Return whether the option with the given name was present on the command line. |
||||
*/ |
||||
public boolean containsOption(String optionName) { |
||||
return this.optionArgs.containsKey(optionName); |
||||
} |
||||
|
||||
/** |
||||
* Return the list of values associated with the given option. {@code null} signifies |
||||
* that the option was not present; empty list signifies that no values were associated |
||||
* with this option. |
||||
*/ |
||||
public List<String> getOptionValues(String optionName) { |
||||
return this.optionArgs.get(optionName); |
||||
} |
||||
|
||||
/** |
||||
* Add the given value to the list of non-option arguments. |
||||
*/ |
||||
public void addNonOptionArg(String value) { |
||||
this.nonOptionArgs.add(value); |
||||
} |
||||
|
||||
/** |
||||
* Return the list of non-option arguments specified on the command line. |
||||
*/ |
||||
public List<String> getNonOptionArgs() { |
||||
return Collections.unmodifiableList(this.nonOptionArgs); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,296 @@
@@ -0,0 +1,296 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import java.util.Collection; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Abstract base class for {@link PropertySource} implementations backed by command line |
||||
* arguments. The parameterized type {@code T} represents the underlying source of command |
||||
* line options. This may be as simple as a String array in the case of |
||||
* {@link SimpleCommandLinePropertySource}, or specific to a particular API such as JOpt's |
||||
* {@code OptionSet} in the case of {@link JOptCommandLinePropertySource}. |
||||
* |
||||
* <h3>Purpose and General Usage</h3> |
||||
* For use in standalone Spring-based applications, i.e. those that are bootstrapped via |
||||
* a traditional {@code main} method accepting a {@code String[]} of arguments from the |
||||
* command line. In many cases, processing command-line arguments directly within the |
||||
* {@code main} method may be sufficient, but in other cases, it may be desirable to |
||||
* inject arguments as values into Spring beans. It is this latter set of cases in which |
||||
* a {@code CommandLinePropertySource} becomes useful. A {@code CommandLinePropertySource} |
||||
* will typically be added to the {@link Environment} of the Spring |
||||
* {@code ApplicationContext}, at which point all command line arguments become available |
||||
* through the {@link Environment#getProperty(String)} family of methods. For example: |
||||
* <pre class="code"> |
||||
* public static void main(String[] args) { |
||||
* CommandLinePropertySource clps = ...; |
||||
* AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); |
||||
* ctx.getEnvironment().getPropertySources().addFirst(clps); |
||||
* ctx.register(AppConfig.class); |
||||
* ctx.refresh(); |
||||
* }</pre> |
||||
* With the bootstrap logic above, the {@code AppConfig} class may {@code @Inject} the |
||||
* Spring {@code Environment} and query it directly for properties: |
||||
* <pre class="code"> |
||||
* @Configuration |
||||
* public class AppConfig { |
||||
* @Inject Environment env; |
||||
* |
||||
* @Bean |
||||
* public void DataSource dataSource() { |
||||
* MyVendorDataSource dataSource = new MyVendorDataSource(); |
||||
* dataSource.setHostname(env.getProperty("db.hostname", "localhost")); |
||||
* dataSource.setUsername(env.getRequiredProperty("db.username")); |
||||
* dataSource.setPassword(env.getRequiredProperty("db.password")); |
||||
* // ...
|
||||
* return dataSource; |
||||
* } |
||||
* }</pre> |
||||
* Because the {@code CommandLinePropertySource} was added to the {@code Environment}'s |
||||
* set of {@link MutablePropertySources} using the {@code #addFirst} method, it has |
||||
* highest search precedence, meaning that while "db.hostname" and other properties may |
||||
* exist in other property sources such as the system environment variables, it will be |
||||
* chosen from the command line property source first. This is a reasonable approach |
||||
* given that arguments specified on the command line are naturally more specific than |
||||
* those specified as environment variables. |
||||
* |
||||
* <p>As an alternative to injecting the {@code Environment}, Spring's {@code @Value} |
||||
* annotation may be used to inject these properties, given that a {@link |
||||
* PropertySourcesPropertyResolver} bean has been registered, either directly or through |
||||
* using the {@code <context:property-placeholder>} element. For example: |
||||
* <pre class="code"> |
||||
* @Component |
||||
* public class MyComponent { |
||||
* @Value("my.property:defaultVal") |
||||
* private String myProperty; |
||||
* |
||||
* public void getMyProperty() { |
||||
* return this.myProperty; |
||||
* } |
||||
* |
||||
* // ...
|
||||
* }</pre> |
||||
* |
||||
* <h3>Working with option arguments</h3> |
||||
* |
||||
* <p>Individual command line arguments are represented as properties through the usual |
||||
* {@link PropertySource#getProperty(String)} and |
||||
* {@link PropertySource#containsProperty(String)} methods. For example, given the |
||||
* following command line: |
||||
* <pre class="code"> |
||||
* --o1=v1 --o2</pre> |
||||
* 'o1' and 'o2' are treated as "option arguments", and the following assertions would |
||||
* evaluate true: |
||||
* <pre class="code"> |
||||
* CommandLinePropertySource<?> ps = ... |
||||
* assert ps.containsProperty("o1") == true; |
||||
* assert ps.containsProperty("o2") == true; |
||||
* assert ps.containsProperty("o3") == false; |
||||
* assert ps.getProperty("o1").equals("v1"); |
||||
* assert ps.getProperty("o2").equals(""); |
||||
* assert ps.getProperty("o3") == null;</pre> |
||||
* |
||||
* Note that the 'o2' option has no argument, but {@code getProperty("o2")} resolves to |
||||
* empty string ({@code ""}) as opposed to {@code null}, while {@code getProperty("o3")} |
||||
* resolves to {@code null} because it was not specified. This behavior is consistent with |
||||
* the general contract to be followed by all {@code PropertySource} implementations. |
||||
* |
||||
* <p>Note also that while "--" was used in the examples above to denote an option |
||||
* argument, this syntax may vary across individual command line argument libraries. For |
||||
* example, a JOpt- or Commons CLI-based implementation may allow for single dash ("-") |
||||
* "short" option arguments, etc. |
||||
* |
||||
* <h3>Working with non-option arguments</h3> |
||||
* |
||||
* <p>Non-option arguments are also supported through this abstraction. Any arguments |
||||
* supplied without an option-style prefix such as "-" or "--" are considered "non-option |
||||
* arguments" and available through the special {@linkplain |
||||
* #DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME "nonOptionArgs"} property. If multiple |
||||
* non-option arguments are specified, the value of this property will be a |
||||
* comma-delimited string containing all of the arguments. This approach ensures a simple |
||||
* and consistent return type (String) for all properties from a {@code |
||||
* CommandLinePropertySource} and at the same time lends itself to conversion when used |
||||
* in conjunction with the Spring {@link Environment} and its built-in {@code |
||||
* ConversionService}. Consider the following example: |
||||
* <pre class="code"> |
||||
* --o1=v1 --o2=v2 /path/to/file1 /path/to/file2</pre> |
||||
* In this example, "o1" and "o2" would be considered "option arguments", while the two |
||||
* filesystem paths qualify as "non-option arguments". As such, the following assertions |
||||
* will evaluate true: |
||||
* <pre class="code"> |
||||
* CommandLinePropertySource<?> ps = ... |
||||
* assert ps.containsProperty("o1") == true; |
||||
* assert ps.containsProperty("o2") == true; |
||||
* assert ps.containsProperty("nonOptionArgs") == true; |
||||
* assert ps.getProperty("o1").equals("v1"); |
||||
* assert ps.getProperty("o2").equals("v2"); |
||||
* assert ps.getProperty("nonOptionArgs").equals("/path/to/file1,/path/to/file2");</pre> |
||||
* |
||||
* <p>As mentioned above, when used in conjunction with the Spring {@code Environment} |
||||
* abstraction, this comma-delimited string may easily be converted to a String array or |
||||
* list: |
||||
* <pre class="code"> |
||||
* Environment env = applicationContext.getEnvironment(); |
||||
* String[] nonOptionArgs = env.getProperty("nonOptionArgs", String[].class); |
||||
* assert nonOptionArgs[0].equals("/path/to/file1"); |
||||
* assert nonOptionArgs[1].equals("/path/to/file2");</pre> |
||||
* |
||||
* <p>The name of the special "non-option arguments" property may be customized through |
||||
* the {@link #setNonOptionArgsPropertyName(String)} method. Doing so is recommended as |
||||
* it gives proper semantic value to non-option arguments. For example, if filesystem |
||||
* paths are being specified as non-option arguments, it is likely preferable to refer to |
||||
* these as something like "file.locations" than the default of "nonOptionArgs": |
||||
* <pre class="code"> |
||||
* public static void main(String[] args) { |
||||
* CommandLinePropertySource clps = ...; |
||||
* clps.setNonOptionArgsPropertyName("file.locations"); |
||||
* |
||||
* AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); |
||||
* ctx.getEnvironment().getPropertySources().addFirst(clps); |
||||
* ctx.register(AppConfig.class); |
||||
* ctx.refresh(); |
||||
* }</pre> |
||||
* |
||||
* <h3>Limitations</h3> |
||||
* This abstraction is not intended to expose the full power of underlying command line |
||||
* parsing APIs such as JOpt or Commons CLI. It's intent is rather just the opposite: to |
||||
* provide the simplest possible abstraction for accessing command line arguments |
||||
* <em>after</em> they have been parsed. So the typical case will involve fully configuring |
||||
* the underlying command line parsing API, parsing the {@code String[]} of arguments |
||||
* coming into the main method, and then simply providing the parsing results to an |
||||
* implementation of {@code CommandLinePropertySource}. At that point, all arguments can |
||||
* be considered either 'option' or 'non-option' arguments and as described above can be |
||||
* accessed through the normal {@code PropertySource} and {@code Environment} APIs. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see PropertySource |
||||
* @see SimpleCommandLinePropertySource |
||||
* @see JOptCommandLinePropertySource |
||||
*/ |
||||
public abstract class CommandLinePropertySource<T> extends PropertySource<T> { |
||||
|
||||
/** The default name given to {@link CommandLinePropertySource} instances: {@value} */ |
||||
public static final String DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME = "commandLineArgs"; |
||||
|
||||
/** The default name of the property representing non-option arguments: {@value} */ |
||||
public static final String DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME = "nonOptionArgs"; |
||||
|
||||
private String nonOptionArgsPropertyName = DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME; |
||||
|
||||
/** |
||||
* Create a new {@code CommandLinePropertySource} having the default name {@value |
||||
* #DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME} and backed by the given source object. |
||||
*/ |
||||
public CommandLinePropertySource(T source) { |
||||
super(DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME, source); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@link CommandLinePropertySource} having the given name and backed by |
||||
* the given source object. |
||||
*/ |
||||
public CommandLinePropertySource(String name, T source) { |
||||
super(name, source); |
||||
} |
||||
|
||||
/** |
||||
* Specify the name of the special "non-option arguments" property. The default is |
||||
* {@value #DEFAULT_NON_OPTION_ARGS_PROPERTY_NAME}. |
||||
*/ |
||||
public void setNonOptionArgsPropertyName(String nonOptionArgsPropertyName) { |
||||
this.nonOptionArgsPropertyName = nonOptionArgsPropertyName; |
||||
} |
||||
|
||||
/** |
||||
* Return whether this {@code PropertySource} contains the given key. |
||||
* <p>This implementation first checks to see if the key specified is the special |
||||
* {@linkplain #setNonOptionArgsPropertyName(String) "non-option arguments" property}, |
||||
* and if so delegates to the abstract {@link #getNonOptionArgs()} method |
||||
* checking to see whether it returns an empty collection. Otherwise delegates to and |
||||
* returns the value of the abstract {@link #containsOption(String)} method. |
||||
*/ |
||||
@Override |
||||
public final boolean containsProperty(String key) { |
||||
if (this.nonOptionArgsPropertyName.equals(key)) { |
||||
return !this.getNonOptionArgs().isEmpty(); |
||||
} |
||||
return this.containsOption(key); |
||||
} |
||||
|
||||
/** |
||||
* {@inheritDoc} |
||||
* <p>This implementation first checks to see if the key specified is the special |
||||
* {@linkplain #setNonOptionArgsPropertyName(String) "non-option arguments" property}, |
||||
* and if so delegates to the abstract {@link #getNonOptionArgs()} method. If so |
||||
* and the collection of non-option arguments is empty, this method returns {@code |
||||
* null}. If not empty, it returns a comma-separated String of all non-option |
||||
* arguments. Otherwise delegates to and returns the result of the abstract {@link |
||||
* #getOptionValues(String)} method. |
||||
*/ |
||||
@Override |
||||
public final String getProperty(String key) { |
||||
if (this.nonOptionArgsPropertyName.equals(key)) { |
||||
Collection<String> nonOptionArguments = this.getNonOptionArgs(); |
||||
if (nonOptionArguments.isEmpty()) { |
||||
return null; |
||||
} |
||||
else { |
||||
return StringUtils.collectionToCommaDelimitedString(nonOptionArguments); |
||||
} |
||||
} |
||||
Collection<String> optionValues = this.getOptionValues(key); |
||||
if (optionValues == null) { |
||||
return null; |
||||
} |
||||
else { |
||||
return StringUtils.collectionToCommaDelimitedString(optionValues); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Return whether the set of option arguments parsed from the command line contains |
||||
* an option with the given name. |
||||
*/ |
||||
protected abstract boolean containsOption(String name); |
||||
|
||||
/** |
||||
* Return the collection of values associated with the command line option having the |
||||
* given name. |
||||
* <ul> |
||||
* <li>if the option is present and has no argument (e.g.: "--foo"), return an empty |
||||
* collection ({@code []})</li> |
||||
* <li>if the option is present and has a single value (e.g. "--foo=bar"), return a |
||||
* collection having one element ({@code ["bar"]})</li> |
||||
* <li>if the option is present and the underlying command line parsing library |
||||
* supports multiple arguments (e.g. "--foo=bar --foo=baz"), return a collection |
||||
* having elements for each value ({@code ["bar", "baz"]})</li> |
||||
* <li>if the option is not present, return {@code null}</li> |
||||
* </ul> |
||||
*/ |
||||
protected abstract List<String> getOptionValues(String name); |
||||
|
||||
/** |
||||
* Return the collection of non-option arguments parsed from the command line. Never |
||||
* {@code null}. |
||||
*/ |
||||
protected abstract List<String> getNonOptionArgs(); |
||||
|
||||
} |
@ -0,0 +1,106 @@
@@ -0,0 +1,106 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import joptsimple.OptionSet; |
||||
|
||||
/** |
||||
* {@link CommandLinePropertySource} implementation backed by a JOpt {@link OptionSet}. |
||||
* |
||||
* <h2>Typical usage</h2> |
||||
* Configure and execute an {@code OptionParser} against the {@code String[]} of arguments |
||||
* supplied to the {@code main} method, and create a {@link JOptCommandLinePropertySource} |
||||
* using the resulting {@code OptionSet} object: |
||||
* <pre class="code"> |
||||
* public static void main(String[] args) { |
||||
* OptionParser parser = new OptionParser(); |
||||
* parser.accepts("option1"); |
||||
* parser.accepts("option2").withRequiredArg(); |
||||
* OptionSet options = parser.parse(args); |
||||
* PropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
* // ...
|
||||
* }</pre> |
||||
* |
||||
* See {@link CommandLinePropertySource} for complete general usage examples. |
||||
* |
||||
* <h3>Requirements</h3> |
||||
* |
||||
* <p>Use of this class requires adding the jopt-simple JAR to your application classpath. |
||||
* Versions 3.0 and better are supported. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see CommandLinePropertySource |
||||
* @see joptsimple.OptionParser |
||||
* @see joptsimple.OptionSet |
||||
*/ |
||||
public class JOptCommandLinePropertySource extends CommandLinePropertySource<OptionSet> { |
||||
|
||||
/** |
||||
* Create a new {@code JOptCommandLinePropertySource} having the default name |
||||
* and backed by the given {@code OptionSet}. |
||||
* @see CommandLinePropertySource#DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME |
||||
* @see CommandLinePropertySource#CommandLinePropertySource(Object) |
||||
*/ |
||||
public JOptCommandLinePropertySource(OptionSet options) { |
||||
super(options); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code JOptCommandLinePropertySource} having the given name |
||||
* and backed by the given {@code OptionSet}. |
||||
*/ |
||||
public JOptCommandLinePropertySource(String name, OptionSet options) { |
||||
super(name, options); |
||||
} |
||||
|
||||
@Override |
||||
protected boolean containsOption(String key) { |
||||
return this.source.has(key); |
||||
} |
||||
|
||||
@Override |
||||
public List<String> getOptionValues(String key) { |
||||
List<?> argValues = this.source.valuesOf(key); |
||||
List<String> stringArgValues = new ArrayList<String>(); |
||||
for(Object argValue : argValues) { |
||||
if (!(argValue instanceof String)) { |
||||
throw new IllegalArgumentException("argument values must be of type String"); |
||||
} |
||||
stringArgValues.add((String)argValue); |
||||
} |
||||
if (stringArgValues.size() == 0) { |
||||
if (this.source.has(key)) { |
||||
return Collections.emptyList(); |
||||
} |
||||
else { |
||||
return null; |
||||
} |
||||
} |
||||
return Collections.unmodifiableList(stringArgValues); |
||||
} |
||||
|
||||
@Override |
||||
protected List<String> getNonOptionArgs() { |
||||
return this.source.nonOptionArguments(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
/** |
||||
* Parses a {@code String[]} of command line arguments in order to populate a |
||||
* {@link CommandLineArgs} object. |
||||
* |
||||
* <h3>Working with option arguments</h3> |
||||
* Option arguments must adhere to the exact syntax: |
||||
* <pre class="code">--optName[=optValue]</pre> |
||||
* That is, options must be prefixed with "{@code --}", and may or may not specify a value. |
||||
* If a value is specified, the name and value must be separated <em>without spaces</em> |
||||
* by an equals sign ("="). |
||||
* |
||||
* <h4>Valid examples of option arguments</h4> |
||||
* <pre class="code"> |
||||
* --foo |
||||
* --foo=bar |
||||
* --foo="bar then baz" |
||||
* --foo=bar,baz,biz</pre> |
||||
* |
||||
* <h4>Invalid examples of option arguments</h4> |
||||
* <pre class="code"> |
||||
* -foo |
||||
* --foo bar |
||||
* --foo = bar |
||||
* --foo=bar --foo=baz --foo=biz</pre> |
||||
* |
||||
* <h3>Working with non-option arguments</h3> |
||||
* Any and all arguments specified at the command line without the "{@code --}" option |
||||
* prefix will be considered as "non-option arguments" and made available through the |
||||
* {@link CommandLineArgs#getNonOptionArgs()} method. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
class SimpleCommandLineArgsParser { |
||||
|
||||
/** |
||||
* Parse the given {@code String} array based on the rules described {@linkplain |
||||
* SimpleCommandLineArgsParser above}, returning a fully-populated |
||||
* {@link CommandLineArgs} object. |
||||
* @param args command line arguments, typically from a {@code main()} method |
||||
*/ |
||||
public CommandLineArgs parse(String... args) { |
||||
CommandLineArgs commandLineArgs = new CommandLineArgs(); |
||||
for (String arg : args) { |
||||
if (arg.startsWith("--")) { |
||||
String optionText = arg.substring(2, arg.length()); |
||||
String optionName; |
||||
String optionValue = null; |
||||
if (optionText.contains("=")) { |
||||
optionName = optionText.substring(0, optionText.indexOf("=")); |
||||
optionValue = optionText.substring(optionText.indexOf("=")+1, optionText.length()); |
||||
} |
||||
else { |
||||
optionName = optionText; |
||||
} |
||||
if (optionName.isEmpty() || (optionValue != null && optionValue.isEmpty())) { |
||||
throw new IllegalArgumentException("Invalid argument syntax: " + arg); |
||||
} |
||||
commandLineArgs.addOptionArg(optionName, optionValue); |
||||
} |
||||
else { |
||||
commandLineArgs.addNonOptionArg(arg); |
||||
} |
||||
} |
||||
return commandLineArgs; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,113 @@
@@ -0,0 +1,113 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import java.util.List; |
||||
|
||||
/** |
||||
* {@link CommandLinePropertySource} implementation backed by a simple String array. |
||||
* |
||||
* <h3>Purpose</h3> |
||||
* This {@code CommandLinePropertySource} implementation aims to provide the simplest |
||||
* possible approach to parsing command line arguments. As with all {@code |
||||
* CommandLinePropertySource} implementations, command line arguments are broken into two |
||||
* distinct groups: <em>option arguments</em> and <em>non-option arguments</em>, as |
||||
* described below <em>(some sections copied from Javadoc for {@link SimpleCommandLineArgsParser})</em>: |
||||
* |
||||
* <h3>Working with option arguments</h3> |
||||
* Option arguments must adhere to the exact syntax: |
||||
* <pre class="code">--optName[=optValue]</pre> |
||||
* That is, options must be prefixed with "{@code --}", and may or may not specify a value. |
||||
* If a value is specified, the name and value must be separated <em>without spaces</em> |
||||
* by an equals sign ("="). |
||||
* |
||||
* <h4>Valid examples of option arguments</h4> |
||||
* <pre class="code"> |
||||
* --foo |
||||
* --foo=bar |
||||
* --foo="bar then baz" |
||||
* --foo=bar,baz,biz</pre> |
||||
* |
||||
* <h4>Invalid examples of option arguments</h4> |
||||
* <pre class="code"> |
||||
* -foo |
||||
* --foo bar |
||||
* --foo = bar |
||||
* --foo=bar --foo=baz --foo=biz</pre> |
||||
* |
||||
* <h3>Working with non-option arguments</h3> |
||||
* Any and all arguments specified at the command line without the "{@code --}" option |
||||
* prefix will be considered as "non-option arguments" and made available through the |
||||
* {@link #getNonOptionArgs()} method. |
||||
* |
||||
* <h2>Typical usage</h2> |
||||
* <pre class="code"> |
||||
* public static void main(String[] args) { |
||||
* PropertySource<?> ps = new SimpleCommandLinePropertySource(args); |
||||
* // ...
|
||||
* }</pre> |
||||
* |
||||
* See {@link CommandLinePropertySource} for complete general usage examples. |
||||
* |
||||
* <h3>Beyond the basics</h3> |
||||
* |
||||
* <p>When more fully-featured command line parsing is necessary, consider using |
||||
* the provided {@link JOptCommandLinePropertySource}, or implement your own |
||||
* {@code CommandLinePropertySource} against the command line parsing library of your |
||||
* choice! |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
* @see CommandLinePropertySource |
||||
* @see JOptCommandLinePropertySource |
||||
*/ |
||||
public class SimpleCommandLinePropertySource extends CommandLinePropertySource<CommandLineArgs> { |
||||
|
||||
/** |
||||
* Create a new {@code SimpleCommandLinePropertySource} having the default name |
||||
* and backed by the given {@code String[]} of command line arguments. |
||||
* @see CommandLinePropertySource#DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME |
||||
* @see CommandLinePropertySource#CommandLinePropertySource(Object) |
||||
*/ |
||||
public SimpleCommandLinePropertySource(String... args) { |
||||
super(new SimpleCommandLineArgsParser().parse(args)); |
||||
} |
||||
|
||||
/** |
||||
* Create a new {@code SimpleCommandLinePropertySource} having the given name |
||||
* and backed by the given {@code String[]} of command line arguments. |
||||
*/ |
||||
public SimpleCommandLinePropertySource(String name, String[] args) { |
||||
super(name, new SimpleCommandLineArgsParser().parse(args)); |
||||
} |
||||
|
||||
@Override |
||||
protected boolean containsOption(String key) { |
||||
return this.source.containsOption(key); |
||||
} |
||||
|
||||
@Override |
||||
protected List<String> getOptionValues(String key) { |
||||
return this.source.getOptionValues(key); |
||||
} |
||||
|
||||
@Override |
||||
protected List<String> getNonOptionArgs() { |
||||
return this.source.getNonOptionArgs(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,165 @@
@@ -0,0 +1,165 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
import joptsimple.OptionParser; |
||||
import joptsimple.OptionSet; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* Unit tests for {@link JOptCommandLinePropertySource}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class JOptCommandLinePropertySourceTests { |
||||
|
||||
@Test |
||||
public void withRequiredArg_andArgIsPresent() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("foo").withRequiredArg(); |
||||
OptionSet options = parser.parse("--foo=bar"); |
||||
|
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertThat((String)ps.getProperty("foo"), equalTo("bar")); |
||||
} |
||||
|
||||
@Test |
||||
public void withOptionalArg_andArgIsMissing() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("foo").withOptionalArg(); |
||||
OptionSet options = parser.parse("--foo"); |
||||
|
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertThat(ps.containsProperty("foo"), is(true)); |
||||
assertThat((String)ps.getProperty("foo"), equalTo("")); |
||||
} |
||||
|
||||
@Test |
||||
public void withNoArg() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("o1"); |
||||
parser.accepts("o2"); |
||||
OptionSet options = parser.parse("--o1"); |
||||
|
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(false)); |
||||
assertThat((String)ps.getProperty("o1"), equalTo("")); |
||||
assertThat(ps.getProperty("o2"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withRequiredArg_andMultipleArgsPresent_usingDelimiter() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("foo").withRequiredArg().withValuesSeparatedBy(','); |
||||
OptionSet options = parser.parse("--foo=bar,baz,biz"); |
||||
|
||||
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertEquals(Arrays.asList("bar","baz","biz"), ps.getOptionValues("foo")); |
||||
assertThat(ps.getProperty("foo"), equalTo("bar,baz,biz")); |
||||
} |
||||
|
||||
@Test |
||||
public void withRequiredArg_andMultipleArgsPresent_usingRepeatedOption() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("foo").withRequiredArg().withValuesSeparatedBy(','); |
||||
OptionSet options = parser.parse("--foo=bar", "--foo=baz", "--foo=biz"); |
||||
|
||||
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertEquals(Arrays.asList("bar","baz","biz"), ps.getOptionValues("foo")); |
||||
assertThat(ps.getProperty("foo"), equalTo("bar,baz,biz")); |
||||
} |
||||
|
||||
@Test |
||||
public void withMissingOption() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("foo").withRequiredArg().withValuesSeparatedBy(','); |
||||
OptionSet options = parser.parse(); // <-- no options whatsoever
|
||||
|
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertThat(ps.getProperty("foo"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withDottedOptionName() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("spring.profiles.active").withRequiredArg(); |
||||
OptionSet options = parser.parse("--spring.profiles.active=p1"); |
||||
|
||||
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options); |
||||
assertThat(ps.getProperty("spring.profiles.active"), equalTo("p1")); |
||||
} |
||||
|
||||
@Test |
||||
public void withDefaultNonOptionArgsNameAndNoNonOptionArgsPresent() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("o1").withRequiredArg(); |
||||
parser.accepts("o2"); |
||||
OptionSet optionSet = parser.parse("--o1=v1", "--o2"); |
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(optionSet); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.getProperty("nonOptionArgs"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withDefaultNonOptionArgsNameAndNonOptionArgsPresent() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("o1").withRequiredArg(); |
||||
parser.accepts("o2"); |
||||
OptionSet optionSet = parser.parse("--o1=v1", "noa1", "--o2", "noa2"); |
||||
PropertySource<?> ps = new JOptCommandLinePropertySource(optionSet); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(true)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
|
||||
String nonOptionArgs = (String)ps.getProperty("nonOptionArgs"); |
||||
assertThat(nonOptionArgs, equalTo("noa1,noa2")); |
||||
} |
||||
|
||||
@Test |
||||
public void withCustomNonOptionArgsNameAndNoNonOptionArgsPresent() { |
||||
OptionParser parser = new OptionParser(); |
||||
parser.accepts("o1").withRequiredArg(); |
||||
parser.accepts("o2"); |
||||
OptionSet optionSet = parser.parse("--o1=v1", "noa1", "--o2", "noa2"); |
||||
CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(optionSet); |
||||
ps.setNonOptionArgsPropertyName("NOA"); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.containsProperty("NOA"), is(true)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
String nonOptionArgs = ps.getProperty("NOA"); |
||||
assertThat(nonOptionArgs, equalTo("noa1,noa2")); |
||||
} |
||||
} |
@ -0,0 +1,114 @@
@@ -0,0 +1,114 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
public class SimpleCommandLineParserTests { |
||||
|
||||
@Test |
||||
public void withNoOptions() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
assertThat(parser.parse().getOptionValues("foo"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withSingleOptionAndNoValue() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
CommandLineArgs args = parser.parse("--o1"); |
||||
assertThat(args.containsOption("o1"), is(true)); |
||||
assertThat(args.getOptionValues("o1"), equalTo(Collections.EMPTY_LIST)); |
||||
} |
||||
|
||||
@Test |
||||
public void withSingleOptionAndValue() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
CommandLineArgs args = parser.parse("--o1=v1"); |
||||
assertThat(args.containsOption("o1"), is(true)); |
||||
assertThat(args.getOptionValues("o1").get(0), equalTo("v1")); |
||||
} |
||||
|
||||
@Test |
||||
public void withMixOfOptionsHavingValueAndOptionsHavingNoValue() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
CommandLineArgs args = parser.parse("--o1=v1", "--o2"); |
||||
assertThat(args.containsOption("o1"), is(true)); |
||||
assertThat(args.containsOption("o2"), is(true)); |
||||
assertThat(args.containsOption("o3"), is(false)); |
||||
assertThat(args.getOptionValues("o1").get(0), equalTo("v1")); |
||||
assertThat(args.getOptionValues("o2"), equalTo(Collections.EMPTY_LIST)); |
||||
assertThat(args.getOptionValues("o3"), nullValue()); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void withEmptyOptionText() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
parser.parse("--"); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void withEmptyOptionName() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
parser.parse("--=v1"); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void withEmptyOptionValue() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
parser.parse("--o1="); |
||||
} |
||||
|
||||
@Test(expected=IllegalArgumentException.class) |
||||
public void withEmptyOptionNameAndEmptyOptionValue() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
parser.parse("--="); |
||||
} |
||||
|
||||
@Test |
||||
public void withNonOptionArguments() { |
||||
SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser(); |
||||
CommandLineArgs args = parser.parse("--o1=v1", "noa1", "--o2=v2", "noa2"); |
||||
assertThat(args.getOptionValues("o1").get(0), equalTo("v1")); |
||||
assertThat(args.getOptionValues("o2").get(0), equalTo("v2")); |
||||
|
||||
List<String> nonOptions = args.getNonOptionArgs(); |
||||
assertThat(nonOptions.get(0), equalTo("noa1")); |
||||
assertThat(nonOptions.get(1), equalTo("noa2")); |
||||
assertThat(nonOptions.size(), equalTo(2)); |
||||
} |
||||
|
||||
@Test(expected=UnsupportedOperationException.class) |
||||
public void assertOptionNamesIsUnmodifiable() { |
||||
CommandLineArgs args = new SimpleCommandLineArgsParser().parse(); |
||||
args.getOptionNames().add("bogus"); |
||||
} |
||||
|
||||
@Test(expected=UnsupportedOperationException.class) |
||||
public void assertNonOptionArgsIsUnmodifiable() { |
||||
CommandLineArgs args = new SimpleCommandLineArgsParser().parse(); |
||||
args.getNonOptionArgs().add("foo"); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,126 @@
@@ -0,0 +1,126 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.core.env; |
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo; |
||||
import static org.hamcrest.CoreMatchers.is; |
||||
import static org.hamcrest.CoreMatchers.nullValue; |
||||
import static org.junit.Assert.assertThat; |
||||
|
||||
import java.util.List; |
||||
|
||||
import org.junit.Test; |
||||
|
||||
/** |
||||
* Unit tests for {@link SimpleCommandLinePropertySource}. |
||||
* |
||||
* @author Chris Beams |
||||
* @since 3.1 |
||||
*/ |
||||
public class SimpleCommandLinePropertySourceTests { |
||||
|
||||
@Test |
||||
public void withDefaultName() { |
||||
PropertySource<?> ps = new SimpleCommandLinePropertySource(); |
||||
assertThat(ps.getName(), |
||||
equalTo(CommandLinePropertySource.DEFAULT_COMMAND_LINE_PROPERTY_SOURCE_NAME)); |
||||
} |
||||
|
||||
@Test |
||||
public void withCustomName() { |
||||
PropertySource<?> ps = new SimpleCommandLinePropertySource("ps1", new String[0]); |
||||
assertThat(ps.getName(), equalTo("ps1")); |
||||
} |
||||
|
||||
@Test |
||||
public void withNoArgs() { |
||||
PropertySource<?> ps = new SimpleCommandLinePropertySource(); |
||||
assertThat(ps.containsProperty("foo"), is(false)); |
||||
assertThat(ps.getProperty("foo"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withOptionArgsOnly() { |
||||
CommandLinePropertySource<?> ps = |
||||
new SimpleCommandLinePropertySource("--o1=v1", "--o2"); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
assertThat(ps.containsProperty("o3"), is(false)); |
||||
assertThat(ps.getProperty("o1"), equalTo("v1")); |
||||
assertThat(ps.getProperty("o2"), equalTo("")); |
||||
assertThat(ps.getProperty("o3"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withDefaultNonOptionArgsNameAndNoNonOptionArgsPresent() { |
||||
PropertySource<?> ps = new SimpleCommandLinePropertySource("--o1=v1", "--o2"); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.getProperty("nonOptionArgs"), nullValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void withDefaultNonOptionArgsNameAndNonOptionArgsPresent() { |
||||
CommandLinePropertySource<?> ps = |
||||
new SimpleCommandLinePropertySource("--o1=v1", "noa1", "--o2", "noa2"); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(true)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
|
||||
String nonOptionArgs = ps.getProperty("nonOptionArgs"); |
||||
assertThat(nonOptionArgs, equalTo("noa1,noa2")); |
||||
} |
||||
|
||||
@Test |
||||
public void withCustomNonOptionArgsNameAndNoNonOptionArgsPresent() { |
||||
CommandLinePropertySource<?> ps = |
||||
new SimpleCommandLinePropertySource("--o1=v1", "noa1", "--o2", "noa2"); |
||||
ps.setNonOptionArgsPropertyName("NOA"); |
||||
|
||||
assertThat(ps.containsProperty("nonOptionArgs"), is(false)); |
||||
assertThat(ps.containsProperty("NOA"), is(true)); |
||||
assertThat(ps.containsProperty("o1"), is(true)); |
||||
assertThat(ps.containsProperty("o2"), is(true)); |
||||
String nonOptionArgs = ps.getProperty("NOA"); |
||||
assertThat(nonOptionArgs, equalTo("noa1,noa2")); |
||||
} |
||||
|
||||
@Test |
||||
public void covertNonOptionArgsToStringArrayAndList() { |
||||
CommandLinePropertySource<?> ps = |
||||
new SimpleCommandLinePropertySource("--o1=v1", "noa1", "--o2", "noa2"); |
||||
StandardEnvironment env = new StandardEnvironment(); |
||||
env.getPropertySources().addFirst(ps); |
||||
|
||||
String nonOptionArgs = env.getProperty("nonOptionArgs"); |
||||
assertThat(nonOptionArgs, equalTo("noa1,noa2")); |
||||
|
||||
String[] nonOptionArgsArray = env.getProperty("nonOptionArgs", String[].class); |
||||
assertThat(nonOptionArgsArray[0], equalTo("noa1")); |
||||
assertThat(nonOptionArgsArray[1], equalTo("noa2")); |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
List<String> nonOptionArgsList = env.getProperty("nonOptionArgs", List.class); |
||||
assertThat(nonOptionArgsList.get(0), equalTo("noa1")); |
||||
assertThat(nonOptionArgsList.get(1), equalTo("noa2")); |
||||
} |
||||
} |
Loading…
Reference in new issue