Introduce CommandLinePropertySource and impls
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-8482
This commit is contained in:
parent
e0d2e20fc4
commit
1eb5811347
|
@ -13,6 +13,7 @@
|
|||
<classpathentry kind="var" path="IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-1.2.0.jar" sourcepath="/IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-sources-1.2.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.woodstox/com.springsource.com.ctc.wstx/3.2.7/com.springsource.com.ctc.wstx-3.2.7.jar" sourcepath="/IVY_CACHE/org.codehaus.woodstox/com.springsource.com.ctc.wstx/3.2.7/com.springsource.com.ctc.wstx-sources-3.2.7.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/net.sourceforge.jopt-simple/com.springsource.joptsimple/3.0.0/com.springsource.joptsimple-3.0.0.jar" sourcepath="IVY_CACHE/net.sourceforge.jopt-simple/com.springsource.joptsimple/3.0.0/com.springsource.joptsimple-sources-3.0.0.jar"/>
|
||||
<classpathentry kind="lib" path="/org.springframework.asm/target/artifacts/org.springframework.asm.jar" sourcepath="/org.springframework.asm/target/artifacts/org.springframework.asm-sources.jar"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15" conf="optional, log4j->compile"/>
|
||||
<dependency org="org.aspectj" name="com.springsource.org.aspectj.weaver" rev="${aspectj.version}" conf="optional, aspectj->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.asm" rev="latest.integration" conf="optional->compile"/>
|
||||
<dependency org="net.sourceforge.jopt-simple" name="com.springsource.joptsimple" rev="3.0.0" conf="optional->compile"/>
|
||||
<!-- test dependencies -->
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.5.0" conf="test->compile"/>
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="${junit.version}" conf="test->runtime"/>
|
||||
|
|
91
org.springframework.core/src/main/java/org/springframework/core/env/CommandLineArgs.java
vendored
Normal file
91
org.springframework.core/src/main/java/org/springframework/core/env/CommandLineArgs.java
vendored
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
296
org.springframework.core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java
vendored
Normal file
296
org.springframework.core/src/main/java/org/springframework/core/env/CommandLinePropertySource.java
vendored
Normal file
|
@ -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 @@
|
|||
/*
|
||||
* 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 @@
|
|||
/*
|
||||
* 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 @@
|
|||
/*
|
||||
* 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 @@
|
|||
/*
|
||||
* 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 @@
|
|||
/*
|
||||
* 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 @@
|
|||
/*
|
||||
* 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"));
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ Import-Template:
|
|||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.springframework.asm.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.apache.log4j.*;version="[1.2.15, 2.0.0)";resolution:=optional,
|
||||
joptsimple.*;version="[3.0.0, 4.0.0)";resolution:=optional,
|
||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||
org.xml.sax.*;version="0";resolution:=optional,
|
||||
org.w3c.dom.*;version="0";resolution:=optional
|
||||
|
|
Loading…
Reference in New Issue