001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.util.args; 028 import org.opends.messages.Message; 029 030 031 032 import static org.opends.messages.UtilityMessages.*; 033 import org.opends.messages.MessageBuilder; 034 035 036 /** 037 * This class defines an argument type that will only accept integer values, 038 * and potentially only those in a given range. 039 */ 040 public class IntegerArgument 041 extends Argument 042 { 043 // Indicates whether a lower bound will be enforced for this argument. 044 private boolean hasLowerBound; 045 046 // Indicates whether an upper bound will be enforced for this argument. 047 private boolean hasUpperBound; 048 049 // The lower bound that will be enforced for this argument. 050 private int lowerBound; 051 052 // The upper bound that will be enforced for this argument. 053 private int upperBound; 054 055 056 057 /** 058 * Creates a new integer argument with the provided information. 059 * 060 * @param name The generic name that should be used to refer to 061 * this argument. 062 * @param shortIdentifier The single-character identifier for this 063 * argument, or <CODE>null</CODE> if there is none. 064 * @param longIdentifier The long identifier for this argument, or 065 * <CODE>null</CODE> if there is none. 066 * @param isRequired Indicates whether this argument must be specified 067 * on the command line. 068 * @param needsValue Indicates whether this argument requires a value. 069 * @param valuePlaceholder The placeholder for the argument value that will 070 * be displayed in usage information, or 071 * <CODE>null</CODE> if this argument does not 072 * require a value. 073 * @param description Message for the description of this 074 * argument. 075 * 076 * @throws ArgumentException If there is a problem with any of the 077 * parameters used to create this argument. 078 */ 079 public IntegerArgument(String name, Character shortIdentifier, 080 String longIdentifier, boolean isRequired, 081 boolean needsValue, Message valuePlaceholder, 082 Message description) 083 throws ArgumentException 084 { 085 super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, 086 valuePlaceholder, null, null, description); 087 088 hasLowerBound = false; 089 hasUpperBound = false; 090 lowerBound = Integer.MIN_VALUE; 091 upperBound = Integer.MAX_VALUE; 092 } 093 094 095 096 /** 097 * Creates a new integer argument with the provided information. 098 * 099 * @param name The generic name that should be used to refer to 100 * this argument. 101 * @param shortIdentifier The single-character identifier for this 102 * argument, or <CODE>null</CODE> if there is none. 103 * @param longIdentifier The long identifier for this argument, or 104 * <CODE>null</CODE> if there is none. 105 * @param isRequired Indicates whether this argument must be specified 106 * on the command line. 107 * @param needsValue Indicates whether this argument requires a value. 108 * @param valuePlaceholder The placeholder for the argument value that will 109 * be displayed in usage information, or 110 * <CODE>null</CODE> if this argument does not 111 * require a value. 112 * @param hasLowerBound Indicates whether a lower bound should be 113 * enforced for values of this argument. 114 * @param lowerBound The lower bound that should be enforced for 115 * values of this argument. 116 * @param hasUpperBound Indicates whether an upperbound should be 117 * enforced for values of this argument. 118 * @param upperBound The upper bound that should be enforced for 119 * values of this argument. 120 * @param description Message for the description of this 121 * argument. 122 * 123 * @throws ArgumentException If there is a problem with any of the 124 * parameters used to create this argument. 125 */ 126 public IntegerArgument(String name, Character shortIdentifier, 127 String longIdentifier, boolean isRequired, 128 boolean needsValue, Message valuePlaceholder, 129 boolean hasLowerBound, int lowerBound, 130 boolean hasUpperBound, int upperBound, 131 Message description) 132 throws ArgumentException 133 { 134 super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue, 135 valuePlaceholder, null, null, description); 136 137 this.hasLowerBound = hasLowerBound; 138 this.hasUpperBound = hasUpperBound; 139 this.lowerBound = lowerBound; 140 this.upperBound = upperBound; 141 142 if (hasLowerBound && hasUpperBound && (lowerBound > upperBound)) 143 { 144 Message message = ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND.get( 145 name, lowerBound, upperBound); 146 throw new ArgumentException(message); 147 } 148 } 149 150 151 152 /** 153 * Creates a new integer argument with the provided information. 154 * 155 * @param name The generic name that should be used to refer to 156 * this argument. 157 * @param shortIdentifier The single-character identifier for this 158 * argument, or <CODE>null</CODE> if there is none. 159 * @param longIdentifier The long identifier for this argument, or 160 * <CODE>null</CODE> if there is none. 161 * @param isRequired Indicates whether this argument must be specified 162 * on the command line. 163 * @param isMultiValued Indicates whether this argument may be specified 164 * more than once to provide multiple values. 165 * @param needsValue Indicates whether this argument requires a value. 166 * @param valuePlaceholder The placeholder for the argument value that will 167 * be displayed in usage information, or 168 * <CODE>null</CODE> if this argument does not 169 * require a value. 170 * @param defaultValue The default value that should be used for this 171 * argument if none is provided in a properties file 172 * or on the command line. This may be 173 * <CODE>null</CODE> if there is no generic default. 174 * @param propertyName The name of the property in a property file that 175 * may be used to override the default value but 176 * will be overridden by a command-line argument. 177 * @param description Message for the description of this 178 * argument. 179 * 180 * @throws ArgumentException If there is a problem with any of the 181 * parameters used to create this argument. 182 */ 183 public IntegerArgument(String name, Character shortIdentifier, 184 String longIdentifier, boolean isRequired, 185 boolean isMultiValued, boolean needsValue, 186 Message valuePlaceholder, int defaultValue, 187 String propertyName, 188 Message description) 189 throws ArgumentException 190 { 191 super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, 192 needsValue, valuePlaceholder, String.valueOf(defaultValue), 193 propertyName, description); 194 195 hasLowerBound = false; 196 hasUpperBound = false; 197 lowerBound = Integer.MIN_VALUE; 198 upperBound = Integer.MAX_VALUE; 199 } 200 201 202 203 /** 204 * Creates a new integer argument with the provided information. 205 * 206 * @param name The generic name that should be used to refer to 207 * this argument. 208 * @param shortIdentifier The single-character identifier for this 209 * argument, or <CODE>null</CODE> if there is none. 210 * @param longIdentifier The long identifier for this argument, or 211 * <CODE>null</CODE> if there is none. 212 * @param isRequired Indicates whether this argument must be specified 213 * on the command line. 214 * @param isMultiValued Indicates whether this argument may be specified 215 * more than once to provide multiple values. 216 * @param needsValue Indicates whether this argument requires a value. 217 * @param valuePlaceholder The placeholder for the argument value that will 218 * be displayed in usage information, or 219 * <CODE>null</CODE> if this argument does not 220 * require a value. 221 * @param defaultValue The default value that should be used for this 222 * argument if none is provided in a properties file 223 * or on the command line. This may be 224 * <CODE>null</CODE> if there is no generic default. 225 * @param propertyName The name of the property in a property file that 226 * may be used to override the default value but 227 * will be overridden by a command-line argument. 228 * @param hasLowerBound Indicates whether a lower bound should be 229 * enforced for values of this argument. 230 * @param lowerBound The lower bound that should be enforced for 231 * values of this argument. 232 * @param hasUpperBound Indicates whether an upperbound should be 233 * enforced for values of this argument. 234 * @param upperBound The upper bound that should be enforced for 235 * values of this argument. 236 * @param description Message for the description of this 237 * argument. 238 * 239 * @throws ArgumentException If there is a problem with any of the 240 * parameters used to create this argument. 241 */ 242 public IntegerArgument(String name, Character shortIdentifier, 243 String longIdentifier, boolean isRequired, 244 boolean isMultiValued, boolean needsValue, 245 Message valuePlaceholder, int defaultValue, 246 String propertyName, boolean hasLowerBound, 247 int lowerBound, boolean hasUpperBound, int upperBound, 248 Message description) 249 throws ArgumentException 250 { 251 super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, 252 needsValue, valuePlaceholder, String.valueOf(defaultValue), 253 propertyName, description); 254 255 this.hasLowerBound = hasLowerBound; 256 this.hasUpperBound = hasUpperBound; 257 this.lowerBound = lowerBound; 258 this.upperBound = upperBound; 259 260 if (hasLowerBound && hasUpperBound && (lowerBound > upperBound)) 261 { 262 Message message = ERR_INTARG_LOWER_BOUND_ABOVE_UPPER_BOUND.get( 263 name, lowerBound, upperBound); 264 throw new ArgumentException(message); 265 } 266 } 267 268 269 270 /** 271 * Indicates whether a lower bound should be enforced for values of this 272 * argument. 273 * 274 * @return <CODE>true</CODE> if a lower bound should be enforced for values 275 * of this argument, or <CODE>false</CODE> if not. 276 */ 277 public boolean hasLowerBound() 278 { 279 return hasLowerBound; 280 } 281 282 283 284 /** 285 * Retrieves the lower bound that may be enforced for values of this argument. 286 * 287 * @return The lower bound that may be enforced for values of this argument. 288 */ 289 public int getLowerBound() 290 { 291 return lowerBound; 292 } 293 294 295 296 /** 297 * Indicates whether a upper bound should be enforced for values of this 298 * argument. 299 * 300 * @return <CODE>true</CODE> if a upper bound should be enforced for values 301 * of this argument, or <CODE>false</CODE> if not. 302 */ 303 public boolean hasUpperBound() 304 { 305 return hasUpperBound; 306 } 307 308 309 310 /** 311 * Retrieves the upper bound that may be enforced for values of this argument. 312 * 313 * @return The upper bound that may be enforced for values of this argument. 314 */ 315 public int getUpperBound() 316 { 317 return upperBound; 318 } 319 320 321 322 /** 323 * Indicates whether the provided value is acceptable for use in this 324 * argument. 325 * 326 * @param valueString The value for which to make the determination. 327 * @param invalidReason A buffer into which the invalid reason may be 328 * written if the value is not acceptable. 329 * 330 * @return <CODE>true</CODE> if the value is acceptable, or 331 * <CODE>false</CODE> if it is not. 332 */ 333 public boolean valueIsAcceptable(String valueString, 334 MessageBuilder invalidReason) 335 { 336 // First, the value must be decodable as an integer. 337 int intValue; 338 try 339 { 340 intValue = Integer.parseInt(valueString); 341 } 342 catch (Exception e) 343 { 344 invalidReason.append(ERR_ARG_CANNOT_DECODE_AS_INT.get( 345 valueString, getName())); 346 return false; 347 } 348 349 350 // If there is a lower bound, then the value must be greater than or equal 351 // to it. 352 if (hasLowerBound && (intValue < lowerBound)) 353 { 354 invalidReason.append(ERR_INTARG_VALUE_BELOW_LOWER_BOUND.get( 355 getName(), intValue, lowerBound)); 356 return false; 357 } 358 359 360 // If there is an upper bound, then the value must be less than or equal to 361 // it. 362 if (hasUpperBound && (intValue > upperBound)) 363 { 364 365 invalidReason.append(ERR_INTARG_VALUE_ABOVE_UPPER_BOUND.get( 366 getName(), intValue, upperBound)); 367 return false; 368 } 369 370 371 // At this point, the value should be acceptable. 372 return true; 373 } 374 } 375