From 2fef5aa0046548cb88034553f522d907195a19f7 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Mon, 02 Dec 2013 10:47:18 +0000
Subject: [PATCH] OpenDJ 3 : config framework

---
 opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java | 1919 +++++++++++++++++++++++++++--------------------------------
 1 files changed, 868 insertions(+), 1,051 deletions(-)

diff --git a/opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java b/opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java
index e570e0d..da13625 100644
--- a/opendj-admin/src/main/java/org/opends/server/admin/AbstractManagedObjectDefinition.java
+++ b/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;
+    }
 }

--
Gitblit v1.10.0