001/*
002 * Copyright 2002-2020 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.core.env;
018
019import java.util.List;
020
021import org.springframework.lang.Nullable;
022import org.springframework.util.StringUtils;
023
024/**
025 * {@link CommandLinePropertySource} implementation backed by a simple String array.
026 *
027 * <h3>Purpose</h3>
028 * <p>This {@code CommandLinePropertySource} implementation aims to provide the simplest
029 * possible approach to parsing command line arguments. As with all {@code
030 * CommandLinePropertySource} implementations, command line arguments are broken into two
031 * distinct groups: <em>option arguments</em> and <em>non-option arguments</em>, as
032 * described below <em>(some sections copied from Javadoc for
033 * {@link SimpleCommandLineArgsParser})</em>:
034 *
035 * <h3>Working with option arguments</h3>
036 * <p>Option arguments must adhere to the exact syntax:
037 *
038 * <pre class="code">--optName[=optValue]</pre>
039 *
040 * <p>That is, options must be prefixed with "{@code --}" and may or may not
041 * specify a value. If a value is specified, the name and value must be separated
042 * <em>without spaces</em> by an equals sign ("="). The value may optionally be
043 * an empty string.
044 *
045 * <h4>Valid examples of option arguments</h4>
046 * <pre class="code">
047 * --foo
048 * --foo=
049 * --foo=""
050 * --foo=bar
051 * --foo="bar then baz"
052 * --foo=bar,baz,biz</pre>
053 *
054 * <h4>Invalid examples of option arguments</h4>
055 * <pre class="code">
056 * -foo
057 * --foo bar
058 * --foo = bar
059 * --foo=bar --foo=baz --foo=biz</pre>
060 *
061 * <h3>Working with non-option arguments</h3>
062 * <p>Any and all arguments specified at the command line without the "{@code --}"
063 * option prefix will be considered as "non-option arguments" and made available
064 * through the {@link CommandLineArgs#getNonOptionArgs()} method.
065 *
066 * <h3>Typical usage</h3>
067 * <pre class="code">
068 * public static void main(String[] args) {
069 *     PropertySource<?> ps = new SimpleCommandLinePropertySource(args);
070 *     // ...
071 * }</pre>
072 *
073 * See {@link CommandLinePropertySource} for complete general usage examples.
074 *
075 * <h3>Beyond the basics</h3>
076 *
077 * <p>When more fully-featured command line parsing is necessary, consider using
078 * the provided {@link JOptCommandLinePropertySource}, or implement your own
079 * {@code CommandLinePropertySource} against the command line parsing library of your
080 * choice.
081 *
082 * @author Chris Beams
083 * @since 3.1
084 * @see CommandLinePropertySource
085 * @see JOptCommandLinePropertySource
086 */
087public class SimpleCommandLinePropertySource extends CommandLinePropertySource<CommandLineArgs> {
088
089        /**
090         * Create a new {@code SimpleCommandLinePropertySource} having the default name
091         * and backed by the given {@code String[]} of command line arguments.
092         * @see CommandLinePropertySource#COMMAND_LINE_PROPERTY_SOURCE_NAME
093         * @see CommandLinePropertySource#CommandLinePropertySource(Object)
094         */
095        public SimpleCommandLinePropertySource(String... args) {
096                super(new SimpleCommandLineArgsParser().parse(args));
097        }
098
099        /**
100         * Create a new {@code SimpleCommandLinePropertySource} having the given name
101         * and backed by the given {@code String[]} of command line arguments.
102         */
103        public SimpleCommandLinePropertySource(String name, String[] args) {
104                super(name, new SimpleCommandLineArgsParser().parse(args));
105        }
106
107        /**
108         * Get the property names for the option arguments.
109         */
110        @Override
111        public String[] getPropertyNames() {
112                return StringUtils.toStringArray(this.source.getOptionNames());
113        }
114
115        @Override
116        protected boolean containsOption(String name) {
117                return this.source.containsOption(name);
118        }
119
120        @Override
121        @Nullable
122        protected List<String> getOptionValues(String name) {
123                return this.source.getOptionValues(name);
124        }
125
126        @Override
127        protected List<String> getNonOptionArgs() {
128                return this.source.getNonOptionArgs();
129        }
130
131}