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

Nicolas Capponi
02.47.2013 2fef5aa0046548cb88034553f522d907195a19f7
OpenDJ 3 : config framework

Reducing compilation errors in org.opends.server.admin packages

* Simple changes in org.opends.server.admin package
** replace Message class by LocalizableMessage
** use Validator class from SDK

* Add stub methods in DirectoryServer and Aci classes to satisfy dependencies

* Remove log level prefix from properties names in admin.properties file
48 files modified
13588 ■■■■■ changed files
opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java 8 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java 1919 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AdminException.java 59 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AdminRuntimeException.java 92 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AdministrationConnector.java 45 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AdministratorAction.java 244 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java 2014 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AliasDefaultBehaviorProvider.java 117 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/AttributeTypePropertyDefinition.java 274 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/BooleanPropertyDefinition.java 6 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java 58 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ClassPropertyDefinition.java 557 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/DNPropertyDefinition.java 300 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/DecodingException.java 7 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java 51 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/DefinitionDecodingException.java 14 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/DurationPropertyDefinition.java 912 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/EnumPropertyDefinition.java 366 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/GenericConstraint.java 299 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/IPAddressMaskPropertyDefinition.java 188 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/IPAddressPropertyDefinition.java 225 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/IllegalPropertyValueException.java 82 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/IllegalPropertyValueStringException.java 83 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/InstantiableRelationDefinition.java 437 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/IntegerPropertyDefinition.java 552 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectAlreadyExistsException.java 35 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java 14 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectNotFoundException.java 49 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java 13 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/OperationsException.java 62 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyDefinition.java 1083 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyDefinitionUsageBuilder.java 583 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyException.java 107 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsMandatoryException.java 34 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsReadOnlyException.java 34 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsSingleValuedException.java 38 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/PropertyNotFoundException.java 55 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/RelationDefinition.java 633 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/SetRelationDefinition.java 384 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/SizePropertyDefinition.java 555 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/StringPropertyDefinition.java 476 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/Tag.java 265 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/UnknownPropertyDefinitionException.java 69 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/client/ClientConstraintHandler.java 8 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/package-info.java 2 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/server/ServerConstraintHandler.java 6 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java 8 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties 166 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/ACIPropertyDefinition.java
@@ -27,11 +27,11 @@
package org.opends.server.admin;
import static com.forgerock.opendj.util.Validator.*;
import org.opends.server.authorization.dseecompat.Aci;
import org.opends.server.authorization.dseecompat.AciException;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.ByteString;
import static org.opends.server.util.Validator.ensureNotNull;
import java.util.EnumSet;
@@ -116,7 +116,7 @@
    ensureNotNull(value);
    try {
      return Aci.decode(ByteString.valueOf(value), DN.NULL_DN);
      return Aci.decode(ByteString.valueOf(value), DN.rootDN());
    } catch (AciException e) {
      // TODO: it would be nice to throw the cause.
      throw new IllegalPropertyValueStringException(this, value);
opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -27,8 +27,6 @@
package org.opends.server.admin;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -41,13 +39,11 @@
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.Vector;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.DefinitionDecodingException.Reason;
/**
 * Defines the structure of an abstract managed object. Abstract managed objects
 * cannot be instantiated.
@@ -56,1103 +52,924 @@
 * overall configuration model of an application.
 *
 * @param <C>
 *          The type of client managed object configuration that this definition
 *          represents.
 *            The type of client managed object configuration that this
 *            definition represents.
 * @param <S>
 *          The type of server managed object configuration that this definition
 *          represents.
 *            The type of server managed object configuration that this
 *            definition represents.
 */
public abstract class AbstractManagedObjectDefinition
    <C extends ConfigurationClient, S extends Configuration> {
public abstract class AbstractManagedObjectDefinition<C extends ConfigurationClient, S extends Configuration> {
  // The name of the definition.
  private final String name;
    // The name of the definition.
    private final String name;
  // The parent managed object definition if applicable.
  private final AbstractManagedObjectDefinition<? super C, ? super S> parent;
    // The parent managed object definition if applicable.
    private final AbstractManagedObjectDefinition<? super C, ? super S> parent;
  // The set of constraints associated with this managed object
  // definition.
  private final Collection<Constraint> constraints;
    // The set of constraints associated with this managed object
    // definition.
    private final Collection<Constraint> constraints;
  // The set of property definitions applicable to this managed object
  // definition.
  private final Map<String, PropertyDefinition<?>> propertyDefinitions;
    // The set of property definitions applicable to this managed object
    // definition.
    private final Map<String, PropertyDefinition<?>> propertyDefinitions;
  // The set of relation definitions applicable to this managed object
  // definition.
  private final Map<String, RelationDefinition<?, ?>> relationDefinitions;
    // The set of relation definitions applicable to this managed object
    // definition.
    private final Map<String, RelationDefinition<?, ?>> relationDefinitions;
  // The set of relation definitions directly referencing this managed
  // object definition.
  private final Set<RelationDefinition<C, S>> reverseRelationDefinitions;
    // The set of relation definitions directly referencing this managed
    // object definition.
    private final Set<RelationDefinition<C, S>> reverseRelationDefinitions;
  // The set of all property definitions associated with this managed
  // object definition including inherited property definitions.
  private final Map<String, PropertyDefinition<?>> allPropertyDefinitions;
    // The set of all property definitions associated with this managed
    // object definition including inherited property definitions.
    private final Map<String, PropertyDefinition<?>> allPropertyDefinitions;
  // The set of all relation definitions associated with this managed
  // object definition including inherited relation definitions.
  private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions;
    // The set of all relation definitions associated with this managed
    // object definition including inherited relation definitions.
    private final Map<String, RelationDefinition<?, ?>> allRelationDefinitions;
  // The set of aggregation property definitions applicable to this
  // managed object definition.
  private final Map<String, AggregationPropertyDefinition<?, ?>>
    aggregationPropertyDefinitions;
    // The set of aggregation property definitions applicable to this
    // managed object definition.
    private final Map<String, AggregationPropertyDefinition<?, ?>> aggregationPropertyDefinitions;
  // The set of aggregation property definitions directly referencing this
  // managed object definition.
  private final Vector<AggregationPropertyDefinition<?, ?>>
    reverseAggregationPropertyDefinitions;
    // The set of aggregation property definitions directly referencing this
    // managed object definition.
    private final Vector<AggregationPropertyDefinition<?, ?>> reverseAggregationPropertyDefinitions;
  // The set of all aggregation property definitions associated with this
  // managed object definition including inherited relation definitions.
  private final Map<String, AggregationPropertyDefinition<?, ?>>
    allAggregationPropertyDefinitions;
    // The set of all aggregation property definitions associated with this
    // managed object definition including inherited relation definitions.
    private final Map<String, AggregationPropertyDefinition<?, ?>> allAggregationPropertyDefinitions;
  // The set of tags associated with this managed object.
  private final Set<Tag> allTags;
    // The set of tags associated with this managed object.
    private final Set<Tag> allTags;
  // Options applicable to this definition.
  private final Set<ManagedObjectOption> options;
    // Options applicable to this definition.
    private final Set<ManagedObjectOption> options;
  // The set of managed object definitions which inherit from this definition.
  private final Map<String,
    AbstractManagedObjectDefinition<? extends C, ? extends S>> children;
    // The set of managed object definitions which inherit from this definition.
    private final Map<String, AbstractManagedObjectDefinition<? extends C, ? extends S>> children;
    /**
     * Create a new abstract managed object definition.
     *
     * @param name
     *            The name of the definition.
     * @param parent
     *            The parent definition, or <code>null</code> if there is no
     *            parent (only the {@link TopCfgDefn} should have a
     *            <code>null</code> parent, unless the definition is being used
     *            for testing).
     */
    protected AbstractManagedObjectDefinition(String name, AbstractManagedObjectDefinition<? super C, ? super S> parent) {
        this.name = name;
        this.parent = parent;
        this.constraints = new LinkedList<Constraint>();
        this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
        this.relationDefinitions = new HashMap<String, RelationDefinition<?, ?>>();
        this.reverseRelationDefinitions = new HashSet<RelationDefinition<C, S>>();
        this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
        this.allRelationDefinitions = new HashMap<String, RelationDefinition<?, ?>>();
        this.aggregationPropertyDefinitions = new HashMap<String, AggregationPropertyDefinition<?, ?>>();
        this.reverseAggregationPropertyDefinitions = new Vector<AggregationPropertyDefinition<?, ?>>();
        this.allAggregationPropertyDefinitions = new HashMap<String, AggregationPropertyDefinition<?, ?>>();
        this.allTags = new HashSet<Tag>();
        this.options = EnumSet.noneOf(ManagedObjectOption.class);
        this.children = new HashMap<String, AbstractManagedObjectDefinition<? extends C, ? extends S>>();
  /**
   * Create a new abstract managed object definition.
   *
   * @param name
   *          The name of the definition.
   * @param parent
   *          The parent definition, or <code>null</code> if there
   *          is no parent (only the {@link TopCfgDefn} should have a
   *          <code>null</code> parent, unless the definition is
   *          being used for testing).
   */
  protected AbstractManagedObjectDefinition(String name,
      AbstractManagedObjectDefinition<? super C, ? super S> parent) {
    this.name = name;
    this.parent = parent;
    this.constraints = new LinkedList<Constraint>();
    this.propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
    this.relationDefinitions = new HashMap<String, RelationDefinition<?,?>>();
    this.reverseRelationDefinitions = new HashSet<RelationDefinition<C,S>>();
    this.allPropertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
    this.allRelationDefinitions =
      new HashMap<String, RelationDefinition<?, ?>>();
    this.aggregationPropertyDefinitions =
      new HashMap<String, AggregationPropertyDefinition<?,?>>();
    this.reverseAggregationPropertyDefinitions =
      new Vector<AggregationPropertyDefinition<?,?>>();
    this.allAggregationPropertyDefinitions =
      new HashMap<String, AggregationPropertyDefinition<?, ?>>();
    this.allTags = new HashSet<Tag>();
    this.options = EnumSet.noneOf(ManagedObjectOption.class);
        // If we have a parent definition then inherit its features.
        if (parent != null) {
            registerInParent();
    this.children = new HashMap<String,
        AbstractManagedObjectDefinition<? extends C, ? extends S>>();
            for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) {
                allPropertyDefinitions.put(pd.getName(), pd);
            }
    // If we have a parent definition then inherit its features.
    if (parent != null) {
      registerInParent();
            for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) {
                allRelationDefinitions.put(rd.getName(), rd);
            }
      for (PropertyDefinition<?> pd : parent.getAllPropertyDefinitions()) {
        allPropertyDefinitions.put(pd.getName(), pd);
      }
            for (AggregationPropertyDefinition<?, ?> apd : parent.getAllAggregationPropertyDefinitions()) {
      for (RelationDefinition<?, ?> rd : parent.getAllRelationDefinitions()) {
        allRelationDefinitions.put(rd.getName(), rd);
      }
                allAggregationPropertyDefinitions.put(apd.getName(), apd);
            }
      for (AggregationPropertyDefinition<?, ?> apd :
        parent.getAllAggregationPropertyDefinitions()) {
        allAggregationPropertyDefinitions.put(apd.getName(), apd);
      }
      // Tag inheritance is performed during preprocessing.
    }
  }
  /**
   * Get all the child managed object definitions which inherit from
   * this managed object definition.
   *
   * @return Returns an unmodifiable collection containing all the
   *         subordinate managed object definitions which inherit from
   *         this managed object definition.
   */
  public final Collection<AbstractManagedObjectDefinition
      <? extends C, ? extends S>> getAllChildren() {
    List<AbstractManagedObjectDefinition<? extends C, ? extends S>> list =
      new ArrayList<AbstractManagedObjectDefinition<? extends C, ? extends S>>(
        children.values());
    for (AbstractManagedObjectDefinition<? extends C, ? extends S> child :
        children.values()) {
      list.addAll(child.getAllChildren());
    }
    return Collections.unmodifiableCollection(list);
  }
  /**
   * Get all the constraints associated with this type of managed
   * object. The returned collection will contain inherited
   * constraints.
   *
   * @return Returns a collection containing all the constraints
   *         associated with this type of managed object. The caller
   *         is free to modify the collection if required.
   */
  public final Collection<Constraint> getAllConstraints() {
    // This method does not used a cached set of constraints because
    // constraints may be updated after child definitions have been
    // defined.
    List<Constraint> allConstraints = new LinkedList<Constraint>();
    if (parent != null) {
      allConstraints.addAll(parent.getAllConstraints());
    }
    allConstraints.addAll(constraints);
    return allConstraints;
  }
  /**
   * Get all the property definitions associated with this type of
   * managed object. The returned collection will contain inherited
   * property definitions.
   *
   * @return Returns an unmodifiable collection containing all the
   *         property definitions associated with this type of managed
   *         object.
   */
  public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() {
    return Collections.unmodifiableCollection(allPropertyDefinitions.values());
  }
  /**
   * Get all the relation definitions associated with this type of
   * managed object. The returned collection will contain inherited
   * relation definitions.
   *
   * @return Returns an unmodifiable collection containing all the
   *         relation definitions associated with this type of managed
   *         object.
   */
  public final Collection<RelationDefinition<?, ?>>
      getAllRelationDefinitions() {
    return Collections.unmodifiableCollection(allRelationDefinitions.values());
  }
  /**
   * Get all the relation definitions which refer to this managed
   * object definition. The returned collection will contain relation
   * definitions which refer to parents of this managed object
   * definition.
   *
   * @return Returns a collection containing all the relation
   *         definitions which refer to this managed object
   *         definition. The caller is free to modify the collection
   *         if required.
   */
  public final Collection<RelationDefinition<? super C, ? super S>>
  getAllReverseRelationDefinitions() {
    // This method does not used a cached set of relations because
    // relations may be updated after child definitions have been
    // defined.
    List<RelationDefinition<? super C, ? super S>> rdlist =
      new LinkedList<RelationDefinition<? super C, ? super S>>();
    if (parent != null) {
      rdlist.addAll(parent.getAllReverseRelationDefinitions());
    }
    rdlist.addAll(reverseRelationDefinitions);
    return rdlist;
  }
  /**
   * Get all the aggregation property definitions associated with this type of
   * managed object. The returned collection will contain inherited
   * aggregation property definitions.
   *
   * @return Returns an unmodifiable collection containing all the
   *         aggregation property definitions associated with this type of
   *         managed object.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
      getAllAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      allAggregationPropertyDefinitions.values());
  }
  /**
   * Get all the aggregation property definitions which refer to this managed
   * object definition. The returned collection will contain aggregation
   * property definitions which refer to parents of this managed object
   * definition.
   *
   * @return Returns a collection containing all the aggregation property
   *         definitions which refer to this managed object
   *         definition. The caller is free to modify the collection
   *         if required.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
  getAllReverseAggregationPropertyDefinitions() {
    // This method does not used a cached set of aggregation properties because
    // aggregation properties may be updated after child definitions have been
    // defined.
    List<AggregationPropertyDefinition<?, ?>> apdlist =
      new LinkedList<AggregationPropertyDefinition<?, ?>>();
    if (parent != null) {
      apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions());
    }
    apdlist.addAll(reverseAggregationPropertyDefinitions);
    return apdlist;
  }
  /**
   * Get all the tags associated with this type of managed object. The
   * returned collection will contain inherited tags.
   *
   * @return Returns an unmodifiable collection containing all the
   *         tags associated with this type of managed object.
   */
  public final Collection<Tag> getAllTags() {
    return Collections.unmodifiableCollection(allTags);
  }
  /**
   * Get the named child managed object definition which inherits from
   * this managed object definition. This method will recursively
   * search down through the inheritance hierarchy.
   *
   * @param name
   *          The name of the managed object definition sub-type.
   * @return Returns the named child managed object definition which
   *         inherits from this managed object definition.
   * @throws IllegalArgumentException
   *           If the specified managed object definition name was
   *           null or empty or if the requested subordinate managed
   *           object definition was not found.
   */
  public final AbstractManagedObjectDefinition<? extends C, ? extends S>
      getChild(String name) throws IllegalArgumentException {
    if ((name == null) || (name.length() == 0)) {
      throw new IllegalArgumentException("null or empty managed object name");
    }
    AbstractManagedObjectDefinition<? extends C, ? extends S> d = children
        .get(name);
    if (d == null) {
      // Recursively search.
      for (AbstractManagedObjectDefinition<? extends C, ? extends S> child :
          children.values()) {
        try {
          d = child.getChild(name);
          break;
        } catch (IllegalArgumentException e) {
          // Try the next child.
            // Tag inheritance is performed during preprocessing.
        }
      }
    }
    if (d == null) {
      throw new IllegalArgumentException("child managed object definition \""
          + name + "\" not found");
    /**
     * Get all the child managed object definitions which inherit from this
     * managed object definition.
     *
     * @return Returns an unmodifiable collection containing all the subordinate
     *         managed object definitions which inherit from this managed object
     *         definition.
     */
    public final Collection<AbstractManagedObjectDefinition<? extends C, ? extends S>> getAllChildren() {
        List<AbstractManagedObjectDefinition<? extends C, ? extends S>> list = new ArrayList<AbstractManagedObjectDefinition<? extends C, ? extends S>>(
                children.values());
        for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : children.values()) {
            list.addAll(child.getAllChildren());
        }
        return Collections.unmodifiableCollection(list);
    }
    return d;
  }
    /**
     * Get all the constraints associated with this type of managed object. The
     * returned collection will contain inherited constraints.
     *
     * @return Returns a collection containing all the constraints associated
     *         with this type of managed object. The caller is free to modify
     *         the collection if required.
     */
    public final Collection<Constraint> getAllConstraints() {
        // This method does not used a cached set of constraints because
        // constraints may be updated after child definitions have been
        // defined.
        List<Constraint> allConstraints = new LinkedList<Constraint>();
        if (parent != null) {
            allConstraints.addAll(parent.getAllConstraints());
        }
        allConstraints.addAll(constraints);
  /**
   * Get the child managed object definitions which inherit directly
   * from this managed object definition.
   *
   * @return Returns an unmodifiable collection containing the
   *         subordinate managed object definitions which inherit
   *         directly from this managed object definition.
   */
  public final Collection<AbstractManagedObjectDefinition
      <? extends C, ? extends S>> getChildren() {
    return Collections.unmodifiableCollection(children.values());
  }
  /**
   * Get the constraints defined by this managed object definition.
   * The returned collection will not contain inherited constraints.
   *
   * @return Returns an unmodifiable collection containing the
   *         constraints defined by this managed object definition.
   */
  public final Collection<Constraint> getConstraints() {
    return Collections.unmodifiableCollection(constraints);
  }
  /**
   * Gets the optional description of this managed object definition
   * in the default locale.
   *
   * @return Returns the description of this managed object definition
   *         in the default locale, or <code>null</code> if there is
   *         no description.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getDescription() throws UnsupportedOperationException {
    return getDescription(Locale.getDefault());
  }
  /**
   * Gets the optional description of this managed object definition
   * in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the description of this managed object definition
   *         in the specified locale, or <code>null</code> if there
   *         is no description.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getDescription(Locale locale)
      throws UnsupportedOperationException {
    try {
      return ManagedObjectDefinitionI18NResource.getInstance()
        .getMessage(this, "description", locale);
    } catch (MissingResourceException e) {
      return null;
    }
  }
  /**
   * Get the name of the definition.
   *
   * @return Returns the name of the definition.
   */
  public final String getName() {
    return name;
  }
  /**
   * Get the parent managed object definition, if applicable.
   *
   * @return Returns the parent of this managed object definition, or
   *         <code>null</code> if this definition is the
   *         {@link TopCfgDefn}.
   */
  public final AbstractManagedObjectDefinition<? super C,
      ? super S> getParent() {
    return parent;
  }
  /**
   * Get the specified property definition associated with this type
   * of managed object. The search will include any inherited property
   * definitions.
   *
   * @param name
   *          The name of the property definition to be retrieved.
   * @return Returns the specified property definition associated with
   *         this type of managed object.
   * @throws IllegalArgumentException
   *           If the specified property name was null or empty or if
   *           the requested property definition was not found.
   */
  public final PropertyDefinition<?> getPropertyDefinition(String name)
      throws IllegalArgumentException {
    if ((name == null) || (name.length() == 0)) {
      throw new IllegalArgumentException("null or empty property name");
        return allConstraints;
    }
    PropertyDefinition<?> d = allPropertyDefinitions.get(name);
    if (d == null) {
      throw new IllegalArgumentException("property definition \"" + name
          + "\" not found");
    /**
     * Get all the property definitions associated with this type of managed
     * object. The returned collection will contain inherited property
     * definitions.
     *
     * @return Returns an unmodifiable collection containing all the property
     *         definitions associated with this type of managed object.
     */
    public final Collection<PropertyDefinition<?>> getAllPropertyDefinitions() {
        return Collections.unmodifiableCollection(allPropertyDefinitions.values());
    }
    return d;
  }
  /**
   * Get the property definitions defined by this managed object
   * definition. The returned collection will not contain inherited
   * property definitions.
   *
   * @return Returns an unmodifiable collection containing the
   *         property definitions defined by this managed object
   *         definition.
   */
  public final Collection<PropertyDefinition<?>> getPropertyDefinitions() {
    return Collections.unmodifiableCollection(propertyDefinitions
        .values());
  }
  /**
   * Get the specified relation definition associated with this type
   * of managed object.The search will include any inherited relation
   * definitions.
   *
   * @param name
   *          The name of the relation definition to be retrieved.
   * @return Returns the specified relation definition associated with
   *         this type of managed object.
   * @throws IllegalArgumentException
   *           If the specified relation name was null or empty or if
   *           the requested relation definition was not found.
   */
  public final RelationDefinition<?, ?> getRelationDefinition(String name)
      throws IllegalArgumentException {
    if ((name == null) || (name.length() == 0)) {
      throw new IllegalArgumentException("null or empty relation name");
    /**
     * Get all the relation definitions associated with this type of managed
     * object. The returned collection will contain inherited relation
     * definitions.
     *
     * @return Returns an unmodifiable collection containing all the relation
     *         definitions associated with this type of managed object.
     */
    public final Collection<RelationDefinition<?, ?>> getAllRelationDefinitions() {
        return Collections.unmodifiableCollection(allRelationDefinitions.values());
    }
    RelationDefinition<?, ?> d = allRelationDefinitions.get(name);
    if (d == null) {
      throw new IllegalArgumentException("relation definition \"" + name
          + "\" not found");
    /**
     * Get all the relation definitions which refer to this managed object
     * definition. The returned collection will contain relation definitions
     * which refer to parents of this managed object definition.
     *
     * @return Returns a collection containing all the relation definitions
     *         which refer to this managed object definition. The caller is free
     *         to modify the collection if required.
     */
    public final Collection<RelationDefinition<? super C, ? super S>> getAllReverseRelationDefinitions() {
        // This method does not used a cached set of relations because
        // relations may be updated after child definitions have been
        // defined.
        List<RelationDefinition<? super C, ? super S>> rdlist = new LinkedList<RelationDefinition<? super C, ? super S>>();
        if (parent != null) {
            rdlist.addAll(parent.getAllReverseRelationDefinitions());
        }
        rdlist.addAll(reverseRelationDefinitions);
        return rdlist;
    }
    return d;
  }
  /**
   * Get the relation definitions defined by this managed object
   * definition. The returned collection will not contain inherited
   * relation definitions.
   *
   * @return Returns an unmodifiable collection containing the
   *         relation definitions defined by this managed object
   *         definition.
   */
  public final Collection<RelationDefinition<?,?>> getRelationDefinitions() {
    return Collections.unmodifiableCollection(relationDefinitions.values());
  }
  /**
   * Get the relation definitions which refer directly to this managed
   * object definition. The returned collection will not contain
   * relation definitions which refer to parents of this managed
   * object definition.
   *
   * @return Returns an unmodifiable collection containing the
   *         relation definitions which refer directly to this managed
   *         object definition.
   */
  public final Collection<RelationDefinition<C, S>>
      getReverseRelationDefinitions() {
    return Collections.unmodifiableCollection(reverseRelationDefinitions);
  }
  /**
   * Get the specified aggregation property definition associated with this type
   * of managed object.The search will include any inherited aggregation
   * property definitions.
   *
   * @param name
   *          The name of the aggregation property definition to be retrieved.
   * @return Returns the specified aggregation property definition associated
   *         with this type of managed object.
   * @throws IllegalArgumentException
   *           If the specified aggregation property name was null or empty or
   *           if the requested aggregation property definition was not found.
   */
  public final AggregationPropertyDefinition<?, ?>
    getAggregationPropertyDefinition(String name)
    throws IllegalArgumentException {
    if ((name == null) || (name.length() == 0)) {
      throw new IllegalArgumentException(
        "null or empty aggregation property name");
    /**
     * Get all the aggregation property definitions associated with this type of
     * managed object. The returned collection will contain inherited
     * aggregation property definitions.
     *
     * @return Returns an unmodifiable collection containing all the aggregation
     *         property definitions associated with this type of managed object.
     */
    public final Collection<AggregationPropertyDefinition<?, ?>> getAllAggregationPropertyDefinitions() {
        return Collections.unmodifiableCollection(allAggregationPropertyDefinitions.values());
    }
    AggregationPropertyDefinition<?, ?> d =
      allAggregationPropertyDefinitions.get(name);
    if (d == null) {
      throw new IllegalArgumentException("aggregation property definition \""
        + name + "\" not found");
    /**
     * Get all the aggregation property definitions which refer to this managed
     * object definition. The returned collection will contain aggregation
     * property definitions which refer to parents of this managed object
     * definition.
     *
     * @return Returns a collection containing all the aggregation property
     *         definitions which refer to this managed object definition. The
     *         caller is free to modify the collection if required.
     */
    public final Collection<AggregationPropertyDefinition<?, ?>> getAllReverseAggregationPropertyDefinitions() {
        // This method does not used a cached set of aggregation properties
        // because
        // aggregation properties may be updated after child definitions have
        // been
        // defined.
        List<AggregationPropertyDefinition<?, ?>> apdlist = new LinkedList<AggregationPropertyDefinition<?, ?>>();
        if (parent != null) {
            apdlist.addAll(parent.getAllReverseAggregationPropertyDefinitions());
        }
        apdlist.addAll(reverseAggregationPropertyDefinitions);
        return apdlist;
    }
    return d;
  }
  /**
   * Get the aggregation property definitions defined by this managed object
   * definition. The returned collection will not contain inherited
   * aggregation property definitions.
   *
   * @return Returns an unmodifiable collection containing the
   *         aggregation property definitions defined by this managed object
   *         definition.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
    getAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      aggregationPropertyDefinitions.values());
  }
  /**
   * Get the aggregation property definitions which refer directly to this
   * managed object definition. The returned collection will not contain
   * aggregation property definitions which refer to parents of this managed
   * object definition.
   *
   * @return Returns an unmodifiable collection containing the
   *         aggregation property definitions which refer directly to this
   *         managed object definition.
   */
  public final Collection<AggregationPropertyDefinition<?, ?>>
    getReverseAggregationPropertyDefinitions() {
    return Collections.unmodifiableCollection(
      reverseAggregationPropertyDefinitions);
  }
  /**
   * Gets the synopsis of this managed object definition in the
   * default locale.
   *
   * @return Returns the synopsis of this managed object definition in
   *         the default locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getSynopsis() throws UnsupportedOperationException {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this managed object definition in the
   * specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this managed object definition in
   *         the specified locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getSynopsis(Locale locale)
      throws UnsupportedOperationException {
    return ManagedObjectDefinitionI18NResource.getInstance()
        .getMessage(this, "synopsis", locale);
  }
  /**
   * Gets the user friendly name of this managed object definition in
   * the default locale.
   *
   * @return Returns the user friendly name of this managed object
   *         definition in the default locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getUserFriendlyName()
      throws UnsupportedOperationException {
    return getUserFriendlyName(Locale.getDefault());
  }
  /**
   * Gets the user friendly name of this managed object definition in
   * the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the user friendly name of this managed object
   *         definition in the specified locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getUserFriendlyName(Locale locale)
      throws UnsupportedOperationException {
    // TODO: have admin framework getMessage return a Message
    return Message.raw(ManagedObjectDefinitionI18NResource.getInstance()
        .getMessage(this, "user-friendly-name", locale));
  }
  /**
   * Gets the user friendly plural name of this managed object
   * definition in the default locale.
   *
   * @return Returns the user friendly plural name of this managed
   *         object definition in the default locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getUserFriendlyPluralName()
      throws UnsupportedOperationException {
    return getUserFriendlyPluralName(Locale.getDefault());
  }
  /**
   * Gets the user friendly plural name of this managed object
   * definition in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the user friendly plural name of this managed
   *         object definition in the specified locale.
   * @throws UnsupportedOperationException
   *           If this managed object definition is the
   *           {@link TopCfgDefn}.
   */
  public final Message getUserFriendlyPluralName(Locale locale)
      throws UnsupportedOperationException {
    return ManagedObjectDefinitionI18NResource.getInstance()
        .getMessage(this, "user-friendly-plural-name", locale);
  }
  /**
   * Determine whether there are any child managed object definitions which
   * inherit from this managed object definition.
   *
   * @return Returns <code>true</code> if this type of managed object has any
   *         child managed object definitions, <code>false</code> otherwise.
   */
  public final boolean hasChildren() {
    return !children.isEmpty();
  }
  /**
   * Determines whether or not this managed object definition has the
   * specified option.
   *
   * @param option
   *          The option to test.
   * @return Returns <code>true</code> if the option is set, or
   *         <code>false</code> otherwise.
   */
  public final boolean hasOption(ManagedObjectOption option) {
    return options.contains(option);
  }
  /**
   * Determines whether or not this managed object definition has the
   * specified tag.
   *
   * @param t
   *          The tag definition.
   * @return Returns <code>true</code> if this managed object
   *         definition has the specified tag.
   */
  public final boolean hasTag(Tag t) {
    return allTags.contains(t);
  }
  /**
   * Determines whether or not this managed object definition is a
   * sub-type of the provided managed object definition. This managed
   * object definition is a sub-type of the provided managed object
   * definition if they are both the same or if the provided managed
   * object definition can be obtained by recursive invocations of the
   * {@link #getParent()} method.
   *
   * @param d
   *          The managed object definition to be checked.
   * @return Returns <code>true</code> if this managed object
   *         definition is a sub-type of the provided managed object
   *         definition.
   */
  public final boolean isChildOf(AbstractManagedObjectDefinition<?, ?> d) {
    AbstractManagedObjectDefinition<?, ?> i;
    for (i = this; i != null; i = i.parent) {
      if (i == d) {
        return true;
      }
    }
    return false;
  }
  /**
   * Determines whether or not this managed object definition is a
   * super-type of the provided managed object definition. This
   * managed object definition is a super-type of the provided managed
   * object definition if they are both the same or if the provided
   * managed object definition is a member of the set of children
   * returned from {@link #getAllChildren()}.
   *
   * @param d
   *          The managed object definition to be checked.
   * @return Returns <code>true</code> if this managed object
   *         definition is a super-type of the provided managed object
   *         definition.
   */
  public final boolean isParentOf(AbstractManagedObjectDefinition<?, ?> d) {
    return d.isChildOf(this);
  }
  /**
   * Determines whether or not this managed object definition is the
   * {@link TopCfgDefn}.
   *
   * @return Returns <code>true</code> if this managed object
   *         definition is the {@link TopCfgDefn}.
   */
  public final boolean isTop() {
    return (this instanceof TopCfgDefn);
  }
  /**
   * Finds a sub-type of this managed object definition which most closely
   * corresponds to the matching criteria of the provided definition resolver.
   *
   * @param r
   *          The definition resolver.
   * @return Returns the sub-type of this managed object definition which most
   *         closely corresponds to the matching criteria of the provided
   *         definition resolver.
   * @throws DefinitionDecodingException
   *           If no matching sub-type could be found or if the resolved
   *           definition was abstract.
   * @see DefinitionResolver
   */
  @SuppressWarnings("unchecked")
  public final ManagedObjectDefinition<? extends C, ? extends S>
      resolveManagedObjectDefinition(
      DefinitionResolver r) throws DefinitionDecodingException {
    AbstractManagedObjectDefinition<? extends C, ? extends S> rd;
    rd = resolveManagedObjectDefinitionAux(this, r);
    if (rd == null) {
      // Unable to resolve the definition.
      throw new DefinitionDecodingException(this,
          Reason.WRONG_TYPE_INFORMATION);
    } else if (rd instanceof ManagedObjectDefinition) {
      return (ManagedObjectDefinition<? extends C, ? extends S>) rd;
    } else {
      // Resolved definition was abstract.
      throw new DefinitionDecodingException(this,
          Reason.ABSTRACT_TYPE_INFORMATION);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final String toString() {
    StringBuilder builder = new StringBuilder();
    toString(builder);
    return builder.toString();
  }
  /**
   * Append a string representation of the managed object definition to the
   * provided string builder.
   *
   * @param builder
   *          The string builder where the string representation should be
   *          appended.
   */
  public final void toString(StringBuilder builder) {
    builder.append(getName());
  }
  /**
   * Initializes all of the components associated with this managed
   * object definition.
   *
   * @throws Exception
   *           If this managed object definition could not be
   *           initialized.
   */
  protected final void initialize() throws Exception {
    for (PropertyDefinition<?> pd : getAllPropertyDefinitions()) {
      pd.initialize();
      pd.getDefaultBehaviorProvider().initialize();
    /**
     * Get all the tags associated with this type of managed object. The
     * returned collection will contain inherited tags.
     *
     * @return Returns an unmodifiable collection containing all the tags
     *         associated with this type of managed object.
     */
    public final Collection<Tag> getAllTags() {
        return Collections.unmodifiableCollection(allTags);
    }
    for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) {
      rd.initialize();
    /**
     * Get the named child managed object definition which inherits from this
     * managed object definition. This method will recursively search down
     * through the inheritance hierarchy.
     *
     * @param name
     *            The name of the managed object definition sub-type.
     * @return Returns the named child managed object definition which inherits
     *         from this managed object definition.
     * @throws IllegalArgumentException
     *             If the specified managed object definition name was null or
     *             empty or if the requested subordinate managed object
     *             definition was not found.
     */
    public final AbstractManagedObjectDefinition<? extends C, ? extends S> getChild(String name)
            throws IllegalArgumentException {
        if ((name == null) || (name.length() == 0)) {
            throw new IllegalArgumentException("null or empty managed object name");
        }
        AbstractManagedObjectDefinition<? extends C, ? extends S> d = children.get(name);
        if (d == null) {
            // Recursively search.
            for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : children.values()) {
                try {
                    d = child.getChild(name);
                    break;
                } catch (IllegalArgumentException e) {
                    // Try the next child.
                }
            }
        }
        if (d == null) {
            throw new IllegalArgumentException("child managed object definition \"" + name + "\" not found");
        }
        return d;
    }
    for (AggregationPropertyDefinition<?, ?> apd :
      getAllAggregationPropertyDefinitions()) {
      apd.initialize();
      // Now register the aggregation property in the referenced managed object
      // definition for reverse lookups.
      registerReverseAggregationPropertyDefinition(apd);
    /**
     * Get the child managed object definitions which inherit directly from this
     * managed object definition.
     *
     * @return Returns an unmodifiable collection containing the subordinate
     *         managed object definitions which inherit directly from this
     *         managed object definition.
     */
    public final Collection<AbstractManagedObjectDefinition<? extends C, ? extends S>> getChildren() {
        return Collections.unmodifiableCollection(children.values());
    }
    for (Constraint constraint : getAllConstraints()) {
      constraint.initialize();
    }
  }
  /**
   * Register a constraint with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param constraint
   *          The constraint to be registered.
   */
  protected final void registerConstraint(Constraint constraint) {
    constraints.add(constraint);
  }
  /**
   * Register a property definition with this managed object definition,
   * overriding any existing property definition with the same name.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param d
   *          The property definition to be registered.
   */
  protected final void registerPropertyDefinition(PropertyDefinition<?> d) {
    String propName = d.getName();
    propertyDefinitions.put(propName, d);
    allPropertyDefinitions.put(propName, d);
    if (d instanceof AggregationPropertyDefinition<?,?>) {
      AggregationPropertyDefinition<?, ?> apd =
        (AggregationPropertyDefinition<?, ?>) d;
      aggregationPropertyDefinitions.put(propName, apd);
      // The key must also contain the managed object name, since several MOs
      // in an inheritance tree may aggregate the same aggregation property name
      allAggregationPropertyDefinitions.put(
        apd.getManagedObjectDefinition().getName() + ":" + propName, apd);
    }
  }
  /**
   * Register a relation definition with this managed object definition,
   * overriding any existing relation definition with the same name.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param d
   *          The relation definition to be registered.
   */
  protected final void registerRelationDefinition(RelationDefinition<?, ?> d) {
    // Register the relation in this managed object definition.
    String relName = d.getName();
    relationDefinitions.put(relName, d);
    allRelationDefinitions.put(relName, d);
    // Now register the relation in the referenced managed object
    // definition for reverse lookups.
    registerReverseRelationDefinition(d);
  }
  /**
   * Register an option with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param option
   *          The option to be registered.
   */
  protected final void registerOption(ManagedObjectOption option) {
    options.add(option);
  }
  /**
   * Register a tag with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param tag
   *          The tag to be registered.
   */
  protected final void registerTag(Tag tag) {
    allTags.add(tag);
  }
  /**
   * Deregister a constraint from the managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications and is
   * only intended for internal testing.
   *
   * @param constraint
   *          The constraint to be deregistered.
   */
  final void deregisterConstraint(Constraint constraint) {
    if (!constraints.remove(constraint)) {
      throw new RuntimeException("Failed to deregister a constraint");
    }
  }
  /**
   * Deregister a relation definition from the managed object
   * definition.
   * <p>
   * This method <b>must not</b> be called by applications and is
   * only intended for internal testing.
   *
   * @param d
   *          The relation definition to be deregistered.
   */
  final void deregisterRelationDefinition(
      RelationDefinition<?, ?> d) {
   // Deregister the relation from this managed object definition.
    String relName = d.getName();
    relationDefinitions.remove(relName);
    allRelationDefinitions.remove(relName);
    // Now deregister the relation from the referenced managed object
    // definition for reverse lookups.
    d.getChildDefinition().reverseRelationDefinitions.remove(d);
  }
  /**
   * Register this managed object definition in its parent.
   * <p>
   * This method <b>must not</b> be called by applications and is
   * only intended for internal testing.
   */
  final void registerInParent() {
    if (parent != null) {
      parent.children.put(name, this);
    }
  }
  // Register a relation definition in the referenced managed object
  // definition's reverse lookup table.
  private <CC extends ConfigurationClient, SS extends Configuration>
  void registerReverseRelationDefinition(RelationDefinition<CC, SS> rd) {
    rd.getChildDefinition().reverseRelationDefinitions.add(rd);
  }
  // Register a aggregation property definition in the referenced managed object
  // definition's reverse lookup table.
  private void registerReverseAggregationPropertyDefinition(
    AggregationPropertyDefinition<?, ?> apd) {
    apd.getRelationDefinition().getChildDefinition().
      reverseAggregationPropertyDefinitions.add(apd);
  }
  // Recursively descend definition hierarchy to find the best match definition.
  private AbstractManagedObjectDefinition<? extends C, ? extends S>
      resolveManagedObjectDefinitionAux(
      AbstractManagedObjectDefinition<? extends C, ? extends S> d,
      DefinitionResolver r) {
    if (!r.matches(d)) {
      return null;
    /**
     * Get the constraints defined by this managed object definition. The
     * returned collection will not contain inherited constraints.
     *
     * @return Returns an unmodifiable collection containing the constraints
     *         defined by this managed object definition.
     */
    public final Collection<Constraint> getConstraints() {
        return Collections.unmodifiableCollection(constraints);
    }
    for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : d
        .getChildren()) {
      AbstractManagedObjectDefinition<? extends C, ? extends S> rd =
        resolveManagedObjectDefinitionAux(child, r);
      if (rd != null) {
        return rd;
      }
    /**
     * Gets the optional description of this managed object definition in the
     * default locale.
     *
     * @return Returns the description of this managed object definition in the
     *         default locale, or <code>null</code> if there is no description.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getDescription() throws UnsupportedOperationException {
        return getDescription(Locale.getDefault());
    }
    return d;
  }
    /**
     * Gets the optional description of this managed object definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the description of this managed object definition in the
     *         specified locale, or <code>null</code> if there is no
     *         description.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getDescription(Locale locale) throws UnsupportedOperationException {
        try {
            return ManagedObjectDefinitionI18NResource.getInstance().getMessage(this, "description", locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
    /**
     * Get the name of the definition.
     *
     * @return Returns the name of the definition.
     */
    public final String getName() {
        return name;
    }
    /**
     * Get the parent managed object definition, if applicable.
     *
     * @return Returns the parent of this managed object definition, or
     *         <code>null</code> if this definition is the {@link TopCfgDefn}.
     */
    public final AbstractManagedObjectDefinition<? super C, ? super S> getParent() {
        return parent;
    }
    /**
     * Get the specified property definition associated with this type of
     * managed object. The search will include any inherited property
     * definitions.
     *
     * @param name
     *            The name of the property definition to be retrieved.
     * @return Returns the specified property definition associated with this
     *         type of managed object.
     * @throws IllegalArgumentException
     *             If the specified property name was null or empty or if the
     *             requested property definition was not found.
     */
    public final PropertyDefinition<?> getPropertyDefinition(String name) throws IllegalArgumentException {
        if ((name == null) || (name.length() == 0)) {
            throw new IllegalArgumentException("null or empty property name");
        }
        PropertyDefinition<?> d = allPropertyDefinitions.get(name);
        if (d == null) {
            throw new IllegalArgumentException("property definition \"" + name + "\" not found");
        }
        return d;
    }
    /**
     * Get the property definitions defined by this managed object definition.
     * The returned collection will not contain inherited property definitions.
     *
     * @return Returns an unmodifiable collection containing the property
     *         definitions defined by this managed object definition.
     */
    public final Collection<PropertyDefinition<?>> getPropertyDefinitions() {
        return Collections.unmodifiableCollection(propertyDefinitions.values());
    }
    /**
     * Get the specified relation definition associated with this type of
     * managed object.The search will include any inherited relation
     * definitions.
     *
     * @param name
     *            The name of the relation definition to be retrieved.
     * @return Returns the specified relation definition associated with this
     *         type of managed object.
     * @throws IllegalArgumentException
     *             If the specified relation name was null or empty or if the
     *             requested relation definition was not found.
     */
    public final RelationDefinition<?, ?> getRelationDefinition(String name) throws IllegalArgumentException {
        if ((name == null) || (name.length() == 0)) {
            throw new IllegalArgumentException("null or empty relation name");
        }
        RelationDefinition<?, ?> d = allRelationDefinitions.get(name);
        if (d == null) {
            throw new IllegalArgumentException("relation definition \"" + name + "\" not found");
        }
        return d;
    }
    /**
     * Get the relation definitions defined by this managed object definition.
     * The returned collection will not contain inherited relation definitions.
     *
     * @return Returns an unmodifiable collection containing the relation
     *         definitions defined by this managed object definition.
     */
    public final Collection<RelationDefinition<?, ?>> getRelationDefinitions() {
        return Collections.unmodifiableCollection(relationDefinitions.values());
    }
    /**
     * Get the relation definitions which refer directly to this managed object
     * definition. The returned collection will not contain relation definitions
     * which refer to parents of this managed object definition.
     *
     * @return Returns an unmodifiable collection containing the relation
     *         definitions which refer directly to this managed object
     *         definition.
     */
    public final Collection<RelationDefinition<C, S>> getReverseRelationDefinitions() {
        return Collections.unmodifiableCollection(reverseRelationDefinitions);
    }
    /**
     * Get the specified aggregation property definition associated with this
     * type of managed object.The search will include any inherited aggregation
     * property definitions.
     *
     * @param name
     *            The name of the aggregation property definition to be
     *            retrieved.
     * @return Returns the specified aggregation property definition associated
     *         with this type of managed object.
     * @throws IllegalArgumentException
     *             If the specified aggregation property name was null or empty
     *             or if the requested aggregation property definition was not
     *             found.
     */
    public final AggregationPropertyDefinition<?, ?> getAggregationPropertyDefinition(String name)
            throws IllegalArgumentException {
        if ((name == null) || (name.length() == 0)) {
            throw new IllegalArgumentException("null or empty aggregation property name");
        }
        AggregationPropertyDefinition<?, ?> d = allAggregationPropertyDefinitions.get(name);
        if (d == null) {
            throw new IllegalArgumentException("aggregation property definition \"" + name + "\" not found");
        }
        return d;
    }
    /**
     * Get the aggregation property definitions defined by this managed object
     * definition. The returned collection will not contain inherited
     * aggregation property definitions.
     *
     * @return Returns an unmodifiable collection containing the aggregation
     *         property definitions defined by this managed object definition.
     */
    public final Collection<AggregationPropertyDefinition<?, ?>> getAggregationPropertyDefinitions() {
        return Collections.unmodifiableCollection(aggregationPropertyDefinitions.values());
    }
    /**
     * Get the aggregation property definitions which refer directly to this
     * managed object definition. The returned collection will not contain
     * aggregation property definitions which refer to parents of this managed
     * object definition.
     *
     * @return Returns an unmodifiable collection containing the aggregation
     *         property definitions which refer directly to this managed object
     *         definition.
     */
    public final Collection<AggregationPropertyDefinition<?, ?>> getReverseAggregationPropertyDefinitions() {
        return Collections.unmodifiableCollection(reverseAggregationPropertyDefinitions);
    }
    /**
     * Gets the synopsis of this managed object definition in the default
     * locale.
     *
     * @return Returns the synopsis of this managed object definition in the
     *         default locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getSynopsis() throws UnsupportedOperationException {
        return getSynopsis(Locale.getDefault());
    }
    /**
     * Gets the synopsis of this managed object definition in the specified
     * locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this managed object definition in the
     *         specified locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getSynopsis(Locale locale) throws UnsupportedOperationException {
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(this, "synopsis", locale);
    }
    /**
     * Gets the user friendly name of this managed object definition in the
     * default locale.
     *
     * @return Returns the user friendly name of this managed object definition
     *         in the default locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getUserFriendlyName() throws UnsupportedOperationException {
        return getUserFriendlyName(Locale.getDefault());
    }
    /**
     * Gets the user friendly name of this managed object definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the user friendly name of this managed object definition
     *         in the specified locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getUserFriendlyName(Locale locale) throws UnsupportedOperationException {
        return LocalizableMessage.raw(ManagedObjectDefinitionI18NResource.getInstance().getMessage(this,
                "user-friendly-name", locale));
    }
    /**
     * Gets the user friendly plural name of this managed object definition in
     * the default locale.
     *
     * @return Returns the user friendly plural name of this managed object
     *         definition in the default locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getUserFriendlyPluralName() throws UnsupportedOperationException {
        return getUserFriendlyPluralName(Locale.getDefault());
    }
    /**
     * Gets the user friendly plural name of this managed object definition in
     * the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the user friendly plural name of this managed object
     *         definition in the specified locale.
     * @throws UnsupportedOperationException
     *             If this managed object definition is the {@link TopCfgDefn}.
     */
    public final LocalizableMessage getUserFriendlyPluralName(Locale locale) throws UnsupportedOperationException {
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(this,
                "user-friendly-plural-name", locale);
    }
    /**
     * Determine whether there are any child managed object definitions which
     * inherit from this managed object definition.
     *
     * @return Returns <code>true</code> if this type of managed object has any
     *         child managed object definitions, <code>false</code> otherwise.
     */
    public final boolean hasChildren() {
        return !children.isEmpty();
    }
    /**
     * Determines whether or not this managed object definition has the
     * specified option.
     *
     * @param option
     *            The option to test.
     * @return Returns <code>true</code> if the option is set, or
     *         <code>false</code> otherwise.
     */
    public final boolean hasOption(ManagedObjectOption option) {
        return options.contains(option);
    }
    /**
     * Determines whether or not this managed object definition has the
     * specified tag.
     *
     * @param t
     *            The tag definition.
     * @return Returns <code>true</code> if this managed object definition has
     *         the specified tag.
     */
    public final boolean hasTag(Tag t) {
        return allTags.contains(t);
    }
    /**
     * Determines whether or not this managed object definition is a sub-type of
     * the provided managed object definition. This managed object definition is
     * a sub-type of the provided managed object definition if they are both the
     * same or if the provided managed object definition can be obtained by
     * recursive invocations of the {@link #getParent()} method.
     *
     * @param d
     *            The managed object definition to be checked.
     * @return Returns <code>true</code> if this managed object definition is a
     *         sub-type of the provided managed object definition.
     */
    public final boolean isChildOf(AbstractManagedObjectDefinition<?, ?> d) {
        AbstractManagedObjectDefinition<?, ?> i;
        for (i = this; i != null; i = i.parent) {
            if (i == d) {
                return true;
            }
        }
        return false;
    }
    /**
     * Determines whether or not this managed object definition is a super-type
     * of the provided managed object definition. This managed object definition
     * is a super-type of the provided managed object definition if they are
     * both the same or if the provided managed object definition is a member of
     * the set of children returned from {@link #getAllChildren()}.
     *
     * @param d
     *            The managed object definition to be checked.
     * @return Returns <code>true</code> if this managed object definition is a
     *         super-type of the provided managed object definition.
     */
    public final boolean isParentOf(AbstractManagedObjectDefinition<?, ?> d) {
        return d.isChildOf(this);
    }
    /**
     * Determines whether or not this managed object definition is the
     * {@link TopCfgDefn}.
     *
     * @return Returns <code>true</code> if this managed object definition is
     *         the {@link TopCfgDefn}.
     */
    public final boolean isTop() {
        return (this instanceof TopCfgDefn);
    }
    /**
     * Finds a sub-type of this managed object definition which most closely
     * corresponds to the matching criteria of the provided definition resolver.
     *
     * @param r
     *            The definition resolver.
     * @return Returns the sub-type of this managed object definition which most
     *         closely corresponds to the matching criteria of the provided
     *         definition resolver.
     * @throws DefinitionDecodingException
     *             If no matching sub-type could be found or if the resolved
     *             definition was abstract.
     * @see DefinitionResolver
     */
    @SuppressWarnings("unchecked")
    public final ManagedObjectDefinition<? extends C, ? extends S> resolveManagedObjectDefinition(DefinitionResolver r)
            throws DefinitionDecodingException {
        AbstractManagedObjectDefinition<? extends C, ? extends S> rd;
        rd = resolveManagedObjectDefinitionAux(this, r);
        if (rd == null) {
            // Unable to resolve the definition.
            throw new DefinitionDecodingException(this, Reason.WRONG_TYPE_INFORMATION);
        } else if (rd instanceof ManagedObjectDefinition) {
            return (ManagedObjectDefinition<? extends C, ? extends S>) rd;
        } else {
            // Resolved definition was abstract.
            throw new DefinitionDecodingException(this, Reason.ABSTRACT_TYPE_INFORMATION);
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        StringBuilder builder = new StringBuilder();
        toString(builder);
        return builder.toString();
    }
    /**
     * Append a string representation of the managed object definition to the
     * provided string builder.
     *
     * @param builder
     *            The string builder where the string representation should be
     *            appended.
     */
    public final void toString(StringBuilder builder) {
        builder.append(getName());
    }
    /**
     * Initializes all of the components associated with this managed object
     * definition.
     *
     * @throws Exception
     *             If this managed object definition could not be initialized.
     */
    protected final void initialize() throws Exception {
        for (PropertyDefinition<?> pd : getAllPropertyDefinitions()) {
            pd.initialize();
            pd.getDefaultBehaviorProvider().initialize();
        }
        for (RelationDefinition<?, ?> rd : getAllRelationDefinitions()) {
            rd.initialize();
        }
        for (AggregationPropertyDefinition<?, ?> apd : getAllAggregationPropertyDefinitions()) {
            apd.initialize();
            // Now register the aggregation property in the referenced managed
            // object
            // definition for reverse lookups.
            registerReverseAggregationPropertyDefinition(apd);
        }
        for (Constraint constraint : getAllConstraints()) {
            constraint.initialize();
        }
    }
    /**
     * Register a constraint with this managed object definition.
     * <p>
     * This method <b>must not</b> be called by applications.
     *
     * @param constraint
     *            The constraint to be registered.
     */
    protected final void registerConstraint(Constraint constraint) {
        constraints.add(constraint);
    }
    /**
     * Register a property definition with this managed object definition,
     * overriding any existing property definition with the same name.
     * <p>
     * This method <b>must not</b> be called by applications.
     *
     * @param d
     *            The property definition to be registered.
     */
    protected final void registerPropertyDefinition(PropertyDefinition<?> d) {
        String propName = d.getName();
        propertyDefinitions.put(propName, d);
        allPropertyDefinitions.put(propName, d);
        if (d instanceof AggregationPropertyDefinition<?, ?>) {
            AggregationPropertyDefinition<?, ?> apd = (AggregationPropertyDefinition<?, ?>) d;
            aggregationPropertyDefinitions.put(propName, apd);
            // The key must also contain the managed object name, since several
            // MOs
            // in an inheritance tree may aggregate the same aggregation
            // property name
            allAggregationPropertyDefinitions.put(apd.getManagedObjectDefinition().getName() + ":" + propName, apd);
        }
    }
    /**
     * Register a relation definition with this managed object definition,
     * overriding any existing relation definition with the same name.
     * <p>
     * This method <b>must not</b> be called by applications.
     *
     * @param d
     *            The relation definition to be registered.
     */
    protected final void registerRelationDefinition(RelationDefinition<?, ?> d) {
        // Register the relation in this managed object definition.
        String relName = d.getName();
        relationDefinitions.put(relName, d);
        allRelationDefinitions.put(relName, d);
        // Now register the relation in the referenced managed object
        // definition for reverse lookups.
        registerReverseRelationDefinition(d);
    }
    /**
     * Register an option with this managed object definition.
     * <p>
     * This method <b>must not</b> be called by applications.
     *
     * @param option
     *            The option to be registered.
     */
    protected final void registerOption(ManagedObjectOption option) {
        options.add(option);
    }
    /**
     * Register a tag with this managed object definition.
     * <p>
     * This method <b>must not</b> be called by applications.
     *
     * @param tag
     *            The tag to be registered.
     */
    protected final void registerTag(Tag tag) {
        allTags.add(tag);
    }
    /**
     * Deregister a constraint from the managed object definition.
     * <p>
     * This method <b>must not</b> be called by applications and is only
     * intended for internal testing.
     *
     * @param constraint
     *            The constraint to be deregistered.
     */
    final void deregisterConstraint(Constraint constraint) {
        if (!constraints.remove(constraint)) {
            throw new RuntimeException("Failed to deregister a constraint");
        }
    }
    /**
     * Deregister a relation definition from the managed object definition.
     * <p>
     * This method <b>must not</b> be called by applications and is only
     * intended for internal testing.
     *
     * @param d
     *            The relation definition to be deregistered.
     */
    final void deregisterRelationDefinition(RelationDefinition<?, ?> d) {
        // Deregister the relation from this managed object definition.
        String relName = d.getName();
        relationDefinitions.remove(relName);
        allRelationDefinitions.remove(relName);
        // Now deregister the relation from the referenced managed object
        // definition for reverse lookups.
        d.getChildDefinition().reverseRelationDefinitions.remove(d);
    }
    /**
     * Register this managed object definition in its parent.
     * <p>
     * This method <b>must not</b> be called by applications and is only
     * intended for internal testing.
     */
    final void registerInParent() {
        if (parent != null) {
            parent.children.put(name, this);
        }
    }
    // Register a relation definition in the referenced managed object
    // definition's reverse lookup table.
    private <CC extends ConfigurationClient, SS extends Configuration> void registerReverseRelationDefinition(
            RelationDefinition<CC, SS> rd) {
        rd.getChildDefinition().reverseRelationDefinitions.add(rd);
    }
    // Register a aggregation property definition in the referenced managed
    // object
    // definition's reverse lookup table.
    private void registerReverseAggregationPropertyDefinition(AggregationPropertyDefinition<?, ?> apd) {
        apd.getRelationDefinition().getChildDefinition().reverseAggregationPropertyDefinitions.add(apd);
    }
    // Recursively descend definition hierarchy to find the best match
    // definition.
    private AbstractManagedObjectDefinition<? extends C, ? extends S> resolveManagedObjectDefinitionAux(
            AbstractManagedObjectDefinition<? extends C, ? extends S> d, DefinitionResolver r) {
        if (!r.matches(d)) {
            return null;
        }
        for (AbstractManagedObjectDefinition<? extends C, ? extends S> child : d.getChildren()) {
            AbstractManagedObjectDefinition<? extends C, ? extends S> rd = resolveManagedObjectDefinitionAux(child, r);
            if (rd != null) {
                return rd;
            }
        }
        return d;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AdminException.java
@@ -27,47 +27,38 @@
package org.opends.server.admin;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.types.OpenDsException;
/**
 * Exceptions thrown when interacting with administration framework.
 */
public abstract class AdminException extends OpenDsException {
  /**
   * Fake serialization ID.
   */
  private static final long serialVersionUID = 1L;
    /**
     * Fake serialization ID.
     */
    private static final long serialVersionUID = 1L;
    /**
     * Create an admin exception with a message and cause.
     *
     * @param message
     *            The message.
     * @param cause
     *            The cause.
     */
    protected AdminException(LocalizableMessage message, Throwable cause) {
        super(message, cause);
    }
  /**
   * Create an admin exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  protected AdminException(Message message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an admin exception with a message.
   *
   * @param message
   *          The message.
   */
  protected AdminException(Message message) {
    super(message);
  }
    /**
     * Create an admin exception with a message.
     *
     * @param message
     *            The message.
     */
    protected AdminException(LocalizableMessage message) {
        super(message);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AdminRuntimeException.java
@@ -27,65 +27,53 @@
package org.opends.server.admin;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Exceptions thrown when interacting with administration framework
 * that applications are not expected to catch.
 * Exceptions thrown when interacting with administration framework that
 * applications are not expected to catch.
 */
public abstract class AdminRuntimeException extends RuntimeException {
  /**
   * Fake serialization ID.
   */
  private static final long serialVersionUID = 1L;
    /**
     * Fake serialization ID.
     */
    private static final long serialVersionUID = 1L;
    // LocalizableMessage that explains the problem.
    private final LocalizableMessage message;
    /**
     * Create an admin runtime exception with a message and cause.
     *
     * @param message
     *            The message.
     * @param cause
     *            The cause.
     */
    protected AdminRuntimeException(LocalizableMessage message, Throwable cause) {
        super(message.toString(), cause);
        this.message = message;
    }
  // Message that explains the problem.
  private final Message message;
    /**
     * Create an admin runtime exception with a message.
     *
     * @param message
     *            The message.
     */
    protected AdminRuntimeException(LocalizableMessage message) {
        super(message.toString());
        this.message = message;
    }
  /**
   * Create an admin runtime exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  protected AdminRuntimeException(Message message, Throwable cause) {
    super(message.toString(), cause);
    this.message = message;
  }
  /**
   * Create an admin runtime exception with a message.
   *
   * @param message
   *          The message.
   */
  protected AdminRuntimeException(Message message) {
    super(message.toString());
    this.message = message;
  }
  /**
   * Returns the message that explains the problem that occurred.
   *
   * @return Returns the message describing the problem that occurred
   *         (never <code>null</code>).
   */
  public Message getMessageObject() {
    return this.message;
  }
    /**
     * Returns the message that explains the problem that occurred.
     *
     * @return Returns the message describing the problem that occurred (never
     *         <code>null</code>).
     */
    public LocalizableMessage getLocalizableMessageObject() {
        return this.message;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AdministrationConnector.java
@@ -27,9 +27,6 @@
 */
package org.opends.server.admin;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.messages.AdminMessages.*;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
@@ -38,36 +35,26 @@
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.naming.ldap.Rdn;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.admin.std.meta.LDAPConnectionHandlerCfgDefn.
  SSLClientAuthPolicy;
import org.opends.server.admin.std.server.AdministrationConnectorCfg;
import org.opends.server.admin.std.server.ConnectionHandlerCfg;
import org.opends.server.admin.std.server.KeyManagerProviderCfg;
import org.opends.server.admin.std.server.FileBasedKeyManagerProviderCfg;
import org.opends.server.admin.std.server.FileBasedTrustManagerProviderCfg;
import org.opends.server.admin.std.server.LDAPConnectionHandlerCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.core.SynchronousStrategy;
import org.opends.server.protocols.ldap.LDAPConnectionHandler;
import org.opends.server.types.AddressMask;
import org.opends.server.types.ConfigChangeResult;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.admin.server.AdministrationConnectorCfg;
import org.forgerock.opendj.admin.server.FileBasedKeyManagerProviderCfg;
import org.forgerock.opendj.admin.server.FileBasedTrustManagerProviderCfg;
import org.forgerock.opendj.admin.server.KeyManagerProviderCfg;
import org.forgerock.opendj.admin.server.LDAPConnectionHandlerCfg;
import org.forgerock.opendj.admin.server.RootCfg;
import org.forgerock.opendj.admin.server.TrustManagerProviderCfg;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.SetupUtils;
import org.opends.server.admin.std.server.TrustManagerProviderCfg;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.FilePermission;
/**
 * This class is a wrapper on top of LDAPConnectionHandler to manage
@@ -218,7 +205,7 @@
   */
  public boolean isConfigurationChangeAcceptable(
      AdministrationConnectorCfg configuration,
      List<Message> unacceptableReasons)
      List<LocalizableMessage> unacceptableReasons)
  {
    LDAPConnectionHandlerCfg cfg = new FakeLDAPConnectionHandlerCfg(
        configuration);
@@ -235,7 +222,7 @@
      AdministrationConnectorCfg configuration)
  {
    return new ConfigChangeResult(ResultCode.SUCCESS, true,
        new ArrayList<Message>());
        new ArrayList<LocalizableMessage>());
  }
@@ -676,7 +663,7 @@
        {
          err += pinFilePath + " ";
        }
        Message message = ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES
        LocalizableMessage message = ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES
            .get(err);
        logError(message);
        throw new InitializationException(message);
@@ -728,7 +715,7 @@
              new FilePermission(0600)))
          {
            // Log a warning that the permissions were not set.
            Message message = WARN_ADMIN_SET_PERMISSIONS_FAILED
            LocalizableMessage message = WARN_ADMIN_SET_PERMISSIONS_FAILED
                .get(pinFilePath);
            ErrorLogger.logError(message);
          }
@@ -736,7 +723,7 @@
        catch (DirectoryException e)
        {
          // Log a warning that the permissions were not set.
          Message message = WARN_ADMIN_SET_PERMISSIONS_FAILED.get(pinFilePath);
          LocalizableMessage message = WARN_ADMIN_SET_PERMISSIONS_FAILED.get(pinFilePath);
          ErrorLogger.logError(message);
        }
      }
@@ -755,7 +742,7 @@
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_ADMIN_CERTIFICATE_GENERATION.get(e.getMessage());
      LocalizableMessage message = ERR_ADMIN_CERTIFICATE_GENERATION.get(e.getMessage());
      logError(message);
      throw new InitializationException(message);
    }
opendj-admin/src/main/java/org/opends/server/admin/AdministratorAction.java
@@ -25,167 +25,143 @@
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import java.util.Locale;
import java.util.MissingResourceException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Defines an optional action which administators must perform after
 * they have modified a property. By default modifications to
 * properties are assumed to take effect immediately and require no
 * additional administrative action. Developers should be aware that,
 * where feasible, they should implement components such that property
 * modifications require no additional administrative action. This is
 * required in order to minimize server downtime during administration
 * and provide a more user-friendly experience.
 * Defines an optional action which administators must perform after they have
 * modified a property. By default modifications to properties are assumed to
 * take effect immediately and require no additional administrative action.
 * Developers should be aware that, where feasible, they should implement
 * components such that property modifications require no additional
 * administrative action. This is required in order to minimize server downtime
 * during administration and provide a more user-friendly experience.
 */
public final class AdministratorAction {
  /**
   * Specifies the type of administrator action which must be
   * performed in order for pending changes to take effect.
   */
  public static enum Type {
    /**
     * Used when modifications to a property require a component
     * restart in order to take effect (usually by disabling and
     * re-enabling the component). May have a description describing
     * any additional administrator action that is required when the
     * component is restarted.
     * Specifies the type of administrator action which must be performed in
     * order for pending changes to take effect.
     */
    COMPONENT_RESTART("component-restart"),
    public static enum Type {
        /**
         * Used when modifications to a property require a component restart in
         * order to take effect (usually by disabling and re-enabling the
         * component). May have a description describing any additional
         * administrator action that is required when the component is
         * restarted.
         */
        COMPONENT_RESTART("component-restart"),
    /**
     * Used when modifications to a property take effect immediately,
     * and no additional administrator action is required. May have a
     * description describing how changes to the modified property
     * will take effect.
     */
    NONE("none"),
        /**
         * Used when modifications to a property take effect immediately, and no
         * additional administrator action is required. May have a description
         * describing how changes to the modified property will take effect.
         */
        NONE("none"),
    /**
     * Used when modifications to a property require an additional
     * administrative action in order to take effect. This should be
     * used when neither a server restart nor a component restart are
     * applicable. Always has a description which describes the
     * additional administrator action which is required when the
     * property is modified.
     */
    OTHER("other"),
        /**
         * Used when modifications to a property require an additional
         * administrative action in order to take effect. This should be used
         * when neither a server restart nor a component restart are applicable.
         * Always has a description which describes the additional administrator
         * action which is required when the property is modified.
         */
        OTHER("other"),
    /**
     * Used when modifications to a property require a server restart
     * in order to take effect. May have a description describing any
     * additional administrator action that is required when the
     * component is restarted.
     */
    SERVER_RESTART("server-restart");
        /**
         * Used when modifications to a property require a server restart in
         * order to take effect. May have a description describing any
         * additional administrator action that is required when the component
         * is restarted.
         */
        SERVER_RESTART("server-restart");
    // The user-friendly name of the type.
    private final String name;
        // The user-friendly name of the type.
        private final String name;
        // Private constructor.
        private Type(String name) {
            this.name = name;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public String toString() {
            return name;
        }
    // Private constructor.
    private Type(String name) {
      this.name = name;
    }
    // The managed object definition associated with this administrator
    // action.
    private final AbstractManagedObjectDefinition<?, ?> definition;
    // The name of the property definition associated with this
    // administrator action.
    private final String propertyName;
    // The type of administration action.
    private final Type type;
    /**
     * {@inheritDoc}
     * Create a new administrator action.
     *
     * @param type
     *            The type of this administration action.
     * @param d
     *            The managed object definition associated with this
     *            administrator action.
     * @param propertyName
     *            The name of the property definition associated with this
     *            administrator action.
     */
    @Override
    public String toString() {
      return name;
    public AdministratorAction(Type type, AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        this.type = type;
        this.definition = d;
        this.propertyName = propertyName;
    }
  }
  // The managed object definition associated with this administrator
  // action.
  private final AbstractManagedObjectDefinition<?, ?> definition;
  // The name of the property definition associated with this
  // administrator action.
  private final String propertyName;
  // The type of administration action.
  private final Type type;
  /**
   * Create a new administrator action.
   *
   * @param type
   *          The type of this administration action.
   * @param d
   *          The managed object definition associated with this
   *          administrator action.
   * @param propertyName
   *          The name of the property definition associated with this
   *          administrator action.
   */
  public AdministratorAction(Type type,
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    this.type = type;
    this.definition = d;
    this.propertyName = propertyName;
  }
  /**
   * Gets the synopsis of this administrator action in the default
   * locale.
   *
   * @return Returns the synopsis of this administrator action in the
   *         default locale, or <code>null</code> if there is no
   *         synopsis defined.
   */
  public final Message getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this administrator action in the specified
   * locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this administrator action in the
   *         specified locale, or <code>null</code> if there is no
   *         synopsis defined.
   */
  public final Message getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName
        + ".requires-admin-action.synopsis";
    try {
      return resource.getMessage(definition, property, locale);
    } catch (MissingResourceException e) {
      return null;
    /**
     * Gets the synopsis of this administrator action in the default locale.
     *
     * @return Returns the synopsis of this administrator action in the default
     *         locale, or <code>null</code> if there is no synopsis defined.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
  }
    /**
     * Gets the synopsis of this administrator action in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this administrator action in the
     *         specified locale, or <code>null</code> if there is no synopsis
     *         defined.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + propertyName + ".requires-admin-action.synopsis";
        try {
            return resource.getLocalizableMessage(definition, property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
  /**
   * Gets the type of this administrator action.
   *
   * @return Returns the type of this administrator action.
   */
  public final Type getType() {
    return type;
  }
    /**
     * Gets the type of this administrator action.
     *
     * @return Returns the type of this administrator action.
     */
    public final Type getType() {
        return type;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AggregationPropertyDefinition.java
@@ -26,12 +26,6 @@
 */
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.Validator.*;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
@@ -44,7 +38,6 @@
import java.util.MissingResourceException;
import java.util.SortedSet;
import org.opends.messages.Message;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.ClientConstraintHandler;
import org.opends.server.admin.client.CommunicationException;
@@ -58,1147 +51,970 @@
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.server.ServerManagedObjectChangeListener;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.config.ConfigException;
import org.opends.server.loggers.ErrorLogger;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.ConfigChangeResult;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.ResultCode;
import org.opends.server.util.StaticUtils;
import org.forgerock.opendj.ldap.ResultCode;
/**
 * Aggregation property definition.
 * <p>
 * An aggregation property names one or more managed objects which are
 * required by the managed object associated with this property. An
 * aggregation property definition takes care to perform referential
 * integrity checks: referenced managed objects cannot be deleted. Nor
 * can an aggregation reference non-existent managed objects.
 * Referential integrity checks are <b>not</b> performed during value
 * validation. Instead they are performed when changes to the managed
 * object are committed.
 * An aggregation property names one or more managed objects which are required
 * by the managed object associated with this property. An aggregation property
 * definition takes care to perform referential integrity checks: referenced
 * managed objects cannot be deleted. Nor can an aggregation reference
 * non-existent managed objects. Referential integrity checks are <b>not</b>
 * performed during value validation. Instead they are performed when changes to
 * the managed object are committed.
 * <p>
 * An aggregation property definition can optionally identify two
 * properties:
 * An aggregation property definition can optionally identify two properties:
 * <ul>
 * <li>an <code>enabled</code> property in the aggregated managed
 * object - the property must be a {@link BooleanPropertyDefinition}
 * and indicate whether the aggregated managed object is enabled or
 * not. If specified, the administration framework will prevent the
 * aggregated managed object from being disabled while it is
 * referenced
 * <li>an <code>enabled</code> property in this property's managed
 * object - the property must be a {@link BooleanPropertyDefinition}
 * and indicate whether this property's managed object is enabled or
 * not. If specified, and as long as there is an equivalent
 * <code>enabled</code> property defined for the aggregated managed
 * object, the <code>enabled</code> property in the aggregated
 * managed object will only be checked when this property is true.
 * <li>an <code>enabled</code> property in the aggregated managed object - the
 * property must be a {@link BooleanPropertyDefinition} and indicate whether the
 * aggregated managed object is enabled or not. If specified, the administration
 * framework will prevent the aggregated managed object from being disabled
 * while it is referenced
 * <li>an <code>enabled</code> property in this property's managed object - the
 * property must be a {@link BooleanPropertyDefinition} and indicate whether
 * this property's managed object is enabled or not. If specified, and as long
 * as there is an equivalent <code>enabled</code> property defined for the
 * aggregated managed object, the <code>enabled</code> property in the
 * aggregated managed object will only be checked when this property is true.
 * </ul>
 * In other words, these properties can be used to make sure that
 * referenced managed objects are not disabled while they are
 * referenced.
 * In other words, these properties can be used to make sure that referenced
 * managed objects are not disabled while they are referenced.
 *
 * @param <C>
 *          The type of client managed object configuration that this
 *          aggregation property definition refers to.
 *            The type of client managed object configuration that this
 *            aggregation property definition refers to.
 * @param <S>
 *          The type of server managed object configuration that this
 *          aggregation property definition refers to.
 *            The type of server managed object configuration that this
 *            aggregation property definition refers to.
 */
public final class AggregationPropertyDefinition
    <C extends ConfigurationClient, S extends Configuration>
    extends PropertyDefinition<String> {
public final class AggregationPropertyDefinition<C extends ConfigurationClient, S extends Configuration> extends
        PropertyDefinition<String> {
  /**
   * An interface for incrementally constructing aggregation property
   * definitions.
   *
   * @param <C>
   *          The type of client managed object configuration that
   *          this aggregation property definition refers to.
   * @param <S>
   *          The type of server managed object configuration that
   *          this aggregation property definition refers to.
   */
  public static class Builder
      <C extends ConfigurationClient, S extends Configuration>
      extends AbstractBuilder<String, AggregationPropertyDefinition<C, S>> {
    /**
     * An interface for incrementally constructing aggregation property
     * definitions.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            aggregation property definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            aggregation property definition refers to.
     */
    public static class Builder<C extends ConfigurationClient, S extends Configuration> extends
            AbstractBuilder<String, AggregationPropertyDefinition<C, S>> {
        // The string representation of the managed object path specifying
        // the parent of the aggregated managed objects.
        private String parentPathString = null;
        // The name of a relation in the parent managed object which
        // contains the aggregated managed objects.
        private String rdName = null;
        // The condition which is used to determine if a referenced
        // managed object is enabled.
        private Condition targetIsEnabledCondition = Conditions.TRUE;
        // The condition which is used to determine whether or not
        // referenced managed objects need to be enabled.
        private Condition targetNeedsEnablingCondition = Conditions.TRUE;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        /**
         * Sets the name of the managed object which is the parent of the
         * aggregated managed objects.
         * <p>
         * This must be defined before the property definition can be built.
         *
         * @param pathString
         *            The string representation of the managed object path
         *            specifying the parent of the aggregated managed objects.
         */
        public final void setParentPath(String pathString) {
            this.parentPathString = pathString;
        }
        /**
         * Sets the relation in the parent managed object which contains the
         * aggregated managed objects.
         * <p>
         * This must be defined before the property definition can be built.
         *
         * @param rdName
         *            The name of a relation in the parent managed object which
         *            contains the aggregated managed objects.
         */
        public final void setRelationDefinition(String rdName) {
            this.rdName = rdName;
        }
        /**
         * Sets the condition which is used to determine if a referenced managed
         * object is enabled. By default referenced managed objects are assumed
         * to always be enabled.
         *
         * @param condition
         *            The condition which is used to determine if a referenced
         *            managed object is enabled.
         */
        public final void setTargetIsEnabledCondition(Condition condition) {
            this.targetIsEnabledCondition = condition;
        }
        /**
         * Sets the condition which is used to determine whether or not
         * referenced managed objects need to be enabled. By default referenced
         * managed objects must always be enabled.
         *
         * @param condition
         *            The condition which is used to determine whether or not
         *            referenced managed objects need to be enabled.
         */
        public final void setTargetNeedsEnablingCondition(Condition condition) {
            this.targetNeedsEnablingCondition = condition;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected AggregationPropertyDefinition<C, S> buildInstance(AbstractManagedObjectDefinition<?, ?> d,
                String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<String> defaultBehavior) {
            // Make sure that the parent path has been defined.
            if (parentPathString == null) {
                throw new IllegalStateException("Parent path undefined");
            }
            // Make sure that the relation definition has been defined.
            if (rdName == null) {
                throw new IllegalStateException("Relation definition undefined");
            }
            return new AggregationPropertyDefinition<C, S>(d, propertyName, options, adminAction, defaultBehavior,
                    parentPathString, rdName, targetNeedsEnablingCondition, targetIsEnabledCondition);
        }
    }
    /**
     * A change listener which prevents the named component from being disabled.
     */
    private class ReferentialIntegrityChangeListener implements ServerManagedObjectChangeListener<S> {
        // The error message which should be returned if an attempt is
        // made to disable the referenced component.
        private final LocalizableMessage message;
        // The path of the referenced component.
        private final ManagedObjectPath<C, S> path;
        // Creates a new referential integrity delete listener.
        private ReferentialIntegrityChangeListener(ManagedObjectPath<C, S> path, LocalizableMessage message) {
            this.path = path;
            this.message = message;
        }
        /**
         * {@inheritDoc}
         */
        public ConfigChangeResult applyConfigurationChange(ServerManagedObject<? extends S> mo) {
            try {
                if (targetIsEnabledCondition.evaluate(mo)) {
                    return new ConfigChangeResult(ResultCode.SUCCESS, false);
                }
            } catch (ConfigException e) {
                // This should not happen - ignore it and throw an exception
                // anyway below.
            }
            // This should not happen - the previous call-back should have
            // trapped this.
            throw new IllegalStateException("Attempting to disable a referenced "
                    + relationDefinition.getChildDefinition().getUserFriendlyName());
        }
        /**
         * {@inheritDoc}
         */
        public boolean isConfigurationChangeAcceptable(ServerManagedObject<? extends S> mo,
                List<LocalizableMessage> unacceptableReasons) {
            // Always prevent the referenced component from being
            // disabled.
            try {
                if (!targetIsEnabledCondition.evaluate(mo)) {
                    unacceptableReasons.add(message);
                    return false;
                } else {
                    return true;
                }
            } catch (ConfigException e) {
                // The condition could not be evaluated.
                if (debugEnabled()) {
                    TRACER.debugCaught(DebugLogLevel.ERROR, e);
                }
                LocalizableMessage message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo.getManagedObjectDefinition()
                        .getUserFriendlyName(), String.valueOf(mo.getDN()), StaticUtils.getExceptionLocalizableMessage(e));
                ErrorLogger.logError(message);
                unacceptableReasons.add(message);
                return false;
            }
        }
        // Gets the path associated with this listener.
        private ManagedObjectPath<C, S> getManagedObjectPath() {
            return path;
        }
    }
    /**
     * A delete listener which prevents the named component from being deleted.
     */
    private class ReferentialIntegrityDeleteListener implements ConfigurationDeleteListener<S> {
        // The DN of the referenced configuration entry.
        private final DN dn;
        // The error message which should be returned if an attempt is
        // made to delete the referenced component.
        private final LocalizableMessage message;
        // Creates a new referential integrity delete listener.
        private ReferentialIntegrityDeleteListener(DN dn, LocalizableMessage message) {
            this.dn = dn;
            this.message = message;
        }
        /**
         * {@inheritDoc}
         */
        public ConfigChangeResult applyConfigurationDelete(S configuration) {
            // This should not happen - the
            // isConfigurationDeleteAcceptable() call-back should have
            // trapped this.
            if (configuration.dn().equals(dn)) {
                // This should not happen - the
                // isConfigurationDeleteAcceptable() call-back should have
                // trapped this.
                throw new IllegalStateException("Attempting to delete a referenced "
                        + relationDefinition.getChildDefinition().getUserFriendlyName());
            } else {
                return new ConfigChangeResult(ResultCode.SUCCESS, false);
            }
        }
        /**
         * {@inheritDoc}
         */
        public boolean isConfigurationDeleteAcceptable(S configuration, List<LocalizableMessage> unacceptableReasons) {
            if (configuration.dn().equals(dn)) {
                // Always prevent deletion of the referenced component.
                unacceptableReasons.add(message);
                return false;
            }
            return true;
        }
    }
    /**
     * The server-side constraint handler implementation.
     */
    private class ServerHandler extends ServerConstraintHandler {
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isUsable(ServerManagedObject<?> managedObject, Collection<LocalizableMessage> unacceptableReasons)
                throws ConfigException {
            SortedSet<String> names = managedObject.getPropertyValues(AggregationPropertyDefinition.this);
            ServerManagementContext context = ServerManagementContext.getInstance();
            LocalizableMessage thisUFN = managedObject.getManagedObjectDefinition().getUserFriendlyName();
            String thisDN = managedObject.getDN().toString();
            LocalizableMessage thatUFN = getRelationDefinition().getUserFriendlyName();
            boolean isUsable = true;
            boolean needsEnabling = targetNeedsEnablingCondition.evaluate(managedObject);
            for (String name : names) {
                ManagedObjectPath<C, S> path = getChildPath(name);
                String thatDN = path.toDN().toString();
                if (!context.managedObjectExists(path)) {
                    LocalizableMessage msg = ERR_SERVER_REFINT_DANGLING_REFERENCE.get(name, getName(), thisUFN, thisDN, thatUFN,
                            thatDN);
                    unacceptableReasons.add(msg);
                    isUsable = false;
                } else if (needsEnabling) {
                    // Check that the referenced component is enabled if
                    // required.
                    ServerManagedObject<? extends S> ref = context.getManagedObject(path);
                    if (!targetIsEnabledCondition.evaluate(ref)) {
                        LocalizableMessage msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name, getName(), thisUFN, thisDN, thatUFN,
                                thatDN);
                        unacceptableReasons.add(msg);
                        isUsable = false;
                    }
                }
            }
            return isUsable;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void performPostAdd(ServerManagedObject<?> managedObject) throws ConfigException {
            // First make sure existing listeners associated with this
            // managed object are removed. This is required in order to
            // prevent multiple change listener registrations from
            // occurring, for example if this call-back is invoked multiple
            // times after the same add event.
            performPostDelete(managedObject);
            // Add change and delete listeners against all referenced
            // components.
            LocalizableMessage thisUFN = managedObject.getManagedObjectDefinition().getUserFriendlyName();
            String thisDN = managedObject.getDN().toString();
            LocalizableMessage thatUFN = getRelationDefinition().getUserFriendlyName();
            // Referenced managed objects will only need a change listener
            // if they have can be disabled.
            boolean needsChangeListeners = targetNeedsEnablingCondition.evaluate(managedObject);
            // Delete listeners need to be registered against the parent
            // entry of the referenced components.
            ServerManagementContext context = ServerManagementContext.getInstance();
            ManagedObjectPath<?, ?> parentPath = getParentPath();
            ServerManagedObject<?> parent = context.getManagedObject(parentPath);
            // Create entries in the listener tables.
            List<ReferentialIntegrityDeleteListener> dlist = new LinkedList<ReferentialIntegrityDeleteListener>();
            deleteListeners.put(managedObject.getDN(), dlist);
            List<ReferentialIntegrityChangeListener> clist = new LinkedList<ReferentialIntegrityChangeListener>();
            changeListeners.put(managedObject.getDN(), clist);
            for (String name : managedObject.getPropertyValues(AggregationPropertyDefinition.this)) {
                ManagedObjectPath<C, S> path = getChildPath(name);
                DN dn = path.toDN();
                String thatDN = dn.toString();
                // Register the delete listener.
                LocalizableMessage msg = ERR_SERVER_REFINT_CANNOT_DELETE.get(thatUFN, thatDN, getName(), thisUFN, thisDN);
                ReferentialIntegrityDeleteListener dl = new ReferentialIntegrityDeleteListener(dn, msg);
                parent.registerDeleteListener(getRelationDefinition(), dl);
                dlist.add(dl);
                // Register the change listener if required.
                if (needsChangeListeners) {
                    ServerManagedObject<? extends S> ref = context.getManagedObject(path);
                    msg = ERR_SERVER_REFINT_CANNOT_DISABLE.get(thatUFN, thatDN, getName(), thisUFN, thisDN);
                    ReferentialIntegrityChangeListener cl = new ReferentialIntegrityChangeListener(path, msg);
                    ref.registerChangeListener(cl);
                    clist.add(cl);
                }
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void performPostDelete(ServerManagedObject<?> managedObject) throws ConfigException {
            // Remove any registered delete and change listeners.
            ServerManagementContext context = ServerManagementContext.getInstance();
            DN dn = managedObject.getDN();
            // Delete listeners need to be deregistered against the parent
            // entry of the referenced components.
            ManagedObjectPath<?, ?> parentPath = getParentPath();
            ServerManagedObject<?> parent = context.getManagedObject(parentPath);
            if (deleteListeners.containsKey(dn)) {
                for (ReferentialIntegrityDeleteListener dl : deleteListeners.get(dn)) {
                    parent.deregisterDeleteListener(getRelationDefinition(), dl);
                }
                deleteListeners.remove(dn);
            }
            // Change listeners need to be deregistered from their
            // associated referenced component.
            if (changeListeners.containsKey(dn)) {
                for (ReferentialIntegrityChangeListener cl : changeListeners.get(dn)) {
                    ManagedObjectPath<C, S> path = cl.getManagedObjectPath();
                    ServerManagedObject<? extends S> ref = context.getManagedObject(path);
                    ref.deregisterChangeListener(cl);
                }
                changeListeners.remove(dn);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public void performPostModify(ServerManagedObject<?> managedObject) throws ConfigException {
            // Remove all the constraints associated with this managed
            // object and then re-register them.
            performPostDelete(managedObject);
            performPostAdd(managedObject);
        }
    }
    /**
     * The client-side constraint handler implementation which enforces
     * referential integrity when aggregating managed objects are added or
     * modified.
     */
    private class SourceClientHandler extends ClientConstraintHandler {
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isAddAcceptable(ManagementContext context, ManagedObject<?> managedObject,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            // If all of this managed object's "enabled" properties are true
            // then any referenced managed objects must also be enabled.
            boolean needsEnabling = targetNeedsEnablingCondition.evaluate(context, managedObject);
            // Check the referenced managed objects exist and, if required,
            // are enabled.
            boolean isAcceptable = true;
            LocalizableMessage ufn = getRelationDefinition().getUserFriendlyName();
            for (String name : managedObject.getPropertyValues(AggregationPropertyDefinition.this)) {
                // Retrieve the referenced managed object and make sure it
                // exists.
                ManagedObjectPath<?, ?> path = getChildPath(name);
                ManagedObject<?> ref;
                try {
                    ref = context.getManagedObject(path);
                } catch (DefinitionDecodingException e) {
                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getLocalizableMessageObject());
                    unacceptableReasons.add(msg);
                    isAcceptable = false;
                    continue;
                } catch (ManagedObjectDecodingException e) {
                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name, getName(), e.getLocalizableMessageObject());
                    unacceptableReasons.add(msg);
                    isAcceptable = false;
                    continue;
                } catch (ManagedObjectNotFoundException e) {
                    LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_DANGLING_REFERENCE.get(ufn, name, getName());
                    unacceptableReasons.add(msg);
                    isAcceptable = false;
                    continue;
                }
                // Make sure the reference managed object is enabled.
                if (needsEnabling) {
                    if (!targetIsEnabledCondition.evaluate(context, ref)) {
                        LocalizableMessage msg = ERR_CLIENT_REFINT_TARGET_DISABLED.get(ufn, name, getName());
                        unacceptableReasons.add(msg);
                        isAcceptable = false;
                    }
                }
            }
            return isAcceptable;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            // The same constraint applies as for adds.
            return isAddAcceptable(context, managedObject, unacceptableReasons);
        }
    }
    /**
     * The client-side constraint handler implementation which enforces
     * referential integrity when aggregated managed objects are deleted or
     * modified.
     */
    private class TargetClientHandler extends ClientConstraintHandler {
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isDeleteAcceptable(ManagementContext context, ManagedObjectPath<?, ?> path,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            // Any references to the deleted managed object should cause a
            // constraint violation.
            boolean isAcceptable = true;
            for (ManagedObject<?> mo : findReferences(context, getManagedObjectDefinition(), path.getName())) {
                String name = mo.getManagedObjectPath().getName();
                if (name == null) {
                    LocalizableMessage msg = ERR_CLIENT_REFINT_CANNOT_DELETE_WITHOUT_NAME.get(getName(), mo
                            .getManagedObjectDefinition().getUserFriendlyName(), getManagedObjectDefinition()
                            .getUserFriendlyName());
                    unacceptableReasons.add(msg);
                } else {
                    LocalizableMessage msg = ERR_CLIENT_REFINT_CANNOT_DELETE_WITH_NAME.get(getName(), mo
                            .getManagedObjectDefinition().getUserFriendlyName(), name, getManagedObjectDefinition()
                            .getUserFriendlyName());
                    unacceptableReasons.add(msg);
                }
                isAcceptable = false;
            }
            return isAcceptable;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            // If the modified managed object is disabled and there are some
            // active references then refuse the change.
            if (targetIsEnabledCondition.evaluate(context, managedObject)) {
                return true;
            }
            // The referenced managed object is disabled. Need to check for
            // active references.
            boolean isAcceptable = true;
            for (ManagedObject<?> mo : findReferences(context, getManagedObjectDefinition(), managedObject
                    .getManagedObjectPath().getName())) {
                if (targetNeedsEnablingCondition.evaluate(context, mo)) {
                    String name = mo.getManagedObjectPath().getName();
                    if (name == null) {
                        LocalizableMessage msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME.get(managedObject
                                .getManagedObjectDefinition().getUserFriendlyName(), getName(), mo
                                .getManagedObjectDefinition().getUserFriendlyName());
                        unacceptableReasons.add(msg);
                    } else {
                        LocalizableMessage msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITH_NAME.get(managedObject
                                .getManagedObjectDefinition().getUserFriendlyName(), getName(), mo
                                .getManagedObjectDefinition().getUserFriendlyName(), name);
                        unacceptableReasons.add(msg);
                    }
                    isAcceptable = false;
                }
            }
            return isAcceptable;
        }
        // Find all managed objects which reference the named managed
        // object using this property.
        private <CC extends ConfigurationClient> List<ManagedObject<? extends CC>> findReferences(
                ManagementContext context, AbstractManagedObjectDefinition<CC, ?> mod, String name)
                throws AuthorizationException, CommunicationException {
            List<ManagedObject<? extends CC>> instances = findInstances(context, mod);
            Iterator<ManagedObject<? extends CC>> i = instances.iterator();
            while (i.hasNext()) {
                ManagedObject<? extends CC> mo = i.next();
                boolean hasReference = false;
                for (String value : mo.getPropertyValues(AggregationPropertyDefinition.this)) {
                    if (compare(value, name) == 0) {
                        hasReference = true;
                        break;
                    }
                }
                if (!hasReference) {
                    i.remove();
                }
            }
            return instances;
        }
        // Find all instances of a specific type of managed object.
        @SuppressWarnings("unchecked")
        private <CC extends ConfigurationClient> List<ManagedObject<? extends CC>> findInstances(
                ManagementContext context, AbstractManagedObjectDefinition<CC, ?> mod) throws AuthorizationException,
                CommunicationException {
            List<ManagedObject<? extends CC>> instances = new LinkedList<ManagedObject<? extends CC>>();
            if (mod == RootCfgDefn.getInstance()) {
                instances.add((ManagedObject<? extends CC>) context.getRootConfigurationManagedObject());
            } else {
                for (RelationDefinition<? super CC, ?> rd : mod.getAllReverseRelationDefinitions()) {
                    for (ManagedObject<?> parent : findInstances(context, rd.getParentDefinition())) {
                        try {
                            if (rd instanceof SingletonRelationDefinition) {
                                SingletonRelationDefinition<? super CC, ?> srd = (SingletonRelationDefinition<? super CC, ?>) rd;
                                ManagedObject<?> mo = parent.getChild(srd);
                                if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                                    instances.add((ManagedObject<? extends CC>) mo);
                                }
                            } else if (rd instanceof OptionalRelationDefinition) {
                                OptionalRelationDefinition<? super CC, ?> ord = (OptionalRelationDefinition<? super CC, ?>) rd;
                                ManagedObject<?> mo = parent.getChild(ord);
                                if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                                    instances.add((ManagedObject<? extends CC>) mo);
                                }
                            } else if (rd instanceof InstantiableRelationDefinition) {
                                InstantiableRelationDefinition<? super CC, ?> ird = (InstantiableRelationDefinition<? super CC, ?>) rd;
                                for (String name : parent.listChildren(ird)) {
                                    ManagedObject<?> mo = parent.getChild(ird, name);
                                    if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                                        instances.add((ManagedObject<? extends CC>) mo);
                                    }
                                }
                            }
                        } catch (OperationsException e) {
                            // Ignore all operations exceptions.
                        }
                    }
                }
            }
            return instances;
        }
    }
    /**
     * The tracer object for the debug logger.
     */
    private static final DebugTracer TRACER = getTracer();
    /**
     * Creates an aggregation property definition builder.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            aggregation property definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            aggregation property definition refers to.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new aggregation property definition builder.
     */
    public static <C extends ConfigurationClient, S extends Configuration> Builder<C, S> createBuilder(
            AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder<C, S>(d, propertyName);
    }
    // The active server-side referential integrity change listeners
    // associated with this property.
    private final Map<DN, List<ReferentialIntegrityChangeListener>> changeListeners = new HashMap<DN, List<ReferentialIntegrityChangeListener>>();
    // The active server-side referential integrity delete listeners
    // associated with this property.
    private final Map<DN, List<ReferentialIntegrityDeleteListener>> deleteListeners = new HashMap<DN, List<ReferentialIntegrityDeleteListener>>();
    // The name of the managed object which is the parent of the
    // aggregated managed objects.
    private ManagedObjectPath<?, ?> parentPath;
    // The string representation of the managed object path specifying
    // the parent of the aggregated managed objects.
    private String parentPathString = null;
    private final String parentPathString;
    // The name of a relation in the parent managed object which
    // contains the aggregated managed objects.
    private String rdName = null;
    private final String rdName;
    // The condition which is used to determine if a referenced
    // managed object is enabled.
    private Condition targetIsEnabledCondition = Conditions.TRUE;
    // The relation in the parent managed object which contains the
    // aggregated managed objects.
    private InstantiableRelationDefinition<C, S> relationDefinition;
    // The source constraint.
    private final Constraint sourceConstraint;
    // The condition which is used to determine if a referenced managed
    // object is enabled.
    private final Condition targetIsEnabledCondition;
    // The condition which is used to determine whether or not
    // referenced managed objects need to be enabled.
    private Condition targetNeedsEnablingCondition = Conditions.TRUE;
    private final Condition targetNeedsEnablingCondition;
    // Private constructor.
    private AggregationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<String> defaultBehavior, String parentPathString, String rdName,
            Condition targetNeedsEnablingCondition, Condition targetIsEnabledCondition) {
        super(d, String.class, propertyName, options, adminAction, defaultBehavior);
        this.parentPathString = parentPathString;
        this.rdName = rdName;
        this.targetNeedsEnablingCondition = targetNeedsEnablingCondition;
        this.targetIsEnabledCondition = targetIsEnabledCondition;
        this.sourceConstraint = new Constraint() {
    // Private constructor
    private Builder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      super(d, propertyName);
    }
    /**
     * Sets the name of the managed object which is the parent of the
     * aggregated managed objects.
     * <p>
     * This must be defined before the property definition can be
     * built.
     *
     * @param pathString
     *          The string representation of the managed object path
     *          specifying the parent of the aggregated managed
     *          objects.
     */
    public final void setParentPath(String pathString) {
      this.parentPathString = pathString;
    }
    /**
     * Sets the relation in the parent managed object which contains
     * the aggregated managed objects.
     * <p>
     * This must be defined before the property definition can be
     * built.
     *
     * @param rdName
     *          The name of a relation in the parent managed object
     *          which contains the aggregated managed objects.
     */
    public final void setRelationDefinition(String rdName) {
      this.rdName = rdName;
    }
    /**
     * Sets the condition which is used to determine if a referenced
     * managed object is enabled. By default referenced managed
     * objects are assumed to always be enabled.
     *
     * @param condition
     *          The condition which is used to determine if a
     *          referenced managed object is enabled.
     */
    public final void setTargetIsEnabledCondition(Condition condition) {
      this.targetIsEnabledCondition = condition;
    }
    /**
     * Sets the condition which is used to determine whether or not
     * referenced managed objects need to be enabled. By default
     * referenced managed objects must always be enabled.
     *
     * @param condition
     *          The condition which is used to determine whether or
     *          not referenced managed objects need to be enabled.
     */
    public final void setTargetNeedsEnablingCondition(Condition condition) {
      this.targetNeedsEnablingCondition = condition;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected AggregationPropertyDefinition<C, S> buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options, AdministratorAction adminAction,
        DefaultBehaviorProvider<String> defaultBehavior) {
      // Make sure that the parent path has been defined.
      if (parentPathString == null) {
        throw new IllegalStateException("Parent path undefined");
      }
      // Make sure that the relation definition has been defined.
      if (rdName == null) {
        throw new IllegalStateException("Relation definition undefined");
      }
      return new AggregationPropertyDefinition<C, S>(d, propertyName, options,
          adminAction, defaultBehavior, parentPathString, rdName,
          targetNeedsEnablingCondition, targetIsEnabledCondition);
    }
  }
  /**
   * A change listener which prevents the named component from being
   * disabled.
   */
  private class ReferentialIntegrityChangeListener implements
      ServerManagedObjectChangeListener<S> {
    // The error message which should be returned if an attempt is
    // made to disable the referenced component.
    private final Message message;
    // The path of the referenced component.
    private final ManagedObjectPath<C, S> path;
    // Creates a new referential integrity delete listener.
    private ReferentialIntegrityChangeListener(ManagedObjectPath<C, S> path,
        Message message) {
      this.path = path;
      this.message = message;
    }
    /**
     * {@inheritDoc}
     */
    public ConfigChangeResult applyConfigurationChange(
        ServerManagedObject<? extends S> mo) {
      try {
        if (targetIsEnabledCondition.evaluate(mo)) {
          return new ConfigChangeResult(ResultCode.SUCCESS, false);
        }
      } catch (ConfigException e) {
        // This should not happen - ignore it and throw an exception
        // anyway below.
      }
      // This should not happen - the previous call-back should have
      // trapped this.
      throw new IllegalStateException("Attempting to disable a referenced "
          + relationDefinition.getChildDefinition().getUserFriendlyName());
    }
    /**
     * {@inheritDoc}
     */
    public boolean isConfigurationChangeAcceptable(
        ServerManagedObject<? extends S> mo,
        List<Message> unacceptableReasons) {
      // Always prevent the referenced component from being
      // disabled.
      try {
        if (!targetIsEnabledCondition.evaluate(mo)) {
          unacceptableReasons.add(message);
          return false;
        } else {
          return true;
        }
      } catch (ConfigException e) {
        // The condition could not be evaluated.
        if (debugEnabled()) {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION.get(mo
            .getManagedObjectDefinition().getUserFriendlyName(), String
            .valueOf(mo.getDN()), StaticUtils.getExceptionMessage(e));
        ErrorLogger.logError(message);
        unacceptableReasons.add(message);
        return false;
      }
    }
    // Gets the path associated with this listener.
    private ManagedObjectPath<C, S> getManagedObjectPath() {
      return path;
    }
  }
  /**
   * A delete listener which prevents the named component from being
   * deleted.
   */
  private class ReferentialIntegrityDeleteListener implements
      ConfigurationDeleteListener<S> {
    // The DN of the referenced configuration entry.
    private final DN dn;
    // The error message which should be returned if an attempt is
    // made to delete the referenced component.
    private final Message message;
    // Creates a new referential integrity delete listener.
    private ReferentialIntegrityDeleteListener(DN dn, Message message) {
      this.dn = dn;
      this.message = message;
    }
    /**
     * {@inheritDoc}
     */
    public ConfigChangeResult applyConfigurationDelete(S configuration) {
      // This should not happen - the
      // isConfigurationDeleteAcceptable() call-back should have
      // trapped this.
      if (configuration.dn().equals(dn)) {
        // This should not happen - the
        // isConfigurationDeleteAcceptable() call-back should have
        // trapped this.
        throw new IllegalStateException("Attempting to delete a referenced "
            + relationDefinition.getChildDefinition().getUserFriendlyName());
      } else {
        return new ConfigChangeResult(ResultCode.SUCCESS, false);
      }
    }
    /**
     * {@inheritDoc}
     */
    public boolean isConfigurationDeleteAcceptable(S configuration,
        List<Message> unacceptableReasons) {
      if (configuration.dn().equals(dn)) {
        // Always prevent deletion of the referenced component.
        unacceptableReasons.add(message);
        return false;
      }
      return true;
    }
  }
  /**
   * The server-side constraint handler implementation.
   */
  private class ServerHandler extends ServerConstraintHandler {
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isUsable(ServerManagedObject<?> managedObject,
        Collection<Message> unacceptableReasons) throws ConfigException {
      SortedSet<String> names = managedObject
          .getPropertyValues(AggregationPropertyDefinition.this);
      ServerManagementContext context = ServerManagementContext.getInstance();
      Message thisUFN = managedObject.getManagedObjectDefinition()
          .getUserFriendlyName();
      String thisDN = managedObject.getDN().toString();
      Message thatUFN = getRelationDefinition().getUserFriendlyName();
      boolean isUsable = true;
      boolean needsEnabling = targetNeedsEnablingCondition
          .evaluate(managedObject);
      for (String name : names) {
        ManagedObjectPath<C, S> path = getChildPath(name);
        String thatDN = path.toDN().toString();
        if (!context.managedObjectExists(path)) {
          Message msg = ERR_SERVER_REFINT_DANGLING_REFERENCE.get(name,
              getName(), thisUFN, thisDN, thatUFN, thatDN);
          unacceptableReasons.add(msg);
          isUsable = false;
        } else if (needsEnabling) {
          // Check that the referenced component is enabled if
          // required.
          ServerManagedObject<? extends S> ref = context.getManagedObject(path);
          if (!targetIsEnabledCondition.evaluate(ref)) {
            Message msg = ERR_SERVER_REFINT_TARGET_DISABLED.get(name,
                getName(), thisUFN, thisDN, thatUFN, thatDN);
            unacceptableReasons.add(msg);
            isUsable = false;
          }
        }
      }
      return isUsable;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void performPostAdd(ServerManagedObject<?> managedObject)
        throws ConfigException {
      // First make sure existing listeners associated with this
      // managed object are removed. This is required in order to
      // prevent multiple change listener registrations from
      // occurring, for example if this call-back is invoked multiple
      // times after the same add event.
      performPostDelete(managedObject);
      // Add change and delete listeners against all referenced
      // components.
      Message thisUFN = managedObject.getManagedObjectDefinition()
          .getUserFriendlyName();
      String thisDN = managedObject.getDN().toString();
      Message thatUFN = getRelationDefinition().getUserFriendlyName();
      // Referenced managed objects will only need a change listener
      // if they have can be disabled.
      boolean needsChangeListeners = targetNeedsEnablingCondition
          .evaluate(managedObject);
      // Delete listeners need to be registered against the parent
      // entry of the referenced components.
      ServerManagementContext context = ServerManagementContext.getInstance();
      ManagedObjectPath<?, ?> parentPath = getParentPath();
      ServerManagedObject<?> parent = context.getManagedObject(parentPath);
      // Create entries in the listener tables.
      List<ReferentialIntegrityDeleteListener> dlist =
        new LinkedList<ReferentialIntegrityDeleteListener>();
      deleteListeners.put(managedObject.getDN(), dlist);
      List<ReferentialIntegrityChangeListener> clist =
        new LinkedList<ReferentialIntegrityChangeListener>();
      changeListeners.put(managedObject.getDN(), clist);
      for (String name : managedObject
          .getPropertyValues(AggregationPropertyDefinition.this)) {
        ManagedObjectPath<C, S> path = getChildPath(name);
        DN dn = path.toDN();
        String thatDN = dn.toString();
        // Register the delete listener.
        Message msg = ERR_SERVER_REFINT_CANNOT_DELETE.get(thatUFN, thatDN,
            getName(), thisUFN, thisDN);
        ReferentialIntegrityDeleteListener dl =
          new ReferentialIntegrityDeleteListener(dn, msg);
        parent.registerDeleteListener(getRelationDefinition(), dl);
        dlist.add(dl);
        // Register the change listener if required.
        if (needsChangeListeners) {
          ServerManagedObject<? extends S> ref = context.getManagedObject(path);
          msg = ERR_SERVER_REFINT_CANNOT_DISABLE.get(thatUFN, thatDN,
              getName(), thisUFN, thisDN);
          ReferentialIntegrityChangeListener cl =
            new ReferentialIntegrityChangeListener(path, msg);
          ref.registerChangeListener(cl);
          clist.add(cl);
        }
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void performPostDelete(ServerManagedObject<?> managedObject)
        throws ConfigException {
      // Remove any registered delete and change listeners.
      ServerManagementContext context = ServerManagementContext.getInstance();
      DN dn = managedObject.getDN();
      // Delete listeners need to be deregistered against the parent
      // entry of the referenced components.
      ManagedObjectPath<?, ?> parentPath = getParentPath();
      ServerManagedObject<?> parent = context.getManagedObject(parentPath);
      if (deleteListeners.containsKey(dn)) {
        for (ReferentialIntegrityDeleteListener dl : deleteListeners.get(dn)) {
          parent.deregisterDeleteListener(getRelationDefinition(), dl);
        }
        deleteListeners.remove(dn);
      }
      // Change listeners need to be deregistered from their
      // associated referenced component.
      if (changeListeners.containsKey(dn)) {
        for (ReferentialIntegrityChangeListener cl : changeListeners.get(dn)) {
          ManagedObjectPath<C, S> path = cl.getManagedObjectPath();
          ServerManagedObject<? extends S> ref = context.getManagedObject(path);
          ref.deregisterChangeListener(cl);
        }
        changeListeners.remove(dn);
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void performPostModify(ServerManagedObject<?> managedObject)
        throws ConfigException {
      // Remove all the constraints associated with this managed
      // object and then re-register them.
      performPostDelete(managedObject);
      performPostAdd(managedObject);
    }
  }
  /**
   * The client-side constraint handler implementation which enforces
   * referential integrity when aggregating managed objects are added
   * or modified.
   */
  private class SourceClientHandler extends ClientConstraintHandler {
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isAddAcceptable(ManagementContext context,
        ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      // If all of this managed object's "enabled" properties are true
      // then any referenced managed objects must also be enabled.
      boolean needsEnabling = targetNeedsEnablingCondition.evaluate(context,
          managedObject);
      // Check the referenced managed objects exist and, if required,
      // are enabled.
      boolean isAcceptable = true;
      Message ufn = getRelationDefinition().getUserFriendlyName();
      for (String name : managedObject
          .getPropertyValues(AggregationPropertyDefinition.this)) {
        // Retrieve the referenced managed object and make sure it
        // exists.
        ManagedObjectPath<?, ?> path = getChildPath(name);
        ManagedObject<?> ref;
        try {
          ref = context.getManagedObject(path);
        } catch (DefinitionDecodingException e) {
          Message msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name,
              getName(), e.getMessageObject());
          unacceptableReasons.add(msg);
          isAcceptable = false;
          continue;
        } catch (ManagedObjectDecodingException e) {
          Message msg = ERR_CLIENT_REFINT_TARGET_INVALID.get(ufn, name,
              getName(), e.getMessageObject());
          unacceptableReasons.add(msg);
          isAcceptable = false;
          continue;
        } catch (ManagedObjectNotFoundException e) {
          Message msg = ERR_CLIENT_REFINT_TARGET_DANGLING_REFERENCE.get(ufn,
              name, getName());
          unacceptableReasons.add(msg);
          isAcceptable = false;
          continue;
        }
        // Make sure the reference managed object is enabled.
        if (needsEnabling) {
          if (!targetIsEnabledCondition.evaluate(context, ref)) {
            Message msg = ERR_CLIENT_REFINT_TARGET_DISABLED.get(ufn, name,
                getName());
            unacceptableReasons.add(msg);
            isAcceptable = false;
          }
        }
      }
      return isAcceptable;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isModifyAcceptable(ManagementContext context,
        ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      // The same constraint applies as for adds.
      return isAddAcceptable(context, managedObject, unacceptableReasons);
    }
  }
  /**
   * The client-side constraint handler implementation which enforces
   * referential integrity when aggregated managed objects are deleted
   * or modified.
   */
  private class TargetClientHandler extends ClientConstraintHandler {
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isDeleteAcceptable(ManagementContext context,
        ManagedObjectPath<?, ?> path, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      // Any references to the deleted managed object should cause a
      // constraint violation.
      boolean isAcceptable = true;
      for (ManagedObject<?> mo : findReferences(context,
          getManagedObjectDefinition(), path.getName())) {
        String name = mo.getManagedObjectPath().getName();
        if (name == null) {
          Message msg = ERR_CLIENT_REFINT_CANNOT_DELETE_WITHOUT_NAME.get(
              getName(), mo.getManagedObjectDefinition().getUserFriendlyName(),
              getManagedObjectDefinition().getUserFriendlyName());
          unacceptableReasons.add(msg);
        } else {
          Message msg = ERR_CLIENT_REFINT_CANNOT_DELETE_WITH_NAME.get(
              getName(), mo.getManagedObjectDefinition().getUserFriendlyName(),
              name, getManagedObjectDefinition().getUserFriendlyName());
          unacceptableReasons.add(msg);
        }
        isAcceptable = false;
      }
      return isAcceptable;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isModifyAcceptable(ManagementContext context,
        ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      // If the modified managed object is disabled and there are some
      // active references then refuse the change.
      if (targetIsEnabledCondition.evaluate(context, managedObject)) {
        return true;
      }
      // The referenced managed object is disabled. Need to check for
      // active references.
      boolean isAcceptable = true;
      for (ManagedObject<?> mo : findReferences(context,
          getManagedObjectDefinition(), managedObject.getManagedObjectPath()
              .getName())) {
        if (targetNeedsEnablingCondition.evaluate(context, mo)) {
          String name = mo.getManagedObjectPath().getName();
          if (name == null) {
            Message msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME.get(
                managedObject.getManagedObjectDefinition()
                    .getUserFriendlyName(), getName(), mo
                    .getManagedObjectDefinition().getUserFriendlyName());
            unacceptableReasons.add(msg);
          } else {
            Message msg = ERR_CLIENT_REFINT_CANNOT_DISABLE_WITH_NAME.get(
                managedObject.getManagedObjectDefinition()
                    .getUserFriendlyName(), getName(), mo
                    .getManagedObjectDefinition().getUserFriendlyName(), name);
            unacceptableReasons.add(msg);
          }
          isAcceptable = false;
        }
      }
      return isAcceptable;
    }
    // Find all managed objects which reference the named managed
    // object using this property.
    private <CC extends ConfigurationClient>
        List<ManagedObject<? extends CC>> findReferences(
        ManagementContext context, AbstractManagedObjectDefinition<CC, ?> mod,
        String name) throws AuthorizationException, CommunicationException {
      List<ManagedObject<? extends CC>> instances = findInstances(context, mod);
      Iterator<ManagedObject<? extends CC>> i = instances.iterator();
      while (i.hasNext()) {
        ManagedObject<? extends CC> mo = i.next();
        boolean hasReference = false;
        for (String value : mo
            .getPropertyValues(AggregationPropertyDefinition.this)) {
          if (compare(value, name) == 0) {
            hasReference = true;
            break;
          }
        }
        if (!hasReference) {
          i.remove();
        }
      }
      return instances;
    }
    // Find all instances of a specific type of managed object.
    @SuppressWarnings("unchecked")
    private <CC extends ConfigurationClient>
        List<ManagedObject<? extends CC>> findInstances(
        ManagementContext context, AbstractManagedObjectDefinition<CC, ?> mod)
        throws AuthorizationException, CommunicationException {
      List<ManagedObject<? extends CC>> instances =
        new LinkedList<ManagedObject<? extends CC>>();
      if (mod == RootCfgDefn.getInstance()) {
        instances.add((ManagedObject<? extends CC>) context
            .getRootConfigurationManagedObject());
      } else {
        for (RelationDefinition<? super CC, ?> rd : mod
            .getAllReverseRelationDefinitions()) {
          for (ManagedObject<?> parent : findInstances(context, rd
              .getParentDefinition())) {
            try {
              if (rd instanceof SingletonRelationDefinition) {
                SingletonRelationDefinition<? super CC, ?> srd =
                  (SingletonRelationDefinition<? super CC, ?>) rd;
                ManagedObject<?> mo = parent.getChild(srd);
                if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                  instances.add((ManagedObject<? extends CC>) mo);
                }
              } else if (rd instanceof OptionalRelationDefinition) {
                OptionalRelationDefinition<? super CC, ?> ord =
                  (OptionalRelationDefinition<? super CC, ?>) rd;
                ManagedObject<?> mo = parent.getChild(ord);
                if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                  instances.add((ManagedObject<? extends CC>) mo);
                }
              } else if (rd instanceof InstantiableRelationDefinition) {
                InstantiableRelationDefinition<? super CC, ?> ird =
                  (InstantiableRelationDefinition<? super CC, ?>) rd;
                for (String name : parent.listChildren(ird)) {
                  ManagedObject<?> mo = parent.getChild(ird, name);
                  if (mo.getManagedObjectDefinition().isChildOf(mod)) {
                    instances.add((ManagedObject<? extends CC>) mo);
                  }
                }
              }
            } catch (OperationsException e) {
              // Ignore all operations exceptions.
            /**
             * {@inheritDoc}
             */
            public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
                ClientConstraintHandler handler = new SourceClientHandler();
                return Collections.singleton(handler);
            }
          }
            /**
             * {@inheritDoc}
             */
            public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
                ServerConstraintHandler handler = new ServerHandler();
                return Collections.singleton(handler);
            }
        };
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitAggregation(this, p);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
        return v.visitAggregation(this, value, p);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
        try {
            validateValue(value);
            return value;
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
      }
      return instances;
    }
  }
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  /**
   * Creates an aggregation property definition builder.
   *
   * @param <C>
   *          The type of client managed object configuration that
   *          this aggregation property definition refers to.
   * @param <S>
   *          The type of server managed object configuration that
   *          this aggregation property definition refers to.
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new aggregation property definition builder.
   */
  public static <C extends ConfigurationClient, S extends Configuration>
      Builder<C, S> createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder<C, S>(d, propertyName);
  }
  // The active server-side referential integrity change listeners
  // associated with this property.
  private final Map<DN, List<ReferentialIntegrityChangeListener>>
    changeListeners = new HashMap<DN,
      List<ReferentialIntegrityChangeListener>>();
  // The active server-side referential integrity delete listeners
  // associated with this property.
  private final Map<DN, List<ReferentialIntegrityDeleteListener>>
    deleteListeners = new HashMap<DN,
      List<ReferentialIntegrityDeleteListener>>();
  // The name of the managed object which is the parent of the
  // aggregated managed objects.
  private ManagedObjectPath<?, ?> parentPath;
  // The string representation of the managed object path specifying
  // the parent of the aggregated managed objects.
  private final String parentPathString;
  // The name of a relation in the parent managed object which
  // contains the aggregated managed objects.
  private final String rdName;
  // The relation in the parent managed object which contains the
  // aggregated managed objects.
  private InstantiableRelationDefinition<C, S> relationDefinition;
  // The source constraint.
  private final Constraint sourceConstraint;
  // The condition which is used to determine if a referenced managed
  // object is enabled.
  private final Condition targetIsEnabledCondition;
  // The condition which is used to determine whether or not
  // referenced managed objects need to be enabled.
  private final Condition targetNeedsEnablingCondition;
  // Private constructor.
  private AggregationPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options, AdministratorAction adminAction,
      DefaultBehaviorProvider<String> defaultBehavior, String parentPathString,
      String rdName, Condition targetNeedsEnablingCondition,
      Condition targetIsEnabledCondition) {
    super(d, String.class, propertyName, options, adminAction, defaultBehavior);
    this.parentPathString = parentPathString;
    this.rdName = rdName;
    this.targetNeedsEnablingCondition = targetNeedsEnablingCondition;
    this.targetIsEnabledCondition = targetIsEnabledCondition;
    this.sourceConstraint = new Constraint() {
      /**
       * {@inheritDoc}
       */
      public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
        ClientConstraintHandler handler = new SourceClientHandler();
        return Collections.singleton(handler);
      }
      /**
       * {@inheritDoc}
       */
      public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
        ServerConstraintHandler handler = new ServerHandler();
        return Collections.singleton(handler);
      }
    };
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitAggregation(this, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
    return v.visitAggregation(this, value, p);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    try {
      validateValue(value);
      return value;
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * Constructs a DN for a referenced managed object having the provided name.
     * This method is implemented by first calling {@link #getChildPath(String)}
     * and then invoking {@code ManagedObjectPath.toDN()} on the returned path.
     *
     * @param name
     *            The name of the child managed object.
     * @return Returns a DN for a referenced managed object having the provided
     *         name.
     */
    public final DN getChildDN(String name) {
        return getChildPath(name).toDN();
    }
  }
  /**
   * Constructs a DN for a referenced managed object having the
   * provided name. This method is implemented by first calling
   * {@link #getChildPath(String)} and then invoking
   * {@code ManagedObjectPath.toDN()} on the returned path.
   *
   * @param name
   *          The name of the child managed object.
   * @return Returns a DN for a referenced managed object having the
   *         provided name.
   */
  public final DN getChildDN(String name) {
    return getChildPath(name).toDN();
  }
  /**
   * Constructs a managed object path for a referenced managed object
   * having the provided name.
   *
   * @param name
   *          The name of the child managed object.
   * @return Returns a managed object path for a referenced managed
   *         object having the provided name.
   */
  public final ManagedObjectPath<C, S> getChildPath(String name) {
    return parentPath.child(relationDefinition, name);
  }
  /**
   * Gets the name of the managed object which is the parent of the
   * aggregated managed objects.
   *
   * @return Returns the name of the managed object which is the
   *         parent of the aggregated managed objects.
   */
  public final ManagedObjectPath<?, ?> getParentPath() {
    return parentPath;
  }
  /**
   * Gets the relation in the parent managed object which contains the
   * aggregated managed objects.
   *
   * @return Returns the relation in the parent managed object which
   *         contains the aggregated managed objects.
   */
  public final InstantiableRelationDefinition<C, S> getRelationDefinition() {
    return relationDefinition;
  }
  /**
   * Gets the constraint which should be enforced on the aggregating
   * managed object.
   *
   * @return Returns the constraint which should be enforced on the
   *         aggregating managed object.
   */
  public final Constraint getSourceConstraint() {
    return sourceConstraint;
  }
  /**
   * Gets the optional constraint synopsis of this aggregation
   * property definition in the default locale. The constraint
   * synopsis describes when and how referenced managed objects must
   * be enabled. When there are no constraints between the source
   * managed object and the objects it references through this
   * aggregation, <code>null</code> is returned.
   *
   * @return Returns the optional constraint synopsis of this
   *         aggregation property definition in the default locale, or
   *         <code>null</code> if there is no constraint synopsis.
   */
  public final Message getSourceConstraintSynopsis() {
    return getSourceConstraintSynopsis(Locale.getDefault());
  }
  /**
   * Gets the optional constraint synopsis of this aggregation
   * property definition in the specified locale.The constraint
   * synopsis describes when and how referenced managed objects must
   * be enabled. When there are no constraints between the source
   * managed object and the objects it references through this
   * aggregation, <code>null</code> is returned.
   *
   * @param locale
   *          The locale.
   * @return Returns the optional constraint synopsis of this
   *         aggregation property definition in the specified locale,
   *         or <code>null</code> if there is no constraint
   *         synopsis.
   */
  public final Message getSourceConstraintSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + getName()
        + ".syntax.aggregation.constraint-synopsis";
    try {
      return resource
          .getMessage(getManagedObjectDefinition(), property, locale);
    } catch (MissingResourceException e) {
      return null;
    /**
     * Constructs a managed object path for a referenced managed object having
     * the provided name.
     *
     * @param name
     *            The name of the child managed object.
     * @return Returns a managed object path for a referenced managed object
     *         having the provided name.
     */
    public final ManagedObjectPath<C, S> getChildPath(String name) {
        return parentPath.child(relationDefinition, name);
    }
  }
  /**
   * Gets the condition which is used to determine if a referenced
   * managed object is enabled.
   *
   * @return Returns the condition which is used to determine if a
   *         referenced managed object is enabled.
   */
  public final Condition getTargetIsEnabledCondition() {
    return targetIsEnabledCondition;
  }
  /**
   * Gets the condition which is used to determine whether or not
   * referenced managed objects need to be enabled.
   *
   * @return Returns the condition which is used to determine whether
   *         or not referenced managed objects need to be enabled.
   */
  public final Condition getTargetNeedsEnablingCondition() {
    return targetNeedsEnablingCondition;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String normalizeValue(String value)
      throws IllegalPropertyValueException {
    try {
      Reference<C, S> reference = Reference.parseName(parentPath,
          relationDefinition, value);
      return reference.getNormalizedName();
    } catch (IllegalArgumentException e) {
      throw new IllegalPropertyValueException(this, value);
    /**
     * Gets the name of the managed object which is the parent of the aggregated
     * managed objects.
     *
     * @return Returns the name of the managed object which is the parent of the
     *         aggregated managed objects.
     */
    public final ManagedObjectPath<?, ?> getParentPath() {
        return parentPath;
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder) {
    super.toString(builder);
    builder.append(" parentPath=");
    builder.append(parentPath);
    builder.append(" relationDefinition=");
    builder.append(relationDefinition.getName());
    builder.append(" targetNeedsEnablingCondition=");
    builder.append(String.valueOf(targetNeedsEnablingCondition));
    builder.append(" targetIsEnabledCondition=");
    builder.append(String.valueOf(targetIsEnabledCondition));
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(String value) throws IllegalPropertyValueException {
    try {
      Reference.parseName(parentPath, relationDefinition, value);
    } catch (IllegalArgumentException e) {
      throw new IllegalPropertyValueException(this, value);
    /**
     * Gets the relation in the parent managed object which contains the
     * aggregated managed objects.
     *
     * @return Returns the relation in the parent managed object which contains
     *         the aggregated managed objects.
     */
    public final InstantiableRelationDefinition<C, S> getRelationDefinition() {
        return relationDefinition;
    }
  }
    /**
     * Gets the constraint which should be enforced on the aggregating managed
     * object.
     *
     * @return Returns the constraint which should be enforced on the
     *         aggregating managed object.
     */
    public final Constraint getSourceConstraint() {
        return sourceConstraint;
    }
    /**
     * Gets the optional constraint synopsis of this aggregation property
     * definition in the default locale. The constraint synopsis describes when
     * and how referenced managed objects must be enabled. When there are no
     * constraints between the source managed object and the objects it
     * references through this aggregation, <code>null</code> is returned.
     *
     * @return Returns the optional constraint synopsis of this aggregation
     *         property definition in the default locale, or <code>null</code>
     *         if there is no constraint synopsis.
     */
    public final LocalizableMessage getSourceConstraintSynopsis() {
        return getSourceConstraintSynopsis(Locale.getDefault());
    }
  /**
   * {@inheritDoc}
   */
  @SuppressWarnings("unchecked")
  @Override
  public void initialize() throws Exception {
    // Decode the path.
    parentPath = ManagedObjectPath.valueOf(parentPathString);
    /**
     * Gets the optional constraint synopsis of this aggregation property
     * definition in the specified locale.The constraint synopsis describes when
     * and how referenced managed objects must be enabled. When there are no
     * constraints between the source managed object and the objects it
     * references through this aggregation, <code>null</code> is returned.
     *
     * @param locale
     *            The locale.
     * @return Returns the optional constraint synopsis of this aggregation
     *         property definition in the specified locale, or <code>null</code>
     *         if there is no constraint synopsis.
     */
    public final LocalizableMessage getSourceConstraintSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + getName() + ".syntax.aggregation.constraint-synopsis";
        try {
            return resource.getLocalizableMessage(getManagedObjectDefinition(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
    // Decode the relation definition.
    AbstractManagedObjectDefinition<?, ?> parent = parentPath
        .getManagedObjectDefinition();
    RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName);
    relationDefinition = (InstantiableRelationDefinition<C, S>) rd;
    /**
     * Gets the condition which is used to determine if a referenced managed
     * object is enabled.
     *
     * @return Returns the condition which is used to determine if a referenced
     *         managed object is enabled.
     */
    public final Condition getTargetIsEnabledCondition() {
        return targetIsEnabledCondition;
    }
    // Now decode the conditions.
    targetNeedsEnablingCondition.initialize(getManagedObjectDefinition());
    targetIsEnabledCondition.initialize(rd.getChildDefinition());
    /**
     * Gets the condition which is used to determine whether or not referenced
     * managed objects need to be enabled.
     *
     * @return Returns the condition which is used to determine whether or not
     *         referenced managed objects need to be enabled.
     */
    public final Condition getTargetNeedsEnablingCondition() {
        return targetNeedsEnablingCondition;
    }
    // Register a client-side constraint with the referenced
    // definition. This will be used to enforce referential integrity
    // for actions performed against referenced managed objects.
    Constraint constraint = new Constraint() {
    /**
     * {@inheritDoc}
     */
    @Override
    public String normalizeValue(String value) throws IllegalPropertyValueException {
        try {
            Reference<C, S> reference = Reference.parseName(parentPath, relationDefinition, value);
            return reference.getNormalizedName();
        } catch (IllegalArgumentException e) {
            throw new IllegalPropertyValueException(this, value);
        }
    }
      /**
       * {@inheritDoc}
       */
      public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
        ClientConstraintHandler handler = new TargetClientHandler();
        return Collections.singleton(handler);
      }
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        super.toString(builder);
        builder.append(" parentPath=");
        builder.append(parentPath);
        builder.append(" relationDefinition=");
        builder.append(relationDefinition.getName());
      /**
       * {@inheritDoc}
       */
      public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
        return Collections.emptyList();
      }
    };
        builder.append(" targetNeedsEnablingCondition=");
        builder.append(String.valueOf(targetNeedsEnablingCondition));
    rd.getChildDefinition().registerConstraint(constraint);
  }
        builder.append(" targetIsEnabledCondition=");
        builder.append(String.valueOf(targetIsEnabledCondition));
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void validateValue(String value) throws IllegalPropertyValueException {
        try {
            Reference.parseName(parentPath, relationDefinition, value);
        } catch (IllegalArgumentException e) {
            throw new IllegalPropertyValueException(this, value);
        }
    }
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public void initialize() throws Exception {
        // Decode the path.
        parentPath = ManagedObjectPath.valueOf(parentPathString);
        // Decode the relation definition.
        AbstractManagedObjectDefinition<?, ?> parent = parentPath.getManagedObjectDefinition();
        RelationDefinition<?, ?> rd = parent.getRelationDefinition(rdName);
        relationDefinition = (InstantiableRelationDefinition<C, S>) rd;
        // Now decode the conditions.
        targetNeedsEnablingCondition.initialize(getManagedObjectDefinition());
        targetIsEnabledCondition.initialize(rd.getChildDefinition());
        // Register a client-side constraint with the referenced
        // definition. This will be used to enforce referential integrity
        // for actions performed against referenced managed objects.
        Constraint constraint = new Constraint() {
            /**
             * {@inheritDoc}
             */
            public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
                ClientConstraintHandler handler = new TargetClientHandler();
                return Collections.singleton(handler);
            }
            /**
             * {@inheritDoc}
             */
            public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
                return Collections.emptyList();
            }
        };
        rd.getChildDefinition().registerConstraint(constraint);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AliasDefaultBehaviorProvider.java
@@ -25,11 +25,10 @@
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import java.util.Locale;
import org.forgerock.i18n.LocalizableMessage;
/**
 * A default behavior provider which indicates special behavior. It should be
@@ -40,76 +39,62 @@
 * values.
 *
 * @param <T>
 *          The type of values represented by this provider.
 *            The type of values represented by this provider.
 */
public final class AliasDefaultBehaviorProvider<T> extends
    DefaultBehaviorProvider<T> {
public final class AliasDefaultBehaviorProvider<T> extends DefaultBehaviorProvider<T> {
  // The managed object definition associated with this default
  // behavior.
  private final AbstractManagedObjectDefinition<?, ?> definition;
    // The managed object definition associated with this default
    // behavior.
    private final AbstractManagedObjectDefinition<?, ?> definition;
  // The name of the property definition associated with this default
  // behavior.
  private final String propertyName;
    // The name of the property definition associated with this default
    // behavior.
    private final String propertyName;
    /**
     * Create an alias default behavior provider.
     *
     * @param d
     *            The managed object definition associated with this default
     *            behavior.
     * @param propertyName
     *            The name of the property definition associated with this
     *            default behavior.
     */
    public AliasDefaultBehaviorProvider(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        this.definition = d;
        this.propertyName = propertyName;
    }
    /**
     * {@inheritDoc}
     */
    public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) {
        return v.visitAlias(this, p);
    }
  /**
   * Create an alias default behavior provider.
   *
   * @param d
   *          The managed object definition associated with this
   *          default behavior.
   * @param propertyName
   *          The name of the property definition associated with this
   *          default behavior.
   */
  public AliasDefaultBehaviorProvider(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    this.definition = d;
    this.propertyName = propertyName;
  }
    /**
     * Gets the synopsis of this alias default behavior in the default locale.
     *
     * @return Returns the synopsis of this alias default behavior in the
     *         default locale.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
  /**
   * {@inheritDoc}
   */
  public <R, P> R accept(DefaultBehaviorProviderVisitor<T, R, P> v, P p) {
    return v.visitAlias(this, p);
  }
  /**
   * Gets the synopsis of this alias default behavior in the
   * default locale.
   *
   * @return Returns the synopsis of this alias default behavior in
   *         the default locale.
   */
  public final Message getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this alias default behavior in the specified
   * locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this alias default behavior in
   *         the specified locale.
   */
  public final Message getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName
        + ".default-behavior.alias.synopsis";
    return resource.getMessage(definition, property, locale);
  }
    /**
     * Gets the synopsis of this alias default behavior in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this alias default behavior in the
     *         specified locale.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + propertyName + ".default-behavior.alias.synopsis";
        return resource.getLocalizableMessage(definition, property, locale);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/AttributeTypePropertyDefinition.java
@@ -27,7 +27,7 @@
package org.opends.server.admin;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
@@ -37,179 +37,141 @@
/**
 * Attribute type property definition.
 */
public final class AttributeTypePropertyDefinition extends
    PropertyDefinition<AttributeType> {
public final class AttributeTypePropertyDefinition extends PropertyDefinition<AttributeType> {
  /**
   * An interface for incrementally constructing attribute type
   * property definitions.
   */
  public static class Builder extends
      AbstractBuilder<AttributeType, AttributeTypePropertyDefinition> {
    /**
     * An interface for incrementally constructing attribute type property
     * definitions.
     */
    public static class Builder extends AbstractBuilder<AttributeType, AttributeTypePropertyDefinition> {
    // Private constructor
    private Builder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      super(d, propertyName);
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected AttributeTypePropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d,
                String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<AttributeType> defaultBehavior) {
            return new AttributeTypePropertyDefinition(d, propertyName, options, adminAction, defaultBehavior);
        }
    }
    // Flag indicating whether or not attribute type names should be
    // validated against the schema.
    private static boolean isCheckSchema = true;
    /**
     * Create a attribute type property definition builder.
     *
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new attribute type property definition builder.
     */
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    /**
     * Determines whether or not attribute type names should be validated
     * against the schema.
     *
     * @return Returns <code>true</code> if attribute type names should be
     *         validated against the schema.
     */
    public static boolean isCheckSchema() {
        return isCheckSchema;
    }
    /**
     * Specify whether or not attribute type names should be validated against
     * the schema.
     * <p>
     * By default validation is switched on.
     *
     * @param value
     *            <code>true</code> if attribute type names should be validated
     *            against the schema.
     */
    public static void setCheckSchema(boolean value) {
        isCheckSchema = value;
    }
    // Private constructor.
    private AttributeTypePropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<AttributeType> defaultBehavior) {
        super(d, AttributeType.class, propertyName, options, adminAction, defaultBehavior);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected AttributeTypePropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<AttributeType> defaultBehavior) {
      return new AttributeTypePropertyDefinition(d, propertyName,
          options, adminAction, defaultBehavior);
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitAttributeType(this, p);
    }
  }
  // Flag indicating whether or not attribute type names should be
  // validated against the schema.
  private static boolean isCheckSchema = true;
  /**
   * Create a attribute type property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new attribute type property definition
   *         builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  /**
   * Determines whether or not attribute type names should be
   * validated against the schema.
   *
   * @return Returns <code>true</code> if attribute type names
   *         should be validated against the schema.
   */
  public static boolean isCheckSchema() {
    return isCheckSchema;
  }
  /**
   * Specify whether or not attribute type names should be validated
   * against the schema.
   * <p>
   * By default validation is switched on.
   *
   * @param value
   *          <code>true</code> if attribute type names should be
   *          validated against the schema.
   */
  public static void setCheckSchema(boolean value) {
    isCheckSchema = value;
  }
  // Private constructor.
  private AttributeTypePropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<AttributeType> defaultBehavior) {
    super(d, AttributeType.class, propertyName, options,
        adminAction, defaultBehavior);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitAttributeType(this, p);
  }
  /**
   * {@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());
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public AttributeType decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    String name = value.trim().toLowerCase();
    AttributeType type = DirectoryServer.getAttributeType(name,
        !isCheckSchema);
    if (type == null) {
      throw new IllegalPropertyValueStringException(this, value);
    } else {
      try {
        validateValue(type);
        return type;
      } catch (IllegalPropertyValueException e) {
        throw new IllegalPropertyValueStringException(this, value);
      }
    /**
     * {@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());
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public AttributeType decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(AttributeType value)
      throws IllegalPropertyValueException {
    return value.getNameOrOID();
  }
        String name = value.trim().toLowerCase();
        AttributeType type = DirectoryServer.getAttributeType(name, !isCheckSchema);
        if (type == null) {
            throw new IllegalPropertyValueStringException(this, value);
        } else {
            try {
                validateValue(type);
                return type;
            } catch (IllegalPropertyValueException e) {
                throw new IllegalPropertyValueStringException(this, value);
            }
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String encodeValue(AttributeType value) throws IllegalPropertyValueException {
        return value.getNameOrOID();
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(AttributeType value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    /**
     * {@inheritDoc}
     */
    @Override
    public void validateValue(AttributeType value) throws IllegalPropertyValueException {
        ensureNotNull(value);
    // No implementation required.
  }
        // No implementation required.
    }
}
opendj-admin/src/main/java/org/opends/server/admin/BooleanPropertyDefinition.java
@@ -27,16 +27,12 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
 * Boolean property definition.
 */
opendj-admin/src/main/java/org/opends/server/admin/ClassLoaderProvider.java
@@ -29,12 +29,7 @@
import static org.opends.messages.AdminMessages.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.ServerConstants.EOL;
import static com.forgerock.opendj.util.Validator.*;
import java.io.ByteArrayOutputStream;
import java.io.BufferedReader;
@@ -58,15 +53,10 @@
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.opends.messages.Message;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.admin.meta.RootCfgDefn;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.InitializationException;
import org.opends.server.util.Validator;
/**
 * Manages the class loader which should be used for loading
@@ -216,7 +206,7 @@
  public synchronized void addExtension(String... extensions)
      throws InitializationException, IllegalStateException,
      IllegalArgumentException {
    Validator.ensureNotNull(extensions);
    ensureNotNull(extensions);
    if (loader == null) {
      throw new IllegalStateException(
@@ -419,7 +409,7 @@
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.
        LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.
            get(extension.getName(), extension.getParent(),
                stackTraceToSingleLineString(e));
        throw new InitializationException(message);
@@ -566,7 +556,7 @@
      if (!extensionsPath.exists()) {
        // The extensions directory does not exist. This is not a
        // critical problem.
        Message message = ERR_ADMIN_NO_EXTENSIONS_DIR.get(
        LocalizableMessage message = ERR_ADMIN_NO_EXTENSIONS_DIR.get(
                String.valueOf(extensionsPath));
        logError(message);
        return;
@@ -575,7 +565,7 @@
      if (!extensionsPath.isDirectory()) {
        // The extensions directory is not a directory. This is more
        // critical.
        Message message =
        LocalizableMessage message =
            ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY.get(
                    String.valueOf(extensionsPath));
        throw new InitializationException(message);
@@ -610,7 +600,7 @@
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES.get(
      LocalizableMessage message = ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES.get(
          String.valueOf(extensionsPath), stackTraceToSingleLineString(e));
      throw new InitializationException(message, e);
    }
@@ -632,7 +622,7 @@
        + CORE_MANIFEST);
    if (is == null) {
      Message message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST);
      LocalizableMessage message = ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST.get(CORE_MANIFEST);
      throw new InitializationException(message);
    }
@@ -643,7 +633,7 @@
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_CLASS_LOADER_CANNOT_LOAD_CORE.get(CORE_MANIFEST,
      LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_CORE.get(CORE_MANIFEST,
          stackTraceToSingleLineString(e));
      throw new InitializationException(message);
    }
@@ -675,7 +665,7 @@
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(
        LocalizableMessage message = ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST.get(
            EXTENSION_MANIFEST, jarFile.getName(),
            stackTraceToSingleLineString(e));
        throw new InitializationException(message);
@@ -688,7 +678,7 @@
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        Message message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile
        LocalizableMessage message = ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION.get(jarFile
            .getName(), EXTENSION_MANIFEST, stackTraceToSingleLineString(e));
        throw new InitializationException(message);
      }
@@ -729,8 +719,8 @@
      try {
        className = reader.readLine();
      } catch (IOException e) {
        Message msg = ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE.get(String
            .valueOf(e.getMessage()));
        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE.get(String
            .valueOf(e.getLocalizableMessage()));
        throw new InitializationException(msg, e);
      }
@@ -750,15 +740,15 @@
        continue;
      }
      TRACER.debugMessage(DebugLogLevel.INFO, "Loading class " + className);
      TRACER.debugLocalizableMessage(DebugLogLevel.INFO, "Loading class " + className);
      // Load the class and get an instance of it if it is a definition.
      Class<?> theClass;
      try {
        theClass = Class.forName(className, true, loader);
      } catch (Exception e) {
        Message msg = ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, String
            .valueOf(e.getMessage()));
        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_LOAD_CLASS.get(className, String
            .valueOf(e.getLocalizableMessage()));
        throw new InitializationException(msg, e);
      }
      if (AbstractManagedObjectDefinition.class.isAssignableFrom(theClass)) {
@@ -767,8 +757,8 @@
        try {
          method = theClass.getMethod("getInstance");
        } catch (Exception e) {
          Message msg = ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD.get(
              className, String.valueOf(e.getMessage()));
          LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD.get(
              className, String.valueOf(e.getLocalizableMessage()));
          throw new InitializationException(msg, e);
        }
@@ -777,8 +767,8 @@
        try {
          d = (AbstractManagedObjectDefinition<?, ?>) method.invoke(null);
        } catch (Exception e) {
          Message msg = ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD.get(
              className, String.valueOf(e.getMessage()));
          LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD.get(
              className, String.valueOf(e.getLocalizableMessage()));
          throw new InitializationException(msg, e);
        }
        definitions.add(d);
@@ -790,8 +780,8 @@
      try {
        d.initialize();
      } catch (Exception e) {
        Message msg = ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(),
            d.getClass().getName(), String.valueOf(e.getMessage()));
        LocalizableMessage msg = ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN.get(d.getName(),
            d.getClass().getName(), String.valueOf(e.getLocalizableMessage()));
        throw new InitializationException(msg, e);
      }
    }
@@ -820,7 +810,7 @@
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      Message message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(
      LocalizableMessage message = ERR_ADMIN_CANNOT_OPEN_JAR_FILE.get(
          jar.getName(), jar.getParent(), stackTraceToSingleLineString(e));
      throw new InitializationException(message);
    }
opendj-admin/src/main/java/org/opends/server/admin/ClassPropertyDefinition.java
@@ -27,356 +27,295 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
/**
 * Class property definition.
 * <p>
 * A class property definition defines a property whose values
 * represent a Java class. It is possible to restrict the type of java
 * class by specifying "instance of" constraints.
 * A class property definition defines a property whose values represent a Java
 * class. It is possible to restrict the type of java class by specifying
 * "instance of" constraints.
 * <p>
 * Note that in a client/server environment, the client is probably
 * not capable of validating the Java class (e.g. it will not be able
 * to load it nor have access to the interfaces it is supposed to
 * implement). For this reason, it is possible to switch off
 * validation in the client by calling the static method
 * Note that in a client/server environment, the client is probably not capable
 * of validating the Java class (e.g. it will not be able to load it nor have
 * access to the interfaces it is supposed to implement). For this reason, it is
 * possible to switch off validation in the client by calling the static method
 * {@link #setAllowClassValidation(boolean)}.
 */
public final class ClassPropertyDefinition extends PropertyDefinition<String> {
  /**
   * An interface for incrementally constructing class property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<String, ClassPropertyDefinition> {
    /**
     * An interface for incrementally constructing class property definitions.
     */
    public static class Builder extends AbstractBuilder<String, ClassPropertyDefinition> {
    // List of interfaces which property values must implement.
    private List<String> instanceOfInterfaces;
        // List of interfaces which property values must implement.
        private List<String> instanceOfInterfaces;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
            this.instanceOfInterfaces = new LinkedList<String>();
        }
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
        /**
         * Add an class name which property values must implement.
         *
         * @param className
         *            The name of a class which property values must implement.
         */
        public final void addInstanceOf(String className) {
            ensureNotNull(className);
      this.instanceOfInterfaces = new LinkedList<String>();
            // Do some basic checks to make sure the string representation
            // is valid.
            String value = className.trim();
            if (!value.matches(CLASS_RE)) {
                throw new IllegalArgumentException("\"" + value + "\" is not a valid Java class name");
            }
            // If possible try and load the class in order to perform
            // additional
            // validation.
            if (isAllowClassValidation()) {
                // Check that the class can be loaded so that validation can
                // be
                // performed.
                try {
                    loadClass(value);
                } catch (ClassNotFoundException e) {
                    // TODO: can we do something better here?
                    throw new RuntimeException(e);
                }
            }
            instanceOfInterfaces.add(value);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected ClassPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<String> defaultBehavior) {
            return new ClassPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior,
                    instanceOfInterfaces);
        }
    }
    // 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_]*(\\$[A-Za-z0-9_]+)*$";
    // Flag indicating whether class property values should be
    // validated.
    private static boolean allowClassValidation = true;
    /**
     * Add an class name which property values must implement.
     * Create a class property definition builder.
     *
     * @param className
     *          The name of a class which property values must
     *          implement.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new class property definition builder.
     */
    public final void addInstanceOf(String className) {
      ensureNotNull(className);
      // Do some basic checks to make sure the string representation
      // is valid.
      String value = className.trim();
      if (!value.matches(CLASS_RE)) {
        throw new IllegalArgumentException("\"" + value
            + "\" is not a valid Java class name");
      }
      // If possible try and load the class in order to perform
      // additional
      // validation.
      if (isAllowClassValidation()) {
        // Check that the class can be loaded so that validation can
        // be
        // performed.
        try {
          loadClass(value);
        } catch (ClassNotFoundException e) {
          // TODO: can we do something better here?
          throw new RuntimeException(e);
        }
      }
      instanceOfInterfaces.add(value);
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    /**
     * Determine whether or not class property definitions should validate class
     * name property values. Validation involves checking that the class exists
     * and that it implements the required interfaces.
     *
     * @return Returns <code>true</code> if class property definitions should
     *         validate class name property values.
     */
    public static boolean isAllowClassValidation() {
        return allowClassValidation;
    }
    /**
     * Specify whether or not class property definitions should validate class
     * name property values. Validation involves checking that the class exists
     * and that it implements the required interfaces.
     * <p>
     * By default validation is switched on.
     *
     * @param value
     *            <code>true</code> if class property definitions should
     *            validate class name property values.
     */
    public static void setAllowClassValidation(boolean value) {
        allowClassValidation = value;
    }
    // Load a named class.
    private static Class<?> loadClass(String className) throws ClassNotFoundException, LinkageError {
        return Class.forName(className, true, ClassLoaderProvider.getInstance().getClassLoader());
    }
    // List of interfaces which property values must implement.
    private final List<String> instanceOfInterfaces;
    // Private constructor.
    private ClassPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<String> defaultBehavior, List<String> instanceOfInterfaces) {
        super(d, String.class, propertyName, options, adminAction, defaultBehavior);
        this.instanceOfInterfaces = Collections.unmodifiableList(new LinkedList<String>(instanceOfInterfaces));
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected ClassPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d,
        String propertyName, EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<String> defaultBehavior) {
      return new ClassPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior, instanceOfInterfaces);
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitClass(this, p);
    }
  }
  // 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_]*(\\$[A-Za-z0-9_]+)*$";
  // Flag indicating whether class property values should be
  // validated.
  private static boolean allowClassValidation = true;
  /**
   * Create a class property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new class property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  /**
   * Determine whether or not class property definitions should
   * validate class name property values. Validation involves checking
   * that the class exists and that it implements the required
   * interfaces.
   *
   * @return Returns <code>true</code> if class property definitions
   *         should validate class name property values.
   */
  public static boolean isAllowClassValidation() {
    return allowClassValidation;
  }
  /**
   * Specify whether or not class property definitions should validate
   * class name property values. Validation involves checking that the
   * class exists and that it implements the required interfaces.
   * <p>
   * By default validation is switched on.
   *
   * @param value
   *          <code>true</code> if class property definitions should
   *          validate class name property values.
   */
  public static void setAllowClassValidation(boolean value) {
    allowClassValidation = value;
  }
  // Load a named class.
  private static Class<?> loadClass(String className)
      throws ClassNotFoundException, LinkageError {
    return Class.forName(className, true, ClassLoaderProvider
        .getInstance().getClassLoader());
  }
  // List of interfaces which property values must implement.
  private final List<String> instanceOfInterfaces;
  // Private constructor.
  private ClassPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<String> defaultBehavior,
      List<String> instanceOfInterfaces) {
    super(d, String.class, propertyName, options, adminAction, defaultBehavior);
    this.instanceOfInterfaces = Collections
        .unmodifiableList(new LinkedList<String>(instanceOfInterfaces));
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitClass(this, p);
  }
  /**
   * {@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);
    try {
      validateValue(value);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
        return v.visitClass(this, value, p);
    }
    return value;
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * Get an unmodifiable list of classes which values of this property
   * must implement.
   *
   * @return Returns an unmodifiable list of classes which values of
   *         this property must implement.
   */
  public List<String> getInstanceOfInterface() {
    return instanceOfInterfaces;
  }
  /**
   * Validate and load the named class, and cast it to a subclass of
   * the specified class.
   *
   * @param <T>
   *          The requested type.
   * @param className
   *          The name of the class to validate and load.
   * @param instanceOf
   *          The class representing the requested type.
   * @return Returns the named class cast to a subclass of the
   *         specified class.
   * @throws IllegalPropertyValueException
   *           If the named class was invalid, could not be loaded, or
   *           did not implement the required interfaces.
   * @throws ClassCastException
   *           If the referenced class does not implement the
   *           requested type.
   */
  public <T> Class<? extends T> loadClass(String className,
      Class<T> instanceOf) throws IllegalPropertyValueException,
      ClassCastException {
    ensureNotNull(className, instanceOf);
    // Make sure that the named class is valid.
    validateClassName(className);
    Class<?> theClass = validateClassInterfaces(className);
    // Cast it to the required type.
    return theClass.asSubclass(instanceOf);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String normalizeValue(String value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    return value.trim();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(String value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    // Always make sure the name is a valid class name.
    validateClassName(value);
    // If additional validation is enabled then attempt to load the
    // class and
    // check the interfaces that it implements/extends.
    if (allowClassValidation) {
      validateClassInterfaces(value);
    }
  }
  // Make sure that named class implements the interfaces named by
  // this
  // definition.
  private Class<?> validateClassInterfaces(String className)
      throws IllegalPropertyValueException {
    String nvalue = className.trim();
    Class<?> theClass;
    try {
      theClass = loadClass(nvalue);
    } catch (Exception e) {
      // If the class cannot be loaded then it is an invalid value.
      throw new IllegalPropertyValueException(this, className);
    }
    for (String i : instanceOfInterfaces) {
      try {
        Class<?> instanceOfClass = loadClass(i);
        if (!instanceOfClass.isAssignableFrom(theClass)) {
          throw new IllegalPropertyValueException(this, className);
        try {
            validateValue(value);
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
      } catch (Exception e) {
        // Should not happen because the class was validated when the
        // property
        // definition was constructed.
        throw new IllegalPropertyValueException(this, className);
      }
        return value;
    }
    return theClass;
  }
  // Do some basic checks to make sure the string representation is
  // valid.
  private void validateClassName(String className)
      throws IllegalPropertyValueException {
    String nvalue = className.trim();
    if (!nvalue.matches(CLASS_RE)) {
      throw new IllegalPropertyValueException(this, className);
    /**
     * Get an unmodifiable list of classes which values of this property must
     * implement.
     *
     * @return Returns an unmodifiable list of classes which values of this
     *         property must implement.
     */
    public List<String> getInstanceOfInterface() {
        return instanceOfInterfaces;
    }
  }
    /**
     * Validate and load the named class, and cast it to a subclass of the
     * specified class.
     *
     * @param <T>
     *            The requested type.
     * @param className
     *            The name of the class to validate and load.
     * @param instanceOf
     *            The class representing the requested type.
     * @return Returns the named class cast to a subclass of the specified
     *         class.
     * @throws IllegalPropertyValueException
     *             If the named class was invalid, could not be loaded, or did
     *             not implement the required interfaces.
     * @throws ClassCastException
     *             If the referenced class does not implement the requested
     *             type.
     */
    public <T> Class<? extends T> loadClass(String className, Class<T> instanceOf)
            throws IllegalPropertyValueException, ClassCastException {
        ensureNotNull(className, instanceOf);
        // Make sure that the named class is valid.
        validateClassName(className);
        Class<?> theClass = validateClassInterfaces(className);
        // Cast it to the required type.
        return theClass.asSubclass(instanceOf);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String normalizeValue(String value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        return value.trim();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void validateValue(String value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // Always make sure the name is a valid class name.
        validateClassName(value);
        // If additional validation is enabled then attempt to load the
        // class and
        // check the interfaces that it implements/extends.
        if (allowClassValidation) {
            validateClassInterfaces(value);
        }
    }
    // Make sure that named class implements the interfaces named by
    // this
    // definition.
    private Class<?> validateClassInterfaces(String className) throws IllegalPropertyValueException {
        String nvalue = className.trim();
        Class<?> theClass;
        try {
            theClass = loadClass(nvalue);
        } catch (Exception e) {
            // If the class cannot be loaded then it is an invalid value.
            throw new IllegalPropertyValueException(this, className);
        }
        for (String i : instanceOfInterfaces) {
            try {
                Class<?> instanceOfClass = loadClass(i);
                if (!instanceOfClass.isAssignableFrom(theClass)) {
                    throw new IllegalPropertyValueException(this, className);
                }
            } catch (Exception e) {
                // Should not happen because the class was validated when the
                // property
                // definition was constructed.
                throw new IllegalPropertyValueException(this, className);
            }
        }
        return theClass;
    }
    // Do some basic checks to make sure the string representation is
    // valid.
    private void validateClassName(String className) throws IllegalPropertyValueException {
        String nvalue = className.trim();
        if (!nvalue.matches(CLASS_RE)) {
            throw new IllegalPropertyValueException(this, className);
        }
    }
}
opendj-admin/src/main/java/org/opends/server/admin/DNPropertyDefinition.java
@@ -27,214 +27,168 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import org.forgerock.opendj.ldap.DN;
import org.opends.server.types.DirectoryException;
/**
 * DN property definition.
 */
public final class DNPropertyDefinition extends PropertyDefinition<DN> {
  // Optional base DN which all valid values must be immediately
  // subordinate to.
  private final DN baseDN;
  /**
   * An interface for incrementally constructing DN property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<DN, DNPropertyDefinition> {
    // Optional base DN which all valid values must be immediately
    // subordinate to.
    private DN baseDN = null;
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
    }
    private final DN baseDN;
    /**
     * Set the base DN which all valid values must be immediately
     * subordinate to. By default there is no based DN.
     *
     * @param baseDN
     *          The string representation of the base DN.
     * @throws IllegalArgumentException
     *           If the provided string is not a valid DN string
     *           representation.
     * An interface for incrementally constructing DN property definitions.
     */
    public void setBaseDN(String baseDN)
        throws IllegalArgumentException {
      if (baseDN == null) {
        setBaseDN((DN) null);
      } else {
        try {
          setBaseDN(DN.decode(baseDN));
        } catch (DirectoryException e) {
          throw new IllegalArgumentException(e);
    public static class Builder extends AbstractBuilder<DN, DNPropertyDefinition> {
        // Optional base DN which all valid values must be immediately
        // subordinate to.
        private DN baseDN = null;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
      }
        /**
         * Set the base DN which all valid values must be immediately
         * subordinate to. By default there is no based DN.
         *
         * @param baseDN
         *            The string representation of the base DN.
         * @throws IllegalArgumentException
         *             If the provided string is not a valid DN string
         *             representation.
         */
        public void setBaseDN(String baseDN) throws IllegalArgumentException {
            if (baseDN == null) {
                setBaseDN((DN) null);
            } else {
                // TODO: is it correct to replace server DN.decode by SDK
                // valueOf ?
                setBaseDN(DN.valueOf(baseDN));
            }
        }
        /**
         * Set the base DN which all valid values must be immediately
         * subordinate to. By default there is no based DN.
         *
         * @param baseDN
         *            The base DN.
         */
        public void setBaseDN(DN baseDN) {
            this.baseDN = baseDN;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected DNPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<DN> defaultBehavior) {
            return new DNPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseDN);
        }
    }
    /**
     * Set the base DN which all valid values must be immediately
     * subordinate to. By default there is no based DN.
     * Create a DN property definition builder.
     *
     * @param baseDN
     *          The base DN.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new boolean property definition builder.
     */
    public void setBaseDN(DN baseDN) {
      this.baseDN = baseDN;
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private DNPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<DN> defaultBehavior, DN baseDN) {
        super(d, DN.class, propertyName, options, adminAction, defaultBehavior);
        this.baseDN = baseDN;
    }
    /**
     * Get the base DN which all valid values must be immediately subordinate
     * to, or <code>null</code> if there is no based DN.
     *
     * @return Returns the base DN which all valid values must be immediately
     *         subordinate to.
     */
    public DN getBaseDN() {
        return baseDN;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected DNPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<DN> defaultBehavior) {
      return new DNPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior, baseDN);
    public void validateValue(DN value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        if (baseDN != null) {
            DN parent = value.parent();
            if (parent == null) {
                parent = DN.rootDN();
            }
            if (!parent.equals(baseDN)) {
                throw new IllegalPropertyValueException(this, value);
            }
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public DN decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * Create a DN property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new boolean property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private DNPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<DN> defaultBehavior, DN baseDN) {
    super(d, DN.class, propertyName, options, adminAction, defaultBehavior);
    this.baseDN = baseDN;
  }
  /**
   * Get the base DN which all valid values must be immediately
   * subordinate to, or <code>null</code> if there is no based DN.
   *
   * @return Returns the base DN which all valid values must be
   *         immediately subordinate to.
   */
  public DN getBaseDN() {
    return baseDN;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(DN value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (baseDN != null) {
      DN parent = value.getParent();
      if (parent == null) {
        parent = DN.nullDN();
      }
      if (!parent.equals(baseDN)) {
        throw new IllegalPropertyValueException(this, value);
      }
        try {
            // TODO: is it correct to replace server DN.decode by SDK valueOf ?
            DN dn = DN.valueOf(value);
            validateValue(dn);
            return dn;
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public DN decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    try {
      DN dn = DN.decode(value);
      validateValue(dn);
      return dn;
    } catch (DirectoryException e) {
      throw new IllegalPropertyValueStringException(this, value);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitDN(this, p);
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, DN value, P p) {
        return v.visitDN(this, value, p);
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitDN(this, p);
  }
  /**
   * {@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);
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(DN o1, DN o2) {
        return o1.compareTo(o2);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/DecodingException.java
@@ -27,10 +27,7 @@
package org.opends.server.admin;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
@@ -51,7 +48,7 @@
   * @param message
   *          The message.
   */
  protected DecodingException(Message message) {
  protected DecodingException(LocalizableMessage message) {
    super(message);
  }
opendj-admin/src/main/java/org/opends/server/admin/DefaultBehaviorException.java
@@ -27,43 +27,34 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
/**
 * This exception is thrown when a property's default values cannot be
 * determined. This can occur in the following situations:
 * <ul>
 * <li>the property has a well-defined set of default values but they
 * are invalid according to the property's syntax
 * <li>the property inherits its default values from another managed
 * object but they could not be retrieved, perhaps because of a
 * communication problem.
 * <li>the property has a well-defined set of default values but they are
 * invalid according to the property's syntax
 * <li>the property inherits its default values from another managed object but
 * they could not be retrieved, perhaps because of a communication problem.
 * </ul>
 */
public class DefaultBehaviorException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -2542117466747573053L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = -2542117466747573053L;
  /**
   * Create a new default behavior exception with a cause.
   *
   * @param pd
   *          The property definition whose default values could not
   *          be determined.
   * @param cause
   *          The exception that prevented the default values from
   *          being determined.
   */
  public DefaultBehaviorException(PropertyDefinition<?> pd, Throwable cause) {
    super(pd, ERR_DEFAULT_BEHAVIOR_PROPERTY_EXCEPTION.get(pd.getName()), cause);
  }
    /**
     * Create a new default behavior exception with a cause.
     *
     * @param pd
     *            The property definition whose default values could not be
     *            determined.
     * @param cause
     *            The exception that prevented the default values from being
     *            determined.
     */
    public DefaultBehaviorException(PropertyDefinition<?> pd, Throwable cause) {
        super(pd, ERR_DEFAULT_BEHAVIOR_PROPERTY_EXCEPTION.get(pd.getName()), cause);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/DefinitionDecodingException.java
@@ -27,13 +27,9 @@
package org.opends.server.admin;
import static com.forgerock.opendj.ldap.AdminMessages.*;
import static org.opends.messages.AdminMessages.*;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * The requested managed object was found but its type could not be
@@ -75,9 +71,9 @@
  // Create the message.
  private static Message createMessage(AbstractManagedObjectDefinition<?, ?> d,
  private static LocalizableMessage createLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d,
      Reason reason) {
    Message ufn = d.getUserFriendlyName();
    LocalizableMessage ufn = d.getUserFriendlyName();
    switch (reason) {
    case NO_TYPE_INFORMATION:
      return ERR_DECODING_EXCEPTION_NO_TYPE_INFO.get(ufn);
@@ -106,7 +102,7 @@
   */
  public DefinitionDecodingException(AbstractManagedObjectDefinition<?, ?> d,
      Reason reason) {
    super(createMessage(d, reason));
    super(createLocalizableMessage(d, reason));
    this.d = d;
    this.reason = reason;
  }
opendj-admin/src/main/java/org/opends/server/admin/DurationPropertyDefinition.java
@@ -27,583 +27,501 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.*;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
/**
 * Duration property definition.
 * <p>
 * A duration property definition comprises of:
 * <ul>
 * <li>a <i>base unit</i> - specifies the minimum granularity which
 * can be used to specify duration property values. For example, if
 * the base unit is in seconds then values represented in milliseconds
 * will not be permitted. The default base unit is seconds
 * <li>an optional <i>maximum unit</i> - specifies the biggest
 * duration unit which can be used to specify duration property
 * values. Values presented in units greater than this unit will not
 * be permitted. There is no default maximum unit
 * <li><i>lower limit</i> - specifies the smallest duration
 * permitted by the property. The default lower limit is 0 and can
 * never be less than 0
 * <li>an optional <i>upper limit</i> - specifies the biggest
 * duration permitted by the property. By default, there is no upper
 * limit
 * <li>support for <i>unlimited</i> durations - when permitted users
 * can specify "unlimited" durations. These are represented using the
 * decoded value, -1, or the encoded string value "unlimited". By
 * default, unlimited durations are not permitted. In addition, it is
 * not possible to define an upper limit and support unlimited values.
 * <li>a <i>base unit</i> - specifies the minimum granularity which can be used
 * to specify duration property values. For example, if the base unit is in
 * seconds then values represented in milliseconds will not be permitted. The
 * default base unit is seconds
 * <li>an optional <i>maximum unit</i> - specifies the biggest duration unit
 * which can be used to specify duration property values. Values presented in
 * units greater than this unit will not be permitted. There is no default
 * maximum unit
 * <li><i>lower limit</i> - specifies the smallest duration permitted by the
 * property. The default lower limit is 0 and can never be less than 0
 * <li>an optional <i>upper limit</i> - specifies the biggest duration permitted
 * by the property. By default, there is no upper limit
 * <li>support for <i>unlimited</i> durations - when permitted users can specify
 * "unlimited" durations. These are represented using the decoded value, -1, or
 * the encoded string value "unlimited". By default, unlimited durations are not
 * permitted. In addition, it is not possible to define an upper limit and
 * support unlimited values.
 * </ul>
 * Decoded values are represented using <code>long</code> values in
 * the base unit defined for the duration property definition.
 * Decoded values are represented using <code>long</code> values in the base
 * unit defined for the duration property definition.
 */
public final class DurationPropertyDefinition extends PropertyDefinition<Long> {
  // String used to represent unlimited durations.
  private static final String UNLIMITED = "unlimited";
  // The base unit for this property definition.
  private final DurationUnit baseUnit;
  // The optional maximum unit for this property definition.
  private final DurationUnit maximumUnit;
  // The lower limit of the property value in milli-seconds.
  private final long lowerLimit;
  // The optional upper limit of the property value in milli-seconds.
  private final Long upperLimit;
  // Indicates whether this property allows the use of the "unlimited"
  // duration value (represented using a -1L or the string
  // "unlimited").
  private final boolean allowUnlimited;
  /**
   * An interface for incrementally constructing duration property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<Long, DurationPropertyDefinition> {
    // String used to represent unlimited durations.
    private static final String UNLIMITED = "unlimited";
    // The base unit for this property definition.
    private DurationUnit baseUnit = DurationUnit.SECONDS;
    private final DurationUnit baseUnit;
    // The optional maximum unit for this property definition.
    private DurationUnit maximumUnit = null;
    private final DurationUnit maximumUnit;
    // The lower limit of the property value in milli-seconds.
    private long lowerLimit = 0L;
    private final long lowerLimit;
    // The optional upper limit of the property value in
    // milli-seconds.
    private Long upperLimit = null;
    // The optional upper limit of the property value in milli-seconds.
    private final Long upperLimit;
    // Indicates whether this property allows the use of the
    // "unlimited" duration value (represented using a -1L or the
    // string "unlimited").
    private boolean allowUnlimited = false;
    // Private constructor
    private Builder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      super(d, propertyName);
    }
    // Indicates whether this property allows the use of the "unlimited"
    // duration value (represented using a -1L or the string
    // "unlimited").
    private final boolean allowUnlimited;
    /**
     * Set the base unit for this property definition (values
     * including limits are specified in this unit). By default a
     * duration property definition uses seconds.
     *
     * @param unit
     *          The string representation of the base unit (must not
     *          be <code>null</code>).
     * @throws IllegalArgumentException
     *           If the provided unit name did not correspond to a
     *           known duration unit, or if the base unit is bigger
     *           than the maximum unit.
     * An interface for incrementally constructing duration property
     * definitions.
     */
    public final void setBaseUnit(String unit) throws IllegalArgumentException {
      ensureNotNull(unit);
    public static class Builder extends AbstractBuilder<Long, DurationPropertyDefinition> {
      setBaseUnit(DurationUnit.getUnit(unit));
    }
        // The base unit for this property definition.
        private DurationUnit baseUnit = DurationUnit.SECONDS;
        // The optional maximum unit for this property definition.
        private DurationUnit maximumUnit = null;
        // The lower limit of the property value in milli-seconds.
        private long lowerLimit = 0L;
    /**
     * Set the base unit for this property definition (values
     * including limits are specified in this unit). By default a
     * duration property definition uses seconds.
     *
     * @param unit
     *          The base unit (must not be <code>null</code>).
     * @throws IllegalArgumentException
     *           If the provided base unit is bigger than the maximum
     *           unit.
     */
    public final void setBaseUnit(DurationUnit unit)
        throws IllegalArgumentException {
      ensureNotNull(unit);
        // The optional upper limit of the property value in
        // milli-seconds.
        private Long upperLimit = null;
      // Make sure that the base unit is not bigger than the maximum
      // unit.
      if (maximumUnit != null) {
        if (unit.getDuration() > maximumUnit.getDuration()) {
          throw new IllegalArgumentException(
              "Base unit greater than maximum unit");
        }
      }
        // Indicates whether this property allows the use of the
        // "unlimited" duration value (represented using a -1L or the
        // string "unlimited").
        private boolean allowUnlimited = false;
      this.baseUnit = unit;
    }
    /**
     * Set the maximum unit for this property definition. By default
     * there is no maximum unit.
     *
     * @param unit
     *          The string representation of the maximum unit, or
     *          <code>null</code> if there should not be a maximum
     *          unit.
     * @throws IllegalArgumentException
     *           If the provided unit name did not correspond to a
     *           known duration unit, or if the maximum unit is
     *           smaller than the base unit.
     */
    public final void setMaximumUnit(String unit)
        throws IllegalArgumentException {
      if (unit == null) {
        setMaximumUnit((DurationUnit) null);
      } else {
        setMaximumUnit(DurationUnit.getUnit(unit));
      }
    }
    /**
     * Set the maximum unit for this property definition. By default
     * there is no maximum unit.
     *
     * @param unit
     *          The maximum unit, or <code>null</code> if there
     *          should not be a maximum unit.
     * @throws IllegalArgumentException
     *           If the provided maximum unit is smaller than the base
     *           unit.
     */
    public final void setMaximumUnit(DurationUnit unit)
        throws IllegalArgumentException {
      if (unit != null) {
        // Make sure that the maximum unit is not smaller than the
        // base unit.
        if (unit.getDuration() < baseUnit.getDuration()) {
          throw new IllegalArgumentException(
              "Maximum unit smaller than base unit");
        }
      }
      this.maximumUnit = unit;
    }
    /**
     * Set the lower limit in milli-seconds.
     *
     * @param lowerLimit
     *          The new lower limit (must be >= 0) in milli-seconds.
     * @throws IllegalArgumentException
     *           If a negative lower limit was specified, or the lower
     *           limit is greater than the upper limit.
     */
    public final void setLowerLimit(long lowerLimit)
        throws IllegalArgumentException {
      if (lowerLimit < 0) {
        throw new IllegalArgumentException("Negative lower limit");
      }
      if (upperLimit != null && lowerLimit > upperLimit) {
        throw new IllegalArgumentException(
            "Lower limit greater than upper limit");
      }
      this.lowerLimit = lowerLimit;
    }
    /**
     * Set the lower limit using a string representation of the limit.
     * If the string does not specify a unit, the current base unit
     * will be used.
     *
     * @param lowerLimit
     *          The string representation of the new lower limit.
     * @throws IllegalArgumentException
     *           If the lower limit could not be parsed, or if a
     *           negative lower limit was specified, or the lower
     *           limit is greater than the upper limit.
     */
    public final void setLowerLimit(String lowerLimit)
        throws IllegalArgumentException {
      setLowerLimit(DurationUnit.parseValue(lowerLimit, baseUnit));
    }
    /**
     * Set the upper limit in milli-seconds.
     *
     * @param upperLimit
     *          The new upper limit in milli-seconds, or
     *          <code>null</code> if there is no upper limit.
     * @throws IllegalArgumentException
     *           If a negative upper limit was specified, or the lower
     *           limit is greater than the upper limit or unlimited
     *           durations are permitted.
     */
    public final void setUpperLimit(Long upperLimit)
        throws IllegalArgumentException {
      if (upperLimit != null) {
        if (upperLimit < 0) {
          throw new IllegalArgumentException("Negative upper limit");
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        if (lowerLimit > upperLimit) {
          throw new IllegalArgumentException(
              "Lower limit greater than upper limit");
        /**
         * Set the base unit for this property definition (values including
         * limits are specified in this unit). By default a duration property
         * definition uses seconds.
         *
         * @param unit
         *            The string representation of the base unit (must not be
         *            <code>null</code>).
         * @throws IllegalArgumentException
         *             If the provided unit name did not correspond to a known
         *             duration unit, or if the base unit is bigger than the
         *             maximum unit.
         */
        public final void setBaseUnit(String unit) throws IllegalArgumentException {
            ensureNotNull(unit);
            setBaseUnit(DurationUnit.getUnit(unit));
        }
        if (allowUnlimited) {
          throw new IllegalArgumentException(
              "Upper limit specified when unlimited durations are permitted");
        /**
         * Set the base unit for this property definition (values including
         * limits are specified in this unit). By default a duration property
         * definition uses seconds.
         *
         * @param unit
         *            The base unit (must not be <code>null</code>).
         * @throws IllegalArgumentException
         *             If the provided base unit is bigger than the maximum
         *             unit.
         */
        public final void setBaseUnit(DurationUnit unit) throws IllegalArgumentException {
            ensureNotNull(unit);
            // Make sure that the base unit is not bigger than the maximum
            // unit.
            if (maximumUnit != null) {
                if (unit.getDuration() > maximumUnit.getDuration()) {
                    throw new IllegalArgumentException("Base unit greater than maximum unit");
                }
            }
            this.baseUnit = unit;
        }
      }
      this.upperLimit = upperLimit;
        /**
         * Set the maximum unit for this property definition. By default there
         * is no maximum unit.
         *
         * @param unit
         *            The string representation of the maximum unit, or
         *            <code>null</code> if there should not be a maximum unit.
         * @throws IllegalArgumentException
         *             If the provided unit name did not correspond to a known
         *             duration unit, or if the maximum unit is smaller than the
         *             base unit.
         */
        public final void setMaximumUnit(String unit) throws IllegalArgumentException {
            if (unit == null) {
                setMaximumUnit((DurationUnit) null);
            } else {
                setMaximumUnit(DurationUnit.getUnit(unit));
            }
        }
        /**
         * Set the maximum unit for this property definition. By default there
         * is no maximum unit.
         *
         * @param unit
         *            The maximum unit, or <code>null</code> if there should not
         *            be a maximum unit.
         * @throws IllegalArgumentException
         *             If the provided maximum unit is smaller than the base
         *             unit.
         */
        public final void setMaximumUnit(DurationUnit unit) throws IllegalArgumentException {
            if (unit != null) {
                // Make sure that the maximum unit is not smaller than the
                // base unit.
                if (unit.getDuration() < baseUnit.getDuration()) {
                    throw new IllegalArgumentException("Maximum unit smaller than base unit");
                }
            }
            this.maximumUnit = unit;
        }
        /**
         * Set the lower limit in milli-seconds.
         *
         * @param lowerLimit
         *            The new lower limit (must be >= 0) in milli-seconds.
         * @throws IllegalArgumentException
         *             If a negative lower limit was specified, or the lower
         *             limit is greater than the upper limit.
         */
        public final void setLowerLimit(long lowerLimit) throws IllegalArgumentException {
            if (lowerLimit < 0) {
                throw new IllegalArgumentException("Negative lower limit");
            }
            if (upperLimit != null && lowerLimit > upperLimit) {
                throw new IllegalArgumentException("Lower limit greater than upper limit");
            }
            this.lowerLimit = lowerLimit;
        }
        /**
         * Set the lower limit using a string representation of the limit. If
         * the string does not specify a unit, the current base unit will be
         * used.
         *
         * @param lowerLimit
         *            The string representation of the new lower limit.
         * @throws IllegalArgumentException
         *             If the lower limit could not be parsed, or if a negative
         *             lower limit was specified, or the lower limit is greater
         *             than the upper limit.
         */
        public final void setLowerLimit(String lowerLimit) throws IllegalArgumentException {
            setLowerLimit(DurationUnit.parseValue(lowerLimit, baseUnit));
        }
        /**
         * Set the upper limit in milli-seconds.
         *
         * @param upperLimit
         *            The new upper limit in milli-seconds, or <code>null</code>
         *            if there is no upper limit.
         * @throws IllegalArgumentException
         *             If a negative upper limit was specified, or the lower
         *             limit is greater than the upper limit or unlimited
         *             durations are permitted.
         */
        public final void setUpperLimit(Long upperLimit) throws IllegalArgumentException {
            if (upperLimit != null) {
                if (upperLimit < 0) {
                    throw new IllegalArgumentException("Negative upper limit");
                }
                if (lowerLimit > upperLimit) {
                    throw new IllegalArgumentException("Lower limit greater than upper limit");
                }
                if (allowUnlimited) {
                    throw new IllegalArgumentException("Upper limit specified when unlimited durations are permitted");
                }
            }
            this.upperLimit = upperLimit;
        }
        /**
         * Set the upper limit using a string representation of the limit. If
         * the string does not specify a unit, the current base unit will be
         * used.
         *
         * @param upperLimit
         *            The string representation of the new upper limit, or
         *            <code>null</code> if there is no upper limit.
         * @throws IllegalArgumentException
         *             If the upper limit could not be parsed, or if the lower
         *             limit is greater than the upper limit.
         */
        public final void setUpperLimit(String upperLimit) throws IllegalArgumentException {
            if (upperLimit == null) {
                setUpperLimit((Long) null);
            } else {
                setUpperLimit(DurationUnit.parseValue(upperLimit, baseUnit));
            }
        }
        /**
         * Specify whether or not this property definition will allow unlimited
         * values (default is false).
         *
         * @param allowUnlimited
         *            <code>true</code> if the property will allow unlimited
         *            values, or <code>false</code> otherwise.
         * @throws IllegalArgumentException
         *             If unlimited values are to be permitted but there is an
         *             upper limit specified.
         */
        public final void setAllowUnlimited(boolean allowUnlimited) throws IllegalArgumentException {
            if (allowUnlimited && upperLimit != null) {
                throw new IllegalArgumentException("Upper limit specified when unlimited durations are permitted");
            }
            this.allowUnlimited = allowUnlimited;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected DurationPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d,
                String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<Long> defaultBehavior) {
            return new DurationPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, baseUnit,
                    maximumUnit, lowerLimit, upperLimit, allowUnlimited);
        }
    }
    /**
     * Set the upper limit using a string representation of the limit.
     * If the string does not specify a unit, the current base unit
     * will be used.
     * Create a duration property definition builder.
     *
     * @param upperLimit
     *          The string representation of the new upper limit, or
     *          <code>null</code> if there is no upper limit.
     * @throws IllegalArgumentException
     *           If the upper limit could not be parsed, or if the
     *           lower limit is greater than the upper limit.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new integer property definition builder.
     */
    public final void setUpperLimit(String upperLimit)
        throws IllegalArgumentException {
      if (upperLimit == null) {
        setUpperLimit((Long) null);
      } else {
        setUpperLimit(DurationUnit.parseValue(upperLimit, baseUnit));
      }
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private DurationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<Long> defaultBehavior, DurationUnit baseUnit, DurationUnit maximumUnit,
            Long lowerLimit, Long upperLimit, boolean allowUnlimited) {
        super(d, Long.class, propertyName, options, adminAction, defaultBehavior);
        this.baseUnit = baseUnit;
        this.maximumUnit = maximumUnit;
        this.lowerLimit = lowerLimit;
        this.upperLimit = upperLimit;
        this.allowUnlimited = allowUnlimited;
    }
    /**
     * Specify whether or not this property definition will allow
     * unlimited values (default is false).
     * Get the base unit for this property definition (values including limits
     * are specified in this unit).
     *
     * @param allowUnlimited
     *          <code>true</code> if the property will allow
     *          unlimited values, or <code>false</code> otherwise.
     * @throws IllegalArgumentException
     *           If unlimited values are to be permitted but there is
     *           an upper limit specified.
     * @return Returns the base unit for this property definition (values
     *         including limits are specified in this unit).
     */
    public final void setAllowUnlimited(boolean allowUnlimited)
        throws IllegalArgumentException {
      if (allowUnlimited && upperLimit != null) {
        throw new IllegalArgumentException(
            "Upper limit specified when unlimited durations are permitted");
      }
      this.allowUnlimited = allowUnlimited;
    public DurationUnit getBaseUnit() {
        return baseUnit;
    }
    /**
     * Get the maximum unit for this property definition if specified.
     *
     * @return Returns the maximum unit for this property definition, or
     *         <code>null</code> if there is no maximum unit.
     */
    public DurationUnit getMaximumUnit() {
        return maximumUnit;
    }
    /**
     * Get the lower limit in milli-seconds.
     *
     * @return Returns the lower limit in milli-seconds.
     */
    public long getLowerLimit() {
        return lowerLimit;
    }
    /**
     * Get the upper limit in milli-seconds.
     *
     * @return Returns the upper limit in milli-seconds, or <code>null</code> if
     *         there is no upper limit.
     */
    public Long getUpperLimit() {
        return upperLimit;
    }
    /**
     * Determine whether this property allows unlimited durations.
     *
     * @return Returns <code>true</code> if this this property allows unlimited
     *         durations.
     */
    public boolean isAllowUnlimited() {
        return allowUnlimited;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected DurationPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<Long> defaultBehavior) {
      return new DurationPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior, baseUnit, maximumUnit, lowerLimit,
          upperLimit, allowUnlimited);
    }
  }
    public void validateValue(Long value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        long nvalue = baseUnit.toMilliSeconds(value);
        if (!allowUnlimited && nvalue < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
            // unlimited allowed
        } else if (nvalue >= 0 && nvalue < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
        }
  /**
   * Create a duration property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new integer property definition builder.
   */
  public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private DurationPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName, EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<Long> defaultBehavior, DurationUnit baseUnit,
      DurationUnit maximumUnit, Long lowerLimit, Long upperLimit,
      boolean allowUnlimited) {
    super(d, Long.class, propertyName, options, adminAction, defaultBehavior);
    this.baseUnit = baseUnit;
    this.maximumUnit = maximumUnit;
    this.lowerLimit = lowerLimit;
    this.upperLimit = upperLimit;
    this.allowUnlimited = allowUnlimited;
  }
  /**
   * Get the base unit for this property definition (values including
   * limits are specified in this unit).
   *
   * @return Returns the base unit for this property definition
   *         (values including limits are specified in this unit).
   */
  public DurationUnit getBaseUnit() {
    return baseUnit;
  }
  /**
   * Get the maximum unit for this property definition if specified.
   *
   * @return Returns the maximum unit for this property definition, or
   *         <code>null</code> if there is no maximum unit.
   */
  public DurationUnit getMaximumUnit() {
    return maximumUnit;
  }
  /**
   * Get the lower limit in milli-seconds.
   *
   * @return Returns the lower limit in milli-seconds.
   */
  public long getLowerLimit() {
    return lowerLimit;
  }
  /**
   * Get the upper limit in milli-seconds.
   *
   * @return Returns the upper limit in milli-seconds, or
   *         <code>null</code> if there is no upper limit.
   */
  public Long getUpperLimit() {
    return upperLimit;
  }
  /**
   * Determine whether this property allows unlimited durations.
   *
   * @return Returns <code>true</code> if this this property allows
   *         unlimited durations.
   */
  public boolean isAllowUnlimited() {
    return allowUnlimited;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    long nvalue = baseUnit.toMilliSeconds(value);
    if (!allowUnlimited && nvalue < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
      // unlimited allowed
    } else if (nvalue >= 0 && nvalue < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
        if ((upperLimit != null) && (nvalue > upperLimit)) {
            throw new IllegalPropertyValueException(this, value);
        }
    }
    if ((upperLimit != null) && (nvalue > upperLimit)) {
      throw new IllegalPropertyValueException(this, value);
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String encodeValue(Long value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // Make sure that we correctly encode negative values as
        // "unlimited".
        if (allowUnlimited) {
            if (value < 0) {
                return UNLIMITED;
            }
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    // Make sure that we correctly encode negative values as
    // "unlimited".
    if (allowUnlimited) {
      if (value < 0) {
        return UNLIMITED;
      }
        // Encode the size value using the base unit.
        StringBuilder builder = new StringBuilder();
        builder.append(value);
        builder.append(' ');
        builder.append(baseUnit.toString());
        return builder.toString();
    }
    // Encode the size value using the base unit.
    StringBuilder builder = new StringBuilder();
    builder.append(value);
    builder.append(' ');
    builder.append(baseUnit.toString());
    return builder.toString();
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public Long decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
        // First check for the special "unlimited" value when necessary.
        if (allowUnlimited) {
            if (value.trim().equalsIgnoreCase(UNLIMITED)) {
                return -1L;
            }
        }
        // Parse the string representation.
        long ms;
        try {
            ms = DurationUnit.parseValue(value);
        } catch (NumberFormatException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public Long decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
        // Check the unit is in range - values must not be more granular
        // than the base unit.
        if ((ms % baseUnit.getDuration()) != 0) {
            throw new IllegalPropertyValueStringException(this, value);
        }
    // First check for the special "unlimited" value when necessary.
    if (allowUnlimited) {
      if (value.trim().equalsIgnoreCase(UNLIMITED)) {
        return -1L;
      }
        // Convert the value a long in the property's required unit.
        Long i = (long) baseUnit.fromMilliSeconds(ms);
        try {
            validateValue(i);
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
        return i;
    }
    // Parse the string representation.
    long ms;
    try {
      ms = DurationUnit.parseValue(value);
    } catch (NumberFormatException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitDuration(this, p);
    }
    // Check the unit is in range - values must not be more granular
    // than the base unit.
    if ((ms % baseUnit.getDuration()) != 0) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) {
        return v.visitDuration(this, value, p);
    }
    // Convert the value a long in the property's required unit.
    Long i = (long) baseUnit.fromMilliSeconds(ms);
    try {
      validateValue(i);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    return i;
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        super.toString(builder);
        builder.append(" baseUnit=");
        builder.append(baseUnit);
        if (maximumUnit != null) {
            builder.append(" maximumUnit=");
            builder.append(maximumUnit);
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitDuration(this, p);
  }
        builder.append(" lowerLimit=");
        builder.append(lowerLimit);
        builder.append("ms");
        if (upperLimit != null) {
            builder.append(" upperLimit=");
            builder.append(upperLimit);
            builder.append("ms");
        }
  /**
   * {@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);
    builder.append(" baseUnit=");
    builder.append(baseUnit);
    if (maximumUnit != null) {
      builder.append(" maximumUnit=");
      builder.append(maximumUnit);
        builder.append(" allowUnlimited=");
        builder.append(allowUnlimited);
    }
    builder.append(" lowerLimit=");
    builder.append(lowerLimit);
    builder.append("ms");
    if (upperLimit != null) {
      builder.append(" upperLimit=");
      builder.append(upperLimit);
      builder.append("ms");
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(Long o1, Long o2) {
        return o1.compareTo(o2);
    }
    builder.append(" allowUnlimited=");
    builder.append(allowUnlimited);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(Long o1, Long o2) {
    return o1.compareTo(o2);
  }
}
opendj-admin/src/main/java/org/opends/server/admin/EnumPropertyDefinition.java
@@ -26,11 +26,8 @@
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import java.util.HashMap;
@@ -38,238 +35,195 @@
import java.util.Map;
import java.util.MissingResourceException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Enumeration property definition.
 *
 * @param <E>
 *          The enumeration that should be used for values of this
 *          property definition.
 *            The enumeration that should be used for values of this property
 *            definition.
 */
public final class EnumPropertyDefinition<E extends Enum<E>> extends
    PropertyDefinition<E> {
  /**
   * An interface for incrementally constructing enumeration property
   * definitions.
   *
   * @param <E>
   *          The enumeration that should be used for values of this
   *          property definition.
   */
  public static class Builder<E extends Enum<E>> extends
      AbstractBuilder<E, EnumPropertyDefinition<E>> {
    // The enumeration class.
    private Class<E> enumClass;
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
      this.enumClass = null;
    }
public final class EnumPropertyDefinition<E extends Enum<E>> extends PropertyDefinition<E> {
    /**
     * Set the enumeration class which should be used for values of
     * this property definition.
     * An interface for incrementally constructing enumeration property
     * definitions.
     *
     * @param enumClass
     *          The enumeration class which should be used for values
     *          of this property definition.
     * @param <E>
     *            The enumeration that should be used for values of this
     *            property definition.
     */
    public final void setEnumClass(Class<E> enumClass) {
      this.enumClass = enumClass;
    public static class Builder<E extends Enum<E>> extends AbstractBuilder<E, EnumPropertyDefinition<E>> {
        // The enumeration class.
        private Class<E> enumClass;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
            this.enumClass = null;
        }
        /**
         * Set the enumeration class which should be used for values of this
         * property definition.
         *
         * @param enumClass
         *            The enumeration class which should be used for values of
         *            this property definition.
         */
        public final void setEnumClass(Class<E> enumClass) {
            this.enumClass = enumClass;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected EnumPropertyDefinition<E> buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<E> defaultBehavior) {
            // Make sure that the enumeration class has been defined.
            if (enumClass == null) {
                throw new IllegalStateException("Enumeration class undefined");
            }
            return new EnumPropertyDefinition<E>(d, propertyName, options, adminAction, defaultBehavior, enumClass);
        }
    }
    /**
     * Create an enumeration property definition builder.
     *
     * @param <E>
     *            The enumeration that should be used for values of this
     *            property definition.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new enumeration property definition builder.
     */
    public static <E extends Enum<E>> Builder<E> createBuilder(AbstractManagedObjectDefinition<?, ?> d,
            String propertyName) {
        return new Builder<E>(d, propertyName);
    }
    // The enumeration class.
    private final Class<E> enumClass;
    // Map used for decoding values.
    private final Map<String, E> decodeMap;
    // Private constructor.
    private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<E> defaultBehavior, Class<E> enumClass) {
        super(d, enumClass, propertyName, options, adminAction, defaultBehavior);
        this.enumClass = enumClass;
        // Initialize the decoding map.
        this.decodeMap = new HashMap<String, E>();
        for (E value : EnumSet.<E> allOf(enumClass)) {
            String s = value.toString().trim().toLowerCase();
            this.decodeMap.put(s, value);
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected EnumPropertyDefinition<E> buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<E> defaultBehavior) {
      // Make sure that the enumeration class has been defined.
      if (enumClass == null) {
        throw new IllegalStateException("Enumeration class undefined");
      }
      return new EnumPropertyDefinition<E>(d, propertyName, options,
          adminAction, defaultBehavior, enumClass);
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitEnum(this, p);
    }
  }
  /**
   * Create an enumeration property definition builder.
   *
   * @param <E>
   *          The enumeration that should be used for values of this
   *          property definition.
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new enumeration property definition builder.
   */
  public static <E extends Enum<E>> Builder<E> createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder<E>(d, propertyName);
  }
  // The enumeration class.
  private final Class<E> enumClass;
  // Map used for decoding values.
  private final Map<String, E> decodeMap;
  // Private constructor.
  private EnumPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName, EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<E> defaultBehavior, Class<E> enumClass) {
    super(d, enumClass, propertyName, options, adminAction, defaultBehavior);
    this.enumClass = enumClass;
    // Initialize the decoding map.
    this.decodeMap = new HashMap<String, E>();
    for (E value : EnumSet.<E> allOf(enumClass)) {
      String s = value.toString().trim().toLowerCase();
      this.decodeMap.put(s, value);
    /**
     * {@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);
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitEnum(this, p);
  }
  /**
   * {@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);
    String nvalue = value.trim().toLowerCase();
    E eValue = decodeMap.get(nvalue);
    if (eValue == null) {
      throw new IllegalPropertyValueStringException(this, value);
    } else {
      return eValue;
        String nvalue = value.trim().toLowerCase();
        E eValue = decodeMap.get(nvalue);
        if (eValue == null) {
            throw new IllegalPropertyValueStringException(this, value);
        } else {
            return eValue;
        }
    }
  }
  /**
   * Get the enumeration class used for values of this property.
   *
   * @return Returns the enumeration class used for values of this
   *         property.
   */
  public Class<E> getEnumClass() {
    return enumClass;
  }
  /**
   * Gets the synopsis of the specified enumeration value of this
   * enumeration property definition in the default locale.
   *
   * @param value
   *          The enumeration value.
   * @return Returns the synopsis of the specified enumeration value
   *         of this enumeration property definition in the default
   *         locale.
   */
  public final Message getValueSynopsis(E value) {
    return getValueSynopsis(Locale.getDefault(), value);
  }
  /**
   * Gets the synopsis of the specified enumeration value of this
   * enumeration property definition in the specified locale.
   *
   * @param value
   *          The enumeration value.
   * @param locale
   *          The locale.
   * @return Returns the synopsis of the specified enumeration value
   *         of this enumeration property definition in the specified
   *         locale.
   */
  public final Message getValueSynopsis(Locale locale, E value) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + getName()
        + ".syntax.enumeration.value." + value.toString()
        + ".synopsis";
    try {
      return resource.getMessage(getManagedObjectDefinition(),
          property, locale);
    } catch (MissingResourceException e) {
      return null;
    /**
     * Get the enumeration class used for values of this property.
     *
     * @return Returns the enumeration class used for values of this property.
     */
    public Class<E> getEnumClass() {
        return enumClass;
    }
  }
    /**
     * Gets the synopsis of the specified enumeration value of this enumeration
     * property definition in the default locale.
     *
     * @param value
     *            The enumeration value.
     * @return Returns the synopsis of the specified enumeration value of this
     *         enumeration property definition in the default locale.
     */
    public final LocalizableMessage getValueSynopsis(E value) {
        return getValueSynopsis(Locale.getDefault(), value);
    }
    /**
     * Gets the synopsis of the specified enumeration value of this enumeration
     * property definition in the specified locale.
     *
     * @param value
     *            The enumeration value.
     * @param locale
     *            The locale.
     * @return Returns the synopsis of the specified enumeration value of this
     *         enumeration property definition in the specified locale.
     */
    public final LocalizableMessage getValueSynopsis(Locale locale, E value) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + getName() + ".syntax.enumeration.value." + value.toString() + ".synopsis";
        try {
            return resource.getMessage(getManagedObjectDefinition(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public String normalizeValue(E value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    /**
     * {@inheritDoc}
     */
    @Override
    public String normalizeValue(E value) throws IllegalPropertyValueException {
        ensureNotNull(value);
    return value.toString().trim().toLowerCase();
  }
        return value.toString().trim().toLowerCase();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void validateValue(E value) throws IllegalPropertyValueException {
        ensureNotNull(value);
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(E value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    // No additional validation required.
  }
        // No additional validation required.
    }
}
opendj-admin/src/main/java/org/opends/server/admin/GenericConstraint.java
@@ -26,13 +26,11 @@
 */
package org.opends.server.admin;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.ClientConstraintHandler;
import org.opends.server.admin.client.CommunicationException;
@@ -43,181 +41,152 @@
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.config.ConfigException;
/**
 * A generic constraint which comprises of an underlying condition and
 * a description. The condition must evaluate to <code>true</code>
 * in order for a new managed object to be created or modified.
 * A generic constraint which comprises of an underlying condition and a
 * description. The condition must evaluate to <code>true</code> in order for a
 * new managed object to be created or modified.
 */
public class GenericConstraint extends Constraint {
  /**
   * The client-side constraint handler.
   */
  private class ClientHandler extends ClientConstraintHandler {
    /**
     * The client-side constraint handler.
     */
    private class ClientHandler extends ClientConstraintHandler {
    // Private constructor.
    private ClientHandler() {
      // No implementation required.
        // Private constructor.
        private ClientHandler() {
            // No implementation required.
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isAddAcceptable(ManagementContext context, ManagedObject<?> managedObject,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            if (!condition.evaluate(context, managedObject)) {
                unacceptableReasons.add(getSynopsis());
                return false;
            } else {
                return true;
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isModifyAcceptable(ManagementContext context, ManagedObject<?> managedObject,
                Collection<LocalizableMessage> unacceptableReasons) throws AuthorizationException, CommunicationException {
            if (!condition.evaluate(context, managedObject)) {
                unacceptableReasons.add(getSynopsis());
                return false;
            } else {
                return true;
            }
        }
    };
    /**
     * The server-side constraint handler.
     */
    private class ServerHandler extends ServerConstraintHandler {
        // Private constructor.
        private ServerHandler() {
            // No implementation required.
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isUsable(ServerManagedObject<?> managedObject, Collection<LocalizableMessage> unacceptableReasons)
                throws ConfigException {
            if (!condition.evaluate(managedObject)) {
                unacceptableReasons.add(getSynopsis());
                return false;
            } else {
                return true;
            }
        }
    };
    // The client-side constraint handler.
    private final ClientConstraintHandler clientHandler = new ClientHandler();
    // The condition associated with this constraint.
    private final Condition condition;
    // The managed object definition associated with this constraint.
    private final AbstractManagedObjectDefinition<?, ?> definition;
    // The constraint ID.
    private final int id;
    // The server-side constraint handler.
    private final ServerConstraintHandler serverHandler = new ServerHandler();
    /**
     * Creates a new generic constraint.
     *
     * @param definition
     *            The managed object definition associated with this constraint.
     * @param id
     *            The constraint ID.
     * @param condition
     *            The condition associated with this constraint.
     */
    public GenericConstraint(AbstractManagedObjectDefinition<?, ?> definition, int id, Condition condition) {
        this.definition = definition;
        this.id = id;
        this.condition = condition;
    }
    /**
     * {@inheritDoc}
     */
    public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
        return Collections.singleton(clientHandler);
    }
    /**
     * {@inheritDoc}
     */
    public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
        return Collections.singleton(serverHandler);
    }
    /**
     * Gets the synopsis of this constraint in the default locale.
     *
     * @return Returns the synopsis of this constraint in the default locale.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
    /**
     * Gets the synopsis of this constraint in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this constraint in the specified locale.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "constraint." + id + ".synopsis";
        return resource.getMessage(definition, property, locale);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isAddAcceptable(ManagementContext context,
        ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      if (!condition.evaluate(context, managedObject)) {
        unacceptableReasons.add(getSynopsis());
        return false;
      } else {
        return true;
      }
    protected void initialize() throws Exception {
        condition.initialize(definition);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isModifyAcceptable(ManagementContext context,
        ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
        throws AuthorizationException, CommunicationException {
      if (!condition.evaluate(context, managedObject)) {
        unacceptableReasons.add(getSynopsis());
        return false;
      } else {
        return true;
      }
    }
  };
  /**
   * The server-side constraint handler.
   */
  private class ServerHandler extends ServerConstraintHandler {
    // Private constructor.
    private ServerHandler() {
      // No implementation required.
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isUsable(ServerManagedObject<?> managedObject,
        Collection<Message> unacceptableReasons) throws ConfigException {
      if (!condition.evaluate(managedObject)) {
        unacceptableReasons.add(getSynopsis());
        return false;
      } else {
        return true;
      }
    }
  };
  // The client-side constraint handler.
  private final ClientConstraintHandler clientHandler = new ClientHandler();
  // The condition associated with this constraint.
  private final Condition condition;
  // The managed object definition associated with this constraint.
  private final AbstractManagedObjectDefinition<?, ?> definition;
  // The constraint ID.
  private final int id;
  // The server-side constraint handler.
  private final ServerConstraintHandler serverHandler = new ServerHandler();
  /**
   * Creates a new generic constraint.
   *
   * @param definition
   *          The managed object definition associated with this
   *          constraint.
   * @param id
   *          The constraint ID.
   * @param condition
   *          The condition associated with this constraint.
   */
  public GenericConstraint(AbstractManagedObjectDefinition<?, ?> definition,
      int id, Condition condition) {
    this.definition = definition;
    this.id = id;
    this.condition = condition;
  }
  /**
   * {@inheritDoc}
   */
  public Collection<ClientConstraintHandler> getClientConstraintHandlers() {
    return Collections.singleton(clientHandler);
  }
  /**
   * {@inheritDoc}
   */
  public Collection<ServerConstraintHandler> getServerConstraintHandlers() {
    return Collections.singleton(serverHandler);
  }
  /**
   * Gets the synopsis of this constraint in the default locale.
   *
   * @return Returns the synopsis of this constraint in the default
   *         locale.
   */
  public final Message getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this constraint in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this constraint in the specified
   *         locale.
   */
  public final Message getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "constraint." + id + ".synopsis";
    return resource.getMessage(definition, property, locale);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected void initialize() throws Exception {
    condition.initialize(definition);
  }
}
opendj-admin/src/main/java/org/opends/server/admin/IPAddressMaskPropertyDefinition.java
@@ -27,140 +27,108 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import org.opends.server.config.ConfigException;
import org.opends.server.types.AddressMask;
/**
 * IP address mask property definition.
 */
public final class IPAddressMaskPropertyDefinition extends
    PropertyDefinition<AddressMask> {
public final class IPAddressMaskPropertyDefinition extends PropertyDefinition<AddressMask> {
  /**
   * An interface for incrementally constructing IP address mask property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<AddressMask, IPAddressMaskPropertyDefinition> {
    /**
     * An interface for incrementally constructing IP address mask property
     * definitions.
     */
    public static class Builder extends AbstractBuilder<AddressMask, IPAddressMaskPropertyDefinition> {
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected IPAddressMaskPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d,
                String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<AddressMask> defaultBehavior) {
            return new IPAddressMaskPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior);
        }
    }
    /**
     * Create a IP address mask property definition builder.
     *
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new IP address mask property definition builder.
     */
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private IPAddressMaskPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<AddressMask> defaultBehavior) {
        super(d, AddressMask.class, propertyName, options, adminAction, defaultBehavior);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected IPAddressMaskPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d,
        String propertyName, EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<AddressMask> defaultBehavior) {
      return new IPAddressMaskPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior);
    public void validateValue(AddressMask value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // No additional validation required.
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public AddressMask decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * Create a IP address mask property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new IP address mask property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private IPAddressMaskPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<AddressMask> defaultBehavior) {
    super(d, AddressMask.class, propertyName, options, adminAction,
        defaultBehavior);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(AddressMask value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    // No additional validation required.
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public AddressMask decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    try {
      return AddressMask.decode(value);
    } catch (ConfigException e) {
      // TODO: it would be nice to throw the cause.
      throw new IllegalPropertyValueStringException(this, value);
        try {
            return AddressMask.decode(value);
        } catch (ConfigException e) {
            // TODO: it would be nice to throw the cause.
            throw new IllegalPropertyValueStringException(this, value);
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitIPAddressMask(this, p);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, AddressMask value, P p) {
        return v.visitIPAddressMask(this, value, p);
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitIPAddressMask(this, p);
  }
  /**
   * {@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());
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(AddressMask o1, AddressMask o2) {
        return o1.toString().compareTo(o2.toString());
    }
}
opendj-admin/src/main/java/org/opends/server/admin/IPAddressPropertyDefinition.java
@@ -27,162 +27,127 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.EnumSet;
/**
 * IP address property definition.
 */
public final class IPAddressPropertyDefinition extends
    PropertyDefinition<InetAddress> {
public final class IPAddressPropertyDefinition extends PropertyDefinition<InetAddress> {
  /**
   * An interface for incrementally constructing IP address property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<InetAddress, IPAddressPropertyDefinition> {
    /**
     * An interface for incrementally constructing IP address property
     * definitions.
     */
    public static class Builder extends AbstractBuilder<InetAddress, IPAddressPropertyDefinition> {
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected IPAddressPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d,
                String propertyName, EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<InetAddress> defaultBehavior) {
            return new IPAddressPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior);
        }
    }
    /**
     * Create a IP address property definition builder.
     *
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new IP address property definition builder.
     */
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private IPAddressPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<InetAddress> defaultBehavior) {
        super(d, InetAddress.class, propertyName, options, adminAction, defaultBehavior);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected IPAddressPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<InetAddress> defaultBehavior) {
      return new IPAddressPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior);
    public void validateValue(InetAddress value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // No additional validation required.
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public InetAddress decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * Create a IP address property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new IP address property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private IPAddressPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<InetAddress> defaultBehavior) {
    super(d, InetAddress.class, propertyName, options, adminAction,
        defaultBehavior);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(InetAddress value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    // No additional validation required.
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public InetAddress decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    try {
      return InetAddress.getByName(value);
    } catch (UnknownHostException e) {
      // TODO: it would be nice to throw the cause.
      throw new IllegalPropertyValueStringException(this, value);
        try {
            return InetAddress.getByName(value);
        } catch (UnknownHostException e) {
            // TODO: it would be nice to throw the cause.
            throw new IllegalPropertyValueStringException(this, value);
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String encodeValue(InetAddress value) throws IllegalPropertyValueException {
        // We should return the host name if it is available, or the IP
        // address if not.
  /**
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(InetAddress value)
      throws IllegalPropertyValueException {
    // We should return the host name if it is available, or the IP
    // address if not.
    // Unforunately, there is no InetAddress method for doing this, so
    // we have to resort to hacking at the toString() encoding.
    String s = value.toString();
    int i = s.indexOf('/');
    if (i > 0) {
      // Host address is before the forward slash.
      return s.substring(0, i);
    } else {
      return value.getHostAddress();
        // Unforunately, there is no InetAddress method for doing this, so
        // we have to resort to hacking at the toString() encoding.
        String s = value.toString();
        int i = s.indexOf('/');
        if (i > 0) {
            // Host address is before the forward slash.
            return s.substring(0, i);
        } else {
            return value.getHostAddress();
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitIPAddress(this, p);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, InetAddress value, P p) {
        return v.visitIPAddress(this, value, p);
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitIPAddress(this, p);
  }
  /**
   * {@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());
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(InetAddress o1, InetAddress o2) {
        return o1.getHostAddress().compareTo(o2.getHostAddress());
    }
}
opendj-admin/src/main/java/org/opends/server/admin/IllegalPropertyValueException.java
@@ -27,62 +27,50 @@
package org.opends.server.admin;
import static com.forgerock.opendj.ldap.AdminMessages.*;
import static org.opends.messages.AdminMessages.*;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Thrown to indicate that a property value was invalid according to
 * its associated property definition.
 * Thrown to indicate that a property value was invalid according to its
 * associated property definition.
 */
public class IllegalPropertyValueException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -3145632074909281823L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = -3145632074909281823L;
  // The illegal property value.
  private final Object value;
    // The illegal property value.
    private final Object value;
    /**
     * Create a new illegal property value exception.
     *
     * @param pd
     *            The property definition.
     * @param value
     *            The illegal property value.
     */
    public IllegalPropertyValueException(PropertyDefinition<?> pd, Object value) {
        super(pd, createMessage(pd, value));
        this.value = value;
    }
    /**
     * Get the illegal property value that caused the exception.
     *
     * @return Returns the illegal property value.
     */
    public final Object getIllegalValue() {
        return value;
    }
  /**
   * Create a new illegal property value exception.
   *
   * @param pd
   *          The property definition.
   * @param value
   *          The illegal property value.
   */
  public IllegalPropertyValueException(PropertyDefinition<?> pd, Object value) {
    super(pd, createMessage(pd, value));
    this.value = value;
  }
  /**
   * Get the illegal property value that caused the exception.
   *
   * @return Returns the illegal property value.
   */
  public final Object getIllegalValue() {
    return value;
  }
  // Create the message.
  private static Message createMessage(PropertyDefinition<?> pd, Object value) {
    PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(
        true);
    return ERR_ILLEGAL_PROPERTY_VALUE_EXCEPTION.get(String.valueOf(value), pd
        .getName(), builder.getUsage(pd));
  }
    // Create the message.
    private static LocalizableMessage createMessage(PropertyDefinition<?> pd, Object value) {
        PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(true);
        return ERR_ILLEGAL_PROPERTY_VALUE_EXCEPTION.get(String.valueOf(value), pd.getName(), builder.getUsage(pd));
    }
}
opendj-admin/src/main/java/org/opends/server/admin/IllegalPropertyValueStringException.java
@@ -27,63 +27,50 @@
package org.opends.server.admin;
import org.forgerock.i18n.LocalizableMessage;
import static org.opends.messages.AdminMessages.*;
import org.opends.messages.Message;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Thrown to indicate that a property value string was invalid
 * according to its associated property definition.
 * Thrown to indicate that a property value string was invalid according to its
 * associated property definition.
 */
public class IllegalPropertyValueStringException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -3145632074909281823L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = -3145632074909281823L;
  // The illegal property value string.
  private final String value;
    // The illegal property value string.
    private final String value;
    /**
     * Create a new illegal property value string exception.
     *
     * @param pd
     *            The property definition.
     * @param value
     *            The illegal property value string.
     */
    public IllegalPropertyValueStringException(PropertyDefinition<?> pd, String value) {
        super(pd, createMessage(pd, value));
        this.value = value;
    }
    /**
     * Get the illegal property value string that caused the exception.
     *
     * @return Returns the illegal property value string.
     */
    public final String getIllegalValueString() {
        return value;
    }
  /**
   * Create a new illegal property value string exception.
   *
   * @param pd
   *          The property definition.
   * @param value
   *          The illegal property value string.
   */
  public IllegalPropertyValueStringException(PropertyDefinition<?> pd,
      String value) {
    super(pd, createMessage(pd, value));
    this.value = value;
  }
  /**
   * Get the illegal property value string that caused the exception.
   *
   * @return Returns the illegal property value string.
   */
  public final String getIllegalValueString() {
    return value;
  }
  // Create the message.
  private static Message createMessage(PropertyDefinition<?> pd, String value) {
    PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(
        true);
    return ERR_ILLEGAL_PROPERTY_VALUE_STRING_EXCEPTION.get(value, pd.getName(),
        builder.getUsage(pd));
  }
    // Create the message.
    private static LocalizableMessage createMessage(PropertyDefinition<?> pd, String value) {
        PropertyDefinitionUsageBuilder builder = new PropertyDefinitionUsageBuilder(true);
        return ERR_ILLEGAL_PROPERTY_VALUE_STRING_EXCEPTION.get(value, pd.getName(), builder.getUsage(pd));
    }
}
opendj-admin/src/main/java/org/opends/server/admin/InstantiableRelationDefinition.java
@@ -26,11 +26,8 @@
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static org.opends.server.util.Validator.*;
import static com.forgerock.opendj.util.Validator.*;
import java.util.Collections;
import java.util.HashMap;
@@ -38,267 +35,227 @@
import java.util.Map;
import java.util.Set;
import org.forgerock.i18n.LocalizableMessage;
/**
 * A managed object composite relationship definition which represents
 * a composition of zero or more managed objects.
 * A managed object composite relationship definition which represents a
 * composition of zero or more managed objects.
 *
 * @param <C>
 *          The type of client managed object configuration that this
 *          relation definition refers to.
 *            The type of client managed object configuration that this relation
 *            definition refers to.
 * @param <S>
 *          The type of server managed object configuration that this
 *          relation definition refers to.
 *            The type of server managed object configuration that this relation
 *            definition refers to.
 */
public final class InstantiableRelationDefinition
    <C extends ConfigurationClient, S extends Configuration>
    extends RelationDefinition<C, S> {
public final class InstantiableRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends
        RelationDefinition<C, S> {
  /**
   * An interface for incrementally constructing instantiable relation
   * definitions.
   *
   * @param <C>
   *          The type of client managed object configuration that
   *          this relation definition refers to.
   * @param <S>
   *          The type of server managed object configuration that
   *          this relation definition refers to.
   */
  public static final class Builder
      <C extends ConfigurationClient, S extends Configuration>
      extends AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> {
    /**
     * An interface for incrementally constructing instantiable relation
     * definitions.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            relation definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            relation definition refers to.
     */
    public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends
            AbstractBuilder<C, S, InstantiableRelationDefinition<C, S>> {
        // The optional naming property definition.
        private PropertyDefinition<?> namingPropertyDefinition = null;
        // The plural name of the relation.
        private final String pluralName;
        // The optional default managed objects associated with this
        // instantiable relation definition.
        private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>();
        /**
         * Creates a new builder which can be used to incrementally build an
         * instantiable relation definition.
         *
         * @param pd
         *            The parent managed object definition.
         * @param name
         *            The name of the relation.
         * @param pluralName
         *            The plural name of the relation.
         * @param cd
         *            The child managed object definition.
         */
        public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName,
                AbstractManagedObjectDefinition<C, S> cd) {
            super(pd, name, cd);
            this.pluralName = pluralName;
        }
        /**
         * Adds the named default managed object to this instantiable relation
         * definition.
         *
         * @param name
         *            The name of the default managed object.
         * @param defaultManagedObject
         *            The default managed object.
         */
        public void setDefaultManagedObject(String name,
                DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
            this.defaultManagedObjects.put(name, defaultManagedObject);
        }
        /**
         * Sets the naming property for the instantiable relation definition.
         *
         * @param namingPropertyDefinition
         *            The property of the child managed object definition which
         *            should be used for naming, or <code>null</code> if this
         *            relation does not use a property for naming.
         */
        public void setNamingProperty(PropertyDefinition<?> namingPropertyDefinition) {
            ensureNotNull(namingPropertyDefinition);
            this.namingPropertyDefinition = namingPropertyDefinition;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected InstantiableRelationDefinition<C, S> buildInstance(Common<C, S> common) {
            return new InstantiableRelationDefinition<C, S>(common, pluralName, namingPropertyDefinition,
                    defaultManagedObjects);
        }
    }
    // The optional naming property definition.
    private PropertyDefinition<?> namingPropertyDefinition = null;
    private final PropertyDefinition<?> namingPropertyDefinition;
    // The plural name of the relation.
    private final String pluralName;
    // The optional default managed objects associated with this
    // instantiable relation definition.
    private final Map<String, DefaultManagedObject<? extends C, ? extends S>>
      defaultManagedObjects = new HashMap<String,
        DefaultManagedObject<? extends C, ? extends S>>();
    private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects;
    /**
     * Creates a new builder which can be used to incrementally build
     * an instantiable relation definition.
     *
     * @param pd
     *          The parent managed object definition.
     * @param name
     *          The name of the relation.
     * @param pluralName
     *          The plural name of the relation.
     * @param cd
     *          The child managed object definition.
     */
    public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name,
        String pluralName, AbstractManagedObjectDefinition<C, S> cd) {
      super(pd, name, cd);
      this.pluralName = pluralName;
    // Private constructor.
    private InstantiableRelationDefinition(Common<C, S> common, String pluralName,
            PropertyDefinition<?> namingPropertyDefinition,
            Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects) {
        super(common);
        this.pluralName = pluralName;
        this.namingPropertyDefinition = namingPropertyDefinition;
        this.defaultManagedObjects = defaultManagedObjects;
    }
    /**
     * Adds the named default managed object to this instantiable
     * relation definition.
     *
     * @param name
     *          The name of the default managed object.
     * @param defaultManagedObject
     *          The default managed object.
     */
    public void setDefaultManagedObject(String name,
        DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
      this.defaultManagedObjects.put(name, defaultManagedObject);
    }
    /**
     * Sets the naming property for the instantiable relation
     * definition.
     *
     * @param namingPropertyDefinition
     *          The property of the child managed object definition
     *          which should be used for naming, or <code>null</code>
     *          if this relation does not use a property for naming.
     */
    public void setNamingProperty(
        PropertyDefinition<?> namingPropertyDefinition) {
      ensureNotNull(namingPropertyDefinition);
      this.namingPropertyDefinition = namingPropertyDefinition;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected InstantiableRelationDefinition<C, S> buildInstance(
        Common<C, S> common) {
      return new InstantiableRelationDefinition<C, S>(common, pluralName,
          namingPropertyDefinition, defaultManagedObjects);
    public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) {
        return v.visitInstantiable(this, p);
    }
  }
  // The optional naming property definition.
  private final PropertyDefinition<?> namingPropertyDefinition;
  // The plural name of the relation.
  private final String pluralName;
  // The optional default managed objects associated with this
  // instantiable relation definition.
  private final Map<String, DefaultManagedObject<? extends C, ? extends S>>
    defaultManagedObjects;
  // Private constructor.
  private InstantiableRelationDefinition(Common<C, S> common,
      String pluralName,
      PropertyDefinition<?> namingPropertyDefinition,
      Map<String, DefaultManagedObject<? extends C, ? extends S>>
        defaultManagedObjects) {
    super(common);
    this.pluralName = pluralName;
    this.namingPropertyDefinition = namingPropertyDefinition;
    this.defaultManagedObjects = defaultManagedObjects;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) {
    return v.visitInstantiable(this, p);
  }
  /**
   * Gets the named default managed object associated with this
   * instantiable relation definition.
   *
   * @param name
   *          The name of the default managed object.
   * @return Returns the named default managed object.
   * @throws IllegalArgumentException
   *           If there is no default managed object associated with
   *           the provided name.
   */
  public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(
      String name) throws IllegalArgumentException {
    if (!defaultManagedObjects.containsKey(name)) {
      throw new IllegalArgumentException(
          "unrecognized default managed object \"" + name + "\"");
    /**
     * Gets the named default managed object associated with this instantiable
     * relation definition.
     *
     * @param name
     *            The name of the default managed object.
     * @return Returns the named default managed object.
     * @throws IllegalArgumentException
     *             If there is no default managed object associated with the
     *             provided name.
     */
    public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(String name)
            throws IllegalArgumentException {
        if (!defaultManagedObjects.containsKey(name)) {
            throw new IllegalArgumentException("unrecognized default managed object \"" + name + "\"");
        }
        return defaultManagedObjects.get(name);
    }
    return defaultManagedObjects.get(name);
  }
  /**
   * Gets the names of the default managed objects associated with
   * this instantiable relation definition.
   *
   * @return Returns an unmodifiable set containing the names of the
   *         default managed object.
   */
  public Set<String> getDefaultManagedObjectNames() {
    return Collections.unmodifiableSet(defaultManagedObjects.keySet());
  }
  /**
   * Get the property of the child managed object definition which
   * should be used for naming children.
   *
   * @return Returns the property of the child managed object
   *         definition which should be used for naming, or
   *         <code>null</code> if this relation does not use a
   *         property for naming.
   */
  public PropertyDefinition<?> getNamingPropertyDefinition() {
    return namingPropertyDefinition;
  }
  /**
   * Get the plural name of the relation.
   *
   * @return Returns the plural name of the relation.
   */
  public String getPluralName() {
    return pluralName;
  }
  /**
   * Gets the user friendly plural name of this relation definition in
   * the default locale.
   *
   * @return Returns the user friendly plural name of this relation
   *         definition in the default locale.
   */
  public Message getUserFriendlyPluralName() {
    return getUserFriendlyPluralName(Locale.getDefault());
  }
  /**
   * Gets the user friendly plural name of this relation definition in
   * the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the user friendly plural name of this relation
   *         definition in the specified locale.
   */
  public Message getUserFriendlyPluralName(Locale locale) {
    String property = "relation." + getName() + ".user-friendly-plural-name";
    return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
        getParentDefinition(), property, locale);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder) {
    builder.append("name=");
    builder.append(getName());
    builder.append(" type=collection parent=");
    builder.append(getParentDefinition().getName());
    builder.append(" child=");
    builder.append(getChildDefinition().getName());
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected void initialize() throws Exception {
    for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) {
      dmo.initialize();
    /**
     * Gets the names of the default managed objects associated with this
     * instantiable relation definition.
     *
     * @return Returns an unmodifiable set containing the names of the default
     *         managed object.
     */
    public Set<String> getDefaultManagedObjectNames() {
        return Collections.unmodifiableSet(defaultManagedObjects.keySet());
    }
  }
    /**
     * Get the property of the child managed object definition which should be
     * used for naming children.
     *
     * @return Returns the property of the child managed object definition which
     *         should be used for naming, or <code>null</code> if this relation
     *         does not use a property for naming.
     */
    public PropertyDefinition<?> getNamingPropertyDefinition() {
        return namingPropertyDefinition;
    }
    /**
     * Get the plural name of the relation.
     *
     * @return Returns the plural name of the relation.
     */
    public String getPluralName() {
        return pluralName;
    }
    /**
     * Gets the user friendly plural name of this relation definition in the
     * default locale.
     *
     * @return Returns the user friendly plural name of this relation definition
     *         in the default locale.
     */
    public LocalizableMessage getUserFriendlyPluralName() {
        return getUserFriendlyPluralName(Locale.getDefault());
    }
    /**
     * Gets the user friendly plural name of this relation definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the user friendly plural name of this relation definition
     *         in the specified locale.
     */
    public LocalizableMessage getUserFriendlyPluralName(Locale locale) {
        String property = "relation." + getName() + ".user-friendly-plural-name";
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        builder.append("name=");
        builder.append(getName());
        builder.append(" type=collection parent=");
        builder.append(getParentDefinition().getName());
        builder.append(" child=");
        builder.append(getChildDefinition().getName());
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected void initialize() throws Exception {
        for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) {
            dmo.initialize();
        }
    }
}
opendj-admin/src/main/java/org/opends/server/admin/IntegerPropertyDefinition.java
@@ -26,17 +26,14 @@
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import java.util.Locale;
import java.util.MissingResourceException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Integer property definition.
@@ -45,350 +42,297 @@
 * constraints. Support is provided for "unlimited" values. These are
 * represented using a negative value or using the string "unlimited".
 */
public final class IntegerPropertyDefinition extends
    PropertyDefinition<Integer> {
public final class IntegerPropertyDefinition extends PropertyDefinition<Integer> {
  // String used to represent unlimited.
  private static final String UNLIMITED = "unlimited";
  // The lower limit of the property value.
  private final int lowerLimit;
  // The optional upper limit of the property value.
  private final Integer upperLimit;
  // Indicates whether this property allows the use of the "unlimited" value
  // (represented using a -1 or the string "unlimited").
  private final boolean allowUnlimited;
  /**
   * An interface for incrementally constructing integer property definitions.
   */
  public static class Builder extends
      AbstractBuilder<Integer, IntegerPropertyDefinition> {
    // String used to represent unlimited.
    private static final String UNLIMITED = "unlimited";
    // The lower limit of the property value.
    private int lowerLimit = 0;
    private final int lowerLimit;
    // The optional upper limit of the property value.
    private Integer upperLimit = null;
    private final Integer upperLimit;
    // Indicates whether this property allows the use of the "unlimited" value
    // (represented using a -1 or the string "unlimited").
    private boolean allowUnlimited = false;
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
    }
    private final boolean allowUnlimited;
    /**
     * Set the lower limit.
     *
     * @param lowerLimit
     *          The new lower limit (must be >= 0).
     * @throws IllegalArgumentException
     *           If a negative lower limit was specified or the lower limit is
     *           greater than the upper limit.
     * An interface for incrementally constructing integer property definitions.
     */
    public final void setLowerLimit(int lowerLimit)
        throws IllegalArgumentException {
      if (lowerLimit < 0) {
        throw new IllegalArgumentException("Negative lower limit");
      }
      if (upperLimit != null && lowerLimit > upperLimit) {
        throw new IllegalArgumentException(
            "Lower limit greater than upper limit");
      }
      this.lowerLimit = lowerLimit;
    }
    public static class Builder extends AbstractBuilder<Integer, IntegerPropertyDefinition> {
        // The lower limit of the property value.
        private int lowerLimit = 0;
        // The optional upper limit of the property value.
        private Integer upperLimit = null;
    /**
     * Set the upper limit.
     *
     * @param upperLimit
     *          The new upper limit or <code>null</code> if there is no upper
     *          limit.
     */
    public final void setUpperLimit(Integer upperLimit) {
      if (upperLimit != null) {
        if (upperLimit < 0) {
          throw new IllegalArgumentException("Negative lower limit");
        // Indicates whether this property allows the use of the "unlimited"
        // value
        // (represented using a -1 or the string "unlimited").
        private boolean allowUnlimited = false;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        if (lowerLimit > upperLimit) {
          throw new IllegalArgumentException(
              "Lower limit greater than upper limit");
        /**
         * Set the lower limit.
         *
         * @param lowerLimit
         *            The new lower limit (must be >= 0).
         * @throws IllegalArgumentException
         *             If a negative lower limit was specified or the lower
         *             limit is greater than the upper limit.
         */
        public final void setLowerLimit(int lowerLimit) throws IllegalArgumentException {
            if (lowerLimit < 0) {
                throw new IllegalArgumentException("Negative lower limit");
            }
            if (upperLimit != null && lowerLimit > upperLimit) {
                throw new IllegalArgumentException("Lower limit greater than upper limit");
            }
            this.lowerLimit = lowerLimit;
        }
      }
      this.upperLimit = upperLimit;
        /**
         * Set the upper limit.
         *
         * @param upperLimit
         *            The new upper limit or <code>null</code> if there is no
         *            upper limit.
         */
        public final void setUpperLimit(Integer upperLimit) {
            if (upperLimit != null) {
                if (upperLimit < 0) {
                    throw new IllegalArgumentException("Negative lower limit");
                }
                if (lowerLimit > upperLimit) {
                    throw new IllegalArgumentException("Lower limit greater than upper limit");
                }
            }
            this.upperLimit = upperLimit;
        }
        /**
         * Specify whether or not this property definition will allow unlimited
         * values (default is false).
         *
         * @param allowUnlimited
         *            <code>true</code> if the property will allow unlimited
         *            values, or <code>false</code> otherwise.
         */
        public final void setAllowUnlimited(boolean allowUnlimited) {
            this.allowUnlimited = allowUnlimited;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected IntegerPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<Integer> defaultBehavior) {
            return new IntegerPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, lowerLimit,
                    upperLimit, allowUnlimited);
        }
    }
    /**
     * Specify whether or not this property definition will allow unlimited
     * values (default is false).
     * Create an integer property definition builder.
     *
     * @param allowUnlimited
     *          <code>true</code> if the property will allow unlimited values,
     *          or <code>false</code> otherwise.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new integer property definition builder.
     */
    public final void setAllowUnlimited(boolean allowUnlimited) {
      this.allowUnlimited = allowUnlimited;
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private IntegerPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<Integer> defaultBehavior, int lowerLimit, Integer upperLimit, boolean allowUnlimited) {
        super(d, Integer.class, propertyName, options, adminAction, defaultBehavior);
        this.lowerLimit = lowerLimit;
        this.upperLimit = upperLimit;
        this.allowUnlimited = allowUnlimited;
    }
    /**
     * Get the lower limit.
     *
     * @return Returns the lower limit.
     */
    public int getLowerLimit() {
        return lowerLimit;
    }
    /**
     * Get the upper limit.
     *
     * @return Returns the upper limit or <code>null</code> if there is no upper
     *         limit.
     */
    public Integer getUpperLimit() {
        return upperLimit;
    }
    /**
     * Gets the optional unit synopsis of this integer property definition in
     * the default locale.
     *
     * @return Returns the unit synopsis of this integer property definition in
     *         the default locale, or <code>null</code> if there is no unit
     *         synopsis.
     */
    public LocalizableMessage getUnitSynopsis() {
        return getUnitSynopsis(Locale.getDefault());
    }
    /**
     * Gets the optional unit synopsis of this integer property definition in
     * the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the unit synopsis of this integer property definition in
     *         the specified locale, or <code>null</code> if there is no unit
     *         synopsis.
     */
    public LocalizableMessage getUnitSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + getName() + ".syntax.integer.unit-synopsis";
        try {
            return resource.getMessage(getManagedObjectDefinition(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
    /**
     * Determine whether this property allows unlimited values.
     *
     * @return Returns <code>true</code> if this this property allows unlimited
     *         values.
     */
    public boolean isAllowUnlimited() {
        return allowUnlimited;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected IntegerPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<Integer> defaultBehavior) {
      return new IntegerPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior, lowerLimit, upperLimit, allowUnlimited);
    public void validateValue(Integer value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        if (!allowUnlimited && value < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
            // unlimited allowed
        } else if (value >= 0 && value < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
        }
        if ((upperLimit != null) && (value > upperLimit)) {
            throw new IllegalPropertyValueException(this, value);
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String encodeValue(Integer value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // Make sure that we correctly encode negative values as "unlimited".
        if (allowUnlimited) {
            if (value < 0) {
                return UNLIMITED;
            }
        }
  /**
   * Create an integer property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new integer property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private IntegerPropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<Integer> defaultBehavior, int lowerLimit,
      Integer upperLimit, boolean allowUnlimited) {
    super(d, Integer.class, propertyName, options, adminAction,
        defaultBehavior);
    this.lowerLimit = lowerLimit;
    this.upperLimit = upperLimit;
    this.allowUnlimited = allowUnlimited;
  }
  /**
   * Get the lower limit.
   *
   * @return Returns the lower limit.
   */
  public int getLowerLimit() {
    return lowerLimit;
  }
  /**
   * Get the upper limit.
   *
   * @return Returns the upper limit or <code>null</code> if there is no upper
   *         limit.
   */
  public Integer getUpperLimit() {
    return upperLimit;
  }
  /**
   * Gets the optional unit synopsis of this integer property
   * definition in the default locale.
   *
   * @return Returns the unit synopsis of this integer property
   *         definition in the default locale, or <code>null</code>
   *         if there is no unit synopsis.
   */
  public Message getUnitSynopsis() {
    return getUnitSynopsis(Locale.getDefault());
  }
  /**
   * Gets the optional unit synopsis of this integer property
   * definition in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the unit synopsis of this integer property
   *         definition in the specified locale, or <code>null</code>
   *         if there is no unit synopsis.
   */
  public Message getUnitSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + getName() + ".syntax.integer.unit-synopsis";
    try {
      return resource.getMessage(getManagedObjectDefinition(),
          property, locale);
    } catch (MissingResourceException e) {
      return null;
    }
  }
  /**
   * Determine whether this property allows unlimited values.
   *
   * @return Returns <code>true</code> if this this property allows unlimited
   *         values.
   */
  public boolean isAllowUnlimited() {
    return allowUnlimited;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(Integer value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (!allowUnlimited && value < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
    // unlimited allowed
    } else if (value >= 0 && value < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
        return value.toString();
    }
    if ((upperLimit != null) && (value > upperLimit)) {
      throw new IllegalPropertyValueException(this, value);
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public Integer decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
  /**
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(Integer value)
          throws IllegalPropertyValueException {
    ensureNotNull(value);
        if (allowUnlimited) {
            if (value.trim().equalsIgnoreCase(UNLIMITED)) {
                return -1;
            }
        }
    // Make sure that we correctly encode negative values as "unlimited".
    if (allowUnlimited) {
      if (value < 0) {
        return UNLIMITED;
      }
        Integer i;
        try {
            i = Integer.valueOf(value);
        } catch (NumberFormatException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
        try {
            validateValue(i);
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
        return i;
    }
    return value.toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Integer decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    if (allowUnlimited) {
      if (value.trim().equalsIgnoreCase(UNLIMITED)) {
        return -1;
      }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitInteger(this, p);
    }
    Integer i;
    try {
      i = Integer.valueOf(value);
    } catch (NumberFormatException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, Integer value, P p) {
        return v.visitInteger(this, value, p);
    }
    try {
      validateValue(i);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        super.toString(builder);
        builder.append(" lowerLimit=");
        builder.append(lowerLimit);
        if (upperLimit != null) {
            builder.append(" upperLimit=");
            builder.append(upperLimit);
        }
        builder.append(" allowUnlimited=");
        builder.append(allowUnlimited);
    }
    return i;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitInteger(this, p);
  }
  /**
   * {@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);
    builder.append(" lowerLimit=");
    builder.append(lowerLimit);
    if (upperLimit != null) {
      builder.append(" upperLimit=");
      builder.append(upperLimit);
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1.compareTo(o2);
    }
    builder.append(" allowUnlimited=");
    builder.append(allowUnlimited);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(Integer o1, Integer o2) {
    return o1.compareTo(o2);
  }
}
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectAlreadyExistsException.java
@@ -27,30 +27,23 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * A managed object could not be created because there is an existing
 * managed object with the same name.
 * A managed object could not be created because there is an existing managed
 * object with the same name.
 */
public final class ManagedObjectAlreadyExistsException extends
    OperationsException {
public final class ManagedObjectAlreadyExistsException extends OperationsException {
  /**
   * Version ID required by serializable classes.
   */
  private static final long serialVersionUID = -2344653674171609366L;
    /**
     * Version ID required by serializable classes.
     */
    private static final long serialVersionUID = -2344653674171609366L;
  /**
   * Create a managed object already exists exception.
   */
  public ManagedObjectAlreadyExistsException() {
    super(ERR_MANAGED_OBJECT_ALREADY_EXISTS_EXCEPTION.get());
  }
    /**
     * Create a managed object already exists exception.
     */
    public ManagedObjectAlreadyExistsException() {
        super(ERR_MANAGED_OBJECT_ALREADY_EXISTS_EXCEPTION.get());
    }
}
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectDefinitionI18NResource.java
@@ -131,9 +131,9 @@
   *           If the provided managed object definition was the
   *           {@link TopCfgDefn}.
   */
  public LocalizableMessage getLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d, String key)
  public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d, String key)
      throws MissingResourceException, UnsupportedOperationException {
    return getLocalizableMessage(d, key, Locale.getDefault(), (String[]) null);
    return getMessage(d, key, Locale.getDefault(), (String[]) null);
  }
@@ -156,10 +156,10 @@
   *           If the provided managed object definition was the
   *           {@link TopCfgDefn}.
   */
  public LocalizableMessage getLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d,
  public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d,
      String key, Locale locale) throws MissingResourceException,
      UnsupportedOperationException {
    return getLocalizableMessage(d, key, locale, (String[]) null);
    return getMessage(d, key, locale, (String[]) null);
  }
@@ -185,7 +185,7 @@
   *           If the provided managed object definition was the
   *           {@link TopCfgDefn}.
   */
  public LocalizableMessage getLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d,
  public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d,
      String key, Locale locale, String... args)
      throws MissingResourceException, UnsupportedOperationException {
    ResourceBundle resource = getResourceBundle(d, locale);
@@ -219,10 +219,10 @@
   *           If the provided managed object definition was the
   *           {@link TopCfgDefn}.
   */
  public LocalizableMessage getLocalizableMessage(AbstractManagedObjectDefinition<?, ?> d,
  public LocalizableMessage getMessage(AbstractManagedObjectDefinition<?, ?> d,
      String key, String... args) throws MissingResourceException,
      UnsupportedOperationException {
    return getLocalizableMessage(d, key, Locale.getDefault(), args);
    return getMessage(d, key, Locale.getDefault(), args);
  }
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectNotFoundException.java
@@ -27,41 +27,32 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * The requested managed object could not be located.
 */
public class ManagedObjectNotFoundException extends OperationsException {
  /**
   * Version ID required by serializable classes.
   */
  private static final long serialVersionUID = -477551786551892978L;
    /**
     * Version ID required by serializable classes.
     */
    private static final long serialVersionUID = -477551786551892978L;
    /**
     * Create a managed object not found exception.
     */
    public ManagedObjectNotFoundException() {
        super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get());
    }
  /**
   * Create a managed object not found exception.
   */
  public ManagedObjectNotFoundException() {
    super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get());
  }
  /**
   * Create a managed object not found exception with the specified
   * cause.
   *
   * @param cause
   *          The cause of this exception.
   */
  public ManagedObjectNotFoundException(Throwable cause) {
    super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get(), cause);
  }
    /**
     * Create a managed object not found exception with the specified cause.
     *
     * @param cause
     *            The cause of this exception.
     */
    public ManagedObjectNotFoundException(Throwable cause) {
        super(ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION.get(), cause);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/ManagedObjectPath.java
@@ -36,11 +36,14 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.admin.std.server.RootCfg;
import org.forgerock.opendj.admin.client.RootCfgClient;
import org.forgerock.opendj.admin.meta.RootCfgDefn;
import org.forgerock.opendj.admin.server.RootCfg;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.RDN;
import org.forgerock.opendj.ldap.schema.AttributeType;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.*;
import org.opends.server.types.DirectoryException;
/**
@@ -138,7 +141,7 @@
    // Create a new DN builder.
    private DNSerializer() {
      this.dn = DN.nullDN();
      this.dn = DN.rootDN();
      this.profile = LDAPProfile.getInstance();
    }
opendj-admin/src/main/java/org/opends/server/admin/OperationsException.java
@@ -27,46 +27,38 @@
package org.opends.server.admin;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Exceptions thrown as a result of errors that occurred when reading,
 * listing, and modifying managed objects.
 * Exceptions thrown as a result of errors that occurred when reading, listing,
 * and modifying managed objects.
 */
public abstract class OperationsException extends AdminException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 6329910102360262187L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = 6329910102360262187L;
    /**
     * Create an operations exception with a message and cause.
     *
     * @param message
     *            The message.
     * @param cause
     *            The cause.
     */
    protected OperationsException(LocalizableMessage message, Throwable cause) {
        super(message, cause);
    }
  /**
   * Create an operations exception with a message and cause.
   *
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  protected OperationsException(Message message, Throwable cause) {
    super(message, cause);
  }
  /**
   * Create an operations exception with a message.
   *
   * @param message
   *          The message.
   */
  protected OperationsException(Message message) {
    super(message);
  }
    /**
     * Create an operations exception with a message.
     *
     * @param message
     *            The message.
     */
    protected OperationsException(LocalizableMessage message) {
        super(message);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyDefinition.java
@@ -27,8 +27,6 @@
package org.opends.server.admin;
import static com.forgerock.opendj.util.Validator.*;
import java.util.Comparator;
@@ -39,637 +37,546 @@
import org.forgerock.i18n.LocalizableMessage;
/**
 * 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.
 *
 * @param <T>
 *          The data-type of values of the property.
 *            The data-type of values of the property.
 */
public abstract class PropertyDefinition<T> implements Comparator<T>,
    Comparable<PropertyDefinition<?>> {
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>> {
    /**
     * 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 administrator action.
        private AdministratorAction adminAction;
        // 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.adminAction = new AdministratorAction(AdministratorAction.Type.NONE, d, propertyName);
            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, adminAction, defaultBehavior);
        }
        /**
         * Set the administrator action.
         *
         * @param adminAction
         *            The administrator action.
         */
        public final void setAdministratorAction(AdministratorAction adminAction) {
            ensureNotNull(adminAction);
            this.adminAction = adminAction;
        }
        /**
         * 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 adminAction
         *            The administrator action.
         * @param defaultBehavior
         *            The default behavior provider.
         * @return The new property definition.
         */
        protected abstract D buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<T> defaultBehavior);
    }
    // The administrator action.
    private AdministratorAction adminAction;
    private final AdministratorAction adminAction;
    // The default behavior provider.
    private DefaultBehaviorProvider<T> defaultBehavior;
    private final DefaultBehaviorProvider<T> defaultBehavior;
    // The abstract managed object
    private final AbstractManagedObjectDefinition<?, ?> definition;
    // The options applicable to this definition.
    private final EnumSet<PropertyOption> options;
    // Options applicable to this definition.
    private final Set<PropertyOption> options;
    // The name of this property definition.
    // The property name.
    private final String propertyName;
    // The property value class.
    private final Class<T> theClass;
    /**
     * Create a property definition builder.
     * Create a property definition.
     *
     * @param d
     *          The managed object definition associated with this
     *          property definition.
     *            The managed object definition associated with this property
     *            definition.
     * @param theClass
     *            The property value class.
     * @param propertyName
     *          The property name.
     */
    protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      this.definition = d;
      this.propertyName = propertyName;
      this.options = EnumSet.noneOf(PropertyOption.class);
      this.adminAction = new AdministratorAction(AdministratorAction.Type.NONE,
          d, propertyName);
      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, adminAction,
          defaultBehavior);
    }
    /**
     * Set the administrator action.
     *
     *            The property name.
     * @param options
     *            Options applicable to this definition.
     * @param adminAction
     *          The administrator action.
     */
    public final void setAdministratorAction(AdministratorAction adminAction) {
      ensureNotNull(adminAction);
      this.adminAction = adminAction;
    }
    /**
     * Set the default behavior provider.
     *
     *            The administrator action.
     * @param defaultBehavior
     *          The default behavior provider.
     *            The default behavior provider.
     */
    public final void setDefaultBehaviorProvider(
        DefaultBehaviorProvider<T> defaultBehavior) {
      ensureNotNull(defaultBehavior);
      this.defaultBehavior = defaultBehavior;
    protected PropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, Class<T> theClass, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction, DefaultBehaviorProvider<T> defaultBehavior) {
        ensureNotNull(d, theClass, propertyName);
        ensureNotNull(options, adminAction, defaultBehavior);
        this.definition = d;
        this.theClass = theClass;
        this.propertyName = propertyName;
        this.options = EnumSet.copyOf(options);
        this.adminAction = adminAction;
        this.defaultBehavior = defaultBehavior;
    }
    /**
     * Apply a visitor to 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 definition visitor.
     * @param p
     *            Optional additional visitor parameter.
     * @return Returns a result as specified by the visitor.
     */
    public abstract <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p);
    /**
     * Add a property definition option.
     * 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);
    /**
     * 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)}.
     * <p>
     * This method guarantees the following expression is always
     * <code>true</code>:
     *
     * <pre>
     *  PropertyDefinition d;
     *  x == d.cast(x);
     * </pre>
     *
     * @param object
     *            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.
     */
    public final T castValue(Object object) throws ClassCastException {
        return theClass.cast(object);
    }
    /**
     * 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>
     * 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.
     */
    public final int compareTo(PropertyDefinition<?> o) {
        int rc = propertyName.compareTo(o.propertyName);
        if (rc == 0) {
            rc = theClass.getName().compareTo(o.theClass.getName());
        }
        return rc;
    }
    /**
     * Parse and validate a string representation of a property value.
     *
     * @param value
     *            The property string value (must not be <code>null</code>).
     * @return Returns the decoded property value.
     * @throws IllegalPropertyValueStringException
     *             If the property value string is invalid.
     */
    public abstract T decodeValue(String value) throws IllegalPropertyValueStringException;
    /**
     * Encode the provided property value into its string representation.
     * <p>
     * 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>).
     * @return Returns the encoded property string value.
     * @throws IllegalPropertyValueException
     *             If the property value is invalid.
     */
    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.
     *
     * @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.
     * @see java.lang.Object#equals(java.lang.Object)
     * @see java.lang.Object#hashCode()
     */
    @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;
        }
    }
    /**
     * Get the administrator action associated with this property definition.
     * The administrator action describes any action which the administrator
     * must perform in order for changes to this property to take effect.
     *
     * @return Returns the administrator action associated with this property
     *         definition.
     */
    public final AdministratorAction getAdministratorAction() {
        return adminAction;
    }
    /**
     * Get the default behavior provider associated with this property
     * definition.
     *
     * @return Returns the default behavior provider associated with this
     *         property definition.
     */
    public final DefaultBehaviorProvider<T> getDefaultBehaviorProvider() {
        return defaultBehavior;
    }
    /**
     * Gets the optional description of this property definition in the default
     * locale.
     *
     * @return Returns the description of this property definition in the
     *         default locale, or <code>null</code> if there is no description.
     */
    public final LocalizableMessage getDescription() {
        return getDescription(Locale.getDefault());
    }
    /**
     * Gets the optional description of this property definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the description of this property definition in the
     *         specified locale, or <code>null</code> if there is no
     *         description.
     */
    public final LocalizableMessage 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;
    }
    /**
     * Get the name of the property.
     *
     * @return Returns the name of the property.
     */
    public final String getName() {
        return propertyName;
    }
    /**
     * Gets the synopsis of this property definition in the default locale.
     *
     * @return Returns the synopsis of this property definition in the default
     *         locale.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
    /**
     * Gets the synopsis of this property definition in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this property definition in the specified
     *         locale.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + propertyName + ".synopsis";
        return resource.getMessage(definition, property, locale);
    }
    /**
     * 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.
     */
    @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.
     *
     * @param option
     *          The property option.
     *            The option to test.
     * @return Returns <code>true</code> if the option is set, or
     *         <code>false</code> otherwise.
     */
    public final void setOption(PropertyOption option) {
      ensureNotNull(option);
      options.add(option);
    public final boolean hasOption(PropertyOption option) {
        return options.contains(option);
    }
    /**
     * Build a property definition based on the properties of this
     * builder.
     * 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)}.
     * <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 d
     *          The managed object definition associated with this
     *          property definition.
     * @param propertyName
     *          The property name.
     * @param options
     *          Options applicable to this definition.
     * @param adminAction
     *          The administrator action.
     * @param defaultBehavior
     *          The default behavior provider.
     * @return The new property definition.
     * @param value
     *            The property value to be normalized.
     * @return Returns the normalized property value.
     * @throws IllegalPropertyValueException
     *             If the property value is invalid.
     */
    protected abstract D buildInstance(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName, EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<T> defaultBehavior);
  }
    public String normalizeValue(T value) throws IllegalPropertyValueException {
        ensureNotNull(value);
  // The administrator action.
  private final AdministratorAction adminAction;
  // 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 adminAction
   *          The administrator action.
   * @param defaultBehavior
   *          The default behavior provider.
   */
  protected PropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      Class<T> theClass, String propertyName, EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<T> defaultBehavior) {
    ensureNotNull(d, theClass, propertyName);
    ensureNotNull(options, adminAction, defaultBehavior);
    this.definition = d;
    this.theClass = theClass;
    this.propertyName = propertyName;
    this.options = EnumSet.copyOf(options);
    this.adminAction = adminAction;
    this.defaultBehavior = defaultBehavior;
  }
  /**
   * Apply a visitor to 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 definition visitor.
   * @param p
   *          Optional additional visitor parameter.
   * @return Returns a result as specified by the visitor.
   */
  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);
  /**
   * 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)}.
   * <p>
   * This method guarantees the following expression is always
   * <code>true</code>:
   *
   * <pre>
   *  PropertyDefinition d;
   *  x == d.cast(x);
   * </pre>
   *
   * @param object
   *          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.
   */
  public final T castValue(Object object) throws ClassCastException {
    return theClass.cast(object);
  }
  /**
   * 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>
   * 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.
   */
  public final int compareTo(PropertyDefinition<?> o) {
    int rc = propertyName.compareTo(o.propertyName);
    if (rc == 0) {
      rc = theClass.getName().compareTo(o.theClass.getName());
        return encodeValue(value);
    }
    return rc;
  }
  /**
   * Parse and validate a string representation of a property value.
   *
   * @param value
   *          The property string value (must not be <code>null</code>).
   * @return Returns the decoded property value.
   * @throws IllegalPropertyValueStringException
   *           If the property value string is invalid.
   */
  public abstract T decodeValue(String value)
      throws IllegalPropertyValueStringException;
  /**
   * Encode the provided property value into its string
   * representation.
   * <p>
   * 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>).
   * @return Returns the encoded property string value.
   * @throws IllegalPropertyValueException
   *           If the property value is invalid.
   */
  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.
   *
   * @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.
   * @see java.lang.Object#equals(java.lang.Object)
   * @see java.lang.Object#hashCode()
   */
  @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;
    /**
     * 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();
    }
  }
  /**
   * Get the administrator action associated with this property
   * definition. The administrator action describes any action which
   * the administrator must perform in order for changes to this
   * property to take effect.
   *
   * @return Returns the administrator action associated with this
   *         property definition.
   */
  public final AdministratorAction getAdministratorAction() {
    return adminAction;
  }
  /**
   * Get the default behavior provider associated with this property
   * definition.
   *
   * @return Returns the default behavior provider associated with
   *         this property definition.
   */
  public final DefaultBehaviorProvider<T> getDefaultBehaviorProvider() {
    return defaultBehavior;
  }
  /**
   * Gets the optional description of this property definition in the
   * default locale.
   *
   * @return Returns the description of this property definition in
   *         the default locale, or <code>null</code> if there is no
   *         description.
   */
  public final LocalizableMessage getDescription() {
    return getDescription(Locale.getDefault());
  }
  /**
   * Gets the optional description of this property definition in the
   * specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the description of this property definition in
   *         the specified locale, or <code>null</code> if there is
   *         no description.
   */
  public final LocalizableMessage getDescription(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName + ".description";
    try {
      return resource.getLocalizableMessage(definition, property, locale);
    } catch (MissingResourceException e) {
      return null;
    /**
     * 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.
     */
    public void toString(StringBuilder builder) {
        builder.append(propertyName);
    }
  }
    /**
     * 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.
     */
    public abstract void validateValue(T value) throws IllegalPropertyValueException;
  /**
   * 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;
  }
  /**
   * Get the name of the property.
   *
   * @return Returns the name of the property.
   */
  public final String getName() {
    return propertyName;
  }
  /**
   * Gets the synopsis of this property definition in the default
   * locale.
   *
   * @return Returns the synopsis of this property definition in the
   *         default locale.
   */
  public final LocalizableMessage getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this property definition in the specified
   * locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this property definition in the
   *         specified locale.
   */
  public final LocalizableMessage getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + propertyName + ".synopsis";
    return resource.getLocalizableMessage(definition, property, locale);
  }
  /**
   * 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.
   */
  @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.
   *
   * @param option
   *          The option to test.
   * @return Returns <code>true</code> if the option is set, or
   *         <code>false</code> otherwise.
   */
  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.
   * <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)}.
   * <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.
   * @return Returns the normalized property value.
   * @throws IllegalPropertyValueException
   *           If the property value is invalid.
   */
  public String normalizeValue(T value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    return encodeValue(value);
  }
  /**
   * 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.
   */
  public void toString(StringBuilder builder) {
    builder.append(propertyName);
  }
  /**
   * 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.
   */
  public abstract void validateValue(T value)
      throws IllegalPropertyValueException;
  /**
   * Performs any run-time initialization required by this property
   * definition. This may include resolving managed object paths and
   * property names.
   *
   * @throws Exception
   *           If this property definition could not be initialized.
   */
  protected void initialize() throws Exception {
    // No implementation required.
  }
    /**
     * Performs any run-time initialization required by this property
     * definition. This may include resolving managed object paths and property
     * names.
     *
     * @throws Exception
     *             If this property definition could not be initialized.
     */
    protected void initialize() throws Exception {
        // No implementation required.
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyDefinitionUsageBuilder.java
@@ -25,354 +25,319 @@
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import java.text.NumberFormat;
import java.util.EnumSet;
import java.util.Set;
import java.util.TreeSet;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
/**
 * A property definition visitor which can be used to generate syntax
 * usage information.
 * A property definition visitor which can be used to generate syntax usage
 * information.
 */
public final class PropertyDefinitionUsageBuilder {
  /**
   * Underlying implementation.
   */
  private class MyPropertyDefinitionVisitor extends
      PropertyDefinitionVisitor<Message, Void> {
    // Flag indicating whether detailed syntax information will be
    // generated.
    private final boolean isDetailed;
    // The formatter to use for numeric values.
    private final NumberFormat numberFormat;
    // Private constructor.
    private MyPropertyDefinitionVisitor(boolean isDetailed) {
      this.isDetailed = isDetailed;
      this.numberFormat = NumberFormat.getNumberInstance();
      this.numberFormat.setGroupingUsed(true);
      this.numberFormat.setMaximumFractionDigits(2);
    }
    /**
     * {@inheritDoc}
     * Underlying implementation.
     */
    @Override
    public <C extends ConfigurationClient, S extends Configuration>
    Message visitAggregation(AggregationPropertyDefinition<C, S> d, Void p) {
      return Message.raw("NAME");
    }
    private class MyPropertyDefinitionVisitor extends PropertyDefinitionVisitor<LocalizableMessage, Void> {
        // Flag indicating whether detailed syntax information will be
        // generated.
        private final boolean isDetailed;
        // The formatter to use for numeric values.
        private final NumberFormat numberFormat;
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitAttributeType(AttributeTypePropertyDefinition d,
        Void p) {
      return Message.raw("OID");
    }
        // Private constructor.
        private MyPropertyDefinitionVisitor(boolean isDetailed) {
            this.isDetailed = isDetailed;
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitACI(ACIPropertyDefinition d,
        Void p) {
      return Message.raw("ACI");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitBoolean(BooleanPropertyDefinition d, Void p) {
      if (isDetailed) {
        return Message.raw("false | true");
      } else {
        return Message.raw("BOOLEAN");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitClass(ClassPropertyDefinition d, Void p) {
      if (isDetailed && !d.getInstanceOfInterface().isEmpty()) {
        return Message.raw("CLASS <= " + d.getInstanceOfInterface().get(0));
      } else {
        return Message.raw("CLASS");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitDN(DNPropertyDefinition d, Void p) {
      if (isDetailed && d.getBaseDN() != null) {
        return Message.raw("DN <= " + d.getBaseDN());
      } else {
        return Message.raw("DN");
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitDuration(DurationPropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      DurationUnit unit = d.getBaseUnit();
      if (isDetailed && d.getLowerLimit() > 0) {
        builder.append(DurationUnit.toString(d.getLowerLimit()));
        builder.append(" <= ");
      }
      builder.append("DURATION (");
      builder.append(unit.getShortName());
      builder.append(")");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          builder.append(" <= ");
          builder.append(DurationUnit.toString(d.getUpperLimit()));
            this.numberFormat = NumberFormat.getNumberInstance();
            this.numberFormat.setGroupingUsed(true);
            this.numberFormat.setMaximumFractionDigits(2);
        }
        if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        }
      }
      return builder.toMessage();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <E extends Enum<E>> Message visitEnum(EnumPropertyDefinition<E> d,
        Void p) {
      if (!isDetailed) {
        // Use the last word in the property name.
        String name = d.getName();
        int i = name.lastIndexOf('-');
        if (i == -1 || i == (name.length() - 1)) {
          return Message.raw(name.toUpperCase());
        } else {
          return Message.raw(name.substring(i + 1).toUpperCase());
        }
      } else {
        Set<String> values = new TreeSet<String>();
        for (Object value : EnumSet.allOf(d.getEnumClass())) {
          values.add(value.toString().trim().toLowerCase());
        /**
         * {@inheritDoc}
         */
        @Override
        public <C extends ConfigurationClient, S extends Configuration> LocalizableMessage visitAggregation(
                AggregationPropertyDefinition<C, S> d, Void p) {
            return LocalizableMessage.raw("NAME");
        }
        boolean isFirst = true;
        MessageBuilder builder = new MessageBuilder();
        for (String s : values) {
          if (!isFirst) {
            builder.append(" | ");
          }
          builder.append(s);
          isFirst = false;
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitAttributeType(AttributeTypePropertyDefinition d, Void p) {
            return LocalizableMessage.raw("OID");
        }
        return builder.toMessage();
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitInteger(IntegerPropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      if (isDetailed) {
        builder.append(String.valueOf(d.getLowerLimit()));
        builder.append(" <= ");
      }
      builder.append("INTEGER");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          builder.append(" <= ");
          builder.append(String.valueOf(d.getUpperLimit()));
        } else if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitACI(ACIPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("ACI");
        }
      }
      return builder.toMessage();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitIPAddress(IPAddressPropertyDefinition d, Void p) {
      return Message.raw("HOST_NAME");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitIPAddressMask(IPAddressMaskPropertyDefinition d,
        Void p) {
      return Message.raw("IP_ADDRESS_MASK");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public Message visitSize(SizePropertyDefinition d, Void p) {
      MessageBuilder builder = new MessageBuilder();
      if (isDetailed && d.getLowerLimit() > 0) {
        SizeUnit unit = SizeUnit.getBestFitUnitExact(d.getLowerLimit());
        builder.append(numberFormat.format(unit.fromBytes(d.getLowerLimit())));
        builder.append(' ');
        builder.append(unit.getShortName());
        builder.append(" <= ");
      }
      builder.append("SIZE");
      if (isDetailed) {
        if (d.getUpperLimit() != null) {
          long upperLimit = d.getUpperLimit();
          SizeUnit unit = SizeUnit.getBestFitUnitExact(upperLimit);
          // Quite often an upper limit is some power of 2 minus 1. In those
          // cases lets use a "less than" relation rather than a "less than
          // or equal to" relation. This will result in a much more readable
          // quantity.
          if (unit == SizeUnit.BYTES && upperLimit < Long.MAX_VALUE) {
            unit = SizeUnit.getBestFitUnitExact(upperLimit + 1);
            if (unit != SizeUnit.BYTES) {
              upperLimit += 1;
              builder.append(" < ");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitBoolean(BooleanPropertyDefinition d, Void p) {
            if (isDetailed) {
                return LocalizableMessage.raw("false | true");
            } else {
              builder.append(" <= ");
                return LocalizableMessage.raw("BOOLEAN");
            }
          } else {
            builder.append(" <= ");
          }
          builder.append(numberFormat.format(unit.fromBytes(upperLimit)));
          builder.append(' ');
          builder.append(unit.getShortName());
        }
        if (d.isAllowUnlimited()) {
          builder.append(" | unlimited");
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitClass(ClassPropertyDefinition d, Void p) {
            if (isDetailed && !d.getInstanceOfInterface().isEmpty()) {
                return LocalizableMessage.raw("CLASS <= " + d.getInstanceOfInterface().get(0));
            } else {
                return LocalizableMessage.raw("CLASS");
            }
        }
      }
      return builder.toMessage();
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitDN(DNPropertyDefinition d, Void p) {
            if (isDetailed && d.getBaseDN() != null) {
                return LocalizableMessage.raw("DN <= " + d.getBaseDN());
            } else {
                return LocalizableMessage.raw("DN");
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitDuration(DurationPropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            DurationUnit unit = d.getBaseUnit();
            if (isDetailed && d.getLowerLimit() > 0) {
                builder.append(DurationUnit.toString(d.getLowerLimit()));
                builder.append(" <= ");
            }
            builder.append("DURATION (");
            builder.append(unit.getShortName());
            builder.append(")");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    builder.append(" <= ");
                    builder.append(DurationUnit.toString(d.getUpperLimit()));
                }
                if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <E extends Enum<E>> LocalizableMessage visitEnum(EnumPropertyDefinition<E> d, Void p) {
            if (!isDetailed) {
                // Use the last word in the property name.
                String name = d.getName();
                int i = name.lastIndexOf('-');
                if (i == -1 || i == (name.length() - 1)) {
                    return LocalizableMessage.raw(name.toUpperCase());
                } else {
                    return LocalizableMessage.raw(name.substring(i + 1).toUpperCase());
                }
            } else {
                Set<String> values = new TreeSet<String>();
                for (Object value : EnumSet.allOf(d.getEnumClass())) {
                    values.add(value.toString().trim().toLowerCase());
                }
                boolean isFirst = true;
                LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
                for (String s : values) {
                    if (!isFirst) {
                        builder.append(" | ");
                    }
                    builder.append(s);
                    isFirst = false;
                }
                return builder.toMessage();
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitInteger(IntegerPropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            if (isDetailed) {
                builder.append(String.valueOf(d.getLowerLimit()));
                builder.append(" <= ");
            }
            builder.append("INTEGER");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    builder.append(" <= ");
                    builder.append(String.valueOf(d.getUpperLimit()));
                } else if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitIPAddress(IPAddressPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("HOST_NAME");
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitIPAddressMask(IPAddressMaskPropertyDefinition d, Void p) {
            return LocalizableMessage.raw("IP_ADDRESS_MASK");
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitSize(SizePropertyDefinition d, Void p) {
            LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
            if (isDetailed && d.getLowerLimit() > 0) {
                SizeUnit unit = SizeUnit.getBestFitUnitExact(d.getLowerLimit());
                builder.append(numberFormat.format(unit.fromBytes(d.getLowerLimit())));
                builder.append(' ');
                builder.append(unit.getShortName());
                builder.append(" <= ");
            }
            builder.append("SIZE");
            if (isDetailed) {
                if (d.getUpperLimit() != null) {
                    long upperLimit = d.getUpperLimit();
                    SizeUnit unit = SizeUnit.getBestFitUnitExact(upperLimit);
                    // Quite often an upper limit is some power of 2 minus 1. In
                    // those
                    // cases lets use a "less than" relation rather than a "less
                    // than
                    // or equal to" relation. This will result in a much more
                    // readable
                    // quantity.
                    if (unit == SizeUnit.BYTES && upperLimit < Long.MAX_VALUE) {
                        unit = SizeUnit.getBestFitUnitExact(upperLimit + 1);
                        if (unit != SizeUnit.BYTES) {
                            upperLimit += 1;
                            builder.append(" < ");
                        } else {
                            builder.append(" <= ");
                        }
                    } else {
                        builder.append(" <= ");
                    }
                    builder.append(numberFormat.format(unit.fromBytes(upperLimit)));
                    builder.append(' ');
                    builder.append(unit.getShortName());
                }
                if (d.isAllowUnlimited()) {
                    builder.append(" | unlimited");
                }
            }
            return builder.toMessage();
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public LocalizableMessage visitString(StringPropertyDefinition d, Void p) {
            if (d.getPattern() != null) {
                if (isDetailed) {
                    LocalizableMessageBuilder builder = new LocalizableMessageBuilder();
                    builder.append(d.getPatternUsage());
                    builder.append(" - ");
                    builder.append(d.getPatternSynopsis());
                    return builder.toMessage();
                } else {
                    return LocalizableMessage.raw(d.getPatternUsage());
                }
            } else {
                return LocalizableMessage.raw("STRING");
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <T> LocalizableMessage visitUnknown(PropertyDefinition<T> d, Void p)
                throws UnknownPropertyDefinitionException {
            return LocalizableMessage.raw("?");
        }
    }
    // Underlying implementation.
    private final MyPropertyDefinitionVisitor pimpl;
    /**
     * {@inheritDoc}
     * Creates a new property usage builder.
     *
     * @param isDetailed
     *            Indicates whether or not the generated usage should contain
     *            detailed information such as constraints.
     */
    @Override
    public Message visitString(StringPropertyDefinition d, Void p) {
      if (d.getPattern() != null) {
        if (isDetailed) {
          MessageBuilder builder = new MessageBuilder();
          builder.append(d.getPatternUsage());
          builder.append(" - ");
          builder.append(d.getPatternSynopsis());
          return builder.toMessage();
        } else {
          return Message.raw(d.getPatternUsage());
        }
      } else {
        return Message.raw("STRING");
      }
    public PropertyDefinitionUsageBuilder(boolean isDetailed) {
        this.pimpl = new MyPropertyDefinitionVisitor(isDetailed);
    }
    /**
     * {@inheritDoc}
     * Generates the usage information for the provided property definition.
     *
     * @param pd
     *            The property definitions.
     * @return Returns the usage information for the provided property
     *         definition.
     */
    @Override
    public <T> Message visitUnknown(PropertyDefinition<T> d, Void p)
        throws UnknownPropertyDefinitionException {
      return Message.raw("?");
    }
  }
  // Underlying implementation.
  private final MyPropertyDefinitionVisitor pimpl;
  /**
   * Creates a new property usage builder.
   *
   * @param isDetailed
   *          Indicates whether or not the generated usage should
   *          contain detailed information such as constraints.
   */
  public PropertyDefinitionUsageBuilder(boolean isDetailed) {
    this.pimpl = new MyPropertyDefinitionVisitor(isDetailed);
  }
  /**
   * Generates the usage information for the provided property
   * definition.
   *
   * @param pd
   *          The property definitions.
   * @return Returns the usage information for the provided property
   *         definition.
   */
  public Message getUsage(PropertyDefinition<?> pd) {
    return pd.accept(pimpl, null);
  };
    public LocalizableMessage getUsage(PropertyDefinition<?> pd) {
        return pd.accept(pimpl, null);
    };
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyException.java
@@ -27,73 +27,62 @@
package org.opends.server.admin;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Exceptions thrown as a result of errors that occurred when decoding
 * and modifying property values.
 * Exceptions thrown as a result of errors that occurred when decoding and
 * modifying property values.
 */
public abstract class PropertyException extends AdminRuntimeException {
  /**
   * Version ID required by serializable classes.
   */
  private static final long serialVersionUID = -8465109598081914482L;
    /**
     * Version ID required by serializable classes.
     */
    private static final long serialVersionUID = -8465109598081914482L;
  // The property definition associated with the property that caused
  // the exception.
  private final PropertyDefinition<?> pd;
    // The property definition associated with the property that caused
    // the exception.
    private final PropertyDefinition<?> pd;
    /**
     * Creates property exception without a cause.
     *
     * @param pd
     *            The property definition associated with the property that
     *            caused the exception.
     * @param message
     *            The message.
     */
    protected PropertyException(PropertyDefinition<?> pd, LocalizableMessage message) {
        super(message);
        this.pd = pd;
    }
    /**
     * Creates property exception with a cause.
     *
     * @param pd
     *            The property definition associated with the property that
     *            caused the exception.
     * @param message
     *            The message.
     * @param cause
     *            The cause.
     */
    protected PropertyException(PropertyDefinition<?> pd, LocalizableMessage message, Throwable cause) {
        super(message, cause);
        this.pd = pd;
    }
  /**
   * Creates property exception without a cause.
   *
   * @param pd
   *          The property definition associated with the property
   *          that caused the exception.
   * @param message
   *          The message.
   */
  protected PropertyException(PropertyDefinition<?> pd, Message message) {
    super(message);
    this.pd = pd;
  }
  /**
   * Creates property exception with a cause.
   *
   * @param pd
   *          The property definition associated with the property
   *          that caused the exception.
   * @param message
   *          The message.
   * @param cause
   *          The cause.
   */
  protected PropertyException(PropertyDefinition<?> pd, Message message,
      Throwable cause) {
    super(message, cause);
    this.pd = pd;
  }
  /**
   * Get the property definition associated with the property that
   * caused the exception.
   *
   * @return Returns the property definition associated with the
   *         property that caused the exception.
   */
  public final PropertyDefinition<?> getPropertyDefinition() {
    return pd;
  }
    /**
     * Get the property definition associated with the property that caused the
     * exception.
     *
     * @return Returns the property definition associated with the property that
     *         caused the exception.
     */
    public final PropertyDefinition<?> getPropertyDefinition() {
        return pd;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsMandatoryException.java
@@ -27,32 +27,26 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Thrown when an attempt is made to remove a mandatory property.
 */
public class PropertyIsMandatoryException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 5328211711156565625L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = 5328211711156565625L;
  /**
   * Create a new property is mandatory exception.
   *
   * @param pd
   *          The property definition.
   */
  public PropertyIsMandatoryException(PropertyDefinition<?> pd) {
    super(pd, ERR_PROPERTY_IS_MANDATORY_EXCEPTION.get(pd.getName()));
  }
    /**
     * Create a new property is mandatory exception.
     *
     * @param pd
     *            The property definition.
     */
    public PropertyIsMandatoryException(PropertyDefinition<?> pd) {
        super(pd, ERR_PROPERTY_IS_MANDATORY_EXCEPTION.get(pd.getName()));
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsReadOnlyException.java
@@ -27,32 +27,26 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Thrown when an attempt is made to modify a read-only property.
 */
public class PropertyIsReadOnlyException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = 5315348044141024459L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = 5315348044141024459L;
  /**
   * Create a new property is read-only exception.
   *
   * @param pd
   *          The property definition.
   */
  public PropertyIsReadOnlyException(PropertyDefinition<?> pd) {
    super(pd, ERR_PROPERTY_IS_READ_ONLY_EXCEPTION.get(pd.getName()));
  }
    /**
     * Create a new property is read-only exception.
     *
     * @param pd
     *            The property definition.
     */
    public PropertyIsReadOnlyException(PropertyDefinition<?> pd) {
        super(pd, ERR_PROPERTY_IS_READ_ONLY_EXCEPTION.get(pd.getName()));
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyIsSingleValuedException.java
@@ -27,32 +27,26 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Thrown when an attempt is made to add more than value to a
 * single-valued property.
 * Thrown when an attempt is made to add more than value to a single-valued
 * property.
 */
public class PropertyIsSingleValuedException extends PropertyException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -8056602690887917027L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = -8056602690887917027L;
  /**
   * Create a new property is single valued exception.
   *
   * @param pd
   *          The property definition.
   */
  public PropertyIsSingleValuedException(PropertyDefinition<?> pd) {
    super(pd, ERR_PROPERTY_IS_SINGLE_VALUED_EXCEPTION.get(pd.getName()));
  }
    /**
     * Create a new property is single valued exception.
     *
     * @param pd
     *            The property definition.
     */
    public PropertyIsSingleValuedException(PropertyDefinition<?> pd) {
        super(pd, ERR_PROPERTY_IS_SINGLE_VALUED_EXCEPTION.get(pd.getName()));
    }
}
opendj-admin/src/main/java/org/opends/server/admin/PropertyNotFoundException.java
@@ -27,8 +27,7 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Thrown when an attempt is made to retrieve a property using its name but the
@@ -39,37 +38,33 @@
 */
public class PropertyNotFoundException extends OperationsException {
  /**
   * Serialization ID.
   */
  private static final long serialVersionUID = -895548482881819610L;
    /**
     * Serialization ID.
     */
    private static final long serialVersionUID = -895548482881819610L;
  // The name of the property that could not be found.
  private final String propertyName;
    // The name of the property that could not be found.
    private final String propertyName;
    /**
     * Create a new property not found exception.
     *
     * @param propertyName
     *            The name of the property that could not be found.
     */
    public PropertyNotFoundException(String propertyName) {
        super(ERR_PROPERTY_NOT_FOUND_EXCEPTION.get(propertyName));
        this.propertyName = propertyName;
    }
  /**
   * Create a new property not found exception.
   *
   * @param propertyName
   *          The name of the property that could not be found.
   */
  public PropertyNotFoundException(String propertyName) {
    super(ERR_PROPERTY_NOT_FOUND_EXCEPTION.get(propertyName));
    this.propertyName = propertyName;
  }
  /**
   * Get the name of the property that could not be found.
   *
   * @return Returns the name of the property that could not be found.
   */
  public String getPropertyName() {
    return propertyName;
  }
    /**
     * Get the name of the property that could not be found.
     *
     * @return Returns the name of the property that could not be found.
     */
    public String getPropertyName() {
        return propertyName;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/RelationDefinition.java
@@ -26,396 +26,335 @@
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static org.opends.server.util.Validator.*;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Set;
import org.forgerock.i18n.LocalizableMessage;
/**
 * Relation definitions define relationships between types of managed
 * objects. In addition they define the ownership model:
 * Relation definitions define relationships between types of managed objects.
 * In addition they define the ownership model:
 * <ul>
 * <li>composition - referenced managed objects are owned by the
 * parent managed object and are deleted when the parent is deleted
 * <li>aggregation - referenced managed objects are not owned by the
 * parent managed object. Instead they are shared by other managed
 * objects.
 * <li>composition - referenced managed objects are owned by the parent managed
 * object and are deleted when the parent is deleted
 * <li>aggregation - referenced managed objects are not owned by the parent
 * managed object. Instead they are shared by other managed objects.
 * </ul>
 * Relations define how clients interact with the configuration. For
 * example, clients manage aggregated managed objects in a shared
 * location and attach them to parent managed objects. Composed
 * managed objects, on the other hand, would be created directly
 * beneath the parent managed object and destroyed with it too.
 * Relations define how clients interact with the configuration. For example,
 * clients manage aggregated managed objects in a shared location and attach
 * them to parent managed objects. Composed managed objects, on the other hand,
 * would be created directly beneath the parent managed object and destroyed
 * with it too.
 * <p>
 * Within the server, listeners can choose to request notification of
 * managed objects being added or removed from relations.
 * Within the server, listeners can choose to request notification of managed
 * objects being added or removed from relations.
 * <p>
 * In LDAP, compositions are represented as follows:
 * <ul>
 * <li>singleton relations (one to one): a referenced managed object
 * is represented using a child entry directly beneath the parent
 * <li>optional relations (one to zero or one): a referenced managed
 * object is represented using a child entry directly beneath the
 * parent
 * <li>instantiable relations (one to many): the relation is
 * represented using a child entry directly beneath the parent.
 * Referenced managed objects are represented using child entries of
 * this "relation entry" and are named by the user
 * <li>set relations (one to many): the relation is
 * represented using a child entry directly beneath the parent.
 * Referenced managed objects are represented using child entries of
 * this "relation entry" whose name is the type of the managed object.
 * </ul>
 * Whereas, aggregations are represented by storing the DNs of the
 * referenced managed objects in an attribute of the aggregating
 * <li>singleton relations (one to one): a referenced managed object is
 * represented using a child entry directly beneath the parent
 * <li>optional relations (one to zero or one): a referenced managed object is
 * represented using a child entry directly beneath the parent
 * <li>instantiable relations (one to many): the relation is represented using a
 * child entry directly beneath the parent. Referenced managed objects are
 * represented using child entries of this "relation entry" and are named by the
 * user
 * <li>set relations (one to many): the relation is represented using a child
 * entry directly beneath the parent. Referenced managed objects are represented
 * using child entries of this "relation entry" whose name is the type of the
 * managed object.
 * </ul>
 * Whereas, aggregations are represented by storing the DNs of the referenced
 * managed objects in an attribute of the aggregating managed object.
 *
 * @param <C>
 *          The type of client managed object configuration that this
 *          relation definition refers to.
 *            The type of client managed object configuration that this relation
 *            definition refers to.
 * @param <S>
 *          The type of server managed object configuration that this
 *          relation definition refers to.
 *            The type of server managed object configuration that this relation
 *            definition refers to.
 */
public abstract class RelationDefinition
    <C extends ConfigurationClient, S extends Configuration> {
public abstract class RelationDefinition<C extends ConfigurationClient, S extends Configuration> {
  /**
   * An interface for incrementally constructing relation definitions.
   *
   * @param <C>
   *          The type of client managed object configuration that
   *          this relation definition refers to.
   * @param <S>
   *          The type of server managed object configuration that
   *          this relation definition refers to.
   * @param <D>
   *          The type of relation definition constructed by this
   *          builder.
   */
  protected abstract static class AbstractBuilder
      <C extends ConfigurationClient, S extends Configuration,
       D extends RelationDefinition<C, S>> {
    /**
     * An interface for incrementally constructing relation definitions.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            relation definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            relation definition refers to.
     * @param <D>
     *            The type of relation definition constructed by this builder.
     */
    protected abstract static class AbstractBuilder<C extends ConfigurationClient, S extends Configuration, D extends RelationDefinition<C, S>> {
        // Common fields.
        private final Common<C, S> common;
        /**
         * Create a property definition builder.
         *
         * @param pd
         *            The parent managed object definition.
         * @param name
         *            The name of the relation.
         * @param cd
         *            The child managed object definition.
         */
        protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> pd, String name,
                AbstractManagedObjectDefinition<C, S> cd) {
            this.common = new Common<C, S>(pd, name, cd);
        }
        /**
         * Construct a relation definition based on the properties of this
         * builder.
         *
         * @return The new relation definition.
         */
        public final D getInstance() {
            return buildInstance(common);
        }
        /**
         * Add a relation definition option.
         *
         * @param option
         *            The relation option.
         */
        public final void setOption(RelationOption option) {
            ensureNotNull(option);
            common.options.add(option);
        }
        /**
         * Build a relation definition based on the properties of this builder.
         *
         * @param common
         *            The common fields of the new relation definition.
         * @return The new relation definition.
         */
        protected abstract D buildInstance(Common<C, S> common);
    }
    /**
     * Opaque structure containing fields common to all relation definition
     * types.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            relation definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            relation definition refers to.
     */
    protected static final class Common<C extends ConfigurationClient, S extends Configuration> {
        // The definition of the child managed object.
        private final AbstractManagedObjectDefinition<C, S> cd;
        // The name of the relation.
        private final String name;
        // Options applicable to this definition.
        private final Set<RelationOption> options;
        // The definition of the parent managed object.
        private final AbstractManagedObjectDefinition<?, ?> pd;
        // Private constructor.
        private Common(AbstractManagedObjectDefinition<?, ?> pd, String name, AbstractManagedObjectDefinition<C, S> cd) {
            this.name = name;
            this.pd = pd;
            this.cd = cd;
            this.options = EnumSet.noneOf(RelationOption.class);
        }
    }
    // Common fields.
    private final Common<C, S> common;
    /**
     * Create a property definition builder.
     *
     * @param pd
     *          The parent managed object definition.
     * @param name
     *          The name of the relation.
     * @param cd
     *          The child managed object definition.
     */
    protected AbstractBuilder(AbstractManagedObjectDefinition<?, ?> pd,
        String name, AbstractManagedObjectDefinition<C, S> cd) {
      this.common = new Common<C, S>(pd, name, cd);
    }
    /**
     * Construct a relation definition based on the properties of this
     * builder.
     *
     * @return The new relation definition.
     */
    public final D getInstance() {
      return buildInstance(common);
    }
    /**
     * Add a relation definition option.
     *
     * @param option
     *          The relation option.
     */
    public final void setOption(RelationOption option) {
      ensureNotNull(option);
      common.options.add(option);
    }
    /**
     * Build a relation definition based on the properties of this
     * builder.
     * Create a new managed object relation definition with the specified common
     * fields.
     *
     * @param common
     *          The common fields of the new relation definition.
     * @return The new relation definition.
     *            The common fields of the new relation definition.
     */
    protected abstract D buildInstance(Common<C, S> common);
  }
  /**
   * Opaque structure containing fields common to all relation
   * definition types.
   *
   * @param <C>
   *          The type of client managed object configuration that
   *          this relation definition refers to.
   * @param <S>
   *          The type of server managed object configuration that
   *          this relation definition refers to.
   */
  protected static final class Common
    <C extends ConfigurationClient, S extends Configuration> {
    // The definition of the child managed object.
    private final AbstractManagedObjectDefinition<C, S> cd;
    // The name of the relation.
    private final String name;
    // Options applicable to this definition.
    private final Set<RelationOption> options;
    // The definition of the parent managed object.
    private final AbstractManagedObjectDefinition<?, ?> pd;
    // Private constructor.
    private Common(AbstractManagedObjectDefinition<?, ?> pd, String name,
        AbstractManagedObjectDefinition<C, S> cd) {
      this.name = name;
      this.pd = pd;
      this.cd = cd;
      this.options = EnumSet.noneOf(RelationOption.class);
    protected RelationDefinition(Common<C, S> common) {
        this.common = common;
    }
  }
  // Common fields.
  private final Common<C, S> common;
    /**
     * Apply a visitor to this relation 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 relation definition visitor.
     * @param p
     *            Optional additional visitor parameter.
     * @return Returns a result as specified by the visitor.
     */
    public abstract <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p);
  /**
   * Create a new managed object relation definition with the
   * specified common fields.
   *
   * @param common
   *          The common fields of the new relation definition.
   */
  protected RelationDefinition(Common<C, S> common) {
    this.common = common;
  }
  /**
   * Apply a visitor to this relation 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 relation definition visitor.
   * @param p
   *          Optional additional visitor parameter.
   * @return Returns a result as specified by the visitor.
   */
  public abstract <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p);
  /**
   * Get the definition of the child managed object.
   *
   * @return Returns the definition of the child managed object.
   */
  public final AbstractManagedObjectDefinition<C, S> getChildDefinition() {
    return common.cd;
  }
  /**
   * Gets the optional description of this relation definition in the
   * default locale.
   *
   * @return Returns the description of this relation definition in
   *         the default locale, or <code>null</code> if there is no
   *         description.
   */
  public final Message getDescription() {
    return getDescription(Locale.getDefault());
  }
  /**
   * Gets the optional description of this relation definition in the
   * specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the description of this relation definition in
   *         the specified locale, or <code>null</code> if there is
   *         no description.
   */
  public final Message getDescription(Locale locale) {
    try {
      String property = "relation." + common.name + ".description";
      return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
          getParentDefinition(), property, locale);
    } catch (MissingResourceException e) {
      return null;
    /**
     * Get the definition of the child managed object.
     *
     * @return Returns the definition of the child managed object.
     */
    public final AbstractManagedObjectDefinition<C, S> getChildDefinition() {
        return common.cd;
    }
  }
    /**
     * Gets the optional description of this relation definition in the default
     * locale.
     *
     * @return Returns the description of this relation definition in the
     *         default locale, or <code>null</code> if there is no description.
     */
    public final LocalizableMessage getDescription() {
        return getDescription(Locale.getDefault());
    }
    /**
     * Gets the optional description of this relation definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the description of this relation definition in the
     *         specified locale, or <code>null</code> if there is no
     *         description.
     */
    public final LocalizableMessage getDescription(Locale locale) {
        try {
            String property = "relation." + common.name + ".description";
            return ManagedObjectDefinitionI18NResource.getInstance()
                    .getMessage(getParentDefinition(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
  /**
   * Get the name of the relation.
   *
   * @return Returns the name of the relation.
   */
  public final String getName() {
    return common.name;
  }
    /**
     * Get the name of the relation.
     *
     * @return Returns the name of the relation.
     */
    public final String getName() {
        return common.name;
    }
    /**
     * Get the definition of the parent managed object.
     *
     * @return Returns the definition of the parent managed object.
     */
    public final AbstractManagedObjectDefinition<?, ?> getParentDefinition() {
        return common.pd;
    }
    /**
     * Gets the synopsis of this relation definition in the default locale.
     *
     * @return Returns the synopsis of this relation definition in the default
     *         locale.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
  /**
   * Get the definition of the parent managed object.
   *
   * @return Returns the definition of the parent managed object.
   */
  public final AbstractManagedObjectDefinition<?, ?> getParentDefinition() {
    return common.pd;
  }
    /**
     * Gets the synopsis of this relation definition in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this relation definition in the specified
     *         locale.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        String property = "relation." + common.name + ".synopsis";
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale);
    }
    /**
     * Gets the user friendly name of this relation definition in the default
     * locale.
     *
     * @return Returns the user friendly name of this relation definition in the
     *         default locale.
     */
    public final LocalizableMessage getUserFriendlyName() {
        return getUserFriendlyName(Locale.getDefault());
    }
    /**
     * Gets the user friendly name of this relation definition in the specified
     * locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the user friendly name of this relation definition in the
     *         specified locale.
     */
    public final LocalizableMessage getUserFriendlyName(Locale locale) {
        String property = "relation." + common.name + ".user-friendly-name";
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale);
    }
  /**
   * Gets the synopsis of this relation definition in the default
   * locale.
   *
   * @return Returns the synopsis of this relation definition in the
   *         default locale.
   */
  public final Message getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
    /**
     * Check if the specified option is set for this relation definition.
     *
     * @param option
     *            The option to test.
     * @return Returns <code>true</code> if the option is set, or
     *         <code>false</code> otherwise.
     */
    public final boolean hasOption(RelationOption option) {
        return common.options.contains(option);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        StringBuilder builder = new StringBuilder();
        toString(builder);
        return builder.toString();
    }
    /**
     * Append a string representation of the managed object relation to the
     * provided string builder.
     *
     * @param builder
     *            The string builder where the string representation should be
     *            appended.
     */
    public abstract void toString(StringBuilder builder);
  /**
   * Gets the synopsis of this relation definition in the specified
   * locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this relation definition in the
   *         specified locale.
   */
  public final Message getSynopsis(Locale locale) {
    String property = "relation." + common.name + ".synopsis";
    return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
        getParentDefinition(), property, locale);
  }
  /**
   * Gets the user friendly name of this relation definition in the
   * default locale.
   *
   * @return Returns the user friendly name of this relation
   *         definition in the default locale.
   */
  public final Message getUserFriendlyName() {
    return getUserFriendlyName(Locale.getDefault());
  }
  /**
   * Gets the user friendly name of this relation definition in the
   * specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the user friendly name of this relation
   *         definition in the specified locale.
   */
  public final Message getUserFriendlyName(Locale locale) {
    String property = "relation." + common.name + ".user-friendly-name";
    return ManagedObjectDefinitionI18NResource.getInstance().getMessage(
        getParentDefinition(), property, locale);
  }
  /**
   * Check if the specified option is set for this relation
   * definition.
   *
   * @param option
   *          The option to test.
   * @return Returns <code>true</code> if the option is set, or
   *         <code>false</code> otherwise.
   */
  public final boolean hasOption(RelationOption option) {
    return common.options.contains(option);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final String toString() {
    StringBuilder builder = new StringBuilder();
    toString(builder);
    return builder.toString();
  }
  /**
   * Append a string representation of the managed object relation to
   * the provided string builder.
   *
   * @param builder
   *          The string builder where the string representation
   *          should be appended.
   */
  public abstract void toString(StringBuilder builder);
  /**
   * Performs any run-time initialization required by this relation
   * definition. This may include resolving managed object paths and
   * property names.
   *
   * @throws Exception
   *           If this relation definition could not be initialized.
   */
  protected void initialize() throws Exception {
    // No implementation required.
  }
    /**
     * Performs any run-time initialization required by this relation
     * definition. This may include resolving managed object paths and property
     * names.
     *
     * @throws Exception
     *             If this relation definition could not be initialized.
     */
    protected void initialize() throws Exception {
        // No implementation required.
    }
}
opendj-admin/src/main/java/org/opends/server/admin/SetRelationDefinition.java
@@ -27,17 +27,13 @@
package org.opends.server.admin;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
/**
 * A managed object composite relationship definition which represents a
@@ -45,245 +41,183 @@
 * different type. The manage objects are named using their type name.
 *
 * @param <C>
 *          The type of client managed object configuration that this
 *          relation definition refers to.
 *            The type of client managed object configuration that this relation
 *            definition refers to.
 * @param <S>
 *          The type of server managed object configuration that this
 *          relation definition refers to.
 *            The type of server managed object configuration that this relation
 *            definition refers to.
 */
public final class SetRelationDefinition
    <C extends ConfigurationClient, S extends Configuration>
    extends RelationDefinition<C, S>
{
public final class SetRelationDefinition<C extends ConfigurationClient, S extends Configuration> extends
        RelationDefinition<C, S> {
  /**
   * An interface for incrementally constructing set relation
   * definitions.
   *
   * @param <C>
   *          The type of client managed object configuration that this
   *          relation definition refers to.
   * @param <S>
   *          The type of server managed object configuration that this
   *          relation definition refers to.
   */
  public static final class Builder
      <C extends ConfigurationClient, S extends Configuration>
      extends AbstractBuilder<C, S, SetRelationDefinition<C, S>>
  {
    /**
     * An interface for incrementally constructing set relation definitions.
     *
     * @param <C>
     *            The type of client managed object configuration that this
     *            relation definition refers to.
     * @param <S>
     *            The type of server managed object configuration that this
     *            relation definition refers to.
     */
    public static final class Builder<C extends ConfigurationClient, S extends Configuration> extends
            AbstractBuilder<C, S, SetRelationDefinition<C, S>> {
        // The plural name of the relation.
        private final String pluralName;
        // The optional default managed objects associated with this
        // set relation definition.
        private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects = new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>();
        /**
         * Creates a new builder which can be used to incrementally build a set
         * relation definition.
         *
         * @param pd
         *            The parent managed object definition.
         * @param name
         *            The name of the relation.
         * @param pluralName
         *            The plural name of the relation.
         * @param cd
         *            The child managed object definition.
         */
        public Builder(AbstractManagedObjectDefinition<?, ?> pd, String name, String pluralName,
                AbstractManagedObjectDefinition<C, S> cd) {
            super(pd, name, cd);
            this.pluralName = pluralName;
        }
        /**
         * Adds the default managed object to this set relation definition.
         *
         * @param defaultManagedObject
         *            The default managed object.
         */
        public void setDefaultManagedObject(DefaultManagedObject<? extends C, ? extends S> defaultManagedObject) {
            this.defaultManagedObjects.put(defaultManagedObject.getManagedObjectDefinition().getName(),
                    defaultManagedObject);
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected SetRelationDefinition<C, S> buildInstance(Common<C, S> common) {
            return new SetRelationDefinition<C, S>(common, pluralName, defaultManagedObjects);
        }
    }
    // The plural name of the relation.
    private final String pluralName;
    // The optional default managed objects associated with this
    // set relation definition.
    private final Map<String,
                      DefaultManagedObject<? extends C, ? extends S>>
      defaultManagedObjects =
        new HashMap<String, DefaultManagedObject<? extends C, ? extends S>>();
    private final Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects;
    /**
     * Creates a new builder which can be used to incrementally build a
     * set relation definition.
     *
     * @param pd
     *          The parent managed object definition.
     * @param name
     *          The name of the relation.
     * @param pluralName
     *          The plural name of the relation.
     * @param cd
     *          The child managed object definition.
     */
    public Builder(AbstractManagedObjectDefinition<?, ?> pd,
        String name, String pluralName,
        AbstractManagedObjectDefinition<C, S> cd)
    {
      super(pd, name, cd);
      this.pluralName = pluralName;
    // Private constructor.
    private SetRelationDefinition(Common<C, S> common, String pluralName,
            Map<String, DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects) {
        super(common);
        this.pluralName = pluralName;
        this.defaultManagedObjects = defaultManagedObjects;
    }
    /**
     * Adds the default managed object to this set relation definition.
     *
     * @param defaultManagedObject
     *          The default managed object.
     */
    public void setDefaultManagedObject(
        DefaultManagedObject<? extends C, ? extends S> defaultManagedObject)
    {
      this.defaultManagedObjects
          .put(defaultManagedObject.getManagedObjectDefinition()
              .getName(), defaultManagedObject);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected SetRelationDefinition<C, S> buildInstance(
        Common<C, S> common)
    {
      return new SetRelationDefinition<C, S>(common, pluralName,
          defaultManagedObjects);
    public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p) {
        return v.visitSet(this, p);
    }
  }
  // The plural name of the relation.
  private final String pluralName;
  // The optional default managed objects associated with this
  // set relation definition.
  private final Map<String,
                    DefaultManagedObject<? extends C, ? extends S>>
    defaultManagedObjects;
  // Private constructor.
  private SetRelationDefinition(
      Common<C, S> common,
      String pluralName,
      Map<String,
          DefaultManagedObject<? extends C, ? extends S>> defaultManagedObjects)
  {
    super(common);
    this.pluralName = pluralName;
    this.defaultManagedObjects = defaultManagedObjects;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(RelationDefinitionVisitor<R, P> v, P p)
  {
    return v.visitSet(this, p);
  }
  /**
   * Gets the named default managed object associated with this set
   * relation definition.
   *
   * @param name
   *          The name of the default managed object (for set relations
   *          this is the type of the default managed object).
   * @return The named default managed object.
   * @throws IllegalArgumentException
   *           If there is no default managed object associated with the
   *           provided name.
   */
  public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(
      String name) throws IllegalArgumentException
  {
    if (!defaultManagedObjects.containsKey(name))
    {
      throw new IllegalArgumentException(
          "unrecognized default managed object \"" + name + "\"");
    /**
     * Gets the named default managed object associated with this set relation
     * definition.
     *
     * @param name
     *            The name of the default managed object (for set relations this
     *            is the type of the default managed object).
     * @return The named default managed object.
     * @throws IllegalArgumentException
     *             If there is no default managed object associated with the
     *             provided name.
     */
    public DefaultManagedObject<? extends C, ? extends S> getDefaultManagedObject(String name)
            throws IllegalArgumentException {
        if (!defaultManagedObjects.containsKey(name)) {
            throw new IllegalArgumentException("unrecognized default managed object \"" + name + "\"");
        }
        return defaultManagedObjects.get(name);
    }
    return defaultManagedObjects.get(name);
  }
  /**
   * Gets the names of the default managed objects associated with this
   * set relation definition.
   *
   * @return An unmodifiable set containing the names of the default
   *         managed object.
   */
  public Set<String> getDefaultManagedObjectNames()
  {
    return Collections.unmodifiableSet(defaultManagedObjects.keySet());
  }
  /**
   * Gets the plural name of the relation.
   *
   * @return The plural name of the relation.
   */
  public String getPluralName()
  {
    return pluralName;
  }
  /**
   * Gets the user friendly plural name of this relation definition in
   * the default locale.
   *
   * @return Returns the user friendly plural name of this relation
   *         definition in the default locale.
   */
  public Message getUserFriendlyPluralName()
  {
    return getUserFriendlyPluralName(Locale.getDefault());
  }
  /**
   * Gets the user friendly plural name of this relation definition in
   * the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the user friendly plural name of this relation
   *         definition in the specified locale.
   */
  public Message getUserFriendlyPluralName(Locale locale)
  {
    String property =
        "relation." + getName() + ".user-friendly-plural-name";
    return ManagedObjectDefinitionI18NResource.getInstance()
        .getMessage(getParentDefinition(), property, locale);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void toString(StringBuilder builder)
  {
    builder.append("name=");
    builder.append(getName());
    builder.append(" type=set parent=");
    builder.append(getParentDefinition().getName());
    builder.append(" child=");
    builder.append(getChildDefinition().getName());
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected void initialize() throws Exception
  {
    for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects
        .values())
    {
      dmo.initialize();
    /**
     * Gets the names of the default managed objects associated with this set
     * relation definition.
     *
     * @return An unmodifiable set containing the names of the default managed
     *         object.
     */
    public Set<String> getDefaultManagedObjectNames() {
        return Collections.unmodifiableSet(defaultManagedObjects.keySet());
    }
  }
    /**
     * Gets the plural name of the relation.
     *
     * @return The plural name of the relation.
     */
    public String getPluralName() {
        return pluralName;
    }
    /**
     * Gets the user friendly plural name of this relation definition in the
     * default locale.
     *
     * @return Returns the user friendly plural name of this relation definition
     *         in the default locale.
     */
    public LocalizableMessage getUserFriendlyPluralName() {
        return getUserFriendlyPluralName(Locale.getDefault());
    }
    /**
     * Gets the user friendly plural name of this relation definition in the
     * specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the user friendly plural name of this relation definition
     *         in the specified locale.
     */
    public LocalizableMessage getUserFriendlyPluralName(Locale locale) {
        String property = "relation." + getName() + ".user-friendly-plural-name";
        return ManagedObjectDefinitionI18NResource.getInstance().getMessage(getParentDefinition(), property, locale);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        builder.append("name=");
        builder.append(getName());
        builder.append(" type=set parent=");
        builder.append(getParentDefinition().getName());
        builder.append(" child=");
        builder.append(getChildDefinition().getName());
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected void initialize() throws Exception {
        for (DefaultManagedObject<?, ?> dmo : defaultManagedObjects.values()) {
            dmo.initialize();
        }
    }
}
opendj-admin/src/main/java/org/opends/server/admin/SizePropertyDefinition.java
@@ -27,14 +27,10 @@
package org.opends.server.admin;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
/**
 * Memory size property definition.
 * <p>
@@ -47,364 +43,309 @@
 */
public final class SizePropertyDefinition extends PropertyDefinition<Long> {
  // String used to represent unlimited memory sizes.
  private static final String UNLIMITED = "unlimited";
  // The lower limit of the property value in bytes.
  private final long lowerLimit;
  // The optional upper limit of the property value in bytes.
  private final Long upperLimit;
  // Indicates whether this property allows the use of the "unlimited" memory
  // size value (represented using a -1L or the string "unlimited").
  private final boolean allowUnlimited;
  /**
   * An interface for incrementally constructing memory size property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<Long, SizePropertyDefinition> {
    // String used to represent unlimited memory sizes.
    private static final String UNLIMITED = "unlimited";
    // The lower limit of the property value in bytes.
    private long lowerLimit = 0L;
    private final long lowerLimit;
    // The optional upper limit of the property value in bytes.
    private Long upperLimit = null;
    private final Long upperLimit;
    // Indicates whether this property allows the use of the "unlimited" memory
    // size value (represented using a -1L or the string "unlimited").
    private boolean allowUnlimited = false;
    // Private constructor
    private Builder(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
      super(d, propertyName);
    }
    private final boolean allowUnlimited;
    /**
     * Set the lower limit in bytes.
     *
     * @param lowerLimit
     *          The new lower limit (must be >= 0) in bytes.
     * @throws IllegalArgumentException
     *           If a negative lower limit was specified, or if the lower limit
     *           is greater than the upper limit.
     * An interface for incrementally constructing memory size property
     * definitions.
     */
    public final void setLowerLimit(long lowerLimit)
        throws IllegalArgumentException {
      if (lowerLimit < 0) {
        throw new IllegalArgumentException("Negative lower limit");
      }
      if (upperLimit != null && lowerLimit > upperLimit) {
        throw new IllegalArgumentException(
            "Lower limit greater than upper limit");
      }
      this.lowerLimit = lowerLimit;
    }
    public static class Builder extends AbstractBuilder<Long, SizePropertyDefinition> {
        // The lower limit of the property value in bytes.
        private long lowerLimit = 0L;
        // The optional upper limit of the property value in bytes.
        private Long upperLimit = null;
    /**
     * Set the lower limit using a string representation of the limit.
     *
     * @param lowerLimit
     *          The string representation of the new lower limit.
     * @throws IllegalArgumentException
     *           If the lower limit could not be parsed, or if a negative lower
     *           limit was specified, or the lower limit is greater than the
     *           upper limit.
     */
    public final void setLowerLimit(String lowerLimit)
        throws IllegalArgumentException {
      setLowerLimit(SizeUnit.parseValue(lowerLimit, SizeUnit.BYTES));
    }
        // Indicates whether this property allows the use of the "unlimited"
        // memory
        // size value (represented using a -1L or the string "unlimited").
        private boolean allowUnlimited = false;
    /**
     * Set the upper limit in bytes.
     *
     * @param upperLimit
     *          The new upper limit in bytes or <code>null</code> if there is
     *          no upper limit.
     * @throws IllegalArgumentException
     *           If the lower limit is greater than the upper limit.
     */
    public final void setUpperLimit(Long upperLimit)
        throws IllegalArgumentException {
      if (upperLimit != null) {
        if (upperLimit < 0) {
          throw new IllegalArgumentException("Negative upper limit");
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        if (lowerLimit > upperLimit) {
          throw new IllegalArgumentException(
              "Lower limit greater than upper limit");
        /**
         * Set the lower limit in bytes.
         *
         * @param lowerLimit
         *            The new lower limit (must be >= 0) in bytes.
         * @throws IllegalArgumentException
         *             If a negative lower limit was specified, or if the lower
         *             limit is greater than the upper limit.
         */
        public final void setLowerLimit(long lowerLimit) throws IllegalArgumentException {
            if (lowerLimit < 0) {
                throw new IllegalArgumentException("Negative lower limit");
            }
            if (upperLimit != null && lowerLimit > upperLimit) {
                throw new IllegalArgumentException("Lower limit greater than upper limit");
            }
            this.lowerLimit = lowerLimit;
        }
      }
      this.upperLimit = upperLimit;
        /**
         * Set the lower limit using a string representation of the limit.
         *
         * @param lowerLimit
         *            The string representation of the new lower limit.
         * @throws IllegalArgumentException
         *             If the lower limit could not be parsed, or if a negative
         *             lower limit was specified, or the lower limit is greater
         *             than the upper limit.
         */
        public final void setLowerLimit(String lowerLimit) throws IllegalArgumentException {
            setLowerLimit(SizeUnit.parseValue(lowerLimit, SizeUnit.BYTES));
        }
        /**
         * Set the upper limit in bytes.
         *
         * @param upperLimit
         *            The new upper limit in bytes or <code>null</code> if there
         *            is no upper limit.
         * @throws IllegalArgumentException
         *             If the lower limit is greater than the upper limit.
         */
        public final void setUpperLimit(Long upperLimit) throws IllegalArgumentException {
            if (upperLimit != null) {
                if (upperLimit < 0) {
                    throw new IllegalArgumentException("Negative upper limit");
                }
                if (lowerLimit > upperLimit) {
                    throw new IllegalArgumentException("Lower limit greater than upper limit");
                }
            }
            this.upperLimit = upperLimit;
        }
        /**
         * Set the upper limit using a string representation of the limit.
         *
         * @param upperLimit
         *            The string representation of the new upper limit, or
         *            <code>null</code> if there is no upper limit.
         * @throws IllegalArgumentException
         *             If the upper limit could not be parsed, or if the lower
         *             limit is greater than the upper limit.
         */
        public final void setUpperLimit(String upperLimit) throws IllegalArgumentException {
            if (upperLimit == null) {
                setUpperLimit((Long) null);
            } else {
                setUpperLimit(SizeUnit.parseValue(upperLimit, SizeUnit.BYTES));
            }
        }
        /**
         * Specify whether or not this property definition will allow unlimited
         * values (default is false).
         *
         * @param allowUnlimited
         *            <code>true</code> if the property will allow unlimited
         *            values, or <code>false</code> otherwise.
         */
        public final void setAllowUnlimited(boolean allowUnlimited) {
            this.allowUnlimited = allowUnlimited;
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected SizePropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<Long> defaultBehavior) {
            return new SizePropertyDefinition(d, propertyName, options, adminAction, defaultBehavior, lowerLimit,
                    upperLimit, allowUnlimited);
        }
    }
    /**
     * Set the upper limit using a string representation of the limit.
     * Create an memory size property definition builder.
     *
     * @param upperLimit
     *          The string representation of the new upper limit, or
     *          <code>null</code> if there is no upper limit.
     * @throws IllegalArgumentException
     *           If the upper limit could not be parsed, or if the lower limit
     *           is greater than the upper limit.
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new integer property definition builder.
     */
    public final void setUpperLimit(String upperLimit)
        throws IllegalArgumentException {
      if (upperLimit == null) {
        setUpperLimit((Long) null);
      } else {
        setUpperLimit(SizeUnit.parseValue(upperLimit, SizeUnit.BYTES));
      }
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Private constructor.
    private SizePropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<Long> defaultBehavior, Long lowerLimit, Long upperLimit, boolean allowUnlimited) {
        super(d, Long.class, propertyName, options, adminAction, defaultBehavior);
        this.lowerLimit = lowerLimit;
        this.upperLimit = upperLimit;
        this.allowUnlimited = allowUnlimited;
    }
    /**
     * Specify whether or not this property definition will allow unlimited
     * values (default is false).
     * Get the lower limit in bytes.
     *
     * @param allowUnlimited
     *          <code>true</code> if the property will allow unlimited values,
     *          or <code>false</code> otherwise.
     * @return Returns the lower limit in bytes.
     */
    public final void setAllowUnlimited(boolean allowUnlimited) {
      this.allowUnlimited = allowUnlimited;
    public long getLowerLimit() {
        return lowerLimit;
    }
    /**
     * Get the upper limit in bytes.
     *
     * @return Returns the upper limit in bytes or <code>null</code> if there is
     *         no upper limit.
     */
    public Long getUpperLimit() {
        return upperLimit;
    }
    /**
     * Determine whether this property allows unlimited memory sizes.
     *
     * @return Returns <code>true</code> if this this property allows unlimited
     *         memory sizes.
     */
    public boolean isAllowUnlimited() {
        return allowUnlimited;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected SizePropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<Long> defaultBehavior) {
      return new SizePropertyDefinition(d, propertyName, options, adminAction,
          defaultBehavior, lowerLimit, upperLimit, allowUnlimited);
    public void validateValue(Long value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        if (!allowUnlimited && value < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
            // unlimited allowed
        } else if (value >= 0 && value < lowerLimit) {
            throw new IllegalPropertyValueException(this, value);
        }
        if ((upperLimit != null) && (value > upperLimit)) {
            throw new IllegalPropertyValueException(this, value);
        }
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String encodeValue(Long value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        // Make sure that we correctly encode negative values as "unlimited".
        if (allowUnlimited) {
            if (value < 0) {
                return UNLIMITED;
            }
        }
        // Encode the size value using the best-fit unit.
        StringBuilder builder = new StringBuilder();
        SizeUnit unit = SizeUnit.getBestFitUnitExact(value);
  /**
   * Create an memory size property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new integer property definition builder.
   */
  public static Builder createBuilder(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
    return new Builder(d, propertyName);
  }
  // Private constructor.
  private SizePropertyDefinition(
      AbstractManagedObjectDefinition<?, ?> d, String propertyName,
      EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<Long> defaultBehavior, Long lowerLimit,
      Long upperLimit, boolean allowUnlimited) {
    super(d, Long.class, propertyName, options, adminAction,
        defaultBehavior);
    this.lowerLimit = lowerLimit;
    this.upperLimit = upperLimit;
    this.allowUnlimited = allowUnlimited;
  }
  /**
   * Get the lower limit in bytes.
   *
   * @return Returns the lower limit in bytes.
   */
  public long getLowerLimit() {
    return lowerLimit;
  }
  /**
   * Get the upper limit in bytes.
   *
   * @return Returns the upper limit in bytes or <code>null</code> if there is
   *         no upper limit.
   */
  public Long getUpperLimit() {
    return upperLimit;
  }
  /**
   * Determine whether this property allows unlimited memory sizes.
   *
   * @return Returns <code>true</code> if this this property allows unlimited
   *         memory sizes.
   */
  public boolean isAllowUnlimited() {
    return allowUnlimited;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (!allowUnlimited && value < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
    // unlimited allowed
    } else if (value >= 0 && value < lowerLimit) {
      throw new IllegalPropertyValueException(this, value);
        // Cast to a long to remove fractional part (which should not be there
        // anyway as the best-fit unit should result in an exact conversion).
        builder.append((long) unit.fromBytes(value));
        builder.append(' ');
        builder.append(unit.toString());
        return builder.toString();
    }
    if ((upperLimit != null) && (value > upperLimit)) {
      throw new IllegalPropertyValueException(this, value);
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public Long decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
        // First check for the special "unlimited" value when necessary.
        if (allowUnlimited) {
            if (value.trim().equalsIgnoreCase(UNLIMITED)) {
                return -1L;
            }
        }
        // Decode the value.
        Long i;
        try {
            i = SizeUnit.parseValue(value, SizeUnit.BYTES);
        } catch (NumberFormatException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public String encodeValue(Long value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    // Make sure that we correctly encode negative values as "unlimited".
    if (allowUnlimited) {
      if (value < 0) {
        return UNLIMITED;
      }
        try {
            validateValue(i);
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
        return i;
    }
    // Encode the size value using the best-fit unit.
    StringBuilder builder = new StringBuilder();
    SizeUnit unit = SizeUnit.getBestFitUnitExact(value);
    // Cast to a long to remove fractional part (which should not be there
    // anyway as the best-fit unit should result in an exact conversion).
    builder.append((long) unit.fromBytes(value));
    builder.append(' ');
    builder.append(unit.toString());
    return builder.toString();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public Long decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    // First check for the special "unlimited" value when necessary.
    if (allowUnlimited) {
      if (value.trim().equalsIgnoreCase(UNLIMITED)) {
        return -1L;
      }
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitSize(this, p);
    }
    // Decode the value.
    Long i;
    try {
      i = SizeUnit.parseValue(value, SizeUnit.BYTES);
    } catch (NumberFormatException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, Long value, P p) {
        return v.visitSize(this, value, p);
    }
    try {
      validateValue(i);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    }
    return i;
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public void toString(StringBuilder builder) {
        super.toString(builder);
        builder.append(" lowerLimit=");
        builder.append(lowerLimit);
        if (upperLimit != null) {
            builder.append(" upperLimit=");
            builder.append(upperLimit);
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
    return v.visitSize(this, p);
  }
        builder.append(" allowUnlimited=");
        builder.append(allowUnlimited);
  /**
   * {@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);
    builder.append(" lowerLimit=");
    builder.append(lowerLimit);
    if (upperLimit != null) {
      builder.append(" upperLimit=");
      builder.append(upperLimit);
    }
    builder.append(" allowUnlimited=");
    builder.append(allowUnlimited);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public int compare(Long o1, Long o2) {
    return o1.compareTo(o2);
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public int compare(Long o1, Long o2) {
        return o1.compareTo(o2);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/StringPropertyDefinition.java
@@ -26,11 +26,8 @@
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static org.opends.server.util.Validator.ensureNotNull;
import static com.forgerock.opendj.util.Validator.*;
import java.util.EnumSet;
import java.util.Locale;
@@ -39,297 +36,248 @@
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.forgerock.i18n.LocalizableMessage;
/**
 * String property definition.
 */
public final class StringPropertyDefinition extends PropertyDefinition<String> {
  /**
   * An interface for incrementally constructing string property
   * definitions.
   */
  public static class Builder extends
      AbstractBuilder<String, StringPropertyDefinition> {
    /**
     * An interface for incrementally constructing string property definitions.
     */
    public static class Builder extends AbstractBuilder<String, StringPropertyDefinition> {
        // Flag indicating whether values of this property are
        // case-insensitive.
        private boolean isCaseInsensitive = true;
        // Optional pattern which values of this property must match.
        private Pattern pattern = null;
        // Pattern usage which provides a user-friendly summary of the
        // pattern if present.
        private String patternUsage = null;
        // Private constructor
        private Builder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
            super(d, propertyName);
        }
        /**
         * Set a flag indicating whether values of this property are
         * case-insensitive.
         *
         * @param value
         *            <code>true</code> if values are case-insensitive, or
         *            <code>false</code> otherwise.
         */
        public final void setCaseInsensitive(boolean value) {
            isCaseInsensitive = value;
        }
        /**
         * Set the regular expression pattern which values of this property must
         * match. By default there is no pattern defined.
         *
         * @param pattern
         *            The regular expression pattern string, or
         *            <code>null</code> if there is no pattern.
         * @param patternUsage
         *            A user-friendly usage string representing the pattern
         *            which can be used in error messages and help (e.g. for
         *            patterns which match a host/port combination, the usage
         *            string "HOST:PORT" would be appropriate).
         * @throws PatternSyntaxException
         *             If the provided regular expression pattern has an invalid
         *             syntax.
         */
        public final void setPattern(String pattern, String patternUsage) throws PatternSyntaxException {
            if (pattern == null) {
                this.pattern = null;
                this.patternUsage = null;
            } else {
                this.pattern = Pattern.compile(pattern);
                this.patternUsage = patternUsage;
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        protected StringPropertyDefinition buildInstance(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
                EnumSet<PropertyOption> options, AdministratorAction adminAction,
                DefaultBehaviorProvider<String> defaultBehavior) {
            return new StringPropertyDefinition(d, propertyName, options, adminAction, defaultBehavior,
                    isCaseInsensitive, pattern, patternUsage);
        }
    }
    /**
     * Create a string property definition builder.
     *
     * @param d
     *            The managed object definition associated with this property
     *            definition.
     * @param propertyName
     *            The property name.
     * @return Returns the new string property definition builder.
     */
    public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d, String propertyName) {
        return new Builder(d, propertyName);
    }
    // Flag indicating whether values of this property are
    // case-insensitive.
    private boolean isCaseInsensitive = true;
    private final boolean isCaseInsensitive;
    // Optional pattern which values of this property must match.
    private Pattern pattern = null;
    private final Pattern pattern;
    // Pattern usage which provides a user-friendly summary of the
    // pattern if present.
    private String patternUsage = null;
    private final String patternUsage;
    // Private constructor
    private Builder(AbstractManagedObjectDefinition<?, ?> d,
        String propertyName) {
      super(d, propertyName);
    }
    /**
     * Set a flag indicating whether values of this property are
     * case-insensitive.
     *
     * @param value
     *          <code>true</code> if values are case-insensitive, or
     *          <code>false</code> otherwise.
     */
    public final void setCaseInsensitive(boolean value) {
      isCaseInsensitive = value;
    }
    /**
     * Set the regular expression pattern which values of this
     * property must match. By default there is no pattern defined.
     *
     * @param pattern
     *          The regular expression pattern string, or
     *          <code>null</code> if there is no pattern.
     * @param patternUsage
     *          A user-friendly usage string representing the pattern
     *          which can be used in error messages and help (e.g. for
     *          patterns which match a host/port combination, the
     *          usage string "HOST:PORT" would be appropriate).
     * @throws PatternSyntaxException
     *           If the provided regular expression pattern has an
     *           invalid syntax.
     */
    public final void setPattern(String pattern, String patternUsage)
        throws PatternSyntaxException {
      if (pattern == null) {
        this.pattern = null;
        this.patternUsage = null;
      } else {
        this.pattern = Pattern.compile(pattern);
    // Private constructor.
    private StringPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d, String propertyName,
            EnumSet<PropertyOption> options, AdministratorAction adminAction,
            DefaultBehaviorProvider<String> defaultBehavior, boolean isCaseInsensitive, Pattern pattern,
            String patternUsage) {
        super(d, String.class, propertyName, options, adminAction, defaultBehavior);
        this.isCaseInsensitive = isCaseInsensitive;
        this.pattern = pattern;
        this.patternUsage = patternUsage;
      }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    protected StringPropertyDefinition buildInstance(
        AbstractManagedObjectDefinition<?, ?> d, String propertyName,
        EnumSet<PropertyOption> options,
        AdministratorAction adminAction,
        DefaultBehaviorProvider<String> defaultBehavior) {
      return new StringPropertyDefinition(d, propertyName, options,
          adminAction, defaultBehavior, isCaseInsensitive, pattern,
          patternUsage);
    public <R, P> R accept(PropertyDefinitionVisitor<R, P> v, P p) {
        return v.visitString(this, p);
    }
  }
  /**
   * Create a string property definition builder.
   *
   * @param d
   *          The managed object definition associated with this
   *          property definition.
   * @param propertyName
   *          The property name.
   * @return Returns the new string property definition builder.
   */
  public static Builder createBuilder(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName) {
    return new Builder(d, propertyName);
  }
  // Flag indicating whether values of this property are
  // case-insensitive.
  private final boolean isCaseInsensitive;
  // Optional pattern which values of this property must match.
  private final Pattern pattern;
  // Pattern usage which provides a user-friendly summary of the
  // pattern if present.
  private final String patternUsage;
  // Private constructor.
  private StringPropertyDefinition(AbstractManagedObjectDefinition<?, ?> d,
      String propertyName, EnumSet<PropertyOption> options,
      AdministratorAction adminAction,
      DefaultBehaviorProvider<String> defaultBehavior,
      boolean isCaseInsensitive, Pattern pattern, String patternUsage) {
    super(d, String.class, propertyName, options, adminAction,
        defaultBehavior);
    this.isCaseInsensitive = isCaseInsensitive;
    this.pattern = pattern;
    this.patternUsage = patternUsage;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  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);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String decodeValue(String value)
      throws IllegalPropertyValueStringException {
    ensureNotNull(value);
    try {
      validateValue(value);
    } catch (IllegalPropertyValueException e) {
      throw new IllegalPropertyValueStringException(this, value);
    /**
     * {@inheritDoc}
     */
    @Override
    public <R, P> R accept(PropertyValueVisitor<R, P> v, String value, P p) {
        return v.visitString(this, value, p);
    }
    return value;
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public String decodeValue(String value) throws IllegalPropertyValueStringException {
        ensureNotNull(value);
        try {
            validateValue(value);
        } catch (IllegalPropertyValueException e) {
            throw new IllegalPropertyValueStringException(this, value);
        }
  /**
   * Gets the optional regular expression pattern which values of this
   * property must match.
   *
   * @return Returns the optional regular expression pattern which
   *         values of this property must match, or <code>null</code>
   *         if there is no pattern.
   */
  public Pattern getPattern() {
    return pattern;
  }
  /**
   * Gets the pattern synopsis of this string property definition in
   * the default locale.
   *
   * @return Returns the pattern synopsis of this string property
   *         definition in the default locale, or <code>null</code>
   *         if there is no pattern synopsis (which is the case when
   *         there is no pattern matching defined for this string
   *         property definition).
   */
  public Message getPatternSynopsis() {
    return getPatternSynopsis(Locale.getDefault());
  }
  /**
   * Gets the optional pattern synopsis of this string property
   * definition in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the pattern synopsis of this string property
   *         definition in the specified locale, or <code>null</code>
   *         if there is no pattern synopsis (which is the case when
   *         there is no pattern matching defined for this string
   *         property definition).
   */
  public Message getPatternSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "property." + getName()
        + ".syntax.string.pattern.synopsis";
    try {
      return resource
          .getMessage(getManagedObjectDefinition(), property, locale);
    } catch (MissingResourceException e) {
      return null;
        return value;
    }
  }
  /**
   * Gets a user-friendly usage string representing the pattern which
   * can be used in error messages and help (e.g. for patterns which
   * match a host/port combination, the usage string "HOST:PORT" would
   * be appropriate).
   *
   * @return Returns the user-friendly pattern usage string, or
   *         <code>null</code> if there is no pattern.
   */
  public String getPatternUsage() {
    return patternUsage;
  }
  /**
   * Query whether values of this property are case-insensitive.
   *
   * @return Returns <code>true</code> if values are
   *         case-insensitive, or <code>false</code> otherwise.
   */
  public boolean isCaseInsensitive() {
    return isCaseInsensitive;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public String normalizeValue(String value)
      throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (isCaseInsensitive()) {
      return value.trim().toLowerCase();
    } else {
      return value.trim();
    /**
     * Gets the optional regular expression pattern which values of this
     * property must match.
     *
     * @return Returns the optional regular expression pattern which values of
     *         this property must match, or <code>null</code> if there is no
     *         pattern.
     */
    public Pattern getPattern() {
        return pattern;
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void validateValue(String value) throws IllegalPropertyValueException {
    ensureNotNull(value);
    if (pattern != null) {
      Matcher matcher = pattern.matcher(value);
      if (!matcher.matches()) {
        throw new IllegalPropertyValueException(this, value);
      }
    /**
     * Gets the pattern synopsis of this string property definition in the
     * default locale.
     *
     * @return Returns the pattern synopsis of this string property definition
     *         in the default locale, or <code>null</code> if there is no
     *         pattern synopsis (which is the case when there is no pattern
     *         matching defined for this string property definition).
     */
    public LocalizableMessage getPatternSynopsis() {
        return getPatternSynopsis(Locale.getDefault());
    }
  }
    /**
     * Gets the optional pattern synopsis of this string property definition in
     * the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the pattern synopsis of this string property definition
     *         in the specified locale, or <code>null</code> if there is no
     *         pattern synopsis (which is the case when there is no pattern
     *         matching defined for this string property definition).
     */
    public LocalizableMessage getPatternSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "property." + getName() + ".syntax.string.pattern.synopsis";
        try {
            return resource.getMessage(getManagedObjectDefinition(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
    /**
     * Gets a user-friendly usage string representing the pattern which can be
     * used in error messages and help (e.g. for patterns which match a
     * host/port combination, the usage string "HOST:PORT" would be
     * appropriate).
     *
     * @return Returns the user-friendly pattern usage string, or
     *         <code>null</code> if there is no pattern.
     */
    public String getPatternUsage() {
        return patternUsage;
    }
    /**
     * Query whether values of this property are case-insensitive.
     *
     * @return Returns <code>true</code> if values are case-insensitive, or
     *         <code>false</code> otherwise.
     */
    public boolean isCaseInsensitive() {
        return isCaseInsensitive;
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public String normalizeValue(String value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        if (isCaseInsensitive()) {
            return value.trim().toLowerCase();
        } else {
            return value.trim();
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void validateValue(String value) throws IllegalPropertyValueException {
        ensureNotNull(value);
        if (pattern != null) {
            Matcher matcher = pattern.matcher(value);
            if (!matcher.matches()) {
                throw new IllegalPropertyValueException(this, value);
            }
        }
    }
}
opendj-admin/src/main/java/org/opends/server/admin/Tag.java
@@ -25,9 +25,8 @@
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
import org.opends.messages.Message;
import static com.forgerock.opendj.util.Validator.*;
import java.util.Collection;
import java.util.Collections;
@@ -36,177 +35,151 @@
import java.util.Map;
import java.util.MissingResourceException;
import org.opends.server.admin.std.meta.RootCfgDefn;
import org.opends.server.util.Validator;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.admin.meta.RootCfgDefn;
/**
 * An interface for querying the properties of a tag.
 * <p>
 * Tags are used to group related managed objects together into
 * categories.
 * Tags are used to group related managed objects together into categories.
 */
public final class Tag implements Comparable<Tag> {
  // All the tags.
  private static final Map<String, Tag> tags = new HashMap<String, Tag>();
    // All the tags.
    private static final Map<String, Tag> tags = new HashMap<String, Tag>();
    /**
     * Defines a new tag with the specified name.
     *
     * @param name
     *            The name of the new tag.
     */
    public static void define(String name) {
        Tag tag = new Tag(name);
  /**
   * Defines a new tag with the specified name.
   *
   * @param name
   *          The name of the new tag.
   */
  public static void define(String name) {
    Tag tag = new Tag(name);
    // Register the tag.
    tags.put(name, tag);
  }
  /**
   * Returns the tag associated with the specified name.
   *
   * @param name
   *          The name of the tag.
   * @return Returns the tag associated with the specified name.
   * @throws IllegalArgumentException
   *           If the tag name was not recognized.
   */
  public static Tag valueOf(String name) throws IllegalArgumentException {
    Validator.ensureNotNull(name);
    // Hack to force initialization of the tag definitions.
    RootCfgDefn.getInstance();
    Tag tag = tags.get(name.toLowerCase());
    if (tag == null) {
      throw new IllegalArgumentException("Unknown tag \"" + name + "\"");
        // Register the tag.
        tags.put(name, tag);
    }
    return tag;
  }
    /**
     * Returns the tag associated with the specified name.
     *
     * @param name
     *            The name of the tag.
     * @return Returns the tag associated with the specified name.
     * @throws IllegalArgumentException
     *             If the tag name was not recognized.
     */
    public static Tag valueOf(String name) throws IllegalArgumentException {
        ensureNotNull(name);
        // Hack to force initialization of the tag definitions.
        RootCfgDefn.getInstance();
        Tag tag = tags.get(name.toLowerCase());
  /**
   * Returns an unmodifiable collection view of the set of registered
   * tags.
   *
   * @return Returns an unmodifiable collection view of the set of
   *         registered tags.
   */
  public static Collection<Tag> values() {
    // Hack to force initialization of the tag definitions.
    RootCfgDefn.getInstance();
        if (tag == null) {
            throw new IllegalArgumentException("Unknown tag \"" + name + "\"");
        }
    return Collections.unmodifiableCollection(tags.values());
  }
  // The name of the tag.
  private final String name;
  // Private constructor.
  private Tag(String name) {
    this.name = name;
  }
  /**
   * {@inheritDoc}
   */
  public final int compareTo(Tag o) {
    return name.compareTo(o.name);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public final boolean equals(Object obj) {
    if (this == obj) {
      return true;
        return tag;
    }
    if (obj instanceof Tag) {
      Tag other = (Tag) obj;
      return other.name.equals(this.name);
    /**
     * Returns an unmodifiable collection view of the set of registered tags.
     *
     * @return Returns an unmodifiable collection view of the set of registered
     *         tags.
     */
    public static Collection<Tag> values() {
        // Hack to force initialization of the tag definitions.
        RootCfgDefn.getInstance();
        return Collections.unmodifiableCollection(tags.values());
    }
    return false;
  }
    // The name of the tag.
    private final String name;
  /**
   * Gets the name of this tag.
   *
   * @return Returns the name of this tag.
   */
  public final String getName() {
    return name;
  }
  /**
   * Gets the synopsis of this tag in the default locale.
   *
   * @return Returns the synopsis of this tag in the default locale.
   */
  public final Message getSynopsis() {
    return getSynopsis(Locale.getDefault());
  }
  /**
   * Gets the synopsis of this tag in the specified locale.
   *
   * @param locale
   *          The locale.
   * @return Returns the synopsis of this tag in the specified locale.
   */
  public final Message getSynopsis(Locale locale) {
    ManagedObjectDefinitionI18NResource resource =
      ManagedObjectDefinitionI18NResource.getInstance();
    String property = "tag." + name + ".synopsis";
    try {
      return resource.getMessage(RootCfgDefn.getInstance(), property, locale);
    } catch (MissingResourceException e) {
      return null;
    // Private constructor.
    private Tag(String name) {
        this.name = name;
    }
  }
    /**
     * {@inheritDoc}
     */
    public final int compareTo(Tag o) {
        return name.compareTo(o.name);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
  /**
   * {@inheritDoc}
   */
  @Override
  public final int hashCode() {
    return name.hashCode();
  }
        if (obj instanceof Tag) {
            Tag other = (Tag) obj;
            return other.name.equals(this.name);
        }
        return false;
    }
    /**
     * Gets the name of this tag.
     *
     * @return Returns the name of this tag.
     */
    public final String getName() {
        return name;
    }
  /**
   * {@inheritDoc}
   */
  @Override
  public final String toString() {
    return name;
  }
    /**
     * Gets the synopsis of this tag in the default locale.
     *
     * @return Returns the synopsis of this tag in the default locale.
     */
    public final LocalizableMessage getSynopsis() {
        return getSynopsis(Locale.getDefault());
    }
    /**
     * Gets the synopsis of this tag in the specified locale.
     *
     * @param locale
     *            The locale.
     * @return Returns the synopsis of this tag in the specified locale.
     */
    public final LocalizableMessage getSynopsis(Locale locale) {
        ManagedObjectDefinitionI18NResource resource = ManagedObjectDefinitionI18NResource.getInstance();
        String property = "tag." + name + ".synopsis";
        try {
            return resource.getMessage(RootCfgDefn.getInstance(), property, locale);
        } catch (MissingResourceException e) {
            return null;
        }
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final int hashCode() {
        return name.hashCode();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public final String toString() {
        return name;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/UnknownPropertyDefinitionException.java
@@ -27,52 +27,41 @@
package org.opends.server.admin;
import static org.opends.messages.AdminMessages.*;
import static com.forgerock.opendj.ldap.AdminMessages.*;
/**
 * Indicates that an unknown type of property definition was
 * encountered. This can occur as the management prototype develops
 * and new kinds of property definitions are added.
 * Indicates that an unknown type of property definition was encountered. This
 * can occur as the management prototype develops and new kinds of property
 * definitions are added.
 */
public final class UnknownPropertyDefinitionException
    extends PropertyException {
public final class UnknownPropertyDefinitionException extends PropertyException {
  // Generated serialization ID.
  private static final long serialVersionUID = 7042646409131322385L;
    // Generated serialization ID.
    private static final long serialVersionUID = 7042646409131322385L;
  // The visitor parameter if there was one.
  private Object parameter;
    // The visitor parameter if there was one.
    private Object parameter;
    /**
     * Creates a new unknown property definition exception.
     *
     * @param pd
     *            The unknown property definition.
     * @param p
     *            The visitor parameter if there was one.
     */
    public UnknownPropertyDefinitionException(PropertyDefinition<?> pd, Object p) {
        super(pd, ERR_UNKNOWN_PROPERTY_DEFINITION_EXCEPTION.get(pd.getName(), pd.getClass().getName()));
        this.parameter = p;
    }
  /**
   * Creates a new unknown property definition exception.
   *
   * @param pd
   *          The unknown property definition.
   * @param p
   *          The visitor parameter if there was one.
   */
  public UnknownPropertyDefinitionException(PropertyDefinition<?> pd,
      Object p) {
    super(pd, ERR_UNKNOWN_PROPERTY_DEFINITION_EXCEPTION.get(pd.getName(), pd
        .getClass().getName()));
    this.parameter = p;
  }
  /**
   * Get the visitor parameter if there was one.
   *
   * @return Returns the visitor parameter if there was one.
   */
  public Object getParameter() {
    return parameter;
  }
    /**
     * Get the visitor parameter if there was one.
     *
     * @return Returns the visitor parameter if there was one.
     */
    public Object getParameter() {
        return parameter;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/client/ClientConstraintHandler.java
@@ -30,7 +30,7 @@
import java.util.Collection;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.ManagedObjectPath;
@@ -87,7 +87,7 @@
   *           from being evaluated.
   */
  public boolean isAddAcceptable(ManagementContext context,
      ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
      ManagedObject<?> managedObject, Collection<LocalizableMessage> unacceptableReasons)
      throws AuthorizationException, CommunicationException {
    return true;
  }
@@ -122,7 +122,7 @@
   *           from being evaluated.
   */
  public boolean isModifyAcceptable(ManagementContext context,
      ManagedObject<?> managedObject, Collection<Message> unacceptableReasons)
      ManagedObject<?> managedObject, Collection<LocalizableMessage> unacceptableReasons)
      throws AuthorizationException, CommunicationException {
    return true;
  }
@@ -158,7 +158,7 @@
   *           from being evaluated.
   */
  public boolean isDeleteAcceptable(ManagementContext context,
      ManagedObjectPath<?, ?> path, Collection<Message> unacceptableReasons)
      ManagedObjectPath<?, ?> path, Collection<LocalizableMessage> unacceptableReasons)
      throws AuthorizationException, CommunicationException {
    return true;
  }
opendj-admin/src/main/java/org/opends/server/admin/package-info.java
@@ -33,7 +33,5 @@
 * This package contains administration related classes and interfaces
 * common to both the client and server.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.PRIVATE)
package org.opends.server.admin;
opendj-admin/src/main/java/org/opends/server/admin/server/ServerConstraintHandler.java
@@ -30,7 +30,7 @@
import java.util.Collection;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.config.ConfigException;
@@ -91,7 +91,7 @@
   *           from being evaluated.
   */
  public boolean isDeleteAllowed(ServerManagedObject<?> managedObject,
      Collection<Message> unacceptableReasons) throws ConfigException {
      Collection<LocalizableMessage> unacceptableReasons) throws ConfigException {
    return true;
  }
@@ -124,7 +124,7 @@
   *           from being evaluated.
   */
  public boolean isUsable(ServerManagedObject<?> managedObject,
      Collection<Message> unacceptableReasons) throws ConfigException {
      Collection<LocalizableMessage> unacceptableReasons) throws ConfigException {
    return true;
  }
opendj-admin/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -36,4 +36,12 @@
        throw new RuntimeException("Not implemented");
    }
    public static String getInstanceRoot() {
        throw new RuntimeException("Not implemented");
    }
    public static String getServerRoot() {
        throw new RuntimeException("Not implemented");
    }
}
opendj-admin/src/main/resources/com/forgerock/opendj/ldap/admin.properties
@@ -41,33 +41,33 @@
#
# ORDINAL is an integer unique among other ordinals in this file
#
SEVERE_ERR_ADMIN_CANNOT_GET_LISTENER_BASE_1=An error occurred while trying to \
ERR_ADMIN_CANNOT_GET_LISTENER_BASE_1=An error occurred while trying to \
 retrieve relation configuration entry %s: %s
SEVERE_ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT_3=An error occurred while trying \
ERR_ADMIN_CANNOT_GET_MANAGED_OBJECT_3=An error occurred while trying \
 to retrieve the managed object configuration entry %s: %s
SEVERE_ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST_4=The managed object \
ERR_ADMIN_MANAGED_OBJECT_DOES_NOT_EXIST_4=The managed object \
 configuration entry %s does not appear to exist in the Directory Server \
 configuration. This is a required entry
SEVERE_ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=An error occurred while \
ERR_ADMIN_MANAGED_OBJECT_DECODING_PROBLEM_5=An error occurred while \
 trying to decode the managed object configuration entry %s: %s
SEVERE_ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=The Directory Server was unable \
ERR_ADMIN_CANNOT_INSTANTIATE_CLASS_6=The Directory Server was unable \
 to load class %s and use it to create a component instance as defined in \
 configuration entry %s.  The error that occurred was:  %s.  This component \
 will be disabled
SEVERE_ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=The Directory Server jar file %s in \
ERR_ADMIN_CANNOT_OPEN_JAR_FILE_9=The Directory Server jar file %s in \
 directory %s cannot be loaded because an unexpected error occurred while \
 trying to open the file for reading:  %s
MILD_ERR_ADMIN_NO_EXTENSIONS_DIR_12=The extensions directory %s does not \
 exist, therefore no extensions will be loaded
SEVERE_ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Unable to read the Directory \
ERR_ADMIN_EXTENSIONS_DIR_NOT_DIRECTORY_13=Unable to read the Directory \
 Server extensions because the extensions directory %s exists but is not a \
 directory
SEVERE_ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=Unable to read the Directory \
ERR_ADMIN_EXTENSIONS_CANNOT_LIST_FILES_14=Unable to read the Directory \
 Server extensions from directory %s because an unexpected error occurred \
 while trying to list the files in that directory:  %s
FATAL_ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=The core administration manifest \
ERR_ADMIN_CANNOT_FIND_CORE_MANIFEST_15=The core administration manifest \
 file %s cannot be located
SEVERE_ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST_17=The administration \
ERR_ADMIN_CANNOT_READ_EXTENSION_MANIFEST_17=The administration \
 manifest file %s associated with the extension %s cannot be loaded because an \
 unexpected error occurred while trying to read it:  %s
INFO_ADMIN_TOOL_DESCRIPTION_18=This utility can be used to perform operations \
@@ -95,30 +95,30 @@
 server group
INFO_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION_31=List server groups in which \
 the specified server is a member
FATAL_ERR_ADMIN_CANNOT_CONNECT_TO_ADS_32=Could not connect to %s. Check that \
ERR_ADMIN_CANNOT_CONNECT_TO_ADS_32=Could not connect to %s. Check that \
 the server is running and that the provided credentials are valid
INFO_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION_33=Create a new ADS DN
INFO_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION_34=Delete an existing ADS DN
FATAL_ERR_ADMIN_MISSING_HOSTNAME_35=The host name is missing
FATAL_ERR_ADMIN_NOVALID_HOSTNAME_36=The host name is not valid
FATAL_ERR_ADMIN_MISSING_IPATH_37=The installation path is missing
FATAL_ERR_ADMIN_NOVALID_IPATH_38=The installation path is not valid
FATAL_ERR_ADMIN_ACCESS_PERMISSION_39=An access permission error occurs
FATAL_ERR_ADMIN_ALREADY_REGISTERED_40=The entity is already registered
FATAL_ERR_ADMIN_BROKEN_INSTALL_41=The administrative repository is broken
FATAL_ERR_ADMIN_NOT_YET_REGISTERED_42=The entity is not yet registered
FATAL_ERR_ADMIN_MISSING_PORT_43=The port is missing
FATAL_ERR_ADMIN_NOVALID_PORT_44=The port is not valid
FATAL_ERR_ADMIN_MISSING_NAME_45=The name is missing
FATAL_ERR_ADMIN_MISSING_ADMIN_UID_46=The administration UID is missing
FATAL_ERR_ADMIN_MISSING_ADMIN_PASSWORD_47=The administrator password is \
ERR_ADMIN_MISSING_HOSTNAME_35=The host name is missing
ERR_ADMIN_NOVALID_HOSTNAME_36=The host name is not valid
ERR_ADMIN_MISSING_IPATH_37=The installation path is missing
ERR_ADMIN_NOVALID_IPATH_38=The installation path is not valid
ERR_ADMIN_ACCESS_PERMISSION_39=An access permission error occurs
ERR_ADMIN_ALREADY_REGISTERED_40=The entity is already registered
ERR_ADMIN_BROKEN_INSTALL_41=The administrative repository is broken
ERR_ADMIN_NOT_YET_REGISTERED_42=The entity is not yet registered
ERR_ADMIN_MISSING_PORT_43=The port is missing
ERR_ADMIN_NOVALID_PORT_44=The port is not valid
ERR_ADMIN_MISSING_NAME_45=The name is missing
ERR_ADMIN_MISSING_ADMIN_UID_46=The administration UID is missing
ERR_ADMIN_MISSING_ADMIN_PASSWORD_47=The administrator password is \
 missing
FATAL_ERR_ADMIN_ERROR_UNEXPECTED_48=An unexpected error occurs
ERR_ADMIN_ERROR_UNEXPECTED_48=An unexpected error occurs
INFO_ADMIN_ERROR_49=[error]
INFO_ADMIN_SUCCESSFUL_50=The operation has been successfully completed
INFO_ADMIN_SUCCESSFUL_NOP_51=The operation has been successfully completed, \
 but no action was required
SEVERE_ERR_ADMIN_NO_MESSAGE_52=
ERR_ADMIN_NO_MESSAGE_52=
INFO_ADMIN_ARG_CREATE_GROUP_GROUPNAME_DESCRIPTION_53=The new group's \
 identifier. This is a required argument
INFO_ADMIN_ARG_GROUPNAME_DESCRIPTION_54=The group's identifier. This is a \
@@ -127,7 +127,7 @@
 required argument
INFO_ADMIN_ARG_BACKENDNAME_DESCRIPTION_56=The name of the backend in which \
 the admin data will be stored
SEVERE_ERR_ADMIN_UNABLE_TO_REGISTER_LISTENER_57=Unable to register an \
ERR_ADMIN_UNABLE_TO_REGISTER_LISTENER_57=Unable to register an \
 add/delete listener against the entry "%s" because it does not exist in the \
 configuration
INFO_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION_58=Register a server into the \
@@ -144,7 +144,7 @@
 properties
INFO_ADMIN_ARG_SERVERID_DESCRIPTION_65=The registered server's unique \
 identifier. This is a required argument
FATAL_ERR_ADMIN_SERVER_NOT_REGISTERED_66=The provided serverId is not \
ERR_ADMIN_SERVER_NOT_REGISTERED_66=The provided serverId is not \
 registered
INFO_ADMIN_SUBCMD_CREATE_ADMIN_USER_DESCRIPTION_67=Creates a new \
 administrator
@@ -160,131 +160,131 @@
 administrator's properties
INFO_ADMIN_ARG_USERID_DESCRIPTION_73=The administrator's unique identifier. \
 This is a required argument
SEVERE_ERR_OPERATION_REJECTED_DEFAULT_74=Reason unknown
SEVERE_ERR_SERVER_CONSTRAINT_EXCEPTION_75=A configuration exception \
ERR_OPERATION_REJECTED_DEFAULT_74=Reason unknown
ERR_SERVER_CONSTRAINT_EXCEPTION_75=A configuration exception \
 occurred while evaluating a constraint: %s
SEVERE_ERR_DECODING_EXCEPTION_NO_TYPE_INFO_82=The %s could \
ERR_DECODING_EXCEPTION_NO_TYPE_INFO_82=The %s could \
 be found but did not contain any type information (e.g. missing object \
 classes in LDAP)
SEVERE_ERR_DECODING_EXCEPTION_WRONG_TYPE_INFO_83=The %s could \
ERR_DECODING_EXCEPTION_WRONG_TYPE_INFO_83=The %s could \
 be found but did not contain the expected type information (e.g. incorrect \
 object classes in LDAP)
SEVERE_ERR_DECODING_EXCEPTION_ABSTRACT_TYPE_INFO_84=The %s \
ERR_DECODING_EXCEPTION_ABSTRACT_TYPE_INFO_84=The %s \
 could be found but its type resolved to an abstract managed object \
 definition
SEVERE_ERR_DEFAULT_BEHAVIOR_PROPERTY_EXCEPTION_86=The default values \
ERR_DEFAULT_BEHAVIOR_PROPERTY_EXCEPTION_86=The default values \
 for the "%s" property could not be determined
SEVERE_ERR_ILLEGAL_PROPERTY_VALUE_EXCEPTION_87=The value "%s" is not \
ERR_ILLEGAL_PROPERTY_VALUE_EXCEPTION_87=The value "%s" is not \
 a valid value for the "%s" property, which must have the following \
 syntax: %s
SEVERE_ERR_ILLEGAL_PROPERTY_VALUE_STRING_EXCEPTION_88=The string value \
ERR_ILLEGAL_PROPERTY_VALUE_STRING_EXCEPTION_88=The string value \
 "%s" is not a valid value for the "%s" property, which must have the \
 following syntax: %s
SEVERE_ERR_PROPERTY_IS_MANDATORY_EXCEPTION_89=The "%s" property must be \
ERR_PROPERTY_IS_MANDATORY_EXCEPTION_89=The "%s" property must be \
 specified as it is mandatory
SEVERE_ERR_PROPERTY_IS_READ_ONLY_EXCEPTION_90=The "%s" property must not \
ERR_PROPERTY_IS_READ_ONLY_EXCEPTION_90=The "%s" property must not \
 be modified as it is read-only
SEVERE_ERR_PROPERTY_IS_SINGLE_VALUED_EXCEPTION_91=The "%s" property \
ERR_PROPERTY_IS_SINGLE_VALUED_EXCEPTION_91=The "%s" property \
 must not contain more than one value
SEVERE_ERR_UNKNOWN_PROPERTY_DEFINITION_EXCEPTION_92=An internal error \
ERR_UNKNOWN_PROPERTY_DEFINITION_EXCEPTION_92=An internal error \
 occurred while processing property "%s": unknown property type "%s"
SEVERE_ERR_AUTHENTICATION_EXCEPTION_DEFAULT_93=Authentication failure
SEVERE_ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT_94=The \
ERR_AUTHENTICATION_EXCEPTION_DEFAULT_93=Authentication failure
ERR_AUTHENTICATION_NOT_SUPPORTED_EXCEPTION_DEFAULT_94=The \
 requested authentication mechanism is not supported by the server
SEVERE_ERR_AUTHORIZATION_EXCEPTION_DEFAULT_95=Authorization failure
SEVERE_ERR_COMMUNICATION_EXCEPTION_DEFAULT_96=A communication problem \
ERR_AUTHORIZATION_EXCEPTION_DEFAULT_95=Authorization failure
ERR_COMMUNICATION_EXCEPTION_DEFAULT_96=A communication problem \
 occurred while contacting the server
SEVERE_ERR_OPERATION_REJECTED_EXCEPTION_SINGLE_97=The operation was rejected \
ERR_OPERATION_REJECTED_EXCEPTION_SINGLE_97=The operation was rejected \
 for the following reason: %s
SEVERE_ERR_OPERATION_REJECTED_EXCEPTION_PLURAL_98=The operation was rejected \
ERR_OPERATION_REJECTED_EXCEPTION_PLURAL_98=The operation was rejected \
 for the following reasons: %s
SEVERE_ERR_CONCURRENT_MODIFICATION_EXCEPTION_DEFAULT_99=The operation could \
ERR_CONCURRENT_MODIFICATION_EXCEPTION_DEFAULT_99=The operation could \
 not be performed because a conflicting change has already occurred. There \
 may be another client administration tool in use
SEVERE_ERR_MANAGED_OBJECT_DECODING_EXCEPTION_SINGLE_100=The %s could not \
ERR_MANAGED_OBJECT_DECODING_EXCEPTION_SINGLE_100=The %s could not \
 be decoded due to the following reason: %s
SEVERE_ERR_MANAGED_OBJECT_DECODING_EXCEPTION_PLURAL_101=The %s could not \
ERR_MANAGED_OBJECT_DECODING_EXCEPTION_PLURAL_101=The %s could not \
 be decoded due to the following reasons: %s
SEVERE_ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_EMPTY_102=Empty managed \
ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_EMPTY_102=Empty managed \
 object names are not permitted
SEVERE_ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_BLANK_103=Blank managed \
ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_BLANK_103=Blank managed \
 object names are not permitted
SEVERE_ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_SYNTAX_104=The managed \
ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_SYNTAX_104=The managed \
 object name "%s" is not a valid value for the naming property "%s", \
 which must have the following syntax: %s
SEVERE_ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_OTHER_105=The managed \
ERR_ILLEGAL_MANAGED_OBJECT_NAME_EXCEPTION_OTHER_105=The managed \
 object name "%s" is not permitted
SEVERE_ERR_MANAGED_OBJECT_ALREADY_EXISTS_EXCEPTION_106=The managed object \
ERR_MANAGED_OBJECT_ALREADY_EXISTS_EXCEPTION_106=The managed object \
 could not be created because there is an existing managed object with \
 the same name
SEVERE_ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION_107=The requested managed \
ERR_MANAGED_OBJECT_NOT_FOUND_EXCEPTION_107=The requested managed \
 object could not be found
SEVERE_ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_SINGLE_108=The "%s" \
ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_SINGLE_108=The "%s" \
 property is mandatory
SEVERE_ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_PLURAL_109=The following \
ERR_MISSING_MANDATORY_PROPERTIES_EXCEPTION_PLURAL_109=The following \
 properties are mandatory: %s
SEVERE_ERR_PROPERTY_NOT_FOUND_EXCEPTION_110=The property "%s" was not \
ERR_PROPERTY_NOT_FOUND_EXCEPTION_110=The property "%s" was not \
 recognized
SEVERE_ERR_COMMUNICATION_EXCEPTION_DEFAULT_CAUSE_111=A communication problem \
ERR_COMMUNICATION_EXCEPTION_DEFAULT_CAUSE_111=A communication problem \
 occurred while contacting the server: %s
SEVERE_ERR_CONSTRAINT_VIOLATION_EXCEPTION_SINGLE_112=The following \
ERR_CONSTRAINT_VIOLATION_EXCEPTION_SINGLE_112=The following \
 constraint violation occurred: %s
SEVERE_ERR_CONSTRAINT_VIOLATION_EXCEPTION_PLURAL_113=The following \
ERR_CONSTRAINT_VIOLATION_EXCEPTION_PLURAL_113=The following \
 constraint violations occurred: %s
SEVERE_ERR_SERVER_REFINT_DANGLING_REFERENCE_114=The value "%s" in \
ERR_SERVER_REFINT_DANGLING_REFERENCE_114=The value "%s" in \
 property "%s" in the %s in entry "%s" refers to a non-existent %s \
 in entry "%s"
SEVERE_ERR_SERVER_REFINT_TARGET_DISABLED_116=The value "%s" in \
ERR_SERVER_REFINT_TARGET_DISABLED_116=The value "%s" in \
 property "%s" in the %s in entry "%s" refers to a disabled %s in \
 entry "%s"
SEVERE_ERR_SERVER_REFINT_CANNOT_DELETE_117=The %s in entry "%s" \
ERR_SERVER_REFINT_CANNOT_DELETE_117=The %s in entry "%s" \
 cannot be deleted because it is referenced by the "%s" property \
 of the %s in entry "%s"
SEVERE_ERR_SERVER_REFINT_CANNOT_DISABLE_118=The %s in entry "%s" \
ERR_SERVER_REFINT_CANNOT_DISABLE_118=The %s in entry "%s" \
 cannot be disabled because it is referenced by the "%s" property \
 of the %s in entry "%s"
SEVERE_ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE_120=An unexpected \
ERR_CLASS_LOADER_CANNOT_READ_MANIFEST_FILE_120=An unexpected \
 error occurred while reading the manifest file: %s
SEVERE_ERR_CLASS_LOADER_CANNOT_LOAD_CLASS_121=An error occurred while \
ERR_CLASS_LOADER_CANNOT_LOAD_CLASS_121=An error occurred while \
 attempting to load class "%s": %s
SEVERE_ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD_122=Unable to \
ERR_CLASS_LOADER_CANNOT_FIND_GET_INSTANCE_METHOD_122=Unable to \
 to find the getInstance() method in the managed object definition \
 class "%s": %s
SEVERE_ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD_123=Unable to \
ERR_CLASS_LOADER_CANNOT_INVOKE_GET_INSTANCE_METHOD_123=Unable to \
 to invoke the getInstance() method in the managed object definition \
 class "%s": %s
SEVERE_ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN_124=Unable initialize the \
ERR_CLASS_LOADER_CANNOT_INITIALIZE_DEFN_124=Unable initialize the \
 "%s" managed object definition in class "%s": %s
SEVERE_ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION_125=The extension "%s" \
ERR_CLASS_LOADER_CANNOT_LOAD_EXTENSION_125=The extension "%s" \
 with manifest file %s cannot be loaded because an unexpected error \
 occurred while trying to initialize it: %s
FATAL_ERR_CLASS_LOADER_CANNOT_LOAD_CORE_126=The core administration \
ERR_CLASS_LOADER_CANNOT_LOAD_CORE_126=The core administration \
 classes could not be loaded from manifest file %s because an unexpected \
 error occurred: %s
SEVERE_ERR_CLIENT_REFINT_TARGET_DANGLING_REFERENCE_127=The %s "%s" referenced in \
ERR_CLIENT_REFINT_TARGET_DANGLING_REFERENCE_127=The %s "%s" referenced in \
 property "%s" does not exist
SEVERE_ERR_CLIENT_REFINT_TARGET_INVALID_128=The %s "%s" referenced in \
ERR_CLIENT_REFINT_TARGET_INVALID_128=The %s "%s" referenced in \
 property "%s" exists but has an invalid configuration: %s
SEVERE_ERR_CLIENT_REFINT_TARGET_DISABLED_129=The %s "%s" referenced in \
ERR_CLIENT_REFINT_TARGET_DISABLED_129=The %s "%s" referenced in \
 property "%s" is disabled
SEVERE_ERR_CLIENT_REFINT_CANNOT_DELETE_WITH_NAME_130=The "%s" property \
ERR_CLIENT_REFINT_CANNOT_DELETE_WITH_NAME_130=The "%s" property \
 in the %s called "%s" references this %s
SEVERE_ERR_CLIENT_REFINT_CANNOT_DELETE_WITHOUT_NAME_131=The "%s" property \
ERR_CLIENT_REFINT_CANNOT_DELETE_WITHOUT_NAME_131=The "%s" property \
 in the %s references this %s
SEVERE_ERR_CLIENT_REFINT_CANNOT_DISABLE_WITH_NAME_132=This %s cannot be \
ERR_CLIENT_REFINT_CANNOT_DISABLE_WITH_NAME_132=This %s cannot be \
 disabled because it is referenced by the "%s" property in the %s called "%s"
SEVERE_ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME_133=This %s cannot be \
ERR_CLIENT_REFINT_CANNOT_DISABLE_WITHOUT_NAME_133=This %s cannot be \
 disabled because it is referenced by the "%s" property in the %s
SEVERE_ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION_134=An error occurred \
ERR_REFINT_UNABLE_TO_EVALUATE_TARGET_CONDITION_134=An error occurred \
 while attempting to determine if the %s in entry %s is enabled: %s
SEVERE_ERR_ADMIN_CERTIFICATE_GENERATION_135=The administration connector \
ERR_ADMIN_CERTIFICATE_GENERATION_135=The administration connector \
self-signed certificate cannot be generated because the following error \
occurred: %s
SEVERE_ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES_136=The administration \
ERR_ADMIN_CERTIFICATE_GENERATION_MISSING_FILES_136=The administration \
connector self-signed certificate cannot be generated because the following \
files are missing: %s
SEVERE_WARN_ADMIN_SET_PERMISSIONS_FAILED_137=Failed to set permissions \
 on file %s
FATAL_ERR_ADMIN_MERGING_138=The registry information of the servers could not \
ERR_ADMIN_MERGING_138=The registry information of the servers could not \
 be merged