001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.cli; 019 020import java.io.Serializable; 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.Iterator; 024import java.util.LinkedList; 025import java.util.List; 026import java.util.Properties; 027 028/** 029 * Represents list of arguments parsed against a {@link Options} descriptor. 030 * <p> 031 * It allows querying of a boolean {@link #hasOption(String opt)}, 032 * in addition to retrieving the {@link #getOptionValue(String opt)} 033 * for options requiring arguments. 034 * <p> 035 * Additionally, any left-over or unrecognized arguments, 036 * are available for further processing. 037 * 038 * @version $Id: CommandLine.java 1444365 2013-02-09 14:21:27Z tn $ 039 */ 040public class CommandLine implements Serializable 041{ 042 /** The serial version UID. */ 043 private static final long serialVersionUID = 1L; 044 045 /** the unrecognised options/arguments */ 046 private final List<String> args = new LinkedList<String>(); 047 048 /** the processed options */ 049 private final List<Option> options = new ArrayList<Option>(); 050 051 /** 052 * Creates a command line. 053 */ 054 protected CommandLine() 055 { 056 // nothing to do 057 } 058 059 /** 060 * Query to see if an option has been set. 061 * 062 * @param opt Short name of the option 063 * @return true if set, false if not 064 */ 065 public boolean hasOption(String opt) 066 { 067 return options.contains(resolveOption(opt)); 068 } 069 070 /** 071 * Query to see if an option has been set. 072 * 073 * @param opt character name of the option 074 * @return true if set, false if not 075 */ 076 public boolean hasOption(char opt) 077 { 078 return hasOption(String.valueOf(opt)); 079 } 080 081 /** 082 * Return the <code>Object</code> type of this <code>Option</code>. 083 * 084 * @param opt the name of the option 085 * @return the type of this <code>Option</code> 086 * @deprecated due to System.err message. Instead use getParsedOptionValue(String) 087 */ 088 @Deprecated 089 public Object getOptionObject(String opt) 090 { 091 try 092 { 093 return getParsedOptionValue(opt); 094 } 095 catch (ParseException pe) 096 { 097 System.err.println("Exception found converting " + opt + " to desired type: " + pe.getMessage()); 098 return null; 099 } 100 } 101 102 /** 103 * Return a version of this <code>Option</code> converted to a particular type. 104 * 105 * @param opt the name of the option 106 * @return the value parsed into a particular object 107 * @throws ParseException if there are problems turning the option value into the desired type 108 * @see PatternOptionBuilder 109 * @since 1.2 110 */ 111 public Object getParsedOptionValue(String opt) throws ParseException 112 { 113 String res = getOptionValue(opt); 114 Option option = resolveOption(opt); 115 116 if (option == null || res == null) 117 { 118 return null; 119 } 120 121 return TypeHandler.createValue(res, option.getType()); 122 } 123 124 /** 125 * Return the <code>Object</code> type of this <code>Option</code>. 126 * 127 * @param opt the name of the option 128 * @return the type of opt 129 */ 130 public Object getOptionObject(char opt) 131 { 132 return getOptionObject(String.valueOf(opt)); 133 } 134 135 /** 136 * Retrieve the first argument, if any, of this option. 137 * 138 * @param opt the name of the option 139 * @return Value of the argument if option is set, and has an argument, 140 * otherwise null. 141 */ 142 public String getOptionValue(String opt) 143 { 144 String[] values = getOptionValues(opt); 145 146 return (values == null) ? null : values[0]; 147 } 148 149 /** 150 * Retrieve the first argument, if any, of this option. 151 * 152 * @param opt the character name of the option 153 * @return Value of the argument if option is set, and has an argument, 154 * otherwise null. 155 */ 156 public String getOptionValue(char opt) 157 { 158 return getOptionValue(String.valueOf(opt)); 159 } 160 161 /** 162 * Retrieves the array of values, if any, of an option. 163 * 164 * @param opt string name of the option 165 * @return Values of the argument if option is set, and has an argument, 166 * otherwise null. 167 */ 168 public String[] getOptionValues(String opt) 169 { 170 List<String> values = new ArrayList<String>(); 171 172 for (Option option : options) 173 { 174 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) 175 { 176 values.addAll(option.getValuesList()); 177 } 178 } 179 180 return values.isEmpty() ? null : values.toArray(new String[values.size()]); 181 } 182 183 /** 184 * Retrieves the option object given the long or short option as a String 185 * 186 * @param opt short or long name of the option 187 * @return Canonicalized option 188 */ 189 private Option resolveOption(String opt) 190 { 191 opt = Util.stripLeadingHyphens(opt); 192 for (Option option : options) 193 { 194 if (opt.equals(option.getOpt())) 195 { 196 return option; 197 } 198 199 if (opt.equals(option.getLongOpt())) 200 { 201 return option; 202 } 203 204 } 205 return null; 206 } 207 208 /** 209 * Retrieves the array of values, if any, of an option. 210 * 211 * @param opt character name of the option 212 * @return Values of the argument if option is set, and has an argument, 213 * otherwise null. 214 */ 215 public String[] getOptionValues(char opt) 216 { 217 return getOptionValues(String.valueOf(opt)); 218 } 219 220 /** 221 * Retrieve the first argument, if any, of an option. 222 * 223 * @param opt name of the option 224 * @param defaultValue is the default value to be returned if the option 225 * is not specified 226 * @return Value of the argument if option is set, and has an argument, 227 * otherwise <code>defaultValue</code>. 228 */ 229 public String getOptionValue(String opt, String defaultValue) 230 { 231 String answer = getOptionValue(opt); 232 233 return (answer != null) ? answer : defaultValue; 234 } 235 236 /** 237 * Retrieve the argument, if any, of an option. 238 * 239 * @param opt character name of the option 240 * @param defaultValue is the default value to be returned if the option 241 * is not specified 242 * @return Value of the argument if option is set, and has an argument, 243 * otherwise <code>defaultValue</code>. 244 */ 245 public String getOptionValue(char opt, String defaultValue) 246 { 247 return getOptionValue(String.valueOf(opt), defaultValue); 248 } 249 250 /** 251 * Retrieve the map of values associated to the option. This is convenient 252 * for options specifying Java properties like <tt>-Dparam1=value1 253 * -Dparam2=value2</tt>. The first argument of the option is the key, and 254 * the 2nd argument is the value. If the option has only one argument 255 * (<tt>-Dfoo</tt>) it is considered as a boolean flag and the value is 256 * <tt>"true"</tt>. 257 * 258 * @param opt name of the option 259 * @return The Properties mapped by the option, never <tt>null</tt> 260 * even if the option doesn't exists 261 * @since 1.2 262 */ 263 public Properties getOptionProperties(String opt) 264 { 265 Properties props = new Properties(); 266 267 for (Option option : options) 268 { 269 if (opt.equals(option.getOpt()) || opt.equals(option.getLongOpt())) 270 { 271 List<String> values = option.getValuesList(); 272 if (values.size() >= 2) 273 { 274 // use the first 2 arguments as the key/value pair 275 props.put(values.get(0), values.get(1)); 276 } 277 else if (values.size() == 1) 278 { 279 // no explicit value, handle it as a boolean 280 props.put(values.get(0), "true"); 281 } 282 } 283 } 284 285 return props; 286 } 287 288 /** 289 * Retrieve any left-over non-recognized options and arguments 290 * 291 * @return remaining items passed in but not parsed as an array 292 */ 293 public String[] getArgs() 294 { 295 String[] answer = new String[args.size()]; 296 297 args.toArray(answer); 298 299 return answer; 300 } 301 302 /** 303 * Retrieve any left-over non-recognized options and arguments 304 * 305 * @return remaining items passed in but not parsed as a <code>List</code>. 306 */ 307 public List<String> getArgList() 308 { 309 return args; 310 } 311 312 /** 313 * jkeyes 314 * - commented out until it is implemented properly 315 * <p>Dump state, suitable for debugging.</p> 316 * 317 * @return Stringified form of this object 318 */ 319 320 /* 321 public String toString() { 322 StringBuilder buf = new StringBuilder(); 323 324 buf.append("[ CommandLine: [ options: "); 325 buf.append(options.toString()); 326 buf.append(" ] [ args: "); 327 buf.append(args.toString()); 328 buf.append(" ] ]"); 329 330 return buf.toString(); 331 } 332 */ 333 334 /** 335 * Add left-over unrecognized option/argument. 336 * 337 * @param arg the unrecognised option/argument. 338 */ 339 protected void addArg(String arg) 340 { 341 args.add(arg); 342 } 343 344 /** 345 * Add an option to the command line. The values of the option are stored. 346 * 347 * @param opt the processed option 348 */ 349 protected void addOption(Option opt) 350 { 351 options.add(opt); 352 } 353 354 /** 355 * Returns an iterator over the Option members of CommandLine. 356 * 357 * @return an <code>Iterator</code> over the processed {@link Option} 358 * members of this {@link CommandLine} 359 */ 360 public Iterator<Option> iterator() 361 { 362 return options.iterator(); 363 } 364 365 /** 366 * Returns an array of the processed {@link Option}s. 367 * 368 * @return an array of the processed {@link Option}s. 369 */ 370 public Option[] getOptions() 371 { 372 Collection<Option> processed = options; 373 374 // reinitialise array 375 Option[] optionsArray = new Option[processed.size()]; 376 377 // return the array 378 return processed.toArray(optionsArray); 379 } 380}