mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

matthew_swift
04.26.2007 c6f391dd4d48922b9cf1c5fac08aecc67008f869
Various improvements to the PropertyDefinition classes:

* pull-up AbstractPropertyDefinition into PropertyDefinition and delete AbstractPropertyDefinition
* fix mildly broken equals(), hashCode(), and compare() methods
* define a new PropertyValueVisitor interface which is similar to PropertyDefinitionVisitor but is designed for handling property values in a flexible type-safe manner.
1 files deleted
1 files added
12 files modified
1401 ■■■■■ changed files
opends/src/server/org/opends/server/admin/AbstractPropertyDefinition.java 445 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/AttributeTypePropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/BooleanPropertyDefinition.java 17 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/ClassPropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/DNPropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/EnumPropertyDefinition.java 17 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/IPAddressMaskPropertyDefinition.java 19 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/IPAddressPropertyDefinition.java 19 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/IntegerPropertyDefinition.java 17 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/PropertyDefinition.java 464 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/PropertyValueVisitor.java 295 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/SizePropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/StringPropertyDefinition.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/AbstractPropertyDefinition.java
File was deleted
opends/src/server/org/opends/server/admin/AttributeTypePropertyDefinition.java
@@ -42,7 +42,7 @@
 * Attribute type property definition.
 */
public final class AttributeTypePropertyDefinition extends
    AbstractPropertyDefinition<AttributeType> {
    PropertyDefinition<AttributeType> {
  /**
   * An interface for incrementally constructing attribute type
@@ -72,11 +72,6 @@
    }
  }
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 4622133184170201490L;
  // Flag indicating whether or not attribute type names should be
  // validated against the schema.
  private static boolean isCheckSchema = true;
@@ -155,6 +150,17 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v,
      AttributeType value, P p) {
    return v.visitAttributeType(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(AttributeType o1, AttributeType o2) {
    return o1.getNameOrOID().compareToIgnoreCase(o2.getNameOrOID());
  }
opends/src/server/org/opends/server/admin/BooleanPropertyDefinition.java
@@ -41,12 +41,7 @@
 * Boolean property definition.
 */
public final class BooleanPropertyDefinition extends
    AbstractPropertyDefinition<Boolean> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -3615113733243221668L;
    PropertyDefinition<Boolean> {
  /**
   * Mapping used for parsing boolean values. This mapping is more flexible than
@@ -178,6 +173,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, Boolean value, P p) {
    return v.visitBoolean(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(Boolean o1, Boolean o2) {
    return o1.compareTo(o2);
  }
opends/src/server/org/opends/server/admin/ClassPropertyDefinition.java
@@ -52,8 +52,7 @@
 * validation in the client by calling the static method
 * {@link #setAllowClassValidation(boolean)}.
 */
public final class ClassPropertyDefinition extends
    AbstractPropertyDefinition<String> {
public final class ClassPropertyDefinition extends PropertyDefinition<String> {
  /**
   * An interface for incrementally constructing class property
@@ -129,11 +128,6 @@
  }
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -7775867133238274392L;
  // Regular expression for validating class names.
  private static final String CLASS_RE =
    "^([A-Za-z]+[A-Za-z0-9_]*)*(\\.[A-Za-z]+[A-Za-z0-9_]*)"
@@ -234,6 +228,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
    return v.visitClass(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
opends/src/server/org/opends/server/admin/DNPropertyDefinition.java
@@ -41,13 +41,7 @@
/**
 * DN property definition.
 */
public final class DNPropertyDefinition extends
    AbstractPropertyDefinition<DN> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -380704355977504890L;
public final class DNPropertyDefinition extends PropertyDefinition<DN> {
  // Optional base DN which all valid values must be immediately
  // subordinate to.
@@ -228,6 +222,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, DN value, P p) {
    return v.visitDN(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(DN o1, DN o2) {
    return o1.compareTo(o2);
  }
opends/src/server/org/opends/server/admin/DurationPropertyDefinition.java
@@ -63,13 +63,7 @@
 * Decoded values are represented using <code>long</code> values in
 * the base unit defined for the duration property definition.
 */
public final class DurationPropertyDefinition extends
    AbstractPropertyDefinition<Long> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -1491050690542547075L;
public final class DurationPropertyDefinition extends PropertyDefinition<Long> {
  // String used to represent unlimited durations.
  private static final String UNLIMITED = "unlimited";
@@ -564,6 +558,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) {
    return v.visitDuration(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder) {
    super.toString(builder);
opends/src/server/org/opends/server/admin/EnumPropertyDefinition.java
@@ -47,7 +47,7 @@
 *          property definition.
 */
public final class EnumPropertyDefinition<E extends Enum<E>> extends
    AbstractPropertyDefinition<E> {
    PropertyDefinition<E> {
  /**
   * An interface for incrementally constructing enumeration property
@@ -106,11 +106,6 @@
    }
  }
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 338458138694686844L;
  /**
@@ -171,6 +166,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, E value, P p) {
    return v.visitEnum(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public E decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
opends/src/server/org/opends/server/admin/IPAddressMaskPropertyDefinition.java
@@ -42,14 +42,7 @@
 * IP address mask property definition.
 */
public final class IPAddressMaskPropertyDefinition extends
    AbstractPropertyDefinition<AddressMask> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -6641292526738863824L;
    PropertyDefinition<AddressMask> {
  /**
   * An interface for incrementally constructing IP address mask property
@@ -154,6 +147,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, AddressMask value, P p) {
    return v.visitIPAddressMask(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(AddressMask o1, AddressMask o2) {
    return o1.toString().compareTo(o2.toString());
  }
opends/src/server/org/opends/server/admin/IPAddressPropertyDefinition.java
@@ -41,14 +41,7 @@
 * IP address property definition.
 */
public final class IPAddressPropertyDefinition extends
    AbstractPropertyDefinition<InetAddress> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -6641292526738863824L;
    PropertyDefinition<InetAddress> {
  /**
   * An interface for incrementally constructing IP address property
@@ -164,6 +157,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, InetAddress value, P p) {
    return v.visitIPAddress(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(InetAddress o1, InetAddress o2) {
    return o1.getHostAddress().compareTo(o2.getHostAddress());
  }
opends/src/server/org/opends/server/admin/IntegerPropertyDefinition.java
@@ -45,12 +45,7 @@
 * represented using a negative value or using the string "unlimited".
 */
public final class IntegerPropertyDefinition extends
    AbstractPropertyDefinition<Integer> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 2819904868308720588L;
    PropertyDefinition<Integer> {
  // String used to represent unlimited.
  private static final String UNLIMITED = "unlimited";
@@ -357,6 +352,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, Integer value, P p) {
    return v.visitInteger(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder) {
    super.toString(builder);
opends/src/server/org/opends/server/admin/PropertyDefinition.java
@@ -29,31 +29,186 @@
import java.io.Serializable;
import static org.opends.server.util.Validator.*;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Set;
/**
 * An interface for querying generic property definition features.
 * <p>
 * Property definitions are analogous to ConfigAttributes in the current model
 * and will play a similar role. Eventually these will replace them.
 * Property definitions are analogous to ConfigAttributes in the
 * current model and will play a similar role. Eventually these will
 * replace them.
 * <p>
 * Implementations <b>must</b> take care to implement the various comparison
 * methods.
 * Implementations <b>must</b> take care to implement the various
 * comparison methods.
 * <p>
 * Implementations of this interface must be serializable. This is required so
 * that management applications can query property meta-information remotely.
 * <p>
 * TODO: define other call-backs (e.g. initial values).
 * Implementations of this interface must be serializable. This is
 * required so that management applications can query property
 * meta-information remotely.
 *
 * @param <T>
 *          The data-type of values of the property.
 */
public interface PropertyDefinition<T> extends Comparator<T>,
    Comparable<PropertyDefinition<?>>, Serializable {
public abstract class PropertyDefinition<T> implements Comparator<T>,
    Comparable<PropertyDefinition<?>> {
  /**
   * An interface for incrementally constructing property definitions.
   *
   * @param <T>
   *          The data-type of values of the property.
   * @param <D>
   *          The type of property definition constructed by this
   *          builder.
   */
  protected abstract static class AbstractBuilder
      <T, D extends PropertyDefinition<T>> {
    // The default behavior provider.
    private DefaultBehaviorProvider<T> defaultBehavior;
    // The abstract managed object
    private final AbstractManagedObjectDefinition<?, ?> definition;
    // The options applicable to this definition.
    private final EnumSet<PropertyOption> options;
    // The name of this property definition.
    private final String propertyName;
    /**
     * Create a property definition builder.
     *
     * @param d
     *          The managed object definition associated with this
     *          property definition.
     * @param propertyName
     *          The property name.
     */
    protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      this.definition = d;
      this.propertyName = propertyName;
      this.options = EnumSet.noneOf(PropertyOption.class);
      this.defaultBehavior = new UndefinedDefaultBehaviorProvider<T>();
    }
    /**
     * Construct a property definition based on the properties of this
     * builder.
     *
     * @return The new property definition.
     */
    public final D getInstance() {
      return buildInstance(definition, propertyName, options, defaultBehavior);
    }
    /**
     * Set the default behavior provider.
     *
     * @param defaultBehavior
     *          The default behavior provider.
     */
    public final void setDefaultBehaviorProvider(
        DefaultBehaviorProvider<T> defaultBehavior) {
      ensureNotNull(defaultBehavior);
      this.defaultBehavior = defaultBehavior;
    }
    /**
     * Add a property definition option.
     *
     * @param option
     *          The property option.
     */
    public final void setOption(PropertyOption option) {
      ensureNotNull(option);
      options.add(option);
    }
    /**
     * Build a property definition based on the properties of this
     * builder.
     *
     * @param d
     *          The managed object definition associated with this
     *          property definition.
     * @param propertyName
     *          The property name.
     * @param options
     *          Options applicable to this definition.
     * @param defaultBehavior
     *          The default behavior provider.
     * @return The new property definition.
     */
    protected abstract D buildInstance(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName, EnumSet<PropertyOption> options,
        DefaultBehaviorProvider<T> defaultBehavior);
  }
  // The default behavior provider.
  private final DefaultBehaviorProvider<T> defaultBehavior;
  // The abstract managed object
  private final AbstractManagedObjectDefinition<?, ?> definition;
  // Options applicable to this definition.
  private final Set<PropertyOption> options;
  // The property name.
  private final String propertyName;
  // The property value class.
  private final Class<T> theClass;
  /**
   * Create a property definition.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param theClass
   *          The property value class.
   * @param propertyName
   *          The property name.
   * @param options
   *          Options applicable to this definition.
   * @param defaultBehavior
   *          The default behavior provider.
   */
  protected PropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      Class<T> theClass, String propertyName, EnumSet<PropertyOption> options,
      DefaultBehaviorProvider<T> defaultBehavior) {
    ensureNotNull(d, theClass, propertyName);
    ensureNotNull(options, defaultBehavior);
    this.definition = d;
    this.theClass = theClass;
    this.propertyName = propertyName;
    this.options = EnumSet.copyOf(options);
    this.defaultBehavior = defaultBehavior;
  }
  /**
   * Apply a visitor to this property definition.
@@ -61,14 +216,36 @@
   * @param <R>
   *          The return type of the visitor's methods.
   * @param <P>
   *          The type of the additional parameters to the visitor's methods.
   *          The type of the additional parameters to the visitor's
   *          methods.
   * @param v
   *          The property definition visitor.
   * @param p
   *          Optional additional visitor parameter.
   * @return Returns a result as specified by the visitor.
   */
  <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p);
  public abstract <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p);
  /**
   * Apply a visitor to a property value associated with this property
   * definition.
   *
   * @param <R>
   *          The return type of the visitor's methods.
   * @param <P>
   *          The type of the additional parameters to the visitor's
   *          methods.
   * @param v
   *          The property value visitor.
   * @param value
   *          The property value.
   * @param p
   *          Optional additional visitor parameter.
   * @return Returns a result as specified by the visitor.
   */
  public abstract <R, P> R accept(PropertyValueVisitor<R, P> v, T value, P p);
@@ -76,9 +253,10 @@
   * Cast the provided value to the type associated with this property
   * definition.
   * <p>
   * This method only casts the object to the required type; it does not
   * validate the value once it has been cast. Subsequent validation should be
   * performed using the method {@link #validateValue(Object)}.
   * This method only casts the object to the required type; it does
   * not validate the value once it has been cast. Subsequent
   * validation should be performed using the method
   * {@link #validateValue(Object)}.
   * <p>
   * This method guarantees the following expression is always
   * <code>true</code>:
@@ -92,28 +270,65 @@
   *          The property value to be cast (can be <code>null</code>).
   * @return Returns the property value cast to the correct type.
   * @throws ClassCastException
   *           If the provided property value did not have the correct type.
   *           If the provided property value did not have the correct
   *           type.
   */
  T castValue(Object object) throws ClassCastException;
  public final T castValue(Object object) throws ClassCastException {
    return theClass.cast(object);
  }
  /**
   * Compares this property definition with the specified property definition
   * for order. Returns a negative integer, zero, or a positive integer if this
   * property definition is less than, equal to, or greater than the specified
   * property definition.
   * Compares two property values for order. Returns a negative
   * integer, zero, or a positive integer as the first argument is
   * less than, equal to, or greater than the second.
   * <p>
   * The ordering must be determined first from the property name and then base
   * on the underlying value type.
   * This default implementation normalizes both values using
   * {@link #normalizeValue(Object)} and then performs a
   * case-sensitive string comparison.
   *
   * @param o1
   *          the first object to be compared.
   * @param o2
   *          the second object to be compared.
   * @return a negative integer, zero, or a positive integer as the
   *         first argument is less than, equal to, or greater than
   *         the second.
   */
  public int compare(T o1, T o2) {
    ensureNotNull(o1, o2);
    String s1 = normalizeValue(o1);
    String s2 = normalizeValue(o2);
    return s1.compareTo(s2);
  }
  /**
   * Compares this property definition with the specified property
   * definition for order. Returns a negative integer, zero, or a
   * positive integer if this property definition is less than, equal
   * to, or greater than the specified property definition.
   * <p>
   * The ordering must be determined first from the property name and
   * then base on the underlying value type.
   *
   * @param o
   *          The reference property definition with which to compare.
   * @return Returns a negative integer, zero, or a positive integer if this
   *         property definition is less than, equal to, or greater than the
   *         specified property definition.
   * @return Returns a negative integer, zero, or a positive integer
   *         if this property definition is less than, equal to, or
   *         greater than the specified property definition.
   */
  int compareTo(PropertyDefinition<?> o);
  public final int compareTo(PropertyDefinition<?> o) {
    int rc = propertyName.compareTo(o.propertyName);
    if (rc == 0) {
      rc = theClass.getName().compareTo(o.theClass.getName());
    }
    return rc;
  }
@@ -126,14 +341,17 @@
   * @throws IllegalPropertyValueStringException
   *           If the property value string is invalid.
   */
  T decodeValue(String value) throws IllegalPropertyValueStringException;
  public abstract T decodeValue(String value)
      throws IllegalPropertyValueStringException;
  /**
   * Encode the provided property value into its string representation.
   * Encode the provided property value into its string
   * representation.
   * <p>
   * TODO: change name to avoid confusion with toString()?
   * This default implementation simply returns invokes the
   * {@link Object#toString()} method on the provided value.
   *
   * @param value
   *          The property value (must not be <code>null</code>).
@@ -141,29 +359,50 @@
   * @throws IllegalPropertyValueException
   *           If the property value is invalid.
   */
  String encodeValue(T value) throws IllegalPropertyValueException;
  public String encodeValue(T value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    return value.toString();
  }
  /**
   * Indicates whether some other object is &quot;equal to&quot; this property
   * definition. This method must obey the general contract of
   * <tt>Object.equals(Object)</tt>. Additionally, this method can return
   * <tt>true</tt> <i>only</i> if the specified Object is also a property
   * definition and it has the same name, as returned by {@link #getName()},
   * and also is deemed to be &quot;compatible&quot; with this property
   * definition. Compatibility means that the two property definitions share the
   * same underlying value type and provide similar comparator implementations.
   * Indicates whether some other object is &quot;equal to&quot; this
   * property definition. This method must obey the general contract
   * of <tt>Object.equals(Object)</tt>. Additionally, this method
   * can return <tt>true</tt> <i>only</i> if the specified Object
   * is also a property definition and it has the same name, as
   * returned by {@link #getName()}, and also is deemed to be
   * &quot;compatible&quot; with this property definition.
   * Compatibility means that the two property definitions share the
   * same underlying value type and provide similar comparator
   * implementations.
   *
   * @param o
   *          The reference object with which to compare.
   * @return Returns <code>true</code> only if the specified object is also a
   *         property definition and it has the same name and is compatible with
   *         this property definition.
   * @return Returns <code>true</code> only if the specified object
   *         is also a property definition and it has the same name
   *         and is compatible with this property definition.
   * @see java.lang.Object#equals(java.lang.Object)
   * @see java.lang.Object#hashCode()
   */
  boolean equals(Object o);
  @Override
  public final boolean equals(Object o) {
    if (this == o) {
      return true;
    } else if (o instanceof PropertyDefinition) {
      PropertyDefinition other = (PropertyDefinition) o;
      if (propertyName.equals(other.propertyName)) {
        if (theClass.equals(other.theClass)) {
          return true;
        }
      }
      return false;
    } else {
      return false;
    }
  }
@@ -171,10 +410,12 @@
   * Get the default behavior provider associated with this property
   * definition.
   *
   * @return Returns the default behavior provider associated with this
   *         property definition.
   * @return Returns the default behavior provider associated with
   *         this property definition.
   */
  DefaultBehaviorProvider<T> getDefaultBehaviorProvider();
  public final DefaultBehaviorProvider<T> getDefaultBehaviorProvider() {
    return defaultBehavior;
  }
@@ -186,7 +427,9 @@
   *         the default locale, or <code>null</code> if there is no
   *         description.
   */
  String getDescription();
  public final String getDescription() {
    return getDescription(Locale.getDefault());
  }
@@ -200,7 +443,30 @@
   *         the specified locale, or <code>null</code> if there is
   *         no description.
   */
  String getDescription(Locale locale);
  public final String getDescription(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName + ".description";
    try {
      return resource.getMessage(definition, property, locale);
    } catch (MissingResourceException e) {
      return null;
    }
  }
  /**
   * Gets the managed object definition associated with this property
   * definition.
   *
   * @return Returns the managed object definition associated with
   *         this property definition.
   */
  public final AbstractManagedObjectDefinition<?, ?>
      getManagedObjectDefinition() {
    return definition;
  }
@@ -209,7 +475,9 @@
   *
   * @return Returns the name of the property.
   */
  String getName();
  public final String getName() {
    return propertyName;
  }
@@ -220,7 +488,9 @@
   * @return Returns the synopsis of this property definition in the
   *         default locale.
   */
  String getSynopsis();
  public final String getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
@@ -233,40 +503,63 @@
   * @return Returns the synopsis of this property definition in the
   *         specified locale.
   */
  String getSynopsis(Locale locale);
  public final String getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName + ".synopsis";
    try {
      return resource.getMessage(definition, property, locale);
    } catch (MissingResourceException e) {
      return null;
    }
  }
  /**
   * Returns a hash code value for this property definition. The hash code
   * should be derived from the property name.
   * Returns a hash code value for this property definition. The hash
   * code should be derived from the property name and the type of
   * values handled by this property definition.
   *
   * @return Returns the hash code value for this property definition.
   */
  int hashCode();
  @Override
  public final int hashCode() {
    int rc = 17 + propertyName.hashCode();
    return 37 * rc + theClass.hashCode();
  }
  /**
   * Check if the specified option is set for this property definition.
   * Check if the specified option is set for this property
   * definition.
   *
   * @param option
   *          The option to test.
   * @return Returns <code>true</code> if the option is set, or
   *         <code>false</code> otherwise.
   */
  boolean hasOption(PropertyOption option);
  public final boolean hasOption(PropertyOption option) {
    return options.contains(option);
  }
  /**
   * Get a normalized string representation of a property value. This can then
   * be used for comparisons and for generating hash-codes.
   * Get a normalized string representation of a property value. This
   * can then be used for comparisons and for generating hash-codes.
   * <p>
   * This method may throw an exception if the provided value is invalid.
   * However, applications should not assume that implementations of this method
   * will always validate a value. This task is the responsibility of
   * {@link #validateValue(Object)}.
   * This method may throw an exception if the provided value is
   * invalid. However, applications should not assume that
   * implementations of this method will always validate a value. This
   * task is the responsibility of {@link #validateValue(Object)}.
   * <p>
   * This default implementation simply returns the string
   * representation of the provided value. Sub-classes might want to
   * override this method if this behavior is insufficient (for
   * example, a string property definition might strip white-space and
   * convert characters to lower-case).
   *
   * @param value
   *          The property value to be normalized.
@@ -274,30 +567,57 @@
   * @throws IllegalPropertyValueException
   *           If the property value is invalid.
   */
  String normalizeValue(T value) throws IllegalPropertyValueException;
  public String normalizeValue(T value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    return encodeValue(value);
  }
  /**
   * Append a string representation of the property definition to the provided
   * string builder.
   * Returns a string representation of this property definition.
   *
   * @return Returns a string representation of this property
   *         definition.
   * @see Object#toString()
   */
  @Override
  public final String toString() {
    StringBuilder builder = new StringBuilder();
    toString(builder);
    return builder.toString();
  }
  /**
   * Append a string representation of the property definition to the
   * provided string builder.
   * <p>
   * This simple implementation just outputs the propertyName of the
   * property definition. Sub-classes should override this method to
   * provide more complete string representations.
   *
   * @param builder
   *          The string builder where the string representation should be
   *          appended.
   *          The string builder where the string representation
   *          should be appended.
   */
  void toString(StringBuilder builder);
  public void toString(StringBuilder builder) {
    builder.append(propertyName);
  }
  /**
   * Determine if the provided property value is valid according to this
   * property definition.
   * Determine if the provided property value is valid according to
   * this property definition.
   *
   * @param value
   *          The property value (must not be <code>null</code>).
   * @throws IllegalPropertyValueException
   *           If the property value is invalid.
   */
  void validateValue(T value) throws IllegalPropertyValueException;
  public abstract void validateValue(T value)
      throws IllegalPropertyValueException;
}
opends/src/server/org/opends/server/admin/PropertyValueVisitor.java
New file
@@ -0,0 +1,295 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import java.net.InetAddress;
import org.opends.server.types.AddressMask;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
/**
 * A visitor of property values, in the style of the visitor design
 * pattern. Classes implementing this interface can query a property a
 * value and its associated property definition in a type-safe manner
 * when the kind of property value is unknown at compile time. When a
 * visitor is passed to a property definition's accept method, the
 * corresponding visit method most applicable to that property
 * definition is invoked.
 * <p>
 * Each <code>visitXXX</code> method is provided with a default
 * implementation which calls
 * {@link #visitUnknown(PropertyDefinition, Object, Object)}.
 * Sub-classes can override any or all of the methods to provide their
 * own type-specific behavior.
 *
 * @param <R>
 *          The return type of this visitor's methods. Use
 *          {@link java.lang.Void} for visitors that do not need to
 *          return results.
 * @param <P>
 *          The type of the additional parameter to this visitor's
 *          methods. Use {@link java.lang.Void} for visitors that do
 *          not need an additional parameter.
 */
public abstract class PropertyValueVisitor<R, P> {
  /**
   * Default constructor.
   */
  protected PropertyValueVisitor() {
    // No implementation required.
  }
  /**
   * Visit an attribute type.
   *
   * @param d
   *          The attribute type property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitAttributeType(AttributeTypePropertyDefinition d,
      AttributeType v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a boolean.
   *
   * @param d
   *          The boolean property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitBoolean(BooleanPropertyDefinition d, Boolean v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a class.
   *
   * @param d
   *          The class property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitClass(ClassPropertyDefinition d, String v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a DN.
   *
   * @param d
   *          The DN property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitDN(DNPropertyDefinition d, DN v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a duration.
   *
   * @param d
   *          The duration property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitDuration(DurationPropertyDefinition d, Long v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit an enumeration.
   *
   * @param <E>
   *          The enumeration that should be used for values of the
   *          property definition.
   * @param v
   *          The property value to visit.
   * @param d
   *          The enumeration property definition.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public <E extends Enum<E>> R visitEnum(
      EnumPropertyDefinition<E> d, E v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit an integer.
   *
   * @param d
   *          The integer property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitInteger(IntegerPropertyDefinition d, Integer v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a IP address.
   *
   * @param d
   *          The IP address property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitIPAddress(IPAddressPropertyDefinition d, InetAddress v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a IP address mask.
   *
   * @param d
   *          The IP address mask property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitIPAddressMask(IPAddressMaskPropertyDefinition d, AddressMask v,
      P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a size.
   *
   * @param d
   *          The size property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitSize(SizePropertyDefinition d, Long v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit a string.
   *
   * @param d
   *          The string property definition.
   * @param v
   *          The property value to visit.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   */
  public R visitString(StringPropertyDefinition d, String v, P p) {
    return visitUnknown(d, v, p);
  }
  /**
   * Visit an unknown type of property value. Implementations of this
   * method can provide default behavior for unknown types of
   * property.
   * <p>
   * The default implementation of this method throws an
   * {@link UnknownPropertyDefinitionException}. Sub-classes can
   * override this method with their own default behavior.
   *
   * @param <T>
   *          The type of property value to visit.
   * @param d
   *          The property definition.
   * @param v
   *          The property value.
   * @param p
   *          A visitor specified parameter.
   * @return Returns a visitor specified result.
   * @throws UnknownPropertyDefinitionException
   *           Visitor implementations may optionally throw this
   *           exception.
   */
  public <T> R visitUnknown(PropertyDefinition<T> d, T v, P p)
      throws UnknownPropertyDefinitionException {
    throw new UnknownPropertyDefinitionException(d, p);
  }
}
opends/src/server/org/opends/server/admin/SizePropertyDefinition.java
@@ -45,13 +45,7 @@
 * represented using a negative memory size value or using the string
 * "unlimited".
 */
public final class SizePropertyDefinition extends
    AbstractPropertyDefinition<Long> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 2263747274588279580L;
public final class SizePropertyDefinition extends PropertyDefinition<Long> {
  // String used to represent unlimited memory sizes.
  private static final String UNLIMITED = "unlimited";
@@ -374,6 +368,16 @@
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) {
    return v.visitSize(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder) {
    super.toString(builder);
opends/src/server/org/opends/server/admin/StringPropertyDefinition.java
@@ -43,13 +43,7 @@
/**
 * String property definition.
 */
public final class StringPropertyDefinition extends
    AbstractPropertyDefinition<String> {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -2739105900274621416L;
public final class StringPropertyDefinition extends PropertyDefinition<String> {
  // Flag indicating whether values of this property are
  // case-insensitive.
@@ -296,4 +290,14 @@
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitString(this, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
    return v.visitString(this, value, p);
  }
}