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 https://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 020/** 021 * OptionBuilder allows the user to create Options using descriptive methods. 022 * <p> 023 * Details on the Builder pattern can be found at 024 * <a href="https://c2.com/cgi-bin/wiki?BuilderPattern">https://c2.com/cgi-bin/wiki?BuilderPattern</a>. 025 * <p> 026 * This class is NOT thread safe. See <a href="https://issues.apache.org/jira/browse/CLI-209">CLI-209</a> 027 * 028 * @since 1.0 029 * @deprecated Since 1.3, use {@link Option#builder(String)} instead. 030 */ 031@Deprecated 032public final class OptionBuilder { 033 034 /** Long option. */ 035 private static String longOption; 036 037 /** Option description. */ 038 private static String description; 039 040 /** Argument name. */ 041 private static String argName; 042 043 /** Required test. */ 044 private static boolean required; 045 046 /** The number of arguments. */ 047 private static int argCount = Option.UNINITIALIZED; 048 049 /** Option type. */ 050 private static Class<?> type; 051 052 /** Option can have an optional argument value. */ 053 private static boolean optionalArg; 054 055 /** Value separator for argument value. */ 056 private static char valueSeparator; 057 058 /** Option builder instance. */ 059 private static final OptionBuilder INSTANCE = new OptionBuilder(); 060 061 static { 062 // ensure the consistency of the initial values. 063 reset(); 064 } 065 066 /** 067 * Creates an Option using the current settings. 068 * 069 * @return the Option instance. 070 * @throws IllegalArgumentException if {@code longOpt} has not been set. 071 */ 072 public static Option create() throws IllegalArgumentException { 073 if (longOption == null) { 074 reset(); 075 throw new IllegalStateException("longopt missing"); 076 } 077 return create(null); 078 } 079 080 /** 081 * Creates an Option using the current settings and with the specified Option {@code char}. 082 * 083 * @param opt the character representation of the Option. 084 * @return the Option instance. 085 * @throws IllegalArgumentException if {@code opt} is not a valid character. See Option. 086 */ 087 public static Option create(final char opt) throws IllegalArgumentException { 088 return create(String.valueOf(opt)); 089 } 090 091 /** 092 * Creates an Option using the current settings and with the specified Option {@code char}. 093 * 094 * @param opt the {@code String} representation of the Option. 095 * @return the Option instance. 096 * @throws IllegalArgumentException if {@code opt} is not a valid character. See Option. 097 */ 098 public static Option create(final String opt) throws IllegalArgumentException { 099 Option option; 100 try { 101 // create the option 102 option = new Option(opt, description); 103 // set the option properties 104 option.setLongOpt(longOption); 105 option.setRequired(required); 106 option.setOptionalArg(optionalArg); 107 option.setArgs(argCount); 108 option.setType(type); 109 option.setConverter(TypeHandler.getDefault().getConverter(type)); 110 option.setValueSeparator(valueSeparator); 111 option.setArgName(argName); 112 } finally { 113 // reset the OptionBuilder properties 114 reset(); 115 } 116 // return the Option instance 117 return option; 118 } 119 120 /** 121 * The next Option created will require an argument value. 122 * 123 * @return the OptionBuilder instance 124 */ 125 public static OptionBuilder hasArg() { 126 argCount = 1; 127 return INSTANCE; 128 } 129 130 /** 131 * The next Option created will require an argument value if {@code hasArg} is true. 132 * 133 * @param hasArg if true then the Option has an argument value. 134 * @return the OptionBuilder instance. 135 */ 136 public static OptionBuilder hasArg(final boolean hasArg) { 137 argCount = hasArg ? 1 : Option.UNINITIALIZED; 138 return INSTANCE; 139 } 140 141 /** 142 * The next Option created can have unlimited argument values. 143 * 144 * @return the OptionBuilder instance. 145 */ 146 public static OptionBuilder hasArgs() { 147 argCount = Option.UNLIMITED_VALUES; 148 return INSTANCE; 149 } 150 151 /** 152 * The next Option created can have {@code num} argument values. 153 * 154 * @param num the number of args that the option can have. 155 * @return the OptionBuilder instance. 156 */ 157 public static OptionBuilder hasArgs(final int num) { 158 argCount = num; 159 return INSTANCE; 160 } 161 162 /** 163 * The next Option can have an optional argument. 164 * 165 * @return the OptionBuilder instance. 166 */ 167 public static OptionBuilder hasOptionalArg() { 168 argCount = 1; 169 optionalArg = true; 170 return INSTANCE; 171 } 172 173 /** 174 * The next Option can have an unlimited number of optional arguments. 175 * 176 * @return the OptionBuilder instance. 177 */ 178 public static OptionBuilder hasOptionalArgs() { 179 argCount = Option.UNLIMITED_VALUES; 180 optionalArg = true; 181 return INSTANCE; 182 } 183 184 /** 185 * The next Option can have the specified number of optional arguments. 186 * 187 * @param numArgs the maximum number of optional arguments the next Option created can have. 188 * @return the OptionBuilder instance. 189 */ 190 public static OptionBuilder hasOptionalArgs(final int numArgs) { 191 argCount = numArgs; 192 optionalArg = true; 193 return INSTANCE; 194 } 195 196 /** 197 * The next Option created will be required. 198 * 199 * @return the OptionBuilder instance. 200 */ 201 public static OptionBuilder isRequired() { 202 required = true; 203 return INSTANCE; 204 } 205 206 /** 207 * The next Option created will be required if {@code required} is true. 208 * 209 * @param newRequired if true then the Option is required. 210 * @return the OptionBuilder instance. 211 */ 212 public static OptionBuilder isRequired(final boolean newRequired) { 213 required = newRequired; 214 return INSTANCE; 215 } 216 217 /** 218 * Resets the member variables to their default values. 219 */ 220 private static void reset() { 221 description = null; 222 argName = null; 223 longOption = null; 224 type = String.class; 225 required = false; 226 argCount = Option.UNINITIALIZED; 227 optionalArg = false; 228 valueSeparator = (char) 0; 229 } 230 231 /** 232 * The next Option created will have the specified argument value name. 233 * 234 * @param name the name for the argument value. 235 * @return the OptionBuilder instance. 236 */ 237 public static OptionBuilder withArgName(final String name) { 238 argName = name; 239 return INSTANCE; 240 } 241 242 /** 243 * The next Option created will have the specified description 244 * 245 * @param newDescription a description of the Option's purpose. 246 * @return the OptionBuilder instance. 247 */ 248 public static OptionBuilder withDescription(final String newDescription) { 249 description = newDescription; 250 return INSTANCE; 251 } 252 253 /** 254 * The next Option created will have the following long option value. 255 * 256 * @param newLongopt the long option value. 257 * @return the OptionBuilder instance. 258 */ 259 public static OptionBuilder withLongOpt(final String newLongopt) { 260 longOption = newLongopt; 261 return INSTANCE; 262 } 263 264 /** 265 * The next Option created will have a value that will be an instance of {@code type}. 266 * 267 * @param newType the type of the Options argument value. 268 * @return the OptionBuilder instance. 269 * @since 1.3 270 */ 271 public static OptionBuilder withType(final Class<?> newType) { 272 type = newType; 273 return INSTANCE; 274 } 275 276 /** 277 * The next Option created will have a value that will be an instance of {@code type}. 278 * <p> 279 * <strong>Note:</strong> this method is kept for binary compatibility and the input type is supposed to be a {@link Class} 280 * object. 281 * 282 * @param newType the type of the Options argument value. 283 * @return the OptionBuilder instance. 284 * @deprecated Since 1.3, use {@link #withType(Class)} instead. 285 */ 286 @Deprecated 287 public static OptionBuilder withType(final Object newType) { 288 return withType((Class<?>) newType); 289 } 290 291 /** 292 * The next Option created uses '{@code =}' as a means to separate argument values. 293 * 294 * <strong>Example:</strong> 295 * 296 * <pre> 297 * Option opt = withValueSeparator().create('D'); 298 * 299 * CommandLine line = parser.parse(args); 300 * String propertyName = opt.getValue(0); 301 * String propertyValue = opt.getValue(1); 302 * </pre> 303 * 304 * @return the OptionBuilder instance. 305 */ 306 public static OptionBuilder withValueSeparator() { 307 valueSeparator = Char.EQUAL; 308 return INSTANCE; 309 } 310 311 /** 312 * The next Option created uses {@code sep} as a means to separate argument values. 313 * <p> 314 * <strong>Example:</strong> 315 * 316 * <pre> 317 * Option opt = OptionBuilder.withValueSeparator('=').create('D'); 318 * 319 * String args = "-Dkey=value"; 320 * CommandLine line = parser.parse(args); 321 * String propertyName = opt.getValue(0); // will be "key" 322 * String propertyValue = opt.getValue(1); // will be "value" 323 * </pre> 324 * 325 * @param sep The value separator to be used for the argument values. 326 * @return the OptionBuilder instance. 327 */ 328 public static OptionBuilder withValueSeparator(final char sep) { 329 valueSeparator = sep; 330 return INSTANCE; 331 } 332 333 /** 334 * private constructor to prevent instances being created. 335 */ 336 private OptionBuilder() { 337 // hide the constructor 338 } 339}