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); } } 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; 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; 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(); } 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; } } 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; } } 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"); } }