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 }