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-8482 git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4643 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/merge
11 changed files with 1100 additions and 0 deletions
@ -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 @@ |
|||||||
|
/* |
||||||
|
* 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")); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue