001/* 002 * Copyright 2002-2018 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.ArrayList; 020import java.util.Collections; 021import java.util.List; 022 023import joptsimple.OptionSet; 024import joptsimple.OptionSpec; 025 026import org.springframework.util.StringUtils; 027 028/** 029 * {@link CommandLinePropertySource} implementation backed by a JOpt {@link OptionSet}. 030 * 031 * <h2>Typical usage</h2> 032 * 033 * Configure and execute an {@code OptionParser} against the {@code String[]} of arguments 034 * supplied to the {@code main} method, and create a {@link JOptCommandLinePropertySource} 035 * using the resulting {@code OptionSet} object: 036 * 037 * <pre class="code"> 038 * public static void main(String[] args) { 039 * OptionParser parser = new OptionParser(); 040 * parser.accepts("option1"); 041 * parser.accepts("option2").withRequiredArg(); 042 * OptionSet options = parser.parse(args); 043 * PropertySource<?> ps = new JOptCommandLinePropertySource(options); 044 * // ... 045 * }</pre> 046 * 047 * See {@link CommandLinePropertySource} for complete general usage examples. 048 * 049 * <p>Requires JOpt Simple version 4.3 or higher. Tested against JOpt up until 5.0. 050 * 051 * @author Chris Beams 052 * @author Juergen Hoeller 053 * @author Dave Syer 054 * @since 3.1 055 * @see CommandLinePropertySource 056 * @see joptsimple.OptionParser 057 * @see joptsimple.OptionSet 058 */ 059public class JOptCommandLinePropertySource extends CommandLinePropertySource<OptionSet> { 060 061 /** 062 * Create a new {@code JOptCommandLinePropertySource} having the default name 063 * and backed by the given {@code OptionSet}. 064 * @see CommandLinePropertySource#COMMAND_LINE_PROPERTY_SOURCE_NAME 065 * @see CommandLinePropertySource#CommandLinePropertySource(Object) 066 */ 067 public JOptCommandLinePropertySource(OptionSet options) { 068 super(options); 069 } 070 071 /** 072 * Create a new {@code JOptCommandLinePropertySource} having the given name 073 * and backed by the given {@code OptionSet}. 074 */ 075 public JOptCommandLinePropertySource(String name, OptionSet options) { 076 super(name, options); 077 } 078 079 080 @Override 081 protected boolean containsOption(String name) { 082 return this.source.has(name); 083 } 084 085 @Override 086 public String[] getPropertyNames() { 087 List<String> names = new ArrayList<String>(); 088 for (OptionSpec<?> spec : this.source.specs()) { 089 List<String> aliases = spec.options(); 090 if (!aliases.isEmpty()) { 091 // Only the longest name is used for enumerating 092 names.add(aliases.get(aliases.size() - 1)); 093 } 094 } 095 return StringUtils.toStringArray(names); 096 } 097 098 @Override 099 public List<String> getOptionValues(String name) { 100 List<?> argValues = this.source.valuesOf(name); 101 List<String> stringArgValues = new ArrayList<String>(); 102 for (Object argValue : argValues) { 103 stringArgValues.add(argValue.toString()); 104 } 105 if (stringArgValues.isEmpty()) { 106 return (this.source.has(name) ? Collections.<String>emptyList() : null); 107 } 108 return Collections.unmodifiableList(stringArgValues); 109 } 110 111 @Override 112 protected List<String> getNonOptionArgs() { 113 List<?> argValues = this.source.nonOptionArguments(); 114 List<String> stringArgValues = new ArrayList<String>(); 115 for (Object argValue : argValues) { 116 stringArgValues.add(argValue.toString()); 117 } 118 return (stringArgValues.isEmpty() ? Collections.<String>emptyList() : 119 Collections.unmodifiableList(stringArgValues)); 120 } 121 122}