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