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 2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.admin;
029 import org.opends.messages.Message;
030
031
032
033 import static org.opends.server.util.Validator.ensureNotNull;
034
035 import java.util.EnumSet;
036 import java.util.Locale;
037 import java.util.MissingResourceException;
038
039
040
041 /**
042 * Integer property definition.
043 * <p>
044 * All values must be zero or positive and within the lower/upper limit
045 * constraints. Support is provided for "unlimited" values. These are
046 * represented using a negative value or using the string "unlimited".
047 */
048 public final class IntegerPropertyDefinition extends
049 PropertyDefinition<Integer> {
050
051 // String used to represent unlimited.
052 private static final String UNLIMITED = "unlimited";
053
054 // The lower limit of the property value.
055 private final int lowerLimit;
056
057 // The optional upper limit of the property value.
058 private final Integer upperLimit;
059
060 // Indicates whether this property allows the use of the "unlimited" value
061 // (represented using a -1 or the string "unlimited").
062 private final boolean allowUnlimited;
063
064
065
066 /**
067 * An interface for incrementally constructing integer property definitions.
068 */
069 public static class Builder extends
070 AbstractBuilder<Integer, IntegerPropertyDefinition> {
071
072 // The lower limit of the property value.
073 private int lowerLimit = 0;
074
075 // The optional upper limit of the property value.
076 private Integer upperLimit = null;
077
078 // Indicates whether this property allows the use of the "unlimited" value
079 // (represented using a -1 or the string "unlimited").
080 private boolean allowUnlimited = false;
081
082
083
084 // Private constructor
085 private Builder(
086 AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
087 super(d, propertyName);
088 }
089
090
091
092 /**
093 * Set the lower limit.
094 *
095 * @param lowerLimit
096 * The new lower limit (must be >= 0).
097 * @throws IllegalArgumentException
098 * If a negative lower limit was specified or the lower limit is
099 * greater than the upper limit.
100 */
101 public final void setLowerLimit(int lowerLimit)
102 throws IllegalArgumentException {
103 if (lowerLimit < 0) {
104 throw new IllegalArgumentException("Negative lower limit");
105 }
106 if (upperLimit != null && lowerLimit > upperLimit) {
107 throw new IllegalArgumentException(
108 "Lower limit greater than upper limit");
109 }
110 this.lowerLimit = lowerLimit;
111 }
112
113
114
115 /**
116 * Set the upper limit.
117 *
118 * @param upperLimit
119 * The new upper limit or <code>null</code> if there is no upper
120 * limit.
121 */
122 public final void setUpperLimit(Integer upperLimit) {
123 if (upperLimit != null) {
124 if (upperLimit < 0) {
125 throw new IllegalArgumentException("Negative lower limit");
126 }
127 if (lowerLimit > upperLimit) {
128 throw new IllegalArgumentException(
129 "Lower limit greater than upper limit");
130 }
131 }
132 this.upperLimit = upperLimit;
133 }
134
135
136
137 /**
138 * Specify whether or not this property definition will allow unlimited
139 * values (default is false).
140 *
141 * @param allowUnlimited
142 * <code>true</code> if the property will allow unlimited values,
143 * or <code>false</code> otherwise.
144 */
145 public final void setAllowUnlimited(boolean allowUnlimited) {
146 this.allowUnlimited = allowUnlimited;
147 }
148
149
150
151 /**
152 * {@inheritDoc}
153 */
154 @Override
155 protected IntegerPropertyDefinition buildInstance(
156 AbstractManagedObjectDefinition<?, ?> d, String propertyName,
157 EnumSet<PropertyOption> options,
158 AdministratorAction adminAction,
159 DefaultBehaviorProvider<Integer> defaultBehavior) {
160 return new IntegerPropertyDefinition(d, propertyName, options,
161 adminAction, defaultBehavior, lowerLimit, upperLimit, allowUnlimited);
162 }
163
164 }
165
166
167
168 /**
169 * Create an integer property definition builder.
170 *
171 * @param d
172 * The managed object definition associated with this
173 * property definition.
174 * @param propertyName
175 * The property name.
176 * @return Returns the new integer property definition builder.
177 */
178 public static Builder createBuilder(
179 AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
180 return new Builder(d, propertyName);
181 }
182
183
184
185 // Private constructor.
186 private IntegerPropertyDefinition(
187 AbstractManagedObjectDefinition<?, ?> d, String propertyName,
188 EnumSet<PropertyOption> options,
189 AdministratorAction adminAction,
190 DefaultBehaviorProvider<Integer> defaultBehavior, int lowerLimit,
191 Integer upperLimit, boolean allowUnlimited) {
192 super(d, Integer.class, propertyName, options, adminAction,
193 defaultBehavior);
194 this.lowerLimit = lowerLimit;
195 this.upperLimit = upperLimit;
196 this.allowUnlimited = allowUnlimited;
197 }
198
199
200
201 /**
202 * Get the lower limit.
203 *
204 * @return Returns the lower limit.
205 */
206 public int getLowerLimit() {
207 return lowerLimit;
208 }
209
210
211
212 /**
213 * Get the upper limit.
214 *
215 * @return Returns the upper limit or <code>null</code> if there is no upper
216 * limit.
217 */
218 public Integer getUpperLimit() {
219 return upperLimit;
220 }
221
222
223
224 /**
225 * Gets the optional unit synopsis of this integer property
226 * definition in the default locale.
227 *
228 * @return Returns the unit synopsis of this integer property
229 * definition in the default locale, or <code>null</code>
230 * if there is no unit synopsis.
231 */
232 public Message getUnitSynopsis() {
233 return getUnitSynopsis(Locale.getDefault());
234 }
235
236
237
238 /**
239 * Gets the optional unit synopsis of this integer property
240 * definition in the specified locale.
241 *
242 * @param locale
243 * The locale.
244 * @return Returns the unit synopsis of this integer property
245 * definition in the specified locale, or <code>null</code>
246 * if there is no unit synopsis.
247 */
248 public Message getUnitSynopsis(Locale locale) {
249 ManagedObjectDefinitionI18NResource resource =
250 ManagedObjectDefinitionI18NResource.getInstance();
251 String property = "property." + getName() + ".syntax.integer.unit-synopsis";
252 try {
253 return resource.getMessage(getManagedObjectDefinition(),
254 property, locale);
255 } catch (MissingResourceException e) {
256 return null;
257 }
258 }
259
260
261
262 /**
263 * Determine whether this property allows unlimited values.
264 *
265 * @return Returns <code>true</code> if this this property allows unlimited
266 * values.
267 */
268 public boolean isAllowUnlimited() {
269 return allowUnlimited;
270 }
271
272
273
274 /**
275 * {@inheritDoc}
276 */
277 @Override
278 public void validateValue(Integer value)
279 throws IllegalPropertyValueException {
280 ensureNotNull(value);
281
282 if (!allowUnlimited && value < lowerLimit) {
283 throw new IllegalPropertyValueException(this, value);
284
285 // unlimited allowed
286 } else if (value >= 0 && value < lowerLimit) {
287 throw new IllegalPropertyValueException(this, value);
288 }
289
290 if ((upperLimit != null) && (value > upperLimit)) {
291 throw new IllegalPropertyValueException(this, value);
292 }
293 }
294
295 /**
296 * {@inheritDoc}
297 */
298 @Override
299 public String encodeValue(Integer value)
300 throws IllegalPropertyValueException {
301 ensureNotNull(value);
302
303 // Make sure that we correctly encode negative values as "unlimited".
304 if (allowUnlimited) {
305 if (value < 0) {
306 return UNLIMITED;
307 }
308 }
309
310 return value.toString();
311 }
312
313 /**
314 * {@inheritDoc}
315 */
316 @Override
317 public Integer decodeValue(String value)
318 throws IllegalPropertyValueStringException {
319 ensureNotNull(value);
320
321 if (allowUnlimited) {
322 if (value.trim().equalsIgnoreCase(UNLIMITED)) {
323 return -1;
324 }
325 }
326
327 Integer i;
328 try {
329 i = Integer.valueOf(value);
330 } catch (NumberFormatException e) {
331 throw new IllegalPropertyValueStringException(this, value);
332 }
333
334 try {
335 validateValue(i);
336 } catch (IllegalPropertyValueException e) {
337 throw new IllegalPropertyValueStringException(this, value);
338 }
339
340 return i;
341 }
342
343
344
345 /**
346 * {@inheritDoc}
347 */
348 @Override
349 public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
350 return v.visitInteger(this, p);
351 }
352
353
354
355 /**
356 * {@inheritDoc}
357 */
358 @Override
359 public <R, P> R accept(PropertyValueVisitor<R, P> v, Integer value, P p) {
360 return v.visitInteger(this, value, p);
361 }
362
363
364
365 /**
366 * {@inheritDoc}
367 */
368 @Override
369 public void toString(StringBuilder builder) {
370 super.toString(builder);
371
372 builder.append(" lowerLimit=");
373 builder.append(lowerLimit);
374
375 if (upperLimit != null) {
376 builder.append(" upperLimit=");
377 builder.append(upperLimit);
378 }
379
380 builder.append(" allowUnlimited=");
381 builder.append(allowUnlimited);
382 }
383
384
385
386 /**
387 * {@inheritDoc}
388 */
389 @Override
390 public int compare(Integer o1, Integer o2) {
391 return o1.compareTo(o2);
392 }
393
394 }