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