From a91c61eed296121aedc3cc600e3336231a68a36b Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 12 Jul 2007 22:48:25 +0000
Subject: [PATCH] Commit missed files from previous revision.

---
 opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java                  |    2 
 opendj-sdk/opends/src/server/org/opends/server/admin/server/DNBuilder.java                  |   17 -
 opendj-sdk/opends/src/server/org/opends/server/admin/server/DelayedConfigAddListener.java   |   32 ++
 opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java        |   10 
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java |   25 --
 opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java                       |  373 ++++++++++++++++++++-----------
 opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java     |  226 ++++++++++++------
 7 files changed, 424 insertions(+), 261 deletions(-)

diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java b/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
index 5d0d807..46e222b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/LDAPProfile.java
@@ -33,6 +33,8 @@
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.MissingResourceException;
+import java.util.NoSuchElementException;
 import java.util.Set;
 
 
@@ -40,24 +42,115 @@
 /**
  * This class is used to map configuration elements to their LDAP
  * schema names.
+ * <p>
+ * It is possible to augment the core LDAP profile with additional
+ * profile mappings at run-time using instances of {@link Wrapper}.
+ * This is useful for unit tests which need to add and remove mock
+ * components.
  */
-public abstract class LDAPProfile {
-
-  // This class is abstract so that we can derive a mock LDAP profile
-  // for testing.
-
-  // The singleton instance.
-  private static final LDAPProfile INSTANCE = new MyLDAPProfile();
-
-
+public final class LDAPProfile {
 
   /**
-   * Protected default constructor.
+   * LDAP profile wrappers can be used to provide temporary LDAP
+   * profile information for components which do not have LDAP profile
+   * property files. These components are typically "mock" components
+   * used in unit-tests.
    */
-  protected LDAPProfile() {
-    // No implementation required.
+  public static abstract class Wrapper {
+
+    /**
+     * Default constructor.
+     */
+    protected Wrapper() {
+      // No implementation required.
+    }
+
+
+
+    /**
+     * Get the name of the LDAP attribute associated with the
+     * specified property definition.
+     * <p>
+     * The default implementation of this method is to return
+     * <code>null</code>.
+     *
+     * @param d
+     *          The managed object definition.
+     * @param pd
+     *          The property definition.
+     * @return Returns the name of the LDAP attribute associated with
+     *         the specified property definition, or <code>null</code>
+     *         if the property definition is not handled by this LDAP
+     *         profile wrapper.
+     */
+    public String getAttributeName(ManagedObjectDefinition<?, ?> d,
+        PropertyDefinition<?> pd) {
+      return null;
+    }
+
+
+
+    /**
+     * Gets the LDAP RDN attribute type for child entries of an
+     * instantiable relation.
+     * <p>
+     * The default implementation of this method is to return
+     * <code>null</code>.
+     *
+     * @param r
+     *          The instantiable relation.
+     * @return Returns the LDAP RDN attribute type for child entries
+     *         of an instantiable relation, or <code>null</code> if
+     *         the instantiable relation is not handled by this LDAP
+     *         profile wrapper.
+     */
+    public String getInstantiableRelationChildRDNType(
+        InstantiableRelationDefinition<?, ?> r) {
+      return null;
+    }
+
+
+
+    /**
+     * Get the principle object class associated with the specified
+     * definition.
+     * <p>
+     * The default implementation of this method is to return
+     * <code>null</code>.
+     *
+     * @param d
+     *          The managed object definition.
+     * @return Returns the principle object class associated with the
+     *         specified definition, or <code>null</code> if the
+     *         managed object definition is not handled by this LDAP
+     *         profile wrapper.
+     */
+    public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d) {
+      return null;
+    }
+
+
+
+    /**
+     * Get an LDAP RDN sequence associatied with a relation.
+     * <p>
+     * The default implementation of this method is to return
+     * <code>null</code>.
+     *
+     * @param r
+     *          The relation.
+     * @return Returns the LDAP RDN sequence associatied with a
+     *         relation, or <code>null</code> if the relation is not
+     *         handled by this LDAP profile wrapper.
+     */
+    public String getRelationRDNSequence(RelationDefinition<?, ?> r) {
+      return null;
+    }
   }
 
+  // The singleton instance.
+  private static final LDAPProfile INSTANCE = new LDAPProfile();
+
 
 
   /**
@@ -69,102 +162,45 @@
     return INSTANCE;
   }
 
+  // The list of profile wrappers.
+  private final LinkedList<Wrapper> profiles = new LinkedList<Wrapper>();;
+
+  // The LDAP profile property table.
+  private final ManagedObjectDefinitionResource resource =
+    ManagedObjectDefinitionResource.createForProfile("ldap");
+
+
+
+  // Prevent construction.
+  private LDAPProfile() {
+    // No implementation required.
+  }
+
 
 
   /**
-   * Concrete implementation.
+   * Get the name of the LDAP attribute associated with the specified
+   * property definition.
+   *
+   * @param d
+   *          The managed object definition.
+   * @param pd
+   *          The property definition.
+   * @return Returns the name of the LDAP attribute associated with
+   *         the specified property definition.
+   * @throws MissingResourceException
+   *           If the LDAP profile properties file associated with the
+   *           provided managed object definition could not be loaded.
    */
-  private static class MyLDAPProfile extends LDAPProfile {
-
-    // The LDAP profile property table.
-    private final ManagedObjectDefinitionResource resource;
-
-
-
-    // Private constructor.
-    private MyLDAPProfile() {
-      this.resource = ManagedObjectDefinitionResource
-          .createForProfile("ldap");
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getInstantiableRelationChildRDNType(
-        InstantiableRelationDefinition<?, ?> r) {
-      return resource.getString(r.getParentDefinition(),
-          "naming-attribute." + r.getName());
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<String> getInstantiableRelationObjectClasses(
-        InstantiableRelationDefinition<?, ?> r) {
-      return Arrays.asList(new String[] { "top", "ds-cfg-branch" });
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getRelationRDNSequence(RelationDefinition<?, ?> r) {
-      return resource.getString(r.getParentDefinition(), "rdn."
-          + r.getName());
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getObjectClass(
-        AbstractManagedObjectDefinition<?, ?> d) {
-      return resource.getString(d, "objectclass");
-    }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public List<String> getObjectClasses(
-        AbstractManagedObjectDefinition<?, ?> d) {
-      LinkedList<String> objectClasses = new LinkedList<String>();
-      Set<String> s = new HashSet<String>();
-
-      // Add the object classes from the parent hierarchy.
-      while (d != null) {
-        String oc = getObjectClass(d);
-        if (!s.contains(oc)) {
-          objectClasses.addFirst(oc);
-          s.add(oc);
-        }
-        d = d.getParent();
+  public String getAttributeName(ManagedObjectDefinition<?, ?> d,
+      PropertyDefinition<?> pd) throws MissingResourceException {
+    for (Wrapper profile : profiles) {
+      String attributeName = profile.getAttributeName(d, pd);
+      if (attributeName != null) {
+        return attributeName;
       }
-
-      // Make sure that we have top.
-      if (!s.contains("top")) {
-        objectClasses.addFirst("top");
-      }
-
-      return objectClasses;
     }
-
-
-
-    /**
-     * {@inheritDoc}
-     */
-    public String getAttributeName(ManagedObjectDefinition<?, ?> d,
-        PropertyDefinition<?> pd) {
-      return resource.getString(d, "attribute." + pd.getName());
-    }
+    return resource.getString(d, "attribute." + pd.getName());
   }
 
 
@@ -177,9 +213,21 @@
    *          The instantiable relation.
    * @return Returns the LDAP RDN attribute type for child entries of
    *         an instantiable relation.
+   * @throws MissingResourceException
+   *           If the LDAP profile properties file associated with the
+   *           provided managed object definition could not be loaded.
    */
-  public abstract String getInstantiableRelationChildRDNType(
-      InstantiableRelationDefinition<?, ?> r);
+  public String getInstantiableRelationChildRDNType(
+      InstantiableRelationDefinition<?, ?> r) throws MissingResourceException {
+    for (Wrapper profile : profiles) {
+      String rdnType = profile.getInstantiableRelationChildRDNType(r);
+      if (rdnType != null) {
+        return rdnType;
+      }
+    }
+    return resource.getString(r.getParentDefinition(), "naming-attribute."
+        + r.getName());
+  }
 
 
 
@@ -193,21 +241,10 @@
    * @return Returns the LDAP object classes associated with an
    *         instantiable relation branch.
    */
-  public abstract List<String> getInstantiableRelationObjectClasses(
-      InstantiableRelationDefinition<?, ?> r);
-
-
-
-  /**
-   * Get an LDAP RDN sequence associatied with a relation.
-   *
-   * @param r
-   *          The relation.
-   * @return Returns the LDAP RDN sequence associatied with a
-   *         relation.
-   */
-  public abstract String getRelationRDNSequence(
-      RelationDefinition<?, ?> r);
+  public List<String> getInstantiableRelationObjectClasses(
+      InstantiableRelationDefinition<?, ?> r) {
+    return Arrays.asList(new String[] { "top", "ds-cfg-branch" });
+  }
 
 
 
@@ -219,9 +256,20 @@
    *          The managed object definition.
    * @return Returns the principle object class associated with the
    *         specified definition.
+   * @throws MissingResourceException
+   *           If the LDAP profile properties file associated with the
+   *           provided managed object definition could not be loaded.
    */
-  public abstract String getObjectClass(
-      AbstractManagedObjectDefinition<?, ?> d);
+  public String getObjectClass(AbstractManagedObjectDefinition<?, ?> d)
+      throws MissingResourceException {
+    for (Wrapper profile : profiles) {
+      String objectClass = profile.getObjectClass(d);
+      if (objectClass != null) {
+        return objectClass;
+      }
+    }
+    return resource.getString(d, "objectclass");
+  }
 
 
 
@@ -236,23 +284,82 @@
    *          The managed object definition.
    * @return Returns all the object classes associated with the
    *         specified definition.
+   * @throws MissingResourceException
+   *           If the LDAP profile properties file associated with the
+   *           provided managed object definition could not be loaded.
    */
-  public abstract List<String> getObjectClasses(
-      AbstractManagedObjectDefinition<?, ?> d);
+  public List<String> getObjectClasses(AbstractManagedObjectDefinition<?, ?> d)
+      throws MissingResourceException {
+    LinkedList<String> objectClasses = new LinkedList<String>();
+    Set<String> s = new HashSet<String>();
+
+    // Add the object classes from the parent hierarchy.
+    while (d != null) {
+      String oc = getObjectClass(d);
+      if (!s.contains(oc)) {
+        objectClasses.addFirst(oc);
+        s.add(oc);
+      }
+      d = d.getParent();
+    }
+
+    // Make sure that we have top.
+    if (!s.contains("top")) {
+      objectClasses.addFirst("top");
+    }
+
+    return objectClasses;
+  }
 
 
 
   /**
-   * Get the name of the LDAP attribute associated with the specified
-   * property definition.
+   * Get an LDAP RDN sequence associatied with a relation.
    *
-   * @param d
-   *          The managed object definition.
-   * @param pd
-   *          The property definition.
-   * @return Returns the name of the LDAP attribute associated with
-   *         the specified property definition.
+   * @param r
+   *          The relation.
+   * @return Returns the LDAP RDN sequence associatied with a
+   *         relation.
+   * @throws MissingResourceException
+   *           If the LDAP profile properties file associated with the
+   *           provided managed object definition could not be loaded.
    */
-  public abstract String getAttributeName(
-      ManagedObjectDefinition<?, ?> d, PropertyDefinition<?> pd);
+  public String getRelationRDNSequence(RelationDefinition<?, ?> r)
+      throws MissingResourceException {
+    for (Wrapper profile : profiles) {
+      String rdnSequence = profile.getRelationRDNSequence(r);
+      if (rdnSequence != null) {
+        return rdnSequence;
+      }
+    }
+    return resource.getString(r.getParentDefinition(), "rdn." + r.getName());
+  }
+
+
+
+  /**
+   * Removes the last LDAP profile wrapper added using
+   * {@link #pushWrapper(org.opends.server.admin.LDAPProfile.Wrapper)}.
+   *
+   * @throws NoSuchElementException
+   *           If there are no LDAP profile wrappers.
+   */
+  public void popWrapper() throws NoSuchElementException {
+    profiles.removeFirst();
+  }
+
+
+
+  /**
+   * Decorates the core LDAP profile with the provided LDAP profile
+   * wrapper. All profile requests will be directed to the provided
+   * wrapper before being forwarded onto the core profile if the
+   * request could not be satisfied.
+   *
+   * @param wrapper
+   *          The LDAP profile wrapper.
+   */
+  public void pushWrapper(Wrapper wrapper) {
+    profiles.addFirst(wrapper);
+  }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
index 63f5b46..0cb44f8 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -112,7 +112,7 @@
    *          The type of the property.
    */
   private static class DefaultValueFinder<T> implements
-      DefaultBehaviorProviderVisitor<T, Collection<T>, ManagedObjectPath> {
+      DefaultBehaviorProviderVisitor<T, Collection<T>, Void> {
 
     /**
      * Get the default values for the specified property.
@@ -125,6 +125,9 @@
      *          The managed object path of the current managed object.
      * @param pd
      *          The property definition.
+     * @param isCreate
+     *          Indicates whether the managed object has been created
+     *          yet.
      * @return Returns the default values for the specified property.
      * @throws DefaultBehaviorException
      *           If the default values could not be retrieved or
@@ -132,20 +135,10 @@
      */
     public static <T> Collection<T> getDefaultValues(
         LDAPManagementContext context, ManagedObjectPath p,
-        PropertyDefinition<T> pd) throws DefaultBehaviorException {
-      DefaultValueFinder<T> v = new DefaultValueFinder<T>(context, pd);
-      Collection<T> values = pd.getDefaultBehaviorProvider().accept(v, p);
-
-      if (v.exception != null) {
-        throw v.exception;
-      }
-
-      if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
-        throw new DefaultBehaviorException(pd,
-            new PropertyIsSingleValuedException(pd));
-      }
-
-      return values;
+        PropertyDefinition<T> pd, boolean isCreate)
+        throws DefaultBehaviorException {
+      DefaultValueFinder<T> v = new DefaultValueFinder<T>(context, p, isCreate);
+      return v.find(p, pd);
     }
 
     // The LDAP management context.
@@ -155,16 +148,26 @@
     // values.
     private DefaultBehaviorException exception = null;
 
-    // The property definition whose default values are required.
-    private final PropertyDefinition<T> pd;
+    // Indicates whether the managed object has been created yet.
+    private final boolean isCreate;
+
+    // The path of the managed object containing the first property.
+    private final ManagedObjectPath firstPath;
+
+    // The path of the managed object containing the next property.
+    private ManagedObjectPath nextPath = null;
+
+    // The next property whose default values were required.
+    private PropertyDefinition<T> nextProperty = null;
 
 
 
     // Private constructor.
     private DefaultValueFinder(LDAPManagementContext context,
-        PropertyDefinition<T> pd) {
+        ManagedObjectPath p, boolean isCreate) {
       this.context = context;
-      this.pd = pd;
+      this.firstPath = p;
+      this.isCreate = isCreate;
     }
 
 
@@ -173,14 +176,14 @@
      * {@inheritDoc}
      */
     public Collection<T> visitAbsoluteInherited(
-        AbsoluteInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
+        AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) {
       try {
         return getInheritedProperty(d.getManagedObjectPath(), d
             .getManagedObjectDefinition(), d.getPropertyName());
       } catch (DefaultBehaviorException e) {
-        exception = new DefaultBehaviorException(pd, e);
+        exception = e;
+        return Collections.emptySet();
       }
-      return Collections.emptySet();
     }
 
 
@@ -189,7 +192,7 @@
      * {@inheritDoc}
      */
     public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d,
-        ManagedObjectPath p) {
+        Void p) {
       return Collections.emptySet();
     }
 
@@ -199,15 +202,15 @@
      * {@inheritDoc}
      */
     public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d,
-        ManagedObjectPath p) {
+        Void p) {
       Collection<String> stringValues = d.getDefaultValues();
       List<T> values = new ArrayList<T>(stringValues.size());
 
       for (String stringValue : stringValues) {
         try {
-          values.add(pd.decodeValue(stringValue));
+          values.add(nextProperty.decodeValue(stringValue));
         } catch (IllegalPropertyValueStringException e) {
-          exception = new DefaultBehaviorException(pd, e);
+          exception = new DefaultBehaviorException(nextProperty, e);
           break;
         }
       }
@@ -221,14 +224,14 @@
      * {@inheritDoc}
      */
     public Collection<T> visitRelativeInherited(
-        RelativeInheritedDefaultBehaviorProvider<T> d, ManagedObjectPath p) {
+        RelativeInheritedDefaultBehaviorProvider<T> d, Void p) {
       try {
-        return getInheritedProperty(d.getManagedObjectPath(p), d
+        return getInheritedProperty(d.getManagedObjectPath(nextPath), d
             .getManagedObjectDefinition(), d.getPropertyName());
       } catch (DefaultBehaviorException e) {
-        exception = new DefaultBehaviorException(pd, e);
+        exception = e;
+        return Collections.emptySet();
       }
-      return Collections.emptySet();
     }
 
 
@@ -237,81 +240,142 @@
      * {@inheritDoc}
      */
     public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d,
-        ManagedObjectPath p) {
+        Void p) {
       return Collections.emptySet();
     }
 
 
 
+    // Find the default values for the next path/property.
+    private Collection<T> find(ManagedObjectPath p, PropertyDefinition<T> pd)
+        throws DefaultBehaviorException {
+      this.nextPath = p;
+      this.nextProperty = pd;
+
+      Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept(
+          this, null);
+
+      if (exception != null) {
+        throw exception;
+      }
+
+      if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
+        throw new DefaultBehaviorException(pd,
+            new PropertyIsSingleValuedException(pd));
+      }
+
+      return values;
+    }
+
+
+
     // Get an inherited property value.
+    @SuppressWarnings("unchecked")
     private Collection<T> getInheritedProperty(ManagedObjectPath target,
         AbstractManagedObjectDefinition<?, ?> d, String propertyName)
         throws DefaultBehaviorException {
+      // First check that the requested type of managed object
+      // corresponds to the path.
+      AbstractManagedObjectDefinition<?, ?> supr = target
+          .getManagedObjectDefinition();
+      if (!supr.isParentOf(d)) {
+        throw new DefaultBehaviorException(nextProperty,
+            new DefinitionDecodingException(Reason.WRONG_TYPE_INFORMATION));
+      }
+
+      // Save the current property in case of recursion.
+      PropertyDefinition<T> pd1 = nextProperty;
+
       try {
-        // First check that the requested type of managed object
-        // corresponds to the path.
-        AbstractManagedObjectDefinition<?, ?> supr = target
-            .getManagedObjectDefinition();
-        if (!supr.isParentOf(d)) {
-          throw new DefinitionDecodingException(Reason.WRONG_TYPE_INFORMATION);
-        }
+        // If the path relates to the current managed object and the
+        // managed object is in the process of being created it won't
+        // exist, so we should just use the default values of the
+        // referenced property.
+        if (isCreate && firstPath.equals(target)) {
+          PropertyDefinition<T> pd2;
+          try {
+            // FIXME: we use the definition taken from the default
+            // behavior here when we should really use the exact
+            // definition of the component being created.
+            PropertyDefinition<?> pdTmp = d.getPropertyDefinition(propertyName);
+            pd2 = pd1.getClass().cast(pdTmp);
+          } catch (IllegalArgumentException e) {
+            throw new PropertyNotFoundException(propertyName);
+          } catch (ClassCastException e) {
+            // FIXME: would be nice to throw a better exception here.
+            throw new PropertyNotFoundException(propertyName);
+          }
 
-        // Get the actual managed object definition.
-        LdapName dn = LDAPNameBuilder.create(target, context.getLDAPProfile());
-        ManagedObjectDefinition<?, ?> mod = getEntryDefinition(context, d, dn);
-
-        PropertyDefinition<?> pd2;
-        try {
-          pd2 = mod.getPropertyDefinition(propertyName);
-        } catch (IllegalArgumentException e) {
-          throw new PropertyNotFoundException(propertyName);
-        }
-
-        String attrID = context.getLDAPProfile().getAttributeName(mod, pd2);
-        Attributes attributes = context.getLDAPConnection().readEntry(dn,
-            Collections.singleton(attrID));
-        Attribute attr = attributes.get(attrID);
-        if (attr == null || attr.size() == 0) {
           // Recursively retrieve this property's default values.
-          Collection<?> tmp = getDefaultValues(context, target, pd2);
+          Collection<T> tmp = find(target, pd2);
           Collection<T> values = new ArrayList<T>(tmp.size());
-          for (Object o : tmp) {
-            T value;
-            try {
-              value = pd.castValue(o);
-            } catch (ClassCastException e) {
-              throw new IllegalPropertyValueException(pd, o);
-            }
-            pd.validateValue(value);
+          for (T value : tmp) {
+            pd1.validateValue(value);
             values.add(value);
           }
           return values;
         } else {
-          Collection<T> values = new LinkedList<T>();
-          NamingEnumeration<?> ne = attr.getAll();
-          while (ne.hasMore()) {
-            Object value = ne.next();
-            if (value != null) {
-              values.add(pd.decodeValue(value.toString()));
-            }
+          // Get the actual managed object definition.
+          LdapName dn = LDAPNameBuilder
+              .create(target, context.getLDAPProfile());
+          ManagedObjectDefinition<?, ?> mod =
+            getEntryDefinition(context, d, dn);
+
+          PropertyDefinition<T> pd2;
+          try {
+            PropertyDefinition<?> pdTmp = mod
+                .getPropertyDefinition(propertyName);
+            pd2 = pd1.getClass().cast(pdTmp);
+          } catch (IllegalArgumentException e) {
+            throw new PropertyNotFoundException(propertyName);
+          } catch (ClassCastException e) {
+            // FIXME: would be nice to throw a better exception here.
+            throw new PropertyNotFoundException(propertyName);
           }
-          return values;
+
+          String attrID = context.getLDAPProfile().getAttributeName(mod, pd2);
+          Attributes attributes = context.getLDAPConnection().readEntry(dn,
+              Collections.singleton(attrID));
+          Attribute attr = attributes.get(attrID);
+          if (attr == null || attr.size() == 0) {
+            // Recursively retrieve this property's default values.
+            Collection<T> tmp = find(target, pd2);
+            Collection<T> values = new ArrayList<T>(tmp.size());
+            for (T value : tmp) {
+              pd1.validateValue(value);
+              values.add(value);
+            }
+            return values;
+          } else {
+            Collection<T> values = new LinkedList<T>();
+            NamingEnumeration<?> ne = attr.getAll();
+            while (ne.hasMore()) {
+              Object value = ne.next();
+              if (value != null) {
+                values.add(pd1.decodeValue(value.toString()));
+              }
+            }
+            return values;
+          }
         }
+      } catch (DefaultBehaviorException e) {
+        // Wrap any errors due to recursion.
+        throw new DefaultBehaviorException(pd1, e);
       } catch (DefinitionDecodingException e) {
-        throw new DefaultBehaviorException(pd, e);
+        throw new DefaultBehaviorException(pd1, e);
       } catch (PropertyNotFoundException e) {
-        throw new DefaultBehaviorException(pd, e);
+        throw new DefaultBehaviorException(pd1, e);
       } catch (IllegalPropertyValueException e) {
-        throw new DefaultBehaviorException(pd, e);
+        throw new DefaultBehaviorException(pd1, e);
       } catch (IllegalPropertyValueStringException e) {
-        throw new DefaultBehaviorException(pd, e);
+        throw new DefaultBehaviorException(pd1, e);
       } catch (NameNotFoundException e) {
-        throw new DefaultBehaviorException(pd,
+        throw new DefaultBehaviorException(pd1,
             new ManagedObjectNotFoundException());
       } catch (NoPermissionException e) {
-        throw new DefaultBehaviorException(pd, new AuthorizationException(e));
+        throw new DefaultBehaviorException(pd1, new AuthorizationException(e));
       } catch (NamingException e) {
-        throw new DefaultBehaviorException(pd, new CommunicationException(e));
+        throw new DefaultBehaviorException(pd1, new CommunicationException(e));
       }
     }
   };
@@ -462,6 +526,7 @@
   /**
    * {@inheritDoc}
    */
+  @SuppressWarnings("unchecked")
   public <M extends ConfigurationClient, N extends M>
       ManagedObject<N> createChild(
       OptionalRelationDefinition<M, ?> r, ManagedObjectDefinition<N, ?> d,
@@ -878,7 +943,7 @@
       PropertyDefinition<T> pd) throws DefaultBehaviorException {
     try {
       Collection<T> defaultValues = DefaultValueFinder.getDefaultValues(
-          context, p, pd);
+          context, p, pd, true);
       properties.addProperty(pd, defaultValues, Collections.<T> emptySet());
     } catch (DefaultBehaviorException e) {
       // Make sure that we have still created the property.
@@ -924,7 +989,8 @@
     // Get the property's default values.
     Collection<T> defaultValues;
     try {
-      defaultValues = DefaultValueFinder.getDefaultValues(context, p, pd);
+      defaultValues = DefaultValueFinder.getDefaultValues(context, p, pd,
+          false);
     } catch (DefaultBehaviorException e) {
       defaultValues = Collections.emptySet();
       exception = e;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
index 6b191f0..6828bc9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/client/ldap/LDAPManagementContext.java
@@ -47,7 +47,7 @@
    * connection.
    *
    * @param connection
-   *          The LDAP connectin.
+   *          The LDAP connection.
    * @return Returns the new management context.
    */
   public static ManagementContext createFromContext(LDAPConnection connection) {
@@ -55,29 +55,6 @@
     return new LDAPManagementContext(connection, LDAPProfile.getInstance());
   }
 
-
-
-  /**
-   * Create a new LDAP management context using the provided LDAP
-   * connection and LDAP profile.
-   * <p>
-   * This constructor is primarily intended for testing purposes so
-   * that unit tests can provide mock LDAP connections and LDAP
-   * profiles.
-   *
-   * @param connection
-   *          The LDAP connection.
-   * @param profile
-   *          The LDAP profile which should be used to construct LDAP
-   *          requests and decode LDAP responses.
-   * @return Returns the new management context.
-   */
-  public static ManagementContext createFromContext(LDAPConnection connection,
-      LDAPProfile profile) {
-    Validator.ensureNotNull(connection, profile);
-    return new LDAPManagementContext(connection, profile);
-  }
-
   // The LDAP connection.
   private final LDAPConnection connection;
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/server/DNBuilder.java b/opendj-sdk/opends/src/server/org/opends/server/admin/server/DNBuilder.java
index 1a832f4..118ec71 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/server/DNBuilder.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/server/DNBuilder.java
@@ -99,23 +99,8 @@
    * Create a new DN builder.
    */
   public DNBuilder() {
-    this(LDAPProfile.getInstance());
-  }
-
-
-
-  /**
-   * Create a new DN builder with the provided LDAP profile.
-   * <p>
-   * This constructor is package private and only intended for testing
-   * purposes against a mock LDAP profile.
-   *
-   * @param profile
-   *          The LDAP profile to use when building the DN.
-   */
-  DNBuilder(LDAPProfile profile) {
     this.dn = DN.nullDN();
-    this.profile = profile;
+    this.profile = LDAPProfile.getInstance();
   }
 
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/server/DelayedConfigAddListener.java b/opendj-sdk/opends/src/server/org/opends/server/admin/server/DelayedConfigAddListener.java
index 7d8be0f..cbfd450 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/server/DelayedConfigAddListener.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/server/DelayedConfigAddListener.java
@@ -27,6 +27,7 @@
 package org.opends.server.admin.server;
 
 
+
 import static org.opends.server.loggers.debug.DebugLogger.*;
 import org.opends.server.loggers.debug.DebugTracer;
 
@@ -117,8 +118,7 @@
   /**
    * {@inheritDoc}
    */
-  public ConfigChangeResult applyConfigurationAdd(
-      ConfigEntry configEntry) {
+  public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry) {
     if (configEntry.getDN().equals(child)) {
       // The subordinate entry matched our criteria so register the
       // listener(s).
@@ -160,4 +160,32 @@
     return true;
   }
 
+
+
+  /**
+   * Gets the delayed add listener.
+   * <p>
+   * This method is provided for unit-testing.
+   *
+   * @return Returns the delayed add listener, or <code>null</code>
+   *         if this listener is delaying a delete listener.
+   */
+  ConfigAddListener getDelayedAddListener() {
+    return delayedAddListener;
+  }
+
+
+
+  /**
+   * Gets the delayed delete listener.
+   * <p>
+   * This method is provided for unit-testing.
+   *
+   * @return Returns the delayed delete listener, or <code>null</code>
+   *         if this listener is delaying a add listener.
+   */
+  ConfigDeleteListener getDelayedDeleteListener() {
+    return delayedDeleteListener;
+  }
+
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java b/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
index f4c3b0c..49be1e0 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/admin/server/ServerManagedObject.java
@@ -598,7 +598,7 @@
       throws IllegalArgumentException {
     validateRelationDefinition(d);
 
-    DN baseDN = DNBuilder.create(path);
+    DN baseDN = DNBuilder.create(path, d).getParent();
     deregisterAddListener(baseDN, listener);
   }
 
@@ -666,7 +666,7 @@
       ConfigurationDeleteListener<M> listener) throws IllegalArgumentException {
     validateRelationDefinition(d);
 
-    DN baseDN = DNBuilder.create(path);
+    DN baseDN = DNBuilder.create(path, d).getParent();
     deregisterDeleteListener(baseDN, listener);
   }
 
@@ -985,7 +985,7 @@
       OptionalRelationDefinition<?, M> d, ConfigurationAddListener<M> listener)
       throws IllegalArgumentException, ConfigException {
     validateRelationDefinition(d);
-    DN baseDN = DNBuilder.create(path);
+    DN baseDN = DNBuilder.create(path, d).getParent();
     ConfigAddListener adaptor = new ConfigAddListenerAdaptor<M>(path, d,
         listener);
     registerAddListener(baseDN, adaptor);
@@ -1061,7 +1061,7 @@
       ConfigurationDeleteListener<M> listener) throws IllegalArgumentException,
       ConfigException {
     validateRelationDefinition(d);
-    DN baseDN = DNBuilder.create(path);
+    DN baseDN = DNBuilder.create(path, d).getParent();
     ConfigDeleteListener adaptor = new ConfigDeleteListenerAdaptor<M>(path, d,
         listener);
     registerDeleteListener(baseDN, adaptor);
@@ -1208,7 +1208,7 @@
             delayedListener);
         parentDN = parentDN.getParent();
       } else {
-        configEntry.registerAddListener(delayedListener);
+        relationEntry.registerAddListener(delayedListener);
         return;
       }
     }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
index eb27982..56e7604 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -666,7 +666,7 @@
         "The backen name is which the admin data will be registered. " +
         "This is a required argument");
     registerMessage(MSGID_ADMIN_UNABLE_TO_REGISTER_LISTENER,
-        "Unable to register an add/delete listener against the entry %s " +
+        "Unable to register an add/delete listener against the entry \"%s\" " +
         "because it does not exist in the configuration");
   }
 }

--
Gitblit v1.10.0