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

Nicolas Capponi
02.13.2013 e1b0862e7251d4f8ec159d704e8db0d5cf1ba212
OpenDJ 3 : config framework

Reducing compilation errors in org.opends.server.admin packages :
all classes but one in package org.opends.server.admin.client.ldap compile

* Simple changes in org.opends.server.admin.client.ldap package
** replace Message class by LocalizableMessage
** use Validator class from SDK
** other minor changes
4 files modified
1134 ■■■■ changed files
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPDriver.java 1065 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPManagedObject.java 8 ●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPManagementContext.java 59 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/package-info.java 2 ●●●●● patch | view | raw | blame | history
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPDriver.java
@@ -27,8 +27,6 @@
 */
package org.opends.server.admin.client.ldap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -48,7 +46,9 @@
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.admin.client.RootCfgClient;
import org.forgerock.opendj.admin.meta.RootCfgDefn;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.Configuration;
@@ -81,626 +81,541 @@
import org.opends.server.admin.client.OperationRejectedException.OperationType;
import org.opends.server.admin.client.spi.Driver;
import org.opends.server.admin.client.spi.PropertySet;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.meta.RootCfgDefn;
/**
 * The LDAP management context driver implementation.
 */
final class LDAPDriver extends Driver {
  /**
   * A visitor which is used to decode property LDAP values.
   */
  private static final class ValueDecoder extends
      PropertyDefinitionVisitor<Object, String> {
    /**
     * A visitor which is used to decode property LDAP values.
     */
    private static final class ValueDecoder extends PropertyDefinitionVisitor<Object, String> {
        /**
         * Decodes the provided property LDAP value.
         *
         * @param <PD>
         *            The type of the property.
         * @param pd
         *            The property definition.
         * @param value
         *            The LDAP string representation.
         * @return Returns the decoded LDAP value.
         * @throws IllegalPropertyValueStringException
         *             If the property value could not be decoded because it was
         *             invalid.
         */
        public static <PD> PD decode(PropertyDefinition<PD> pd, Object value)
                throws IllegalPropertyValueStringException {
            String s = String.valueOf(value);
            return pd.castValue(pd.accept(new ValueDecoder(), s));
        }
        // Prevent instantiation.
        private ValueDecoder() {
            // No implementation required.
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <C extends ConfigurationClient, S extends Configuration> Object visitAggregation(
                AggregationPropertyDefinition<C, S> d, String p) {
            // Aggregations values are stored as full DNs in LDAP, but
            // just their common name is exposed in the admin framework.
            try {
                Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d.getRelationDefinition(), p);
                return reference.getName();
            } catch (IllegalArgumentException e) {
                throw new IllegalPropertyValueStringException(d, p);
            }
        }
        /**
         * {@inheritDoc}
         */
        @Override
        public <T> Object visitUnknown(PropertyDefinition<T> d, String p) throws UnknownPropertyDefinitionException {
            // By default the property definition's decoder will do.
            return d.decodeValue(p);
        }
    }
    // The LDAP connection.
    private final LDAPConnection connection;
    // The LDAP management context.
    private final LDAPManagementContext context;
    // The LDAP profile which should be used to construct LDAP
    // requests and decode LDAP responses.
    private final LDAPProfile profile;
    /**
     * Decodes the provided property LDAP value.
     * Creates a new LDAP driver using the specified LDAP connection and
     * profile.
     *
     * @param <PD>
     *          The type of the property.
     * @param pd
     *          The property definition.
     * @param value
     *          The LDAP string representation.
     * @return Returns the decoded LDAP value.
     * @throws IllegalPropertyValueStringException
     *           If the property value could not be decoded because it
     *           was invalid.
     * @param context
     *            The LDAP management context.
     * @param connection
     *            The LDAP connection.
     * @param profile
     *            The LDAP profile.
     */
    public static <PD> PD decode(PropertyDefinition<PD> pd, Object value)
        throws IllegalPropertyValueStringException {
      String s = String.valueOf(value);
      return pd.castValue(pd.accept(new ValueDecoder(), s));
    public LDAPDriver(LDAPManagementContext context, LDAPConnection connection, LDAPProfile profile) {
        this.context = context;
        this.connection = connection;
        this.profile = profile;
    }
    // Prevent instantiation.
    private ValueDecoder() {
      // No implementation required.
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <C extends ConfigurationClient, S extends Configuration>
    Object visitAggregation(AggregationPropertyDefinition<C, S> d, String p) {
      // Aggregations values are stored as full DNs in LDAP, but
      // just their common name is exposed in the admin framework.
      try {
        Reference<C, S> reference = Reference.parseDN(d.getParentPath(), d
            .getRelationDefinition(), p);
        return reference.getName();
      } catch (IllegalArgumentException e) {
        throw new IllegalPropertyValueStringException(d, p);
      }
    public void close() {
        connection.unbind();
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public <T> Object visitUnknown(PropertyDefinition<T> d, String p)
        throws UnknownPropertyDefinitionException {
      // By default the property definition's decoder will do.
      return d.decodeValue(p);
    }
  }
    public <C extends ConfigurationClient, S extends Configuration> ManagedObject<? extends C> getManagedObject(
            ManagedObjectPath<C, S> path) throws DefinitionDecodingException, ManagedObjectDecodingException,
            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
        if (!managedObjectExists(path)) {
            throw new ManagedObjectNotFoundException();
        }
  // The LDAP connection.
  private final LDAPConnection connection;
  // The LDAP management context.
  private final LDAPManagementContext context;
  // The LDAP profile which should be used to construct LDAP
  // requests and decode LDAP responses.
  private final LDAPProfile profile;
  /**
   * Creates a new LDAP driver using the specified LDAP connection and
   * profile.
   *
   * @param context
   *          The LDAP management context.
   * @param connection
   *          The LDAP connection.
   * @param profile
   *          The LDAP profile.
   */
  public LDAPDriver(LDAPManagementContext context, LDAPConnection connection,
      LDAPProfile profile) {
    this.context = context;
    this.connection = connection;
    this.profile = profile;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void close() {
    connection.unbind();
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <C extends ConfigurationClient, S extends Configuration>
  ManagedObject<? extends C> getManagedObject(
      ManagedObjectPath<C, S> path) throws DefinitionDecodingException,
      ManagedObjectDecodingException, ManagedObjectNotFoundException,
      AuthorizationException, CommunicationException {
    if (!managedObjectExists(path)) {
      throw new ManagedObjectNotFoundException();
    }
    try {
      // Read the entry associated with the managed object.
      LdapName dn = LDAPNameBuilder.create(path, profile);
      AbstractManagedObjectDefinition<C, S> d = path
          .getManagedObjectDefinition();
      ManagedObjectDefinition<? extends C, ? extends S> mod =
        getEntryDefinition(d, dn);
      ArrayList<String> attrIds = new ArrayList<String>();
      for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
        String attrId = profile.getAttributeName(mod, pd);
        attrIds.add(attrId);
      }
      Attributes attributes = connection.readEntry(dn, attrIds);
      // Build the managed object's properties.
      List<PropertyException> exceptions = new LinkedList<PropertyException>();
      PropertySet newProperties = new PropertySet();
      for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
        String attrID = profile.getAttributeName(mod, pd);
        Attribute attribute = attributes.get(attrID);
        try {
          decodeProperty(newProperties, path, pd, attribute);
        } catch (PropertyException e) {
          exceptions.add(e);
            // Read the entry associated with the managed object.
            LdapName dn = LDAPNameBuilder.create(path, profile);
            AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
            ManagedObjectDefinition<? extends C, ? extends S> mod = getEntryDefinition(d, dn);
            ArrayList<String> attrIds = new ArrayList<String>();
            for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
                String attrId = profile.getAttributeName(mod, pd);
                attrIds.add(attrId);
            }
            Attributes attributes = connection.readEntry(dn, attrIds);
            // Build the managed object's properties.
            List<PropertyException> exceptions = new LinkedList<PropertyException>();
            PropertySet newProperties = new PropertySet();
            for (PropertyDefinition<?> pd : mod.getAllPropertyDefinitions()) {
                String attrID = profile.getAttributeName(mod, pd);
                Attribute attribute = attributes.get(attrID);
                try {
                    decodeProperty(newProperties, path, pd, attribute);
                } catch (PropertyException e) {
                    exceptions.add(e);
                }
            }
            // If there were no decoding problems then return the object,
            // otherwise throw an operations exception.
            ManagedObject<? extends C> mo = createExistingManagedObject(mod, path, newProperties);
            if (exceptions.isEmpty()) {
                return mo;
            } else {
                throw new ManagedObjectDecodingException(mo, exceptions);
            }
        } catch (NameNotFoundException e) {
            throw new ManagedObjectNotFoundException();
        } catch (NoPermissionException e) {
            throw new AuthorizationException(e);
        } catch (NamingException e) {
            throw new CommunicationException(e);
        }
      }
      // If there were no decoding problems then return the object,
      // otherwise throw an operations exception.
      ManagedObject<? extends C> mo = createExistingManagedObject(mod, path,
          newProperties);
      if (exceptions.isEmpty()) {
        return mo;
      } else {
        throw new ManagedObjectDecodingException(mo, exceptions);
      }
    } catch (NameNotFoundException e) {
      throw new ManagedObjectNotFoundException();
    } catch (NoPermissionException e) {
      throw new AuthorizationException(e);
    } catch (NamingException e) {
      throw new CommunicationException(e);
    }
  }
  /**
   * {@inheritDoc}
   */
  @SuppressWarnings("unchecked")
  @Override
  public <C extends ConfigurationClient, S extends Configuration, PD>
  SortedSet<PD> getPropertyValues(ManagedObjectPath<C, S> path,
      PropertyDefinition<PD> pd) throws IllegalArgumentException,
      DefinitionDecodingException, AuthorizationException,
      ManagedObjectNotFoundException, CommunicationException,
      PropertyException {
    // Check that the requested property is from the definition
    // associated with the path.
    AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
    PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
    if (tmp != pd) {
      throw new IllegalArgumentException("The property " + pd.getName()
          + " is not associated with a " + d.getName());
    }
    if (!managedObjectExists(path)) {
      throw new ManagedObjectNotFoundException();
    }
    try {
      // Read the entry associated with the managed object.
      LdapName dn = LDAPNameBuilder.create(path, profile);
      ManagedObjectDefinition<? extends C, ? extends S> mod;
      mod = getEntryDefinition(d, dn);
      // Make sure we use the correct property definition, the
      // provided one might have been overridden in the resolved
      // definition.
      pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
      String attrID = profile.getAttributeName(mod, pd);
      Attributes attributes = connection.readEntry(dn, Collections
          .singleton(attrID));
      Attribute attribute = attributes.get(attrID);
      // Decode the values.
      SortedSet<PD> values = new TreeSet<PD>(pd);
      if (attribute != null) {
        NamingEnumeration<?> ldapValues = attribute.getAll();
        while (ldapValues.hasMore()) {
          Object obj = ldapValues.next();
          if (obj != null) {
            PD value = ValueDecoder.decode(pd, obj);
            values.add(value);
          }
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public <C extends ConfigurationClient, S extends Configuration, PD> SortedSet<PD> getPropertyValues(
            ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) throws IllegalArgumentException,
            DefinitionDecodingException, AuthorizationException, ManagedObjectNotFoundException,
            CommunicationException, PropertyException {
        // Check that the requested property is from the definition
        // associated with the path.
        AbstractManagedObjectDefinition<C, S> d = path.getManagedObjectDefinition();
        PropertyDefinition<?> tmp = d.getPropertyDefinition(pd.getName());
        if (tmp != pd) {
            throw new IllegalArgumentException("The property " + pd.getName() + " is not associated with a "
                    + d.getName());
        }
      }
      // Sanity check the returned values.
      if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
        throw new PropertyIsSingleValuedException(pd);
      }
      if (values.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
        throw new PropertyIsMandatoryException(pd);
      }
      if (values.isEmpty()) {
        // Use the property's default values.
        values.addAll(findDefaultValues(path.asSubType(mod), pd, false));
      }
      return values;
    } catch (NameNotFoundException e) {
      throw new ManagedObjectNotFoundException();
    } catch (NoPermissionException e) {
      throw new AuthorizationException(e);
    } catch (NamingException e) {
      throw new CommunicationException(e);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
    return new LDAPManagedObject<RootCfgClient>(this,
        RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(),
        new PropertySet(), true, null);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <C extends ConfigurationClient, S extends Configuration>
  String[] listManagedObjects(
      ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
      AbstractManagedObjectDefinition<? extends C, ? extends S> d)
      throws IllegalArgumentException, ManagedObjectNotFoundException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(parent, rd);
    if (!managedObjectExists(parent)) {
      throw new ManagedObjectNotFoundException();
    }
    // Get the search base DN.
    LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
    // Retrieve only those entries which are sub-types of the
    // specified definition.
    StringBuilder builder = new StringBuilder();
    builder.append("(objectclass=");
    builder.append(profile.getObjectClass(d));
    builder.append(')');
    String filter = builder.toString();
    List<String> children = new ArrayList<String>();
    try {
      for (LdapName child : connection.listEntries(dn, filter)) {
        children.add(child.getRdn(child.size() - 1).getValue().toString());
      }
    } catch (NameNotFoundException e) {
      // Ignore this - it means that the base entry does not exist
      // (which it might not if this managed object has just been
      // created.
    } catch (NamingException e) {
      adaptNamingException(e);
    }
    return children.toArray(new String[children.size()]);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public <C extends ConfigurationClient, S extends Configuration>
  String[] listManagedObjects(
      ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
      AbstractManagedObjectDefinition<? extends C, ? extends S> d)
      throws IllegalArgumentException, ManagedObjectNotFoundException,
      AuthorizationException, CommunicationException {
    validateRelationDefinition(parent, rd);
    if (!managedObjectExists(parent)) {
      throw new ManagedObjectNotFoundException();
    }
    // Get the search base DN.
    LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
    // Retrieve only those entries which are sub-types of the
    // specified definition.
    StringBuilder builder = new StringBuilder();
    builder.append("(objectclass=");
    builder.append(profile.getObjectClass(d));
    builder.append(')');
    String filter = builder.toString();
    List<String> children = new ArrayList<String>();
    try {
      for (LdapName child : connection.listEntries(dn, filter)) {
        children.add(child.getRdn(child.size() - 1).getValue().toString());
      }
    } catch (NameNotFoundException e) {
      // Ignore this - it means that the base entry does not exist
      // (which it might not if this managed object has just been
      // created.
    } catch (NamingException e) {
      adaptNamingException(e);
    }
    return children.toArray(new String[children.size()]);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean managedObjectExists(ManagedObjectPath<?, ?> path)
      throws ManagedObjectNotFoundException, AuthorizationException,
      CommunicationException {
    if (path.isEmpty()) {
      return true;
    }
    ManagedObjectPath<?, ?> parent = path.parent();
    LdapName dn = LDAPNameBuilder.create(parent, profile);
    if (!entryExists(dn)) {
      throw new ManagedObjectNotFoundException();
    }
    dn = LDAPNameBuilder.create(path, profile);
    return entryExists(dn);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected <C extends ConfigurationClient, S extends Configuration>
  void deleteManagedObject(
      ManagedObjectPath<C, S> path) throws OperationRejectedException,
      AuthorizationException, CommunicationException {
    // Delete the entry and any subordinate entries.
    LdapName dn = LDAPNameBuilder.create(path, profile);
    try {
      connection.deleteSubtree(dn);
    } catch (OperationNotSupportedException e) {
      // Unwilling to perform.
      AbstractManagedObjectDefinition<?, ?> d =
        path.getManagedObjectDefinition();
      if (e.getMessage() == null) {
        throw new OperationRejectedException(OperationType.DELETE, d
            .getUserFriendlyName());
      } else {
        Message m = Message.raw("%s", e.getMessage());
        throw new OperationRejectedException(OperationType.DELETE, d
            .getUserFriendlyName(), m);
      }
    } catch (NamingException e) {
      adaptNamingException(e);
    }
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected LDAPManagementContext getManagementContext() {
    return context;
  }
  /**
   * Adapts a naming exception to an appropriate admin client
   * exception.
   *
   * @param ne
   *          The naming exception.
   * @throws CommunicationException
   *           If the naming exception mapped to a communication
   *           exception.
   * @throws AuthorizationException
   *           If the naming exception mapped to an authorization
   *           exception.
   */
  void adaptNamingException(NamingException ne) throws CommunicationException,
      AuthorizationException {
    try {
      throw ne;
    } catch (javax.naming.CommunicationException e) {
      throw new CommunicationException(e);
    } catch (javax.naming.ServiceUnavailableException e) {
      throw new CommunicationException(e);
    } catch (javax.naming.NoPermissionException e) {
      throw new AuthorizationException(e);
    } catch (NamingException e) {
      // Just treat it as a communication problem.
      throw new CommunicationException(e);
    }
  }
  /**
   * Determines whether the named LDAP entry exists.
   *
   * @param dn
   *          The LDAP entry name.
   * @return Returns <code>true</code> if the named LDAP entry
   *         exists.
   * @throws AuthorizationException
   *           If the server refuses to make the determination because
   *           the client does not have the correct privileges.
   * @throws CommunicationException
   *           If the client cannot contact the server due to an
   *           underlying communication problem.
   */
  boolean entryExists(LdapName dn) throws CommunicationException,
      AuthorizationException {
    try {
      return connection.entryExists(dn);
    } catch (NamingException e) {
      adaptNamingException(e);
    }
    return false;
  }
  /**
   * Gets the LDAP connection used for interacting with the server.
   *
   * @return Returns the LDAP connection used for interacting with the
   *         server.
   */
  LDAPConnection getLDAPConnection() {
    return connection;
  }
  /**
   * Gets the LDAP profile which should be used to construct LDAP
   * requests and decode LDAP responses.
   *
   * @return Returns the LDAP profile which should be used to
   *         construct LDAP requests and decode LDAP responses.
   */
  LDAPProfile getLDAPProfile() {
    return profile;
  }
  // Create a managed object which already exists on the server.
  private <M extends ConfigurationClient, N extends Configuration>
  ManagedObject<M> createExistingManagedObject(
      ManagedObjectDefinition<M, N> d,
      ManagedObjectPath<? super M, ? super N> p, PropertySet properties) {
    RelationDefinition<?, ?> rd = p.getRelationDefinition();
    PropertyDefinition<?> pd = null;
    if (rd instanceof InstantiableRelationDefinition) {
      InstantiableRelationDefinition<?, ?> ird =
        (InstantiableRelationDefinition<?, ?>) rd;
      pd = ird.getNamingPropertyDefinition();
    }
    return new LDAPManagedObject<M>(this, d, p.asSubType(d), properties, true,
        pd);
  }
  // Create a property using the provided string values.
  private <PD> void decodeProperty(PropertySet newProperties,
      ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd,
      Attribute attribute) throws PropertyException,
      NamingException {
    PropertyException exception = null;
    // Get the property's active values.
    SortedSet<PD> activeValues = new TreeSet<PD>(pd);
    if (attribute != null) {
      NamingEnumeration<?> ldapValues = attribute.getAll();
      while (ldapValues.hasMore()) {
        Object obj = ldapValues.next();
        if (obj != null) {
          PD value = ValueDecoder.decode(pd, obj);
          activeValues.add(value);
        if (!managedObjectExists(path)) {
            throw new ManagedObjectNotFoundException();
        }
      }
        try {
            // Read the entry associated with the managed object.
            LdapName dn = LDAPNameBuilder.create(path, profile);
            ManagedObjectDefinition<? extends C, ? extends S> mod;
            mod = getEntryDefinition(d, dn);
            // Make sure we use the correct property definition, the
            // provided one might have been overridden in the resolved
            // definition.
            pd = (PropertyDefinition<PD>) mod.getPropertyDefinition(pd.getName());
            String attrID = profile.getAttributeName(mod, pd);
            Attributes attributes = connection.readEntry(dn, Collections.singleton(attrID));
            Attribute attribute = attributes.get(attrID);
            // Decode the values.
            SortedSet<PD> values = new TreeSet<PD>(pd);
            if (attribute != null) {
                NamingEnumeration<?> ldapValues = attribute.getAll();
                while (ldapValues.hasMore()) {
                    Object obj = ldapValues.next();
                    if (obj != null) {
                        PD value = ValueDecoder.decode(pd, obj);
                        values.add(value);
                    }
                }
            }
            // Sanity check the returned values.
            if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
                throw new PropertyIsSingleValuedException(pd);
            }
            if (values.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
                throw new PropertyIsMandatoryException(pd);
            }
            if (values.isEmpty()) {
                // Use the property's default values.
                values.addAll(findDefaultValues(path.asSubType(mod), pd, false));
            }
            return values;
        } catch (NameNotFoundException e) {
            throw new ManagedObjectNotFoundException();
        } catch (NoPermissionException e) {
            throw new AuthorizationException(e);
        } catch (NamingException e) {
            throw new CommunicationException(e);
        }
    }
    if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
      // This exception takes precedence over previous exceptions.
      exception = new PropertyIsSingleValuedException(pd);
      PD value = activeValues.first();
      activeValues.clear();
      activeValues.add(value);
    /**
     * {@inheritDoc}
     */
    @Override
    public ManagedObject<RootCfgClient> getRootConfigurationManagedObject() {
        return new LDAPManagedObject<RootCfgClient>(this, RootCfgDefn.getInstance(), ManagedObjectPath.emptyPath(),
                new PropertySet(), true, null);
    }
    // Get the property's default values.
    Collection<PD> defaultValues;
    try {
      defaultValues = findDefaultValues(p, pd, false);
    } catch (DefaultBehaviorException e) {
      defaultValues = Collections.emptySet();
      exception = e;
    /**
     * {@inheritDoc}
     */
    @Override
    public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
            ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd,
            AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws IllegalArgumentException,
            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
        validateRelationDefinition(parent, rd);
        if (!managedObjectExists(parent)) {
            throw new ManagedObjectNotFoundException();
        }
        // Get the search base DN.
        LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
        // Retrieve only those entries which are sub-types of the
        // specified definition.
        StringBuilder builder = new StringBuilder();
        builder.append("(objectclass=");
        builder.append(profile.getObjectClass(d));
        builder.append(')');
        String filter = builder.toString();
        List<String> children = new ArrayList<String>();
        try {
            for (LdapName child : connection.listEntries(dn, filter)) {
                children.add(child.getRdn(child.size() - 1).getValue().toString());
            }
        } catch (NameNotFoundException e) {
            // Ignore this - it means that the base entry does not exist
            // (which it might not if this managed object has just been
            // created.
        } catch (NamingException e) {
            adaptNamingException(e);
        }
        return children.toArray(new String[children.size()]);
    }
    newProperties.addProperty(pd, defaultValues, activeValues);
    /**
     * {@inheritDoc}
     */
    @Override
    public <C extends ConfigurationClient, S extends Configuration> String[] listManagedObjects(
            ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd,
            AbstractManagedObjectDefinition<? extends C, ? extends S> d) throws IllegalArgumentException,
            ManagedObjectNotFoundException, AuthorizationException, CommunicationException {
        validateRelationDefinition(parent, rd);
    if (activeValues.isEmpty() && defaultValues.isEmpty()
        && pd.hasOption(PropertyOption.MANDATORY)) {
      // The active values maybe empty because of a previous
      // exception.
      if (exception == null) {
        exception = new PropertyIsMandatoryException(pd);
      }
        if (!managedObjectExists(parent)) {
            throw new ManagedObjectNotFoundException();
        }
        // Get the search base DN.
        LdapName dn = LDAPNameBuilder.create(parent, rd, profile);
        // Retrieve only those entries which are sub-types of the
        // specified definition.
        StringBuilder builder = new StringBuilder();
        builder.append("(objectclass=");
        builder.append(profile.getObjectClass(d));
        builder.append(')');
        String filter = builder.toString();
        List<String> children = new ArrayList<String>();
        try {
            for (LdapName child : connection.listEntries(dn, filter)) {
                children.add(child.getRdn(child.size() - 1).getValue().toString());
            }
        } catch (NameNotFoundException e) {
            // Ignore this - it means that the base entry does not exist
            // (which it might not if this managed object has just been
            // created.
        } catch (NamingException e) {
            adaptNamingException(e);
        }
        return children.toArray(new String[children.size()]);
    }
    if (exception != null) {
      throw exception;
    }
  }
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean managedObjectExists(ManagedObjectPath<?, ?> path) throws ManagedObjectNotFoundException,
            AuthorizationException, CommunicationException {
        if (path.isEmpty()) {
            return true;
        }
        ManagedObjectPath<?, ?> parent = path.parent();
        LdapName dn = LDAPNameBuilder.create(parent, profile);
        if (!entryExists(dn)) {
            throw new ManagedObjectNotFoundException();
        }
  // Determine the type of managed object associated with the named
  // entry.
  private <C extends ConfigurationClient, S extends Configuration>
  ManagedObjectDefinition<? extends C, ? extends S> getEntryDefinition(
      AbstractManagedObjectDefinition<C, S> d, LdapName dn)
      throws NamingException, DefinitionDecodingException {
    Attributes attributes = connection.readEntry(dn, Collections
        .singleton("objectclass"));
    Attribute oc = attributes.get("objectclass");
    if (oc == null) {
      // No object classes.
      throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION);
        dn = LDAPNameBuilder.create(path, profile);
        return entryExists(dn);
    }
    final Set<String> objectClasses = new HashSet<String>();
    NamingEnumeration<?> values = oc.getAll();
    while (values.hasMore()) {
      Object value = values.next();
      if (value != null) {
        objectClasses.add(value.toString().toLowerCase().trim());
      }
    /**
     * {@inheritDoc}
     */
    @Override
    protected <C extends ConfigurationClient, S extends Configuration> void deleteManagedObject(
            ManagedObjectPath<C, S> path) throws OperationRejectedException, AuthorizationException,
            CommunicationException {
        // Delete the entry and any subordinate entries.
        LdapName dn = LDAPNameBuilder.create(path, profile);
        try {
            connection.deleteSubtree(dn);
        } catch (OperationNotSupportedException e) {
            // Unwilling to perform.
            AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition();
            if (e.getMessage() == null) {
                throw new OperationRejectedException(OperationType.DELETE, d.getUserFriendlyName());
            } else {
                LocalizableMessage m = LocalizableMessage.raw("%s", e.getMessage());
                throw new OperationRejectedException(OperationType.DELETE, d.getUserFriendlyName(), m);
            }
        } catch (NamingException e) {
            adaptNamingException(e);
        }
    }
    if (objectClasses.isEmpty()) {
      // No object classes.
      throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION);
    /**
     * {@inheritDoc}
     */
    @Override
    protected LDAPManagementContext getManagementContext() {
        return context;
    }
    // Resolve the appropriate sub-type based on the object classes.
    DefinitionResolver resolver = new DefinitionResolver() {
    /**
     * Adapts a naming exception to an appropriate admin client exception.
     *
     * @param ne
     *            The naming exception.
     * @throws CommunicationException
     *             If the naming exception mapped to a communication exception.
     * @throws AuthorizationException
     *             If the naming exception mapped to an authorization exception.
     */
    void adaptNamingException(NamingException ne) throws CommunicationException, AuthorizationException {
        try {
            throw ne;
        } catch (javax.naming.CommunicationException e) {
            throw new CommunicationException(e);
        } catch (javax.naming.ServiceUnavailableException e) {
            throw new CommunicationException(e);
        } catch (javax.naming.NoPermissionException e) {
            throw new AuthorizationException(e);
        } catch (NamingException e) {
            // Just treat it as a communication problem.
            throw new CommunicationException(e);
        }
    }
      public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
        String objectClass = profile.getObjectClass(d);
        return objectClasses.contains(objectClass);
      }
    /**
     * Determines whether the named LDAP entry exists.
     *
     * @param dn
     *            The LDAP entry name.
     * @return Returns <code>true</code> if the named LDAP entry exists.
     * @throws AuthorizationException
     *             If the server refuses to make the determination because the
     *             client does not have the correct privileges.
     * @throws CommunicationException
     *             If the client cannot contact the server due to an underlying
     *             communication problem.
     */
    boolean entryExists(LdapName dn) throws CommunicationException, AuthorizationException {
        try {
            return connection.entryExists(dn);
        } catch (NamingException e) {
            adaptNamingException(e);
        }
        return false;
    }
    };
    /**
     * Gets the LDAP connection used for interacting with the server.
     *
     * @return Returns the LDAP connection used for interacting with the server.
     */
    LDAPConnection getLDAPConnection() {
        return connection;
    }
    return d.resolveManagedObjectDefinition(resolver);
  }
    /**
     * Gets the LDAP profile which should be used to construct LDAP requests and
     * decode LDAP responses.
     *
     * @return Returns the LDAP profile which should be used to construct LDAP
     *         requests and decode LDAP responses.
     */
    LDAPProfile getLDAPProfile() {
        return profile;
    }
    // Create a managed object which already exists on the server.
    private <M extends ConfigurationClient, N extends Configuration> ManagedObject<M> createExistingManagedObject(
            ManagedObjectDefinition<M, N> d, ManagedObjectPath<? super M, ? super N> p, PropertySet properties) {
        RelationDefinition<?, ?> rd = p.getRelationDefinition();
        PropertyDefinition<?> pd = null;
        if (rd instanceof InstantiableRelationDefinition) {
            InstantiableRelationDefinition<?, ?> ird = (InstantiableRelationDefinition<?, ?>) rd;
            pd = ird.getNamingPropertyDefinition();
        }
        return new LDAPManagedObject<M>(this, d, p.asSubType(d), properties, true, pd);
    }
    // Create a property using the provided string values.
    private <PD> void decodeProperty(PropertySet newProperties, ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd,
            Attribute attribute) throws PropertyException, NamingException {
        PropertyException exception = null;
        // Get the property's active values.
        SortedSet<PD> activeValues = new TreeSet<PD>(pd);
        if (attribute != null) {
            NamingEnumeration<?> ldapValues = attribute.getAll();
            while (ldapValues.hasMore()) {
                Object obj = ldapValues.next();
                if (obj != null) {
                    PD value = ValueDecoder.decode(pd, obj);
                    activeValues.add(value);
                }
            }
        }
        if (activeValues.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) {
            // This exception takes precedence over previous exceptions.
            exception = new PropertyIsSingleValuedException(pd);
            PD value = activeValues.first();
            activeValues.clear();
            activeValues.add(value);
        }
        // Get the property's default values.
        Collection<PD> defaultValues;
        try {
            defaultValues = findDefaultValues(p, pd, false);
        } catch (DefaultBehaviorException e) {
            defaultValues = Collections.emptySet();
            exception = e;
        }
        newProperties.addProperty(pd, defaultValues, activeValues);
        if (activeValues.isEmpty() && defaultValues.isEmpty() && pd.hasOption(PropertyOption.MANDATORY)) {
            // The active values maybe empty because of a previous
            // exception.
            if (exception == null) {
                exception = new PropertyIsMandatoryException(pd);
            }
        }
        if (exception != null) {
            throw exception;
        }
    }
    // Determine the type of managed object associated with the named
    // entry.
    private <C extends ConfigurationClient, S extends Configuration> ManagedObjectDefinition<? extends C, ? extends S> getEntryDefinition(
            AbstractManagedObjectDefinition<C, S> d, LdapName dn) throws NamingException, DefinitionDecodingException {
        Attributes attributes = connection.readEntry(dn, Collections.singleton("objectclass"));
        Attribute oc = attributes.get("objectclass");
        if (oc == null) {
            // No object classes.
            throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION);
        }
        final Set<String> objectClasses = new HashSet<String>();
        NamingEnumeration<?> values = oc.getAll();
        while (values.hasMore()) {
            Object value = values.next();
            if (value != null) {
                objectClasses.add(value.toString().toLowerCase().trim());
            }
        }
        if (objectClasses.isEmpty()) {
            // No object classes.
            throw new DefinitionDecodingException(d, Reason.NO_TYPE_INFORMATION);
        }
        // Resolve the appropriate sub-type based on the object classes.
        DefinitionResolver resolver = new DefinitionResolver() {
            public boolean matches(AbstractManagedObjectDefinition<?, ?> d) {
                String objectClass = profile.getObjectClass(d);
                return objectClasses.contains(objectClass);
            }
        };
        return d.resolveManagedObjectDefinition(resolver);
    }
}
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPManagedObject.java
@@ -40,7 +40,7 @@
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import org.opends.messages.Message;
import org.forgerock.i18n.LocalizableMessage;
import org.opends.server.admin.AggregationPropertyDefinition;
import org.opends.server.admin.Configuration;
import org.opends.server.admin.ConfigurationClient;
@@ -217,7 +217,7 @@
            throw new OperationRejectedException(OperationType.CREATE, d
                .getUserFriendlyName());
          } else {
            Message m = Message.raw("%s", e.getMessage());
            LocalizableMessage m = LocalizableMessage.raw("%s", e.getMessage());
            throw new OperationRejectedException(OperationType.CREATE, d
                .getUserFriendlyName(), m);
          }
@@ -268,7 +268,7 @@
        throw new OperationRejectedException(OperationType.CREATE, d
            .getUserFriendlyName());
      } else {
        Message m = Message.raw("%s", e.getMessage());
        LocalizableMessage m = LocalizableMessage.raw("%s", e.getMessage());
        throw new OperationRejectedException(OperationType.CREATE, d
            .getUserFriendlyName(), m);
      }
@@ -323,7 +323,7 @@
          throw new OperationRejectedException(OperationType.MODIFY, d
              .getUserFriendlyName());
        } else {
          Message m = Message.raw("%s", e.getMessage());
          LocalizableMessage m = LocalizableMessage.raw("%s", e.getMessage());
          throw new OperationRejectedException(OperationType.MODIFY, d
              .getUserFriendlyName(), m);
        }
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/LDAPManagementContext.java
@@ -27,51 +27,42 @@
package org.opends.server.admin.client.ldap;
import org.opends.server.admin.LDAPProfile;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.spi.Driver;
import org.opends.server.util.Validator;
import com.forgerock.opendj.util.Validator;
/**
 * An LDAP management connection context.
 */
public final class LDAPManagementContext extends ManagementContext {
  /**
   * Create a new LDAP management context using the provided LDAP
   * connection.
   *
   * @param connection
   *          The LDAP connection.
   * @return Returns the new management context.
   */
  public static ManagementContext createFromContext(LDAPConnection connection) {
    Validator.ensureNotNull(connection);
    return new LDAPManagementContext(connection, LDAPProfile.getInstance());
  }
    /**
     * Create a new LDAP management context using the provided LDAP connection.
     *
     * @param connection
     *            The LDAP connection.
     * @return Returns the new management context.
     */
    public static ManagementContext createFromContext(LDAPConnection connection) {
        Validator.ensureNotNull(connection);
        return new LDAPManagementContext(connection, LDAPProfile.getInstance());
    }
  // The LDAP management context driver.
  private final LDAPDriver driver;
    // The LDAP management context driver.
    private final LDAPDriver driver;
    // Private constructor.
    private LDAPManagementContext(LDAPConnection connection, LDAPProfile profile) {
        this.driver = new LDAPDriver(this, connection, profile);
    }
  // Private constructor.
  private LDAPManagementContext(LDAPConnection connection,
      LDAPProfile profile) {
    this.driver = new LDAPDriver(this, connection, profile);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected Driver getDriver() {
    return driver;
  }
    /**
     * {@inheritDoc}
     */
    @Override
    protected Driver getDriver() {
        return driver;
    }
}
opendj-admin/src/main/java/org/opends/server/admin/client/ldap/package-info.java
@@ -34,7 +34,5 @@
 * that, at some point in the future, we will replace this implementation
 * with our own LDAP client SDK based implementation.
 */
@org.opends.server.types.PublicAPI(
     stability=org.opends.server.types.StabilityLevel.PRIVATE)
package org.opends.server.admin.client.ldap;