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

jvergara
27.51.2007 ceef7ba098240a8b10aee4f36d1653795652481c
Move some of the panels specific of the installer to the package org.opends.quicksetup.installer.ui.

Made a small change in the code of the quicksetup panels to display the "Loading" message only on those panels th
at really require it (this modifications avoids unnecessary flickering).

Update the code of the status panel to reflect the changes in terms of naming and the names of the attributes (th
e terminology has changed from synchronization to replication).

Add some of the code required to handle the ADS and some of the panels to configure replication during setup (how
ever this is not visible to the user). The panels reflect the design made by Brian.

13 files added
5 files renamed
29 files modified
6702 ■■■■■ changed files
opends/build.xml 22 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContext.java 1917 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContextException.java 176 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java 100 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java 90 ●●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java 151 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java 7 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Step.java 14 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 236 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java 139 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java 116 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java 76 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java 1 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 1088 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java 147 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java 155 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java 36 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java 102 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java 540 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java 324 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java 115 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java 5 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java 13 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java 5 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java 7 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java 530 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java 43 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 96 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java 40 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java 40 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java 47 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java 17 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java 11 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java 84 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java 1 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java 8 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java 10 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java 16 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java 1 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java 20 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java 64 ●●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java 38 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/StatusCli.java 4 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties 6 ●●●● patch | view | raw | blame | history
opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java 38 ●●●● patch | view | raw | blame | history
opends/build.xml
@@ -77,6 +77,7 @@
  <property name="quicksetup.src.dir" location="src/quicksetup"       />
  <property name="quicksetup.classes.dir"
            location="${build.dir}/quicksetup/classes"                />
    <property name="ads.src.dir" location="src/ads"       />
  <!-- Properties for use with the Status Panel.                      -->
  <property name="statuspanel.src.dir" location="src/statuspanel"       />
@@ -370,6 +371,12 @@
      <formatter type="plain" />
    </checkstyle>
    <checkstyle config="${checkstyle.dir}/opends-checkstyle.xml"
      failOnViolation="true">
      <fileset dir="${ads.src.dir}" includes="**/*.java" />
      <formatter type="plain" />
    </checkstyle>
    <checkstyle config="${checkstyle.dir}/opends-checkstyle.xml"
         failOnViolation="true">
      <fileset dir="${quicksetup.src.dir}" includes="**/*.java" />
@@ -412,8 +419,7 @@
       depends="cleaninit,compilequicksetup,weave,compilestatuspanel"
       description="Recompile the Directory Server source files.">
  </target>
  <!-- Compile the Directory Server source files. -->
  <target name="compile"
@@ -472,6 +478,18 @@
  <target name="compilequicksetup" depends="buildtools,weave"
          description="Compile the Quick Setup source files.">
    <mkdir dir="${quicksetup.classes.dir}" />
    <javac srcdir="${ads.src.dir}" destdir="${quicksetup.classes.dir}"
                optimize="true" debug="on" debuglevel="lines,source" source="1.5"
        target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
        memoryMaximumSize="${MEM}">
        <compilerarg value="-Xlint:all" />
          <classpath>
          <fileset dir="${build.dir}/build-tools">
                <include name="build-tools.jar" />
            </fileset>
            <pathelement path="${classes.dir}"/>
        </classpath>
    </javac>
    <javac srcdir="${src.dir}" destdir="${quicksetup.classes.dir}"
               debug="on" debuglevel="${build.debuglevel}" source="1.5"
               target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
opends/src/ads/org/opends/admin/ads/ADSContext.java
New file
@@ -0,0 +1,1917 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import javax.naming.InvalidNameException;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.NotContextException;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchResult;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.SearchControls;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
/**
 * Class used to update and read the contents of the Administration Data.
 */
public class ADSContext
{
  /**
   * Enumeration containing the different server properties that are stored in
   * the ADS.
   */
  public enum ServerProperty
  {
    /**
     * The ID used to identify the server.
     */
    ID("cn"),
    /**
     * The host name of the server.
     */
    HOSTNAME("hostname"),
    /**
     * The LDAP port of the server.
     */
    PORT("ldapport"),
    /**
     * The JMX port of the server.
     */
    JMX_PORT("jmxport"),
    /**
     * The LDAPS port of the server.
     */
    SECURE_PORT("ldapsport"),
    /**
     * The certificate used by the server.
     */
    CERTIFICATE("certificate"),
    /**
     * The path where the server is installed.
     */
    INSTANCE_PATH("instancepath"),
    /**
     * The description of the server.
     */
    DESCRIPTION("description"),
    /**
     * The OS of the machine where the server is installed.
     */
    HOST_OS("os"),
    /**
     * Whether LDAP is enabled or not.
     */
    LDAP_ENABLED("ldapEnabled"),
    /**
     * Whether LDAPS is enabled or not.
     */
    LDAPS_ENABLED("ldapsEnabled"),
    /**
     * Whether StartTLS is enabled or not.
     */
    STARTTLS_ENABLED("startTLSEnabled"),
    /**
     * Whether JMX is enabled or not.
     */
    JMX_ENABLED("jmxEnabled"),
    /**
     * The location of the server.
     */
    LOCATION("location"),
    /**
     * The groups to which this server belongs.
     */
    GROUPS("memberofgroups");
    private String attrName;
    /**
     * Private constructor.
     * @param n the name of the attribute.
     */
    private ServerProperty(String n)
    {
      attrName = n;
    }
    /**
     * Returns the attribute name.
     * @return the attribute name.
     */
    public String getAttributeName()
    {
      return attrName;
    }
  };
  /**
   * The list of server properties that are multivalued.
   */
  private final static Set<ServerProperty> MULTIVALUED_SERVER_PROPERTIES =
    new HashSet<ServerProperty>();
  static
  {
    MULTIVALUED_SERVER_PROPERTIES.add(ServerProperty.GROUPS);
  }
  /**
   * Enumeration containing the different server group properties that are
   * stored in the ADS.
   */
  public enum ServerGroupProperty
  {
    /**
     * The UID of the server group.
     */
    UID("cn"),
    /**
     * The description of the server group.
     */
    DESCRIPTION("description"),
    /**
     * The members of the server group.
     */
    MEMBERS("members");
    private String attrName;
    /**
     * Private constructor.
     * @param n the attribute name.
     */
    private ServerGroupProperty(String n)
    {
      attrName = n;
    }
    /**
     * Returns the attribute name.
     * @return the attribute name.
     */
    public String getAttributeName()
    {
      return attrName;
    }
  };
  /**
   * The list of server group properties that are multivalued.
   */
  private final static
  Set<ServerGroupProperty> MULTIVALUED_SERVER_GROUP_PROPERTIES =
    new HashSet<ServerGroupProperty>();
  static
  {
    MULTIVALUED_SERVER_GROUP_PROPERTIES.add(ServerGroupProperty.MEMBERS);
  }
  /**
   * The enumeration containing the different Administrator properties.
   */
  public enum AdministratorProperty
  {
    /**
     * The UID of the administrator.
     */
    UID,
    /**
     * The password of the administrator.
     */
    PASSWORD,
    /**
     * The description of the administrator.
     */
    DESCRIPTION,
    /**
     * The DN of the administrator.
     */
    ADMINISTRATOR_DN
  };
  /**
   * Character used to separate hostname from ipath in RDN.
   */
  public final static String HNP_SEPARATOR = "@";
  // The context used to retrieve information
  InitialLdapContext dirContext;
  /**
   * Constructor of the ADSContext.
   * @param dirContext the DirContext that must be used to retrieve information.
   */
  public ADSContext(InitialLdapContext dirContext)
  {
    this.dirContext = dirContext;
  }
  /**
   * Returns the DirContext used to retrieve information by this ADSContext.
   * @return the DirContext used to retrieve information by this ADSContext.
   */
  public InitialLdapContext getDirContext()
  {
    return dirContext;
  }
  /**
   * Method called to register a server in the ADS.
   * @param serverProperties the properties of the server.
   * @throws ADSContextException if the server could not be registered.
   */
  public void registerServer(Map<ServerProperty, Object> serverProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerProperties(serverProperties);
    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
    try
    {
      DirContext ctx = dirContext.createSubcontext(dn, attrs);
      ctx.close();
    }
    catch (NameAlreadyBoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ALREADY_REGISTERED);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Method called to udpate the properties of a server in the ADS.
   * @param serverProperties the new properties of the server.
   * @throws ADSContextException if the server could not be registered.
   */
  public void updateServer(Map<ServerProperty, Object> serverProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerProperties(serverProperties);
    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
    try
    {
      dirContext.modifyAttributes(dn, InitialLdapContext.REPLACE_ATTRIBUTE,
          attrs);
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Method called to unregister a server in the ADS.
   * @param serverProperties the properties of the server.
   * @throws ADSContextException if the server could not be unregistered.
   */
  public void unregisterServer(Map<ServerProperty, Object> serverProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerProperties(serverProperties);
    try
    {
      dirContext.destroySubcontext(dn);
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Returns whether a given server is already registered or not.
   * @param serverProperties the server properties.
   * @return <CODE>true</CODE> if the server was registered and
   * <CODE>false</CODE> otherwise.
   * @throws ADSContextException if something went wrong.
   */
  public boolean isServerAlreadyRegistered(
      Map<ServerProperty, Object> serverProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerProperties(serverProperties);
    return isExistingEntry(dn);
  }
  /**
   * Returns whether a given administrator is already registered or not.
   * @param adminProperties the administrator properties.
   * @return <CODE>true</CODE> if the administrator was registered and
   * <CODE>false</CODE> otherwise.
   * @throws ADSContextException if something went wrong.
   */
  public boolean isAdministratorAlreadyRegistered(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromAdministratorProperties(adminProperties);
    return isExistingEntry(dn);
  }
  /**
   * A convenience method that takes some server properties as parameter and
   * if there is no server registered associated with those properties,
   * registers it and if it is already registered, updates it.
   * @param serverProperties the server properties.
   * @throws ADSContextException if something goes wrong.
   */
  public void registerOrUpdateServer(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    try
    {
      registerServer(serverProperties);
    }
    catch(ADSContextException x)
    {
      if (x.getError() == ADSContextException.ErrorType.ALREADY_REGISTERED)
      {
        updateServer(serverProperties);
      }
      else
      {
        throw x;
      }
    }
  }
  /**
   * Returns the properties of a server for a given host name and installation
   * path.
   * @param hostname the host Name.
   * @param ipath the installation path.
   * @return the properties of a server for a given host name and installation
   * path.
   * @throws ADSContextException if something goes wrong.
   */
  public Map<ServerProperty, Object> lookupServerRegistry(String hostname,
      String ipath) throws ADSContextException
  {
    LdapName dn = makeDNFromHostnameAndPath(hostname, ipath);
    Map<ServerProperty, Object> result;
    try
    {
      result = makePropertiesFromServerAttrs(hostname, ipath,
          dirContext.getAttributes(dn));
    }
    catch (NameNotFoundException x)
    {
      result = null;
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns a set containing the servers that are registered in the ADS.
   * @return a set containing the servers that are registered in the ADS.
   * @throws ADSContextException if something goes wrong.
   */
  public Set<Map<ServerProperty,Object>> readServerRegistry()
  throws ADSContextException
  {
    Set<Map<ServerProperty,Object>> result =
      new HashSet<Map<ServerProperty,Object>>();
    try
    {
      NamingEnumeration ne;
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      ne = dirContext.search(getServerContainerDN(), "(objectclass=*)", sc);
      while (ne.hasMore())
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<ServerProperty,Object> properties =
          makePropertiesFromServerAttrs(sr.getName(), sr.getAttributes());
        result.add(properties);
      }
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.BROKEN_INSTALL);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns a set of the server properties that are registered in the ADS and
   * that contain the properties specified in serverProperties.
   * @param serverProperties the properties that are used as search criteria.
   * @return a set of the server properties that are registered in the ADS and
   * that contain the properties specified in serverProperties.
   * @throws ADSContextException if something goes wrong.
   */
  public Set<Map<ServerProperty, Object>> searchServerRegistry(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    Set<Map<ServerProperty, Object>> result =
      new HashSet<Map<ServerProperty, Object>>();
    StringBuffer filter = new StringBuffer();
    // Build the filter according the properties passed in serverProperties
    int operandCount = 0;
    if (serverProperties.containsKey(ServerProperty.HOSTNAME))
    {
      filter.append("(cn=");
      filter.append(serverProperties.get(ServerProperty.HOSTNAME));
      filter.append("*");
      if (serverProperties.containsKey(ServerProperty.INSTANCE_PATH))
      {
        filter.append(HNP_SEPARATOR);
        filter.append(serverProperties.get(ServerProperty.INSTANCE_PATH));
      }
      filter.append(")");
      operandCount++;
    }
    if (serverProperties.containsKey(ServerProperty.PORT))
    {
      filter.append("(");
      filter.append(ServerProperty.PORT);
      filter.append("=");
      filter.append(serverProperties.get(ServerProperty.PORT));
      filter.append(")");
      operandCount++;
    }
    if (operandCount >= 2)
    {
      filter.insert(0, '(');
      filter.append("&)");
    }
    // Search the ADS
    try
    {
      NamingEnumeration ne;
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      ne = dirContext.search(getServerContainerDN(), filter.toString(), sc);
      while (ne.hasMore())
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<ServerProperty, Object> properties = makePropertiesFromServerAttrs(
            sr.getName(), sr.getAttributes());
        result.add(properties);
      }
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.BROKEN_INSTALL);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Creates a Server Group in the ADS.
   * @param serverGroupProperties the properties of the server group to be
   * created.
   * @throws ADSContextException if somethings goes wrong.
   */
  public void createServerGroup(
      Map<ServerGroupProperty, Object> serverGroupProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
    BasicAttributes attrs = makeAttrsFromServerGroupProperties(
        serverGroupProperties);
    try
    {
      DirContext ctx = dirContext.createSubcontext(dn, attrs);
      ctx.close();
    }
    catch (NameAlreadyBoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ALREADY_REGISTERED);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Updates the properties of a Server Group in the ADS.
   * @param serverGroupProperties the new properties of the server group to be
   * updated.
   * @throws ADSContextException if somethings goes wrong.
   */
  public void updateServerGroup(
      Map<ServerGroupProperty, Object> serverGroupProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
    BasicAttributes attrs =
      makeAttrsFromServerGroupProperties(serverGroupProperties);
    try
    {
      dirContext.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, attrs);
    }
    catch (NameAlreadyBoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ALREADY_REGISTERED);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Deletes a Server Group in the ADS.
   * @param serverGroupProperties the properties of the server group to be
   * deleted.
   * @throws ADSContextException if somethings goes wrong.
   */
  public void deleteServerGroup(
      Map<ServerGroupProperty, Object> serverGroupProperties)
  throws ADSContextException
  {
    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
    try
    {
      dirContext.destroySubcontext(dn);
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Returns a set containing the server groups that are defined in the ADS.
   * @return a set containing the server groups that are defined in the ADS.
   * @throws ADSContextException if something goes wrong.
   */
  public Set<Map<ServerGroupProperty, Object>> readServerGroupRegistry()
  throws ADSContextException
  {
    Set<Map<ServerGroupProperty, Object>> result =
      new HashSet<Map<ServerGroupProperty, Object>>();
    try
    {
      NamingEnumeration ne;
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      ne = dirContext.search(getServerGroupContainerDN(), "(objectclass=*)",
          sc);
      while (ne.hasMore())
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<ServerGroupProperty, Object> properties =
          makePropertiesFromServerGroupAttrs(sr.getAttributes());
        result.add(properties);
      }
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.BROKEN_INSTALL);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns a set containing the administrators that are defined in the ADS.
   * @return a set containing the administrators that are defined in the ADS.
   * @throws ADSContextException if something goes wrong.
   */
  public Set<Map<AdministratorProperty, Object>> readAdministratorRegistry()
  throws ADSContextException
  {
    Set<Map<AdministratorProperty, Object>> result =
      new HashSet<Map<AdministratorProperty, Object>>();
    try {
      NamingEnumeration ne;
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
      ne = dirContext.search(getAdministratorContainerDN(), "(objectclass=*)",
          sc);
      while (ne.hasMore())
      {
        SearchResult sr = (SearchResult)ne.next();
        Map<AdministratorProperty, Object> properties =
          makePropertiesFromAdministratorAttrs(
              sr.getName(), sr.getAttributes());
        result.add(properties);
      }
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.BROKEN_INSTALL);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Creates the Administration Data in the server.
   * NOTE: until we use the Administration Framework this does not work.
   * TODO: remove the installPath parameter once we are integrated in the
   * Administration Framework.
   * The call to this method assumes that OpenDS.jar has already been loaded.
   * So this should not be called by the Java Web Start before being sure that
   * this jar is loaded.
   * @throws ADSContextException if something goes wrong.
   */
  public void createAdminData() throws ADSContextException
  {
    // Add the administration suffix
    createAdministrationSuffix();
    // Create the DIT below the administration suffix
    createTopContainerEntry();
    createAdministratorContainerEntry();
    createContainerEntry(getServerContainerDN());
    createContainerEntry(getServerGroupContainerDN());
  }
  /**
   * NOTE: this can only be called locally.
   * The call to this method assumes that OpenDS.jar has already been loaded.
   * So this should not be called by the Java Web Start before being sure that
   * this jar is loaded.
   * @param serverProperties the properties of the server to register.
   * @param installPath the installation path of the server.
   * @param backendName the backend where we create the administration data.
   * @throws ADSContextException if something goes wrong.
   */
  public static void createOfflineAdminData(
      Map<ServerProperty, Object> serverProperties, String installPath,
      String backendName)
  throws ADSContextException
  {
    // Add the administration suffix
    createOfflineAdministrationSuffix(installPath);
    // Create the DIT below the administration suffix
    try
    {
      File ldifFile = File.createTempFile("ads", ".ldif");
      ldifFile.deleteOnExit();
      LinkedList<String> lines = new LinkedList<String>();
      lines.add("dn: "+getAdministrationSuffixDN());
      lines.add("objectclass: extensibleobject");
      lines.add("aci: "+getTopContainerACI());
      lines.add("");
      lines.add("dn: "+getAdministratorContainerDN());
      lines.add("objectclass: groupOfUniqueNames");
      lines.add("objectclass: groupofurls");
      lines.add("memberURL: ldap:///" + getAdministratorContainerDN() +
      "??one?(objectclass=*)");
      lines.add("description: Group of identities which have full access.");
      lines.add("dn: "+getServerContainerDN());
      lines.add("objectclass: extensibleobject");
      lines.add("");
      lines.add("dn: "+getServerGroupContainerDN());
      lines.add("objectclass: extensibleobject");
      lines.add("");
      LdapName dn = makeDNFromServerProperties(serverProperties);
      BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
      lines.add("dn: "+dn.toString());
      NamingEnumeration<String> ids = attrs.getIDs();
      while (ids.hasMoreElements())
      {
        String attrID = ids.nextElement();
        Attribute attr = attrs.get(attrID);
        try
        {
          NamingEnumeration values = attr.getAll();
          while (values.hasMoreElements())
          {
            lines.add(attrID+": "+values.nextElement());
          }
        }
        catch (NamingException ne)
        {
          // This should not happen
          throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED, ne);
        }
      }
      BufferedWriter writer = new BufferedWriter(new FileWriter(ldifFile));
      for (String line : lines)
      {
        writer.write(line);
        writer.newLine();
      }
      writer.flush();
      writer.close();
      ArrayList<String> argList = new ArrayList<String>();
      argList.add("-C");
      argList.add(
          org.opends.server.extensions.ConfigFileHandler.class.getName());
      argList.add("-c");
      argList.add(installPath+File.separator+"config"+File.separator+
          "config.ldif");
      argList.add("-n");
      argList.add(backendName);
      argList.add("-t");
      argList.add(ldifFile.getAbsolutePath());
      argList.add("-S");
      argList.add("0");
      String[] args = new String[argList.size()];
      argList.toArray(args);
      try
      {
        int result = org.opends.server.tools.ImportLDIF.mainImportLDIF(args);
        if (result != 0)
        {
          throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED);
        }
      } catch (Throwable t)
      {
//      This should not happen
        throw new ADSContextException(
            ADSContextException.ErrorType.ERROR_UNEXPECTED, t);
      }
    }
    catch (IOException ioe)
    {
//    This should not happen
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, ioe);
    }
  }
  /**
   * Removes the administration data.
   * @throws ADSContextException if something goes wrong.
   */
  public void removeAdminData() throws ADSContextException
  {
    removeAdministrationSuffix();
  }
  /**
   * Returns <CODE>true</CODE> if the server contains Administration Data and
   * <CODE>false</CODE> otherwise.
   * @return <CODE>true</CODE> if the server contains Administration Data and
   * <CODE>false</CODE> otherwise.
   * @throws ADSContextException if something goes wrong.
   */
  public boolean hasAdminData() throws ADSContextException
  {
    return isExistingEntry(nameFromDN(getAdministrationSuffixDN()));
  }
  /**
   * Returns the DN of the administrator for a given UID.
   * @param uid the UID to be used to generate the DN.
   * @return the DN of the administrator for the given UID:
   */
  public static String getAdministratorDN(String uid)
  {
    return "cn=" + Rdn.escapeValue(uid) + "," + getAdministratorContainerDN();
  }
  /**
   * Creates an Administrator in the ADS.
   * @param adminProperties the properties of the administrator to be created.
   * @throws ADSContextException if something goes wrong.
   */
  public void createAdministrator(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException {
    LdapName dnCentralAdmin =
      makeDNFromAdministratorProperties(adminProperties);
    BasicAttributes attrs = makeAttrsFromAdministratorProperties(
        adminProperties);
    try
    {
      DirContext ctx = dirContext.createSubcontext(dnCentralAdmin, attrs);
      ctx.close();
    }
    catch (NameAlreadyBoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ALREADY_REGISTERED);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Deletes the administrator in the ADS.
   * @param adminProperties the properties of the administrator to be deleted.
   * @throws ADSContextException if something goes wrong.
   */
  public void deleteAdministrator(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException {
    LdapName dnCentralAdmin =
      makeDNFromAdministratorProperties(adminProperties);
    try
    {
      dirContext.destroySubcontext(dnCentralAdmin);
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NotContextException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Updates and administrator registered in the ADS.
   * @param adminProperties the new properties of the administrator.
   * @throws ADSContextException if something goes wrong.
   */
  public void updateAdministrator(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException
  {
    LdapName dnCentralAdmin =
      makeDNFromAdministratorProperties(adminProperties);
    BasicAttributes attrs = makeAttrsFromAdministratorProperties(
        adminProperties);
    try
    {
      dirContext.modifyAttributes(dnCentralAdmin, DirContext.REPLACE_ATTRIBUTE,
          attrs);
    }
    catch (NameNotFoundException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOT_YET_REGISTERED);
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch (NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Returns the DN of the suffix that contains the administration data.
   * @return the DN of the suffix that contains the administration data.
   */
  public static String getAdministrationSuffixDN()
  {
    return "cn=admin data";
  }
  /**
   * Used to modify the configuration on the server that must be managed; this
   * setups the ACIs on the server so that the Administrator can access the
   * server configuration.
   * TODO: complete this.
   * @param dirCtx the DirContext to the server that must be updated.
   * @param enable whether to enable or disable the access to the server.
   * @return <CODE>true</CODE> if something modified and <CODE>false</CODE>
   * otherwise.
   * @throws ADSContextException if the ACIs could not be set up.
   */
  public static boolean setupACIOnServer(LdapContext dirCtx,
      boolean enable) throws ADSContextException
  {
    boolean result;
    Attributes currentAttrs;
    Attribute currentAttr, newAttr;
    ModificationItem modItem;
    try
    {
      // Get the ACI value on the root entry
      currentAttrs = dirCtx.getAttributes("", new String[] { "aci" });
      currentAttr = currentAttrs.get("aci");
      // Check what ACIs values must be added or removed
      newAttr = new BasicAttribute("aci");
      modItem = null;
      if (enable)
      {
        if ((currentAttr == null) || !currentAttr.contains(getAdminACI1()))
        {
          newAttr.add(getAdminACI1());
        }
        if ((currentAttr == null) || !currentAttr.contains(getAdminACI2()))
        {
          newAttr.add(getAdminACI2());
        }
        if (newAttr.size() >= 1)
        {
          modItem = new ModificationItem(LdapContext.ADD_ATTRIBUTE, newAttr);
        }
      }
      else
      {
        if ((currentAttr != null) && currentAttr.contains(getAdminACI1()))
        {
          newAttr.add(getAdminACI1());
        }
        if ((currentAttr != null) && currentAttr.contains(getAdminACI2()))
        {
          newAttr.add(getAdminACI2());
        }
        if (newAttr.size() >= 1)
        {
          modItem = new ModificationItem(LdapContext.REMOVE_ATTRIBUTE, newAttr);
        }
      }
      // Update the ACI values on the root entry
      if (modItem != null)
      {
        dirCtx.modifyAttributes("", new ModificationItem[] { modItem});
        result = true;
      }
      else
      {
        result = false;
      }
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * This method returns the DN of the entry that corresponds to the given host
   * name and installation path.
   * @param hostname the host name.
   * @param ipath the installation path.
   * @return the DN of the entry that corresponds to the given host name and
   * installation path.
   * @throws ADSContextException if something goes wrong.
   */
  private static LdapName makeDNFromHostnameAndPath(String hostname,
      String ipath) throws ADSContextException
  {
    String cnValue = Rdn.escapeValue(hostname + HNP_SEPARATOR + ipath);
    return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
  }
  /**
   * This method returns the DN of the entry that corresponds to the given
   * server group properties.
   * @param serverGroupProperties the server group properties
   * @return the DN of the entry that corresponds to the given server group
   * properties.
   * @throws ADSContextException if something goes wrong.
   */
  private LdapName makeDNFromServerGroupProperties(
      Map<ServerGroupProperty, Object> serverGroupProperties)
  throws ADSContextException
  {
    String serverGroupId = (String)serverGroupProperties.get(
        ServerGroupProperty.UID);
    if (serverGroupId == null)
    {
      throw new ADSContextException(ADSContextException.ErrorType.MISSING_NAME);
    }
    return nameFromDN("cn=" + Rdn.escapeValue(serverGroupId) + "," +
          getServerGroupContainerDN());
  }
  /**
   * This method returns the DN of the entry that corresponds to the given
   * server properties.
   * @param serverProperties the server properties.
   * @return the DN of the entry that corresponds to the given server
   * properties.
   * @throws ADSContextException if something goes wrong.
   */
  private static LdapName makeDNFromServerProperties(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    String hostname = getHostname(serverProperties);
    String ipath = getInstallPath(serverProperties);
    return makeDNFromHostnameAndPath(hostname, ipath);
  }
  /**
   * This method returns the DN of the entry that corresponds to the given
   * administrator properties.
   * @param adminProperties the administrator properties.
   * @return the DN of the entry that corresponds to the given administrator
   * properties.
   * @throws ADSContextException if something goes wrong.
   */
  private LdapName makeDNFromAdministratorProperties(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException
  {
    String adminUid = getAdministratorUID(adminProperties);
    String dnCentralAdmin = getAdministratorDN(adminUid);
    return nameFromDN(dnCentralAdmin);
  }
  /**
   * Returns the attributes for some administrator properties.
   * @param adminProperties the administrator properties.
   * @return the attributes for the given administrator properties.
   * @throws ADSContextException if something goes wrong.
   */
  private BasicAttributes makeAttrsFromAdministratorProperties(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException
  {
    BasicAttributes attrs = new BasicAttributes();
    String adminPassword = getAdministratorPassword(adminProperties);
    attrs.put("objectclass", "person");
    attrs.put("sn", "admin");
    attrs.put("userPassword", adminPassword);
    return attrs;
  }
  /**
   * Returns the attributes for some server properties.
   * @param serverProperties the server properties.
   * @return the attributes for the given server properties.
   * @throws ADSContextException if something goes wrong.
   */
  private static BasicAttributes makeAttrsFromServerProperties(
      Map<ServerProperty, Object> serverProperties)
  {
    BasicAttributes result = new BasicAttributes();
    // Transform 'properties' into 'attributes'
    for (ServerProperty prop: serverProperties.keySet())
    {
      Attribute attr = makeAttrFromServerProperty(prop,
          serverProperties.get(prop));
      if (attr != null)
      {
        result.put(attr);
      }
    }
    // Add the objectclass attribute value
    result.put("objectclass", "extensibleobject");
    return result;
  }
  /**
   * Returns the attribute for a given server property.
   * @param property the server property.
   * @return the attribute for a given server property.
   * @throws ADSContextException if something goes wrong.
   */
  private static Attribute makeAttrFromServerProperty(ServerProperty property,
      Object value)
  {
    Attribute result;
    switch(property)
    {
    case HOSTNAME:
      result = null;
      break;
    case INSTANCE_PATH:
      result = null;
      break;
    case GROUPS:
      result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName());
      Iterator groupIterator = ((Set)value).iterator();
      while (groupIterator.hasNext())
      {
        result.add(groupIterator.next());
      }
      break;
    default:
      result = new BasicAttribute(property.getAttributeName(), value);
    }
    return result;
  }
  /**
   * Returns the attributes for some server group properties.
   * @param serverProperties the server group properties.
   * @return the attributes for the given server group properties.
   * @throws ADSContextException if something goes wrong.
   */
  private BasicAttributes makeAttrsFromServerGroupProperties(
      Map<ServerGroupProperty, Object> serverGroupProperties)
  {
    BasicAttributes result = new BasicAttributes();
    // Transform 'properties' into 'attributes'
    for (ServerGroupProperty prop: serverGroupProperties.keySet())
    {
      Attribute attr = makeAttrFromServerGroupProperty(prop,
          serverGroupProperties.get(prop));
      if (attr != null)
      {
        result.put(attr);
      }
    }
    // Add the objectclass attribute value
    result.put("objectclass", "extensibleobject");
    return result;
  }
  /**
   * Returns the attribute for a given server group property.
   * @param property the server group property.
   * @return the attribute for a given server group property.
   * @throws ADSContextException if something goes wrong.
   */
  private Attribute makeAttrFromServerGroupProperty(
      ServerGroupProperty property, Object value)
  {
    Attribute result;
    switch(property)
    {
    case MEMBERS:
      result = new BasicAttribute(
          ServerGroupProperty.MEMBERS.getAttributeName());
      Iterator memberIterator = ((Set)value).iterator();
      while (memberIterator.hasNext())
      {
        result.add(memberIterator.next());
      }
      break;
    default:
      result = new BasicAttribute(property.getAttributeName(), value);
    }
    return result;
  }
  /**
   * Returns the properties of a server group for some LDAP attributes.
   * @param attrs the LDAP attributes.
   * @return the properties of a server group for some LDAP attributes.
   * @throws ADSContextException if something goes wrong.
   */
  private Map<ServerGroupProperty, Object> makePropertiesFromServerGroupAttrs(
      Attributes attrs) throws ADSContextException
  {
    HashMap<ServerGroupProperty, Object> result =
      new HashMap<ServerGroupProperty, Object>();
    try
    {
      NamingEnumeration ne = attrs.getAll();
      while (ne.hasMore())
      {
        Attribute attr = (Attribute)ne.next();
        String attrID = attr.getID();
        Object value = null;
        ServerGroupProperty prop = null;
        ServerGroupProperty[] props = ServerGroupProperty.values();
        for (int i=0; i<props.length && (prop == null); i++)
        {
          String v = props[i].getAttributeName();
          if (attrID.equalsIgnoreCase(v))
          {
            prop = props[i];
          }
        }
        if (prop == null)
        {
          throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED);
        }
        if (attr.size() >= 1 &&
            MULTIVALUED_SERVER_GROUP_PROPERTIES.contains(prop))
        {
          Set<String> set = new HashSet<String>();
          NamingEnumeration ae = attr.getAll();
          while (ae.hasMore())
          {
            set.add((String)ae.next());
          }
          value = set;
        }
        else
        {
          value = attr.get(0);
        }
        result.put(prop, value);
      }
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns the properties of a server for some LDAP attributes.
   * @param attrs the LDAP attributes.
   * @return the properties of a server for some LDAP attributes.
   * @throws ADSContextException if something goes wrong.
   */
  private Map<ServerProperty, Object> makePropertiesFromServerAttrs(
      Attributes attrs) throws ADSContextException
  {
    HashMap<ServerProperty, Object> result =
      new HashMap<ServerProperty, Object>();
    try
    {
      NamingEnumeration ne = attrs.getAll();
      while (ne.hasMore())
      {
        Attribute attr = (Attribute)ne.next();
        String attrID = attr.getID();
        Object value = null;
        if (attrID.endsWith(";binary"))
        {
          attrID = attrID.substring(0, attrID.lastIndexOf(";binary"));
        }
        ServerProperty prop = null;
        ServerProperty[] props = ServerProperty.values();
        for (int i=0; i<props.length && (prop == null); i++)
        {
          String v = props[i].getAttributeName();
          if (attrID.equalsIgnoreCase(v))
          {
            prop = props[i];
          }
        }
        if (prop == null)
        {
          throw new ADSContextException(
              ADSContextException.ErrorType.ERROR_UNEXPECTED);
        }
        if (attr.size() >= 1 && MULTIVALUED_SERVER_PROPERTIES.contains(prop))
        {
          Set<String> set = new HashSet<String>();
          NamingEnumeration ae = attr.getAll();
          while (ae.hasMore())
          {
            set.add((String)ae.next());
          }
          value = set;
        }
        else
        {
          value = attr.get(0);
        }
        result.put(prop, value);
      }
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns the properties of a server group for an RDN and some LDAP
   * attributes.
   * @param rdnName the RDN.
   * @param attrs the LDAP attributes.
   * @return the properties of a server group for an RDN and some LDAP
   * attributes.
   * @throws ADSContextException if something goes wrong.
   */
  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String rdnName,
      Attributes attrs) throws ADSContextException
  {
    String hostName, ipath;
    LdapName nameObj;
    nameObj = nameFromDN(rdnName);
    //
    // Extract the hostname and ipath from the dn
    //
    Rdn rdnObj = nameObj.getRdn(nameObj.size() - 1);
    String hostNamePath = (String)Rdn.unescapeValue((String)rdnObj.getValue());
    int sepIndex = hostNamePath.indexOf(HNP_SEPARATOR);
    if (sepIndex != -1)
    {
      hostName = hostNamePath.substring(0, sepIndex);
      ipath = hostNamePath.substring(sepIndex+1, hostNamePath.length());
    }
    else
    { // Emergency logic...
      hostName = hostNamePath;
      ipath = "undefined";
    }
    //
    // Delegate...
    //
    return makePropertiesFromServerAttrs(hostName, ipath, attrs);
  }
  /**
   * Returns the properties of a server for some host name, installation path
   * and LDAP attributes.
   * @param hostName the host name.
   * @param ipath the installation path.
   * @param attrs the LDAP attributes.
   * @return the properties of a server for the given host name, installation
   * path and LDAP attributes.
   * @throws ADSContextException if something goes wrong.
   */
  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String hostName,
      String ipath, Attributes attrs) throws ADSContextException
  {
    Map<ServerProperty, Object> result = new HashMap<ServerProperty, Object>();
    //
    // Put hostname and ipath
    //
    result.put(ServerProperty.HOSTNAME, hostName);
    result.put(ServerProperty.INSTANCE_PATH, ipath);
    //
    // Get other properties from the attributes
    //
    result.putAll(makePropertiesFromServerAttrs(attrs));
    return result;
  }
  /**
   * Returns the properties of an administrator for some rdn and LDAP
   * attributes.
   * @param rdn the RDN.
   * @param attrs the LDAP attributes.
   * @return the properties of an administrator for the given rdn and LDAP
   * attributes.
   * @throws ADSContextException if something goes wrong.
   */
  private Map<AdministratorProperty, Object>
  makePropertiesFromAdministratorAttrs(String rdn, Attributes attrs)
  throws ADSContextException
  {
    Map<AdministratorProperty, Object> result =
      new HashMap<AdministratorProperty, Object>();
    String dn = rdn + "," + getAdministratorContainerDN();
    result.put(AdministratorProperty.ADMINISTRATOR_DN, dn);
    try
    {
      NamingEnumeration ne = attrs.getAll();
      while (ne.hasMore()) {
        Attribute attr = (Attribute)ne.next();
        String attrID = attr.getID();
        Object value = null;
        if (attrID.equalsIgnoreCase("cn"))
        {
          value = attr.get(0);
          result.put(AdministratorProperty.UID, value);
        }
        else if (attrID.equalsIgnoreCase("userpassword"))
        {
          value = attr.get(0);
          result.put(AdministratorProperty.PASSWORD, value);
        }
        else if (attrID.equalsIgnoreCase("description"))
        {
          value = attr.get(0);
          result.put(AdministratorProperty.DESCRIPTION, value);
        }
      }
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Returns the parent entry of the server entries.
   * @return the parent entry of the server entries.
   */
  private static String getServerContainerDN()
  {
    return "cn=Servers," + getAdministrationSuffixDN();
  }
  /**
   * Returns the parent entry of the administrator entries.
   * @return the parent entry of the administrator entries.
   */
  private static String getAdministratorContainerDN()
  {
    return "cn=Administrators," + getAdministrationSuffixDN();
  }
  /**
   * Returns the parent entry of the server group entries.
   * @return the parent entry of the server group entries.
   */
  private static String getServerGroupContainerDN()
  {
    return "cn=Server Groups," + getAdministrationSuffixDN();
  }
  /**
   * Returns the host name for the given properties.
   * @param serverProperties the server properties.
   * @return the host name for the given properties.
   * @throws ADSContextException if the host name could not be found or its
   * value is not valid.
   */
  private static String getHostname(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    String result = (String)serverProperties.get(ServerProperty.HOSTNAME);
    if (result == null)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.MISSING_HOSTNAME);
    }
    else if (result.length() == 0)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOVALID_HOSTNAME);
    }
    return result;
  }
  /**
   * Returns the install path for the given properties.
   * @param serverProperties the server properties.
   * @return the install path for the given properties.
   * @throws ADSContextException if the install path could not be found or its
   * value is not valid.
   */
  private static String getInstallPath(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    String result = (String)serverProperties.get(ServerProperty.INSTANCE_PATH);
    if (result == null)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.MISSING_IPATH);
    }
    else if (result.length() == 0)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.NOVALID_IPATH);
    }
    return result;
  }
  /**
   * Returns the Administrator UID for the given properties.
   * @param adminProperties the server properties.
   * @return the Administrator UID for the given properties.
   * @throws ADSContextException if the administrator UID could not be found.
   */
  private String getAdministratorUID(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException {
    String result = (String)adminProperties.get(
        AdministratorProperty.UID);
    if (result == null)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.MISSING_ADMIN_UID);
    }
    return result;
  }
  /**
   * Returns the Administrator password for the given properties.
   * @param adminProperties the server properties.
   * @return the Administrator password for the given properties.
   * @throws ADSContextException if the administrator password could not be
   * found.
   */
  private String getAdministratorPassword(
      Map<AdministratorProperty, Object> adminProperties)
  throws ADSContextException {
    String result = (String)adminProperties.get(
        AdministratorProperty.PASSWORD);
    if (result == null)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.MISSING_ADMIN_PASSWORD);
    }
    return result;
  }
  //
  // LDAP utilities
  //
  /**
   * Returns the LdapName object for the given dn.
   * @return the LdapName object for the given dn.
   * @throws ADSContextException if a valid LdapName could not be retrieved
   * for the given dn.
   */
  private static LdapName nameFromDN(String dn) throws ADSContextException
  {
    LdapName result = null;
    try
    {
      result = new LdapName(dn);
    }
    catch (InvalidNameException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Tells whether an entry with the provided DN exists.
   * @return <CODE>true</CODE> if the entry exists and <CODE>false</CODE> if
   * it does not.
   * @throws ADSContextException if an error occurred while checking if the
   * entry exists or not.
   */
  private boolean isExistingEntry(LdapName dn) throws ADSContextException
  {
    boolean result;
    try
    {
      SearchControls sc = new SearchControls();
      sc.setSearchScope(SearchControls.OBJECT_SCOPE);
      result = getDirContext().search(dn, "(objectclass=*)", sc).hasMore();
    }
    catch (NameNotFoundException x)
    {
      result = false;
    }
    catch (NoPermissionException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ACCESS_PERMISSION);
    }
    catch(javax.naming.NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
    return result;
  }
  /**
   * Creates a container entry with the given dn.
   * @param dn the entry of the new entry to be created.
   * @throws ADSContextException if the entry could not be created.
   */
  private void createContainerEntry(String dn) throws ADSContextException
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "extensibleobject");
    createEntry(dn, attrs);
  }
  /**
   * Creates the administrator container entry.
   * @throws ADSContextException if the entry could not be created.
   */
  private void createAdministratorContainerEntry() throws ADSContextException
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "groupOfUniqueNames");
    attrs.put("objectclass", "groupofurls");
    attrs.put("memberURL", "ldap:///" + getAdministratorContainerDN() +
        "??one?(objectclass=*)");
    attrs.put("description", "Group of identities which have full access.");
    createEntry(getAdministratorContainerDN(), attrs);
  }
  /**
   * Creates the top container entry.
   * @throws ADSContextException if the entry could not be created.
   */
  private void createTopContainerEntry() throws ADSContextException
  {
    BasicAttributes attrs = new BasicAttributes();
    attrs.put("objectclass", "extensibleobject");
    attrs.put("aci", getTopContainerACI());
    createEntry(getAdministrationSuffixDN(), attrs);
  }
  /**
   * Creates an entry with the provided dn and attributes.
   * @param dn the dn of the entry.
   * @param attrs the attributes of the entry.
   * @throws ADSContextException if the entry could not be created.
   */
  private void createEntry(String dn, Attributes attrs)
  throws ADSContextException {
    try
    {
      DirContext ctx = getDirContext().createSubcontext(nameFromDN(dn), attrs);
      ctx.close();
    }
    catch(NamingException x)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
    }
  }
  /**
   * Returns the DN of the ACI container entry.
   * @return the DN of the ACI container entry.
   */
  private static String getTopContainerACI()
  {
    return
    "(targetattr = \"*\")" +
    "(version 3.0;" +
    "acl \"Enable full access for Directory Services Managers group\";" +
    "allow (all)" +
    "(groupdn = \"ldap:///" + getAdministratorContainerDN() + "\");" +
    ")";
  }
  /**
   * Creates the Administration Suffix.
   * @throws ADSContextException if something goes wrong.
   */
  private void createAdministrationSuffix()
  throws ADSContextException
  {
    // TODO: use new administration framework.
  }
  /**
   * Creates the Administration Suffix when the server is down.  This can only
   * be called locally.
   * @param installPath the installation path of the server
   * @throws ADSContextException if something goes wrong.
   */
  private static void createOfflineAdministrationSuffix(String installPath)
  throws ADSContextException
  {
    // TODO: the call to this method assumes
    // that OpenDS.jar has already been loaded.  So this should not be called by
    // the Java Web Start before being sure that this jar is loaded.
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(org.opends.server.extensions.ConfigFileHandler.class.getName());
    argList.add("-c");
    argList.add(installPath+File.separator+"config"+File.separator+
        "config.ldif");
    argList.add("-b");
    argList.add(getAdministrationSuffixDN());
    String[] args = new String[argList.size()];
    argList.toArray(args);
    int returnValue = org.opends.server.tools.ConfigureDS.configMain(args);
    if (returnValue != 0)
    {
      throw new ADSContextException(
          ADSContextException.ErrorType.ERROR_UNEXPECTED);
    }
  }
  /**
   * Removes the administration suffix.
   * @throws ADSContextException
   */
  private void removeAdministrationSuffix() throws ADSContextException
  {
    // TODO: use new administration framework
  }
  /**
   * Returns the first ACI required to provide access to administrators.
   * @return the first ACI required to provide access to administrators.
   */
  private static String getAdminACI1()
  {
    return
    "(targetattr = \"*\") " +
    "(version 3.0; " +
    "acl \"Enable full access for Global Administrators.\"; " +
    "allow (all)(userdn = \"ldap:///" +
    getAdministratorDN("*") +
    "\");)";
  }
  /**
   * Returns the second ACI required to provide access to administrators.
   * @return the second ACI required to provide access to administrators.
   */
  private static String getAdminACI2()
  {
    return
    "(targetattr = \"aci\") (targetscope = \"base\") " +
    "(version 3.0; " +
    "acl \"Enable root ACI modification by Global Administrators.\"; "+
    "allow (all)(userdn = \"ldap:///" +
    getAdministratorDN("*") +
    "\");)";
  }
}
opends/src/ads/org/opends/admin/ads/ADSContextException.java
New file
@@ -0,0 +1,176 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
/**
 * This is the exception that is thrown in ADSContext.
 * @see ADSContext.
 *
 */
public class ADSContextException extends Exception {
  private static final long serialVersionUID = 1984039711031042813L;
  private String toString;
  /**
   * The enumeration containing the different error types.
   *
   */
  public enum ErrorType
  {
    /**
     * The host name is missing.
     */
    MISSING_HOSTNAME,
    /**
     * The host name is not valid.
     */
    NOVALID_HOSTNAME,
    /**
     * The installation path is missing.
     */
    MISSING_IPATH,
    /**
     * The installation path is not valid.
     */
    NOVALID_IPATH,
    /**
     * An access permission error.
     */
    ACCESS_PERMISSION,
    /**
     * The entity is already registered.
     */
    ALREADY_REGISTERED,
    /**
     * The installation is broken.
     */
    BROKEN_INSTALL,
    /**
     * The entity is not yet registered.
     */
    NOT_YET_REGISTERED,
    /**
     * The port is missing.
     */
    MISSING_PORT,
    /**
     * The port is not valid.
     */
    NOVALID_PORT,
    /**
     * The name is missing.
     */
    MISSING_NAME,
    /**
     * The administration UID is missing.
     */
    MISSING_ADMIN_UID,
    /**
     * The administratior password is missing.
     */
    MISSING_ADMIN_PASSWORD,
    /**
     * Unexpected error (potential bug).
     */
    ERROR_UNEXPECTED
  };
  ErrorType error;
  Throwable embeddedException;
  /**
   * Creates an ADSContextException of the given error type.
   * @param error the error type.
   */
  public ADSContextException(ErrorType error)
  {
    this.error = error;
  }
  /**
   * Creates an ADSContextException of the given error type with the provided
   * error cause.
   * @param error the error type.
   * @param x the throwable that generated this exception.
   */
  public ADSContextException(ErrorType error, Throwable x)
  {
    this.error = error;
    this.embeddedException = x;
  }
  /**
   * Returns the error type of this exception.
   * @return the error type of this exception.
   */
  public ErrorType getError()
  {
    return error;
  }
  /**
   * Returns the throwable that caused this exception.  It might be null.
   * @return the throwable that caused this exception.
   */
  public Throwable getCause()
  {
    return embeddedException;
  }
  /**
   * {@inheritDoc}
   */
  public String toString()
  {
    if (toString == null)
    {
      toString = "ADSContextException: error type"+error+".";
      if (getCause() != null)
      {
        toString += "  Root cause: "+getCause().toString();
      }
    }
    return toString;
  }
  /**
   * {@inheritDoc}
   */
  public void printStackTrace()
  {
    super.printStackTrace();
    if (embeddedException != null)
    {
      System.out.println("embeddedException = {");
      embeddedException.printStackTrace();
      System.out.println("}");
    }
  }
}
opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
New file
@@ -0,0 +1,100 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
/**
 * The object of this class represent a Replica (i.e. a suffix in a given
 * server).
 */
public class ReplicaDescriptor
{
  private SuffixDescriptor suffix;
  private int entries = -1;
  private ServerDescriptor server;
  /**
   * Returns the number of entries contained in the replica.
   * @return the number of entries contained in the replica.
   */
  public int getEntries()
  {
    return entries;
  }
  /**
   * Sets the number of entries contained in the replica.
   * @param entries the number of entries contained in the replica.
   */
  public void setEntries(int entries)
  {
    this.entries = entries;
  }
  /**
   * Returns the ServerDescriptor object associated with the server where this
   * replica is located.
   * @return the ServerDescriptor object associated with the server where this
   * replica is located.
   */
  public ServerDescriptor getServer()
  {
    return server;
  }
  /**
   * Sets the server where this replica is located.
   * @param server the ServerDescriptor object associated with the server where
   * this replica is located.
   */
  public void setServer(ServerDescriptor server)
  {
    this.server = server;
  }
  /**
   * Returns the SuffixDescriptor object representing the suffix topology
   * across servers to which this replica belongs.
   * @return the SuffixDescriptor object representing the suffix topology
   * across servers to which this replica belongs.
   */
  public SuffixDescriptor getSuffix()
  {
    return suffix;
  }
  /**
   * Sets the SuffixDescriptor object representing the suffix topology
   * across servers to which this replica belongs.
   * @param suffix the SuffixDescriptor object representing the suffix topology
   * across servers to which this replica belongs.
   */
  public void setSuffix(SuffixDescriptor suffix)
  {
    this.suffix = suffix;
  }
}
opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
New file
@@ -0,0 +1,90 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
 * The object of this class represent an OpenDS server.
 */
public class ServerDescriptor
{
  private Map<ADSContext.ServerProperty, Object> adsProperties =
    new HashMap<ADSContext.ServerProperty, Object>();
  private Set<ReplicaDescriptor> replicas = new HashSet<ReplicaDescriptor>();
  /**
   * Returns the replicas contained on the server.
   * @return the replicas contained on the server.
   */
  public Set<ReplicaDescriptor> getReplicas()
  {
    return replicas;
  }
  /**
   * Sets the replicas contained on the server.
   * @param replicas the replicas contained on the server.
   */
  public void setReplicas(Set<ReplicaDescriptor> replicas)
  {
    this.replicas = replicas;
  }
  /**
   * Returns a Map containing the properties of the server.
   * @return a Map containing the properties of the server.
   */
  public Map<ADSContext.ServerProperty, Object> getAdsProperties()
  {
    return adsProperties;
  }
  /**
   * Tells whether this server is registered in the ADS or not.
   * @return <CODE>true</CODE> if the server is registered in the ADS and
   * <CODE>false</CODE> otherwise.
   */
  public boolean isRegistered()
  {
    return !adsProperties.isEmpty();
  }
  /**
   * Sets the properties of the server.
   * @param adsProperties a Map containing the properties of the server.
   */
  public void setAdsProperties(
      Map<ADSContext.ServerProperty, Object> adsProperties)
  {
    this.adsProperties = adsProperties;
  }
}
opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java
New file
@@ -0,0 +1,151 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
import java.util.HashSet;
import java.util.Set;
/**
 * The object of this class represent a topology of replicas across servers
 * that have the same suffix DN.  They may or might not be replicated.
 */
public class SuffixDescriptor
{
  private String suffixDN;
  private Set<ReplicaDescriptor> replicas = new HashSet<ReplicaDescriptor>();
  /**
   * Returns the DN associated with this suffix descriptor.
   * @return the DN associated with this suffix descriptor.
   */
  public String getDN()
  {
    return suffixDN;
  }
  /**
   * Sets the DN associated with this suffix descriptor.
   * @param suffixDN the DN associated with this suffix descriptor.
   */
  public void setDN(String suffixDN)
  {
    this.suffixDN = suffixDN;
  }
  /**
   * Returns the replicas associated with this SuffixDescriptor.
   * @return a Set containing the replicas associated with this
   * SuffixDescriptor.
   */
  public Set<ReplicaDescriptor> getReplicas()
  {
    return replicas;
  }
  /**
   * Sets the replicas associated with this SuffixDescriptor.
   * @param replicas a Set containing the replicas associated with this
   * SuffixDescriptor.
   */
  public void setReplicas(Set<ReplicaDescriptor> replicas)
  {
    this.replicas = replicas;
  }
  /**
   * {@inheritDoc}
   */
  public boolean equals(Object v)
  {
    // TODO: this is buggy code
    boolean equals = false;
    if (this != v)
    {
      if (v instanceof SuffixDescriptor)
      {
        SuffixDescriptor desc = (SuffixDescriptor)v;
        equals = getDN().equals(desc.getDN());
        if (equals)
        {
          equals = getReplicas().size() == desc.getReplicas().size();
        }
        if (equals)
        {
          for (ReplicaDescriptor repl : getReplicas())
          {
            boolean serverFound = false;
            ServerDescriptor server = repl.getServer();
            for (ReplicaDescriptor repl1 : desc.getReplicas())
            {
              serverFound = serversEqual(server, repl1.getServer());
              if (serverFound)
              {
                break;
              }
            }
            if (!serverFound)
            {
              equals = false;
              break;
            }
          }
        }
      }
    }
    else
    {
      equals = true;
    }
    return equals;
  }
  /**
   * Tells whether the two provided objects represent the same server or not.
   * @param serv1 the first ServerDescriptor to compare.
   * @param serv2 the second ServerDescriptor to compare.
   * @return <CODE>true</CODE> if the two objects represent the same server
   * and <CODE>false</CODE> otherwise.
   */
  private boolean serversEqual(ServerDescriptor serv1, ServerDescriptor serv2)
  {
    return serv1.getAdsProperties().equals(serv2.getAdsProperties());
  }
  /**
   * {@inheritDoc}
   */
  public int hashCode()
  {
//  FIXME: this is buggy code
    return getDN().hashCode();
  }
}
opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
@@ -109,7 +109,7 @@
      }
      else if (isInstalled)
      {
        StringBuffer buf = new StringBuffer();
        StringBuilder buf = new StringBuilder();
        buf.append("<ul>");
        for (String msg : msgs)
        {
@@ -412,7 +412,7 @@
  {
    if (configFileContents == null)
    {
      StringBuffer buf = new StringBuffer();
      StringBuilder buf = new StringBuilder();
      try
      {
        Installation installation = getInstallationFromClassPath();
opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java
@@ -33,7 +33,6 @@
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.webstart.JnlpProperties;
import org.opends.quicksetup.util.Utils;
import org.opends.server.tools.ConfigureWindowsService;
/**
 * This is the only class that uses classes in org.opends.server (excluding the
@@ -94,9 +93,11 @@
    "error-enabling-windows-service");
    switch (code) {
      case ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
      case
      org.opends.server.tools.ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
        break;
      case ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
      case
      org.opends.server.tools.ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
        break;
      default:
        throw new QuickSetupException(
opends/src/quicksetup/org/opends/quicksetup/Step.java
@@ -51,9 +51,21 @@
  SERVER_SETTINGS("server-settings-step"),
  /**
   * Data Replication panel (standalone or replicated).
   */
  REPLICATION_OPTIONS("data-replication-step"),
  /**
   * Global Administrator creation panel.
   */
  CREATE_GLOBAL_ADMINISTRATOR("create-global-administrator-step"),
  /**
   * Suffixes to Replicate.
   */
  SUFFIXES_OPTIONS("suffixes-step"),
  /**
   * Data Options panel (suffix dn, LDIF path, etc.).
   */
  DATA_OPTIONS("data-options-step"),
  NEW_SUFFIX_OPTIONS("data-options-step"),
  /**
   * Review panel for the install.
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -27,30 +27,60 @@
package org.opends.quicksetup;
import java.util.HashSet;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.installer.AuthenticationData;
import org.opends.quicksetup.installer.DataReplicationOptions;
import org.opends.quicksetup.installer.NewSuffixOptions;
import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
import org.opends.quicksetup.util.Utils;
/**
 * Represents user specified input data to an application.
 * This class is used to provide a data model for the different parameters
 * that the user can provide in the installation wizard.
 *
 * @see DataOptions.
 *
 */
public class UserData {
public class UserData
{
  private String serverLocation;
  private int serverPort;
  private String directoryManagerDn;
  private String directoryManagerPwd;
  private DataOptions dataOptions;
  private String globalAdministratorUID;
  private String globalAdministratorPassword;
  private SecurityOptions securityOptions;
  private int serverJMXPort;
  private boolean startServer;
  private boolean stopServer;
  private NewSuffixOptions newSuffixOptions;
  private DataReplicationOptions replicationOptions;
  private boolean createAdministrator;
  private SuffixesToReplicateOptions suffixesToReplicateOptions;
  /**
   * Creates a user data object with default values.
   */
  public UserData() {
    startServer = true;
    DataOptions defaultDataOptions = new DefaultDataOptions();
    NewSuffixOptions defaultNewSuffixOptions = new NewSuffixOptions(
        NewSuffixOptions.Type.CREATE_BASE_ENTRY, "dc=example,dc=com");
    setNewSuffixOptions(defaultNewSuffixOptions);
    setServerLocation(Utils.getDefaultServerLocation());
    // See what we can propose as port
@@ -62,7 +92,21 @@
    setDirectoryManagerDn("cn=Directory Manager");
    setDataOptions(defaultDataOptions);
    setNewSuffixOptions(defaultNewSuffixOptions);
    AuthenticationData data = new AuthenticationData();
    data.setDn("cn=Directory Manager");
    data.setPort(389);
    DataReplicationOptions repl = new DataReplicationOptions(
        DataReplicationOptions.Type.STANDALONE, data);
    setReplicationOptions(repl);
    setGlobalAdministratorUID("admin");
    SuffixesToReplicateOptions suffixes =
      new SuffixesToReplicateOptions(
          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES,
          new HashSet<SuffixDescriptor>(),
          new HashSet<SuffixDescriptor>());
    setSuffixesToReplicateOptions(suffixes);
    SecurityOptions sec = SecurityOptions.createNoCertificateOptions();
    sec.setSslPort(getDefaultSslPort());
    sec.setCertificateUserName(getDefaultSelfSignedName());
@@ -106,6 +150,24 @@
  }
  /**
   * Sets the server JMX port.
   * @param serverJMXPort the new server JMX port.
   */
  public void setServerJMXPort(int serverJMXPort)
  {
    this.serverJMXPort = serverJMXPort;
  }
  /**
   * Returns the server JMX port.
   * @return the server JMX port.
   */
  public int getServerJMXPort()
  {
    return serverJMXPort;
  }
  /**
   * Returns the Directory Manager DN.
   * @return the Directory Manager DN.
   */
@@ -142,46 +204,6 @@
  }
  /**
   * Returns the DataOptions object representing the data in the Data Options
   * panel.
   * @return the DataOptions object representing the data in the Data Options
   * panel.
   */
  public DataOptions getDataOptions()
  {
    return dataOptions;
  }
  /**
   * Sets the DataOptions object representing the data in the Data Options
   * panel.
   * @param dataOptions the DataOptions object representing the data in the Data
   * Options panel.
   */
  public void setDataOptions(DataOptions dataOptions)
  {
    this.dataOptions = dataOptions;
  }
  /**
   * Sets the server JMX port.
   * @param serverJMXPort the new server JMX port.
   */
  public void setServerJMXPort(int serverJMXPort)
  {
    this.serverJMXPort = serverJMXPort;
  }
  /**
   * Returns the server JMX port.
   * @return the server JMX port.
   */
  public int getServerJMXPort()
  {
    return serverJMXPort;
  }
  /**
   * Returns <CODE>true</CODE> if the server must be started once the
   * installation is finished, <CODE>false</CODE> if not.
   * @return <CODE>true</CODE> if the server must be started once the
@@ -223,6 +245,127 @@
  }
  /**
   * Returns the NewSuffixOptions object representing the data in the New Suffix
   * Data Options panel.
   * @return the NewSuffixOptions object representing the data in the New Suffix
   * Data Options panel.
   */
  public NewSuffixOptions getNewSuffixOptions()
  {
    return newSuffixOptions;
  }
  /**
   * Sets the NewSuffixOptions object representing the data in the New Suffix
   * Data Options panel.
   * @param newSuffixOptions the NewSuffixOptions object representing the data
   * in the New Suffix Data Options panel.
   */
  public void setNewSuffixOptions(NewSuffixOptions newSuffixOptions)
  {
    this.newSuffixOptions = newSuffixOptions;
  }
  /**
   * Returns the DataReplicationOptions object representing the data in the
   * Data Replication panel.
   * @return the DataReplicationOptions object representing the data in the
   * Data Replication panel.
   */
  public DataReplicationOptions getReplicationOptions()
  {
    return replicationOptions;
  }
  /**
   * Sets the DataReplicationOptions object representing the data in the
   * Data Replication panel.
   * @param replicationOptions the DataReplicationOptions object
   * representing the data in the Data Replication panel.
   */
  public void setReplicationOptions(
      DataReplicationOptions replicationOptions)
  {
    this.replicationOptions = replicationOptions;
  }
  /**
   * Returns whether must create a global administrator or not.
   * @return <CODE>true</CODE> if we must create a global administrator and
   * <CODE>false</CODE> otherwise.
   */
  public boolean mustCreateAdministrator()
  {
    return createAdministrator;
  }
  /**
   * Sets whether must create a global administrator or not.
   * @param createAdministrator whether we must create a global administrator or
   * not.
   */
  public void createAdministrator(boolean createAdministrator)
  {
    this.createAdministrator = createAdministrator;
  }
  /**
   * Returns the UID of the global administrator.
   * @return the UID of the global administrator.
   */
  public String getGlobalAdministratorUID()
  {
    return globalAdministratorUID;
  }
  /**
   * Sets the UID of the global administrator.
   * @param globalAdministratorUID the UID of the global administrator.
   */
  public void setGlobalAdministratorUID(String globalAdministratorUID)
  {
    this.globalAdministratorUID = globalAdministratorUID;
  }
  /**
   * Returns the password of the global administrator.
   * @return the password of the global administrator.
   */
  public String getGlobalAdministratorPassword()
  {
    return globalAdministratorPassword;
  }
  /**
   * Sets the password of the global administrator.
   * @param globalAdministratorPwd the password of the global administrator.
   */
  public void setGlobalAdministratorPassword(String globalAdministratorPwd)
  {
    this.globalAdministratorPassword = globalAdministratorPwd;
  }
  /**
   * Sets the suffixes to replicate options.
   * @param suffixesToReplicateOptions the suffixes to replicate options
   * object.
   */
  public void setSuffixesToReplicateOptions(
      SuffixesToReplicateOptions suffixesToReplicateOptions)
  {
    this.suffixesToReplicateOptions = suffixesToReplicateOptions;
  }
  /**
   * Returns the suffixes to replicate options.
   * @return the suffixes to replicate options.
   */
  public SuffixesToReplicateOptions getSuffixesToReplicateOptions()
  {
    return suffixesToReplicateOptions;
  }
  /**
   * Returns the SecurityOptions representing the SSL/StartTLS configuration
   * chosen by the user.
   * @return the SecurityOptions representing the SSL/StartTLS configuration
@@ -318,7 +461,6 @@
    }
    return defaultJMXPort;
  }
  /**
   * Provides the default name for the self signed certificate that will be
   * created.
opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java
New file
@@ -0,0 +1,139 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer;
/**
 * This class is used to provide a data model for the different parameters used
 * to connect to a server that we want to replicate contents with.
 *
 * @see DataReplicationOptions.
 *
 */
public class AuthenticationData
{
  private String hostName;
  private int port;
  private String dn;
  private String pwd;
  private boolean useSecureConnection;
  /**
   * Sets the server LDAP port.
   * @param port the server LDAP port.
   */
  public void setPort(int port)
  {
    this.port = port;
  }
  /**
   * Returns the server LDAP port.
   * @return the server LDAP port.
   */
  public int getPort()
  {
    return port;
  }
  /**
   * Returns the Authentication DN.
   * @return the Authentication DN.
   */
  public String getDn()
  {
    return dn;
  }
  /**
   * Sets the Authentication DN.
   * @param dn the Authentication DN.
   */
  public void setDn(String dn)
  {
    this.dn = dn;
  }
  /**
   * Returns the authentication password.
   * @return the authentication password.
   */
  public String getPwd()
  {
    return pwd;
  }
  /**
   * Sets the authentication password.
   * @param pwd the authentication password.
   */
  public void setPwd(String pwd)
  {
    this.pwd = pwd;
  }
  /**
   * Returns the host name to connect to.
   * @return the host name to connect to.
   */
  public String getHostName()
  {
    return hostName;
  }
  /**
   * Sets the host name to connect to.
   * @param hostName the host name to connect to.
   */
  public void setHostName(String hostName)
  {
    this.hostName = hostName;
  }
  /**
   * Returns whether to use a secure connection or not.
   * @return <CODE>true</CODE> if we must use a secure connection and
   * <CODE>false</CODE> otherwise.
   */
  public boolean useSecureConnection()
  {
    return useSecureConnection;
  }
  /**
   * Tells to use a secure connection or not.
   * @param useSecureConnection use a secure connection or not.
   */
  public void setUseSecureConnection(boolean useSecureConnection)
  {
    this.useSecureConnection = useSecureConnection;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
New file
@@ -0,0 +1,116 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer;
/**
 * This class is used to provide a data model for the Data Replication
 * Options panel of the installer.
 *
 */
public class DataReplicationOptions
{
  /**
   * This enumeration is used to know what the user wants to do for the data
   * (import data or not, what use as source of the data...).
   *
   */
  public enum Type
  {
    /**
     * Standalone server.
     */
    STANDALONE,
    /**
     * Replicate Contents and this is the first server in topology..
     */
    FIRST_IN_TOPOLOGY,
    /**
     * Replicate Contents of the new Suffix with existings server.
     */
    IN_EXISTING_TOPOLOGY
  }
  private Type type;
  private AuthenticationData authenticationData;
  /**
   * Constructor for the DataReplicationOptions object.
   *
   * If the Data Replication Options is STANDALONE or FIRST_IN_TOPOLOGY no
   * args are considered.
   *
   * If the Data Options is IN_EXISTING_TOPOLOGY the args is the authentication
   * data on the remote server (AuthenticationData object).
   *
   * @param type the Type of DataReplicationOptions.
   * @param args the different argument objects (depending on the Type
   * specified)
   */
  public DataReplicationOptions(Type type, Object... args)
  {
    this.type = type;
    switch (type)
    {
    case IN_EXISTING_TOPOLOGY:
      authenticationData = (AuthenticationData)args[0];
      break;
    default:
      // If there is something put it.
      if ((args != null) && (args.length > 0))
      {
        authenticationData = (AuthenticationData)args[0];
      }
    }
  }
  /**
   * Returns the type of DataReplicationOptions represented by this object
   * (replicate or not).
   *
   * @return the type of DataReplicationOptions.
   */
  public Type getType()
  {
    return type;
  }
  /**
   * Returns the AuthenticationData to the server used to replicate.
   * If it is standalone returns null.
   *
   * @return the AuthenticationData to the server used to replicate.
   */
  public AuthenticationData getAuthenticationData()
  {
    return authenticationData;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java
New file
@@ -0,0 +1,76 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer;
/**
 * This class is used to provide a data model for the global administrator
 * options.
 *
 */
public class GlobalAdministratorOptions
{
  private String uid;
  private String pwd;
  /**
   * Returns the UID of the global administrator.
   * @return the UID of the global administrator.
   */
  public String getUid()
  {
    return uid;
  }
  /**
   * Sets the UID of the global administrator.
   * @param uid the UID of the global administrator.
   */
  public void setUid(String uid)
  {
    this.uid = uid;
  }
  /**
   * Returns the password of the global administrator.
   * @return the password of the global administrator.
   */
  public String getPwd()
  {
    return pwd;
  }
  /**
   * Sets the password of the global administrator.
   * @param pwd the password of the global administrator.
   */
  public void setPwd(String pwd)
  {
    this.pwd = pwd;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
@@ -180,5 +180,4 @@
    return org.opends.server.tools.InstallDS.installMain(newArgs);
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -37,11 +37,26 @@
import java.util.*;
import java.awt.event.WindowEvent;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.ReplicaDescriptor;
import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.ui.*;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.*;
import org.opends.server.util.CertificateManager;
import org.opends.quicksetup.installer.ui.DataOptionsPanel;
import org.opends.quicksetup.installer.ui.DataReplicationPanel;
import org.opends.quicksetup.installer.ui.GlobalAdministratorPanel;
import org.opends.quicksetup.installer.ui.InstallReviewPanel;
import org.opends.quicksetup.installer.ui.InstallWelcomePanel;
import org.opends.quicksetup.installer.ui.ServerSettingsPanel;
import org.opends.quicksetup.installer.ui.SuffixesToReplicatePanel;
import org.opends.server.util.SetupUtils;
import javax.naming.ldap.Rdn;
@@ -88,6 +103,17 @@
  private List<WizardStep> lstSteps = new ArrayList<WizardStep>();
  private final HashSet<WizardStep> SUBSTEPS = new HashSet<WizardStep>();
  {
    SUBSTEPS.add(Step.CREATE_GLOBAL_ADMINISTRATOR);
//  TODO: remove this comment once the replication code is in place.
    SUBSTEPS.add(Step.SUFFIXES_OPTIONS);
    //SUBSTEPS.add(Step.NEW_SUFFIX_OPTIONS);
  }
  private HashMap<WizardStep, WizardStep> hmPreviousSteps =
    new HashMap<WizardStep, WizardStep>();
  /**
   * An static String that contains the class name of ConfigFileHandler.
   */
@@ -100,7 +126,12 @@
  public Installer() {
    lstSteps.add(WELCOME);
    lstSteps.add(SERVER_SETTINGS);
    lstSteps.add(DATA_OPTIONS);
    /*
    lstSteps.add(REPLICATION_OPTIONS);
    lstSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
    lstSteps.add(SUFFIXES_OPTIONS);
    */
    lstSteps.add(NEW_SUFFIX_OPTIONS);
    lstSteps.add(REVIEW);
    lstSteps.add(PROGRESS);
  }
@@ -159,14 +190,57 @@
  /**
   * {@inheritDoc}
   */
  public void previousClicked(WizardStep cStep) {
    if (cStep == WELCOME) {
      throw new IllegalStateException(
          "Cannot click on previous from progress step");
    } else if (cStep == PROGRESS) {
      throw new IllegalStateException(
          "Cannot click on previous from progress step");
  public boolean isSubStep(WizardStep step)
  {
    return SUBSTEPS.contains(step);
  }
  /**
   * {@inheritDoc}
   */
  public boolean isVisible(WizardStep step)
  {
    boolean isVisible;
    if (step == CREATE_GLOBAL_ADMINISTRATOR)
    {
       isVisible = getUserData().mustCreateAdministrator();
    }
    else if (step == NEW_SUFFIX_OPTIONS)
    {
      SuffixesToReplicateOptions suf =
        getUserData().getSuffixesToReplicateOptions();
      if (suf != null)
      {
        isVisible = suf.getType() !=
          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES;
      }
      else
      {
        isVisible = false;
      }
    }
    else if (step == SUFFIXES_OPTIONS)
    {
      DataReplicationOptions repl =
        getUserData().getReplicationOptions();
      if (repl != null)
      {
        isVisible =
          (repl.getType() != DataReplicationOptions.Type.STANDALONE) &&
          (repl.getType() != DataReplicationOptions.Type.FIRST_IN_TOPOLOGY);
      }
      else
      {
        isVisible = false;
      }
    }
    else
    {
      isVisible = true;
    }
    // TODO: to delete the following line once the replication code works.
    isVisible = true;
    return isVisible;
  }
  /**
@@ -284,7 +358,13 @@
        p = new InstallWelcomePanel(this);
    } else if (step == SERVER_SETTINGS) {
        p = new ServerSettingsPanel(this);
    } else if (step == DATA_OPTIONS) {
    } else if (step == REPLICATION_OPTIONS) {
      p = new DataReplicationPanel(this);
    } else if (step == CREATE_GLOBAL_ADMINISTRATOR) {
      p = new GlobalAdministratorPanel(this);
    } else if (step == SUFFIXES_OPTIONS) {
      p = new SuffixesToReplicatePanel(this);
    } else if (step == NEW_SUFFIX_OPTIONS) {
        p = new DataOptionsPanel(this);
    } else if (step == REVIEW) {
        p = new InstallReviewPanel(this);
@@ -338,7 +418,13 @@
   * {@inheritDoc}
   */
  public void previousClicked(WizardStep cStep, QuickSetup qs) {
    // do nothing;
    if (cStep == WELCOME) {
      throw new IllegalStateException(
          "Cannot click on previous from progress step");
    } else if (cStep == PROGRESS) {
      throw new IllegalStateException(
          "Cannot click on previous from progress step");
    }
  }
  /**
@@ -349,7 +435,7 @@
  }
  /** Indicates the current progress step. */
  protected InstallProgressStep status =
  private InstallProgressStep status =
          InstallProgressStep.NOT_STARTED;
  /**
@@ -359,7 +445,6 @@
                                      UserData userData,
                                      WizardStep step) {
    if (!installStatus.isInstalled() || forceToDisplaySetup) {
      // Set the default button for the frame
      if (step == REVIEW) {
        dlg.setFocusOnButton(ButtonName.FINISH);
@@ -400,9 +485,49 @@
   */
  public WizardStep getNextWizardStep(WizardStep step) {
    WizardStep next = null;
    int i = lstSteps.indexOf(step);
    if (i != -1 && i + 1 < lstSteps.size()) {
      next = lstSteps.get(i + 1);
    if (step == Step.REPLICATION_OPTIONS)
    {
      if (getUserData().mustCreateAdministrator())
      {
        next = Step.CREATE_GLOBAL_ADMINISTRATOR;
      }
      else
      {
        switch (getUserData().getReplicationOptions().getType())
        {
        case FIRST_IN_TOPOLOGY:
          next = Step.NEW_SUFFIX_OPTIONS;
          break;
        case STANDALONE:
          next = Step.NEW_SUFFIX_OPTIONS;
          break;
        default:
          next = Step.SUFFIXES_OPTIONS;
        }
      }
    }
    else if (step == Step.SUFFIXES_OPTIONS)
    {
      switch (getUserData().getSuffixesToReplicateOptions().
          getType())
      {
      case REPLICATE_WITH_EXISTING_SUFFIXES:
        next = Step.REVIEW;
        break;
      default:
        next = Step.NEW_SUFFIX_OPTIONS;
      }
    }
    else
    {
      int i = lstSteps.indexOf(step);
      if (i != -1 && i + 1 < lstSteps.size()) {
        next = lstSteps.get(i + 1);
      }
    }
    if (next != null)
    {
      hmPreviousSteps.put(next, step);
    }
    return next;
  }
@@ -410,11 +535,36 @@
  /**
   * {@inheritDoc}
   */
  public LinkedHashSet<WizardStep> getOrderedSteps()
  {
    LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
    orderedSteps.add(WELCOME);
    orderedSteps.add(SERVER_SETTINGS);
    // TODO: remove this comment once the replication code is in place.
    /*
    orderedSteps.add(REPLICATION_OPTIONS);
    orderedSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
    orderedSteps.add(SUFFIXES_OPTIONS);
    */
    orderedSteps.add(NEW_SUFFIX_OPTIONS);
    orderedSteps.add(REVIEW);
    orderedSteps.add(PROGRESS);
    return orderedSteps;
  }
  /**
   * {@inheritDoc}
   */
  public WizardStep getPreviousWizardStep(WizardStep step) {
    WizardStep prev = null;
    int i = lstSteps.indexOf(step);
    if (i != -1 && i > 0) {
      prev = lstSteps.get(i - 1);
    //  Try with the steps calculated in method getNextWizardStep.
    WizardStep prev = hmPreviousSteps.get(step);
    if (prev == null)
    {
      int i = lstSteps.indexOf(step);
      if (i != -1 && i > 0) {
        prev = lstSteps.get(i - 1);
      }
    }
    return prev;
  }
@@ -432,8 +582,8 @@
    try
    {
      return SetupUtils.createTemplateFile(
                  getUserData().getDataOptions().getBaseDn(),
                  getUserData().getDataOptions().getNumberEntries());
                  getUserData().getNewSuffixOptions().getBaseDn(),
                  getUserData().getNewSuffixOptions().getNumberEntries());
    }
    catch (IOException ioe)
    {
@@ -527,8 +677,11 @@
    argList.add("-w");
    argList.add(getUserData().getDirectoryManagerPwd());
    argList.add("-b");
    argList.add(getUserData().getDataOptions().getBaseDn());
    if (createNotReplicatedSuffix())
    {
      argList.add("-b");
      argList.add(getUserData().getNewSuffixOptions().getBaseDn());
    }
    String[] args = new String[argList.size()];
    argList.toArray(args);
@@ -665,12 +818,12 @@
   */
  protected void createBaseEntry() throws QuickSetupException {
    String[] arg =
      { getUserData().getDataOptions().getBaseDn() };
      { getUserData().getNewSuffixOptions().getBaseDn() };
    notifyListeners(getFormattedWithPoints(
        getMsg("progress-creating-base-entry", arg)));
    InstallerHelper helper = new InstallerHelper();
    String baseDn = getUserData().getDataOptions().getBaseDn();
    String baseDn = getUserData().getNewSuffixOptions().getBaseDn();
    File tempFile = helper.createBaseEntryTempFile(baseDn);
    ArrayList<String> argList = new ArrayList<String>();
@@ -718,7 +871,7 @@
   */
  protected void importLDIF() throws QuickSetupException {
    String[] arg =
      { getUserData().getDataOptions().getLDIFPath() };
      { getUserData().getNewSuffixOptions().getLDIFPath() };
    notifyListeners(getFormattedProgress(getMsg("progress-importing-ldif", arg))
        + getLineBreak());
@@ -731,7 +884,7 @@
    argList.add("-n");
    argList.add(getBackendName());
    argList.add("-l");
    argList.add(getUserData().getDataOptions().getLDIFPath());
    argList.add(getUserData().getNewSuffixOptions().getLDIFPath());
    String[] args = new String[argList.size()];
    argList.toArray(args);
@@ -762,7 +915,7 @@
   */
  protected void importAutomaticallyGenerated() throws QuickSetupException {
    File templatePath = createTemplateFile();
    int nEntries = getUserData().getDataOptions().getNumberEntries();
    int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
    String[] arg =
      { String.valueOf(nEntries) };
    notifyListeners(getFormattedProgress(getMsg(
@@ -886,11 +1039,28 @@
  public void updateUserData(WizardStep cStep, QuickSetup qs)
          throws UserDataException
  {
    if (cStep == SERVER_SETTINGS) {
    if (cStep == SERVER_SETTINGS)
    {
      updateUserDataForServerSettingsPanel(qs);
    } else if (cStep == DATA_OPTIONS) {
      updateUserDataForDataOptionsPanel(qs);
    } else if (cStep == REVIEW) {
    }
    else if (cStep == REPLICATION_OPTIONS)
    {
      updateUserDataForReplicationOptionsPanel(qs);
    }
    else if (cStep == CREATE_GLOBAL_ADMINISTRATOR)
    {
      updateUserDataForCreateAdministratorPanel(qs);
    }
    else if (cStep == SUFFIXES_OPTIONS)
    {
      updateUserDataForSuffixesOptionsPanel(qs);
    }
    else if (cStep == NEW_SUFFIX_OPTIONS)
    {
      updateUserDataForNewSuffixOptionsPanel(qs);
    }
    else if (cStep ==  REVIEW)
    {
      updateUserDataForReviewPanel(qs);
    }
  }
@@ -905,6 +1075,324 @@
  }
  /**
   * Sets the current status of the installation process.
   * @param status the current status of the installation process.
   */
  protected void setStatus(InstallProgressStep status)
  {
    this.status = status;
  }
  /**
   * This methods updates the data on the server based on the contents of the
   * UserData object provided in the constructor.
   * @throws QuickSetupException if something goes wrong.
   */
  protected void createData() throws QuickSetupException
  {
    if (createNotReplicatedSuffix())
    {
      switch (getUserData().getNewSuffixOptions().getType())
      {
      case CREATE_BASE_ENTRY:
        status = InstallProgressStep.CREATING_BASE_ENTRY;
        notifyListeners(getTaskSeparator());
        createBaseEntry();
        break;
      case IMPORT_FROM_LDIF_FILE:
        status = InstallProgressStep.IMPORTING_LDIF;
        notifyListeners(getTaskSeparator());
        importLDIF();
        break;
      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
        notifyListeners(getTaskSeparator());
        importAutomaticallyGenerated();
        break;
      }
    }
    else
    {
      /* We must replicate some suffixes: for the moment just create them. */
      /* TODO: replicate them. */
      Set<SuffixDescriptor> suffixesToReplicate =
        getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes();
      for (SuffixDescriptor suffix: suffixesToReplicate)
      {
        notifyListeners(getFormattedWithPoints("Creating Suffix"));
        ArrayList<String> argList = new ArrayList<String>();
        argList.add("-C");
        argList.add(CONFIG_CLASS_NAME);
        argList.add("-c");
        argList.add(getInstallation().getCurrentConfigurationFile().toString());
        argList.add("-b");
        argList.add(suffix.getDN());
        String[] args = new String[argList.size()];
        argList.toArray(args);
        try
        {
          InstallerHelper helper = new InstallerHelper();
          int result = helper.invokeConfigureServer(args);
          if (result != 0)
          {
            throw new QuickSetupException(
                QuickSetupException.Type.CONFIGURATION_ERROR,
                getMsg("error-configuring"), null);
          }
        } catch (Throwable t)
        {
          throw new QuickSetupException(
              QuickSetupException.Type.CONFIGURATION_ERROR,
              getThrowableMsg("error-configuring", null, t), t);
        }
        notifyListeners(getFormattedDone());
        // TO REMOVE
        notifyListeners(
            getFormattedProgress("One day we will replicate the suffixes!"));
      }
    }
  }
  /**
   * This methods updates the ADS contents (and creates the according suffixes).
   * @throws QuickSetupException if something goes wrong.
   */
  protected void updateADS() throws QuickSetupException
  {
    if (true) return;
    /* First check if the remote server contains an ADS: if it is the case the
     * best is to update its contents with the new data and then configure the
     * local server to be replicated with the remote server.
     */
    DataReplicationOptions repl =
      getUserData().getReplicationOptions();
    boolean remoteServer =
      repl.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
    if (remoteServer)
    {
      // Try to connect
      AuthenticationData auth = repl.getAuthenticationData();
      String ldapUrl = getLdapUrl(auth);
      String dn = auth.getDn();
      String pwd = auth.getPwd();
      InitialLdapContext ctx = null;
      try
      {
        ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
            Utils.getDefaultLDAPTimeout(), null);
        ADSContext adsContext = new ADSContext(ctx);
        if (adsContext.hasAdminData())
        {
          /* Add global administrator if the user specified one. */
          if (getUserData().mustCreateAdministrator())
          {
            try
            {
              String[] arg = {getHostDisplay(auth)};
              notifyListeners(getFormattedWithPoints(
                  getMsg("creating-administrator", arg)));
              adsContext.createAdministrator(getAdministratorProperties());
              notifyListeners(getFormattedDone());
            }
            catch (ADSContextException ade)
            {
              if (ade.getError() ==
                ADSContextException.ErrorType.ALREADY_REGISTERED)
              {
                notifyListeners(getFormattedWarning(
                    getMsg("administrator-already-registered")));
              }
              else
              {
                throw ade;
              }
            }
          }
          Map<ADSContext.ServerProperty, Object> serverProperties =
            getNewServerProperties();
          /* Register new server data. */
          adsContext.registerServer(serverProperties);
          /* Configure local server to have an ADS and replicate it */
          // TODO
          notifyListeners(getFormattedProgress(
              "Here we create the new server ADS and we replicate it.\n"));
        }
        else
        {
          /* TODO: We need to integrate in remote framework to make this work.
           */
          /*
          adsContext.createAdminData();
          adsContext.createAdministrator(getAdministratorProperties());
          adsContext.registerServer(
              getRemoteServerProperties(adsContext.getDirContext()));
          adsContext.registerServer(getNewServerProperties());
          */
          notifyListeners(getFormattedProgress(
              "Here we update the server in "+getHostDisplay(auth)+"\n"));
          /* Configure local server to have an ADS and replicate it */
          // TODO
          notifyListeners(getFormattedProgress(
              "Here we create the new server ADS and we replicate it.\n"));
        }
      }
      catch (NoPermissionException x)
      {
        String[] arg = {getHostDisplay(auth)};
        throw new QuickSetupException(
            QuickSetupException.Type.CONFIGURATION_ERROR,
            getMsg("cannot-connect-to-remote-permissions", arg), x);
      }
      catch (NamingException ne)
      {
        String[] arg = {getHostDisplay(auth)};
        throw new QuickSetupException(
            QuickSetupException.Type.CONFIGURATION_ERROR,
            getMsg("cannot-connect-to-remote-generic", arg), ne);
      }
      catch (ADSContextException ace)
      {
        String[] args = {getHostDisplay(auth), ace.toString()};
        throw new QuickSetupException(
            QuickSetupException.Type.CONFIGURATION_ERROR,
            getMsg("remote-ads-exception", args), ace);
      }
      finally
      {
        if (ctx != null)
        {
          try
          {
            ctx.close();
          }
          catch (Throwable t)
          {
          }
        }
      }
    }
    else
    {
      notifyListeners(getFormattedWithPoints(getMsg("creating-ads")));
      Map<ADSContext.ServerProperty, Object> serverProperties =
        getNewServerProperties();
      try
      {
        ADSContext.createOfflineAdminData(serverProperties,
            getUserData().getServerLocation(), getBackendName());
      }
      catch (ADSContextException ace)
      {
        throw new QuickSetupException(
            QuickSetupException.Type.CONFIGURATION_ERROR,
            getMsg("local-ads-exception"), ace);
      }
      notifyListeners(getFormattedDone());
    }
  }
  /**
   * Tells whether we must create a suffix that we are not going to replicate
   * with other servers or not.
   * @return <CODE>true</CODE> if we must create a new suffix and
   * <CODE>false</CODE> otherwise.
   */
  private boolean createNotReplicatedSuffix()
  {
    boolean createSuffix;
    DataReplicationOptions repl =
      getUserData().getReplicationOptions();
    SuffixesToReplicateOptions suf =
      getUserData().getSuffixesToReplicateOptions();
    createSuffix =
      (repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY) ||
      (repl.getType() == DataReplicationOptions.Type.STANDALONE) ||
      (suf.getType() ==
        SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
    return createSuffix;
  }
  private String getLdapUrl(AuthenticationData auth)
  {
    return "ldap://"+auth.getHostName()+":"+auth.getPort();
  }
  private String getHostDisplay(AuthenticationData auth)
  {
    return auth.getHostName()+":"+auth.getPort();
  }
  private Map<ADSContext.ServerProperty, Object> getNewServerProperties()
  {
    Map<ADSContext.ServerProperty, Object> serverProperties =
      new HashMap<ADSContext.ServerProperty, Object>();
    // TODO: this might not work
    try
    {
      serverProperties.put(ADSContext.ServerProperty.HOSTNAME,
          java.net.InetAddress.getLocalHost().getHostName());
    }
    catch (Throwable t)
    {
      t.printStackTrace();
    }
    serverProperties.put(ADSContext.ServerProperty.PORT,
        String.valueOf(getUserData().getServerPort()));
    serverProperties.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
    // TODO: even if the user does not configure SSL maybe we should choose
    // a secure port that is not being used and that we can actually use.
    serverProperties.put(ADSContext.ServerProperty.SECURE_PORT, "636");
    serverProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
    serverProperties.put(ADSContext.ServerProperty.JMX_PORT,
        String.valueOf(getUserData().getServerJMXPort()));
    serverProperties.put(ADSContext.ServerProperty.JMX_ENABLED, "true");
    serverProperties.put(ADSContext.ServerProperty.INSTANCE_PATH,
        getUserData().getServerLocation());
    String serverID = serverProperties.get(ADSContext.ServerProperty.HOSTNAME)+
    ":"+getUserData().getServerPort();
    /* TODO: do we want to ask this specifically to the user? */
    serverProperties.put(ADSContext.ServerProperty.ID, serverID);
    serverProperties.put(ADSContext.ServerProperty.HOST_OS,
        Utils.getOSString());
    return serverProperties;
  }
  private Map<ADSContext.AdministratorProperty, Object>
  getAdministratorProperties()
  {
    Map<ADSContext.AdministratorProperty, Object> adminProperties =
      new HashMap<ADSContext.AdministratorProperty, Object>();
    adminProperties.put(ADSContext.AdministratorProperty.UID,
        getUserData().getGlobalAdministratorUID());
    adminProperties.put(ADSContext.AdministratorProperty.UID,
        getUserData().getGlobalAdministratorPassword());
    adminProperties.put(ADSContext.AdministratorProperty.DESCRIPTION,
        getMsg("global-administrator-description"));
    return adminProperties;
  }
  /**
   * Validate the data provided by the user in the server settings panel and
   * update the userData object according to that content.
   *
@@ -1186,11 +1674,392 @@
   *           valid.
   *
   */
  private void updateUserDataForDataOptionsPanel(QuickSetup qs)
  private void updateUserDataForReplicationOptionsPanel(QuickSetup qs)
      throws UserDataException {
    boolean hasGlobalAdministrators = false;
    String host = null;
    Integer port = null;
    String dn = null;
    String pwd = null;
    ArrayList<String> errorMsgs = new ArrayList<String>();
    DataOptions dataOptions = null;
    DataReplicationOptions.Type type = (DataReplicationOptions.Type)
      qs.getFieldValue(FieldName.REPLICATION_OPTIONS);
    host = qs.getFieldStringValue(FieldName.REMOTE_SERVER_HOST);
    dn = qs.getFieldStringValue(FieldName.REMOTE_SERVER_DN);
    pwd = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PWD);
    switch (type)
    {
    case IN_EXISTING_TOPOLOGY:
    {
      // Check host name
      if ((host == null) || (host.length() == 0))
      {
        errorMsgs.add(getMsg("empty-remote-host"));
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
      }
      else
      {
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, false);
      }
      // Check port
      String sPort = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PORT);
      try
      {
        port = Integer.parseInt(sPort);
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, false);
      }
      catch (Throwable t)
      {
        errorMsgs.add(getMsg("invalid-remote-port"));
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
      }
      // Check dn
      if ((dn == null) || (dn.length() == 0))
      {
        errorMsgs.add(getMsg("empty-remote-dn"));
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
      }
      else
      {
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, false);
      }
      // Check password
      if ((pwd == null) || (pwd.length() == 0))
      {
        errorMsgs.add(getMsg("empty-remote-pwd"));
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
      }
      else
      {
        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, false);
      }
      if (errorMsgs.size() == 0)
      {
        // Try to connect
        String ldapUrl = "ldap://"+host+":"+port;
        InitialLdapContext ctx = null;
        try
        {
          try
          {
            ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
                Utils.getDefaultLDAPTimeout(), null);
          }
          catch (Throwable t)
          {
            // Try using a global administrator
            dn = ADSContext.getAdministratorDN(dn);
            ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
                Utils.getDefaultLDAPTimeout(), null);
          }
          ADSContext adsContext = new ADSContext(ctx);
          if (adsContext.hasAdminData())
          {
            /* Check if there are already global administrators */
            Set administrators = adsContext.readAdministratorRegistry();
            if (administrators.size() > 0)
            {
              hasGlobalAdministrators = true;
            }
            updateUserDataWithSuffixesInADS(adsContext);
          }
          else
          {
            getUserData().setSuffixesToReplicateOptions(
                new SuffixesToReplicateOptions(
                    SuffixesToReplicateOptions.Type.
                    REPLICATE_WITH_EXISTING_SUFFIXES,
                    staticSuffixes(),
                    staticSuffixes()));
          }
        }
        catch (NoPermissionException x)
        {
          String[] arg = {host+":"+port};
          errorMsgs.add(getMsg("cannot-connect-to-remote-permissions", arg));
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
        }
        catch (NamingException ne)
        {
          String[] arg = {host+":"+port};
          errorMsgs.add(getMsg("cannot-connect-to-remote-generic", arg));
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
        }
        catch (ADSContextException ace)
        {
          String[] args = {host+":"+port, ace.toString()};
          errorMsgs.add(getMsg("remote-ads-exception", args));
        }
        finally
        {
          if (ctx != null)
          {
            try
            {
              ctx.close();
            }
            catch (Throwable t)
            {
            }
          }
        }
      }
      break;
    }
    case STANDALONE:
    {
      Set<SuffixDescriptor> available;
      SuffixesToReplicateOptions repl =
        getUserData().getSuffixesToReplicateOptions();
      if (repl != null)
      {
        available = repl.getAvailableSuffixes();
      }
      else
      {
        available = new HashSet<SuffixDescriptor>();
      }
      Set<SuffixDescriptor> chosen;
      if (repl != null)
      {
        chosen = repl.getSuffixes();
      }
      else
      {
        chosen = new HashSet<SuffixDescriptor>();
      }
      getUserData().setSuffixesToReplicateOptions(
          new SuffixesToReplicateOptions(
              SuffixesToReplicateOptions.Type.NO_SUFFIX_TO_REPLICATE,
              available,
              chosen));
      break;
    }
    case FIRST_IN_TOPOLOGY:
    {
      Set<SuffixDescriptor> available;
      SuffixesToReplicateOptions repl =
        getUserData().getSuffixesToReplicateOptions();
      if (repl != null)
      {
        available = repl.getAvailableSuffixes();
      }
      else
      {
        available = new HashSet<SuffixDescriptor>();
      }
      Set<SuffixDescriptor> chosen;
      if (repl != null)
      {
        chosen = repl.getSuffixes();
      }
      else
      {
        chosen = new HashSet<SuffixDescriptor>();
      }
      getUserData().setSuffixesToReplicateOptions(
          new SuffixesToReplicateOptions(
              SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY,
              available,
              chosen));
      break;
    }
    default:
      throw new IllegalStateException("Do not know what to do with type: "+
          type);
    }
    if (errorMsgs.size() == 0)
    {
      AuthenticationData auth = new AuthenticationData();
      auth.setHostName(host);
      if (port != null)
      {
        auth.setPort(port);
      }
      auth.setDn(dn);
      auth.setPwd(pwd);
      DataReplicationOptions repl = new DataReplicationOptions(type,
          auth);
      getUserData().setReplicationOptions(repl);
      getUserData().createAdministrator(!hasGlobalAdministrators &&
      type == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
    }
    if (errorMsgs.size() > 0)
    {
      throw new UserDataException(Step.REPLICATION_OPTIONS,
          Utils.getStringFromCollection(errorMsgs, "\n"));
    }
  }
  /**
   * Validate the data provided by the user in the create global administrator
   * panel and update the UserInstallData object according to that content.
   *
   * @throws an
   *           UserInstallDataException if the data provided by the user is not
   *           valid.
   *
   */
  private void updateUserDataForCreateAdministratorPanel(QuickSetup qs)
  throws UserDataException
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    // Check the Global Administrator UID
    String uid = qs.getFieldStringValue(FieldName.GLOBAL_ADMINISTRATOR_UID);
    if ((uid == null) || (uid.trim().length() == 0))
    {
      errorMsgs.add(getMsg("empty-administrator-uid"));
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_UID, true);
    }
    else
    {
      getUserData().setGlobalAdministratorUID(uid);
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_UID, false);
    }
    // Check the provided passwords
    String pwd1 = qs.getFieldStringValue(FieldName.GLOBAL_ADMINISTRATOR_PWD);
    String pwd2 = qs.getFieldStringValue(
        FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM);
    if (pwd1 == null)
    {
      pwd1 = "";
    }
    boolean pwdValid = true;
    if (!pwd1.equals(pwd2))
    {
      errorMsgs.add(getMsg("not-equal-pwd"));
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM, true);
      pwdValid = false;
    }
    if (pwd1.length() < MIN_DIRECTORY_MANAGER_PWD)
    {
      errorMsgs.add(getMsg(("pwd-too-short"), new String[]
        { String.valueOf(MIN_DIRECTORY_MANAGER_PWD) }));
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD, true);
      if ((pwd2 == null) || (pwd2.length() < MIN_DIRECTORY_MANAGER_PWD))
      {
        qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
            true);
      }
      pwdValid = false;
    }
    if (pwdValid)
    {
      getUserData().setDirectoryManagerPwd(pwd1);
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD, false);
      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM, false);
    }
    if (errorMsgs.size() > 0)
    {
      throw new UserDataException(Step.CREATE_GLOBAL_ADMINISTRATOR,
          Utils.getStringFromCollection(errorMsgs, "\n"));
    }
  }
  /**
   * Validate the data provided by the user in the replicate suffixes options
   * panel and update the UserInstallData object according to that content.
   *
   * @throws an
   *           UserInstallDataException if the data provided by the user is not
   *           valid.
   *
   */
  private void updateUserDataForSuffixesOptionsPanel(QuickSetup qs)
  throws UserDataException
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    if (qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE_OPTIONS) ==
      SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES)
    {
      Set s = (Set)qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE);
      if (s.size() == 0)
      {
        errorMsgs.add(getMsg("no-suffixes-chosen-to-replicate"));
        qs.displayFieldInvalid(FieldName.SUFFIXES_TO_REPLICATE, true);
      }
      else
      {
        Set<SuffixDescriptor> chosen = new HashSet<SuffixDescriptor>();
        for (Object o: s)
        {
          chosen.add((SuffixDescriptor)o);
        }
        qs.displayFieldInvalid(FieldName.SUFFIXES_TO_REPLICATE, false);
        Set<SuffixDescriptor> available = getUserData().
        getSuffixesToReplicateOptions().getAvailableSuffixes();
        SuffixesToReplicateOptions options =
          new SuffixesToReplicateOptions(
          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES,
              available,
              chosen);
        getUserData().setSuffixesToReplicateOptions(options);
      }
    }
    else
    {
      Set<SuffixDescriptor> available = getUserData().
      getSuffixesToReplicateOptions().getAvailableSuffixes();
      Set<SuffixDescriptor> chosen = getUserData().
      getSuffixesToReplicateOptions().getSuffixes();
      SuffixesToReplicateOptions options =
        new SuffixesToReplicateOptions(
            SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY,
            available,
            chosen);
      getUserData().setSuffixesToReplicateOptions(options);
    }
    if (errorMsgs.size() > 0)
    {
      throw new UserDataException(Step.SUFFIXES_OPTIONS,
          Utils.getStringFromCollection(errorMsgs, "\n"));
    }
  }
  /**
   * Validate the data provided by the user in the new suffix data options panel
   * and update the UserInstallData object according to that content.
   *
   * @throws an
   *           UserInstallDataException if the data provided by the user is not
   *           valid.
   *
   */
  private void updateUserDataForNewSuffixOptionsPanel(QuickSetup qs)
      throws UserDataException
  {
    ArrayList<String> errorMsgs = new ArrayList<String>();
    NewSuffixOptions dataOptions = null;
    // Check the base dn
    boolean validBaseDn = false;
@@ -1214,8 +2083,8 @@
    }
    // Check the data options
    DataOptions.Type type =
        (DataOptions.Type) qs.getFieldValue(FieldName.DATA_OPTIONS);
    NewSuffixOptions.Type type =
        (NewSuffixOptions.Type) qs.getFieldValue(FieldName.DATA_OPTIONS);
    switch (type)
    {
@@ -1231,7 +2100,7 @@
        qs.displayFieldInvalid(FieldName.LDIF_PATH, true);
      } else if (validBaseDn)
      {
        dataOptions = new DataOptions(type, baseDn, ldifPath);
        dataOptions = new NewSuffixOptions(type, baseDn, ldifPath);
        qs.displayFieldInvalid(FieldName.LDIF_PATH, false);
      }
      break;
@@ -1274,7 +2143,7 @@
      if (startErrors == errorMsgs.size() && validBaseDn)
      {
        // No validation errors
        dataOptions = new DataOptions(type, baseDn, new Integer(nEntries));
        dataOptions = new NewSuffixOptions(type, baseDn, new Integer(nEntries));
      }
      break;
@@ -1283,22 +2152,23 @@
      qs.displayFieldInvalid(FieldName.NUMBER_ENTRIES, false);
      if (validBaseDn)
      {
        dataOptions = new DataOptions(type, baseDn);
        dataOptions = new NewSuffixOptions(type, baseDn);
      }
    }
    if (dataOptions != null)
    {
      getUserData().setDataOptions(dataOptions);
      getUserData().setNewSuffixOptions(dataOptions);
    }
    if (errorMsgs.size() > 0)
    {
      throw new UserDataException(Step.DATA_OPTIONS,
      throw new UserDataException(Step.NEW_SUFFIX_OPTIONS,
          Utils.getStringFromCollection(errorMsgs, "\n"));
    }
  }
  /**
   * Update the userData object according to the content of the review
   * panel.
@@ -1324,6 +2194,142 @@
    return 15 * 1024 * 1024;
  }
  private Map<ADSContext.ServerProperty, Object> getRemoteServerProperties(
      InitialLdapContext ctx) throws NamingException
  {
    // TODO: use administration framework.
    return new HashMap<ADSContext.ServerProperty, Object>();
  }
  /**
   * Update the UserInstallData object according to the content of the review
   * panel.
   */
  private void updateUserDataWithSuffixesInADS(ADSContext adsContext)
  {
    SuffixesToReplicateOptions suf =
      getUserData().getSuffixesToReplicateOptions();
    SuffixesToReplicateOptions.Type type;
    Set<SuffixDescriptor> suffixes = null;
    if (suf == null)
    {
      type = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
    }
    else
    {
      type = suf.getType();
    }
    // TODO: get the suffixes using the adsContext.
    if (suffixes == null)
    {
      suffixes = new HashSet<SuffixDescriptor>();
    }
    suffixes = staticSuffixes();
    getUserData().setSuffixesToReplicateOptions(
        new SuffixesToReplicateOptions(type, suffixes, suffixes));
  }
  private Set<SuffixDescriptor> staticSuffixes()
  {
    ServerDescriptor server1 = new ServerDescriptor();
    Map<ADSContext.ServerProperty, Object> serverProp1 =
      new HashMap<ADSContext.ServerProperty, Object>();
    serverProp1.put(ADSContext.ServerProperty.HOSTNAME, "potato.france");
    serverProp1.put(ADSContext.ServerProperty.PORT, "389");
    serverProp1.put(ADSContext.ServerProperty.SECURE_PORT, "689");
    serverProp1.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
    serverProp1.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
    serverProp1.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl1");
    server1.setAdsProperties(serverProp1);
    ServerDescriptor server2 = new ServerDescriptor();
    Map<ADSContext.ServerProperty, Object> serverProp2 =
      new HashMap<ADSContext.ServerProperty, Object>();
    serverProp2.put(ADSContext.ServerProperty.HOSTNAME, "skalariak.france");
    serverProp2.put(ADSContext.ServerProperty.PORT, "389");
    serverProp2.put(ADSContext.ServerProperty.SECURE_PORT, "689");
    serverProp2.put(ADSContext.ServerProperty.LDAP_ENABLED, "false");
    serverProp2.put(ADSContext.ServerProperty.LDAPS_ENABLED, "true");
    serverProp2.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl2");
    server2.setAdsProperties(serverProp2);
    SuffixDescriptor suffix1 = new SuffixDescriptor();
    suffix1.setDN("dc=example,dc=com");
    Set<ReplicaDescriptor> replicas1 = new HashSet<ReplicaDescriptor>();
    SuffixDescriptor suffix2 = new SuffixDescriptor();
    suffix2.setDN("dc=for real,dc=com");
    Set<ReplicaDescriptor> replicas2 = new HashSet<ReplicaDescriptor>();
    SuffixDescriptor suffix3 = new SuffixDescriptor();
    suffix3.setDN("dc=s3,dc=com");
    Set<ReplicaDescriptor> replicas3 = new HashSet<ReplicaDescriptor>();
    SuffixDescriptor suffix4 = new SuffixDescriptor();
    suffix4.setDN("dc=s4,dc=com");
    Set<ReplicaDescriptor> replicas4 = new HashSet<ReplicaDescriptor>();
    ReplicaDescriptor replica1 = new ReplicaDescriptor();
    replica1.setSuffix(suffix1);
    replica1.setServer(server1);
    replica1.setEntries(1002);
    replicas1.add(replica1);
    ReplicaDescriptor replica2 = new ReplicaDescriptor();
    replica2.setSuffix(suffix1);
    replica2.setServer(server2);
    replica2.setEntries(1003);
    replicas1.add(replica2);
    suffix1.setReplicas(replicas1);
    ReplicaDescriptor replica3 = new ReplicaDescriptor();
    replica3.setSuffix(suffix2);
    replica3.setServer(server2);
    replicas2.add(replica3);
    suffix2.setReplicas(replicas2);
    ReplicaDescriptor replica5 = new ReplicaDescriptor();
    replica5.setSuffix(suffix3);
    replica5.setServer(server1);
    replica5.setEntries(1003);
    replicas3.add(replica5);
    ReplicaDescriptor replica6 = new ReplicaDescriptor();
    replica6.setSuffix(suffix3);
    replica6.setServer(server2);
    replica6.setEntries(1003);
    replicas3.add(replica6);
    suffix3.setReplicas(replicas3);
    ReplicaDescriptor replica7 = new ReplicaDescriptor();
    replica7.setSuffix(suffix4);
    replica7.setServer(server1);
    replica7.setEntries(1003);
    replicas4.add(replica7);
    ReplicaDescriptor replica8 = new ReplicaDescriptor();
    replica8.setSuffix(suffix3);
    replica8.setServer(server2);
    replica8.setEntries(1003);
    replicas4.add(replica8);
    suffix4.setReplicas(replicas4);
    Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
    suffixes.add(suffix1);
    suffixes.add(suffix2);
    suffixes.add(suffix3);
    suffixes.add(suffix4);
    //suffixes.clear();
    return suffixes;
  }
  /**
   * Returns the keystore path to be used for generating a self-signed
   * certificate.
opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
New file
@@ -0,0 +1,147 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer;
/**
 * This class is used to provide a data model for the Data Options panel of the
 * installer.
 *
 */
public class NewSuffixOptions
{
  /**
   * This enumeration is used to know what the user wants to do for the data
   * (import data or not, what use as source of the data...).
   *
   */
  public enum Type
  {
    /**
     * Do nothing.
     */
    NOTHING,
    /**
     * Create base entry.
     */
    CREATE_BASE_ENTRY,
    /**
     * Do not add any entry to the suffix.
     */
    LEAVE_DATABASE_EMPTY,
    /**
     * Import data from an LDIF file.
     */
    IMPORT_FROM_LDIF_FILE,
    /**
     * Generate data and import it to the suffix.
     */
    IMPORT_AUTOMATICALLY_GENERATED_DATA
  }
  private Type type = Type.NOTHING;
  private String baseDn;
  private String ldifPath;
  private int numberEntries = 2000;
  /**
   * Constructor for the NewSuffixOptions object.
   *
   * If the Data Options is IMPORT_FROM_LDIF_FILE the args are the baseDn and
   * a String with the ldif location.
   *
   * If the Data Options is IMPORT_AUTOMATICALLY_GENERATED_DATA the args
   * are the baseDn and an Integer with the number of entries.
   *
   * For the rest of the types the args are just the baseDn.
   *
   * @param type the Type of NewSuffixOptions.
   * @param args the different argument objects (depending on the Type
   * specified)
   */
  public NewSuffixOptions(Type type, Object... args)
  {
    this.type = type;
    baseDn = (String) args[0];
    switch (type)
    {
    case IMPORT_FROM_LDIF_FILE:
      ldifPath = (String) args[1];
      break;
    case IMPORT_AUTOMATICALLY_GENERATED_DATA:
      numberEntries = ((Integer) args[1]).intValue();
      break;
    }
  }
  /**
   * Returns the type of NewSuffixOptions represented by this object (import
   * data or not, what use as source of the data...).
   *
   * @return the type of NewSuffixOptions.
   */
  public Type getType()
  {
    return type;
  }
  /**
   * Returns the path of the LDIF file used to import data.
   * @return the path of the LDIF file used to import data.
   */
  public String getLDIFPath()
  {
    return ldifPath;
  }
  /**
   * Returns the number of entries that will be automatically generated.
   *
   * @return the number of entries that will be automatically generated.
   */
  public int getNumberEntries()
  {
    return numberEntries;
  }
  /**
   * Returns the base DN of the suffix that will be created in the server.
   *
   * @return the base DN of the suffix that will be created in the server.
   */
  public String getBaseDn()
  {
    return baseDn;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java
New file
@@ -0,0 +1,155 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer;
import java.util.HashSet;
import java.util.Set;
import org.opends.admin.ads.SuffixDescriptor;
/**
 * This class is used to provide a data model for the Suffix to Replicate
 * Options panel of the installer.
 *
 */
public class SuffixesToReplicateOptions
{
  /**
   * This enumeration is used to know what the user wants to do for the data
   * (import data or not, what use as source of the data...).
   *
   */
  public enum Type
  {
    /**
     * Do not replicate suffix.
     */
    NO_SUFFIX_TO_REPLICATE,
    /**
     * This is a new suffix in topology..
     */
    NEW_SUFFIX_IN_TOPOLOGY,
    /**
     * Replicate Contents of the new Suffix with existings server.
     */
    REPLICATE_WITH_EXISTING_SUFFIXES
  }
  private Type type;
  private Set<SuffixDescriptor> availableSuffixes;
  private Set<SuffixDescriptor> suffixesToReplicate;
  /**
   * Constructor for the SuffixesToReplicateOptions object.
   *
   * If the Data Replicate Options is NO_SUFFIX_TO_REPLICATE or
   * NEW_SUFFIX_IN_TOPOLOGY no args are considered.
   *
   * If the Data Options is REPLICATE_WITH_EXISTING_SUFFIXES a Set of
   * SuffixDescriptor is passed as argument.
   *
   * @param type the Type of DataReplicationOptions.
   * @param args the different argument objects (depending on the Type
   * specified)
   */
  public SuffixesToReplicateOptions(Type type, Object... args)
  {
    this.type = type;
    switch (type)
    {
    case REPLICATE_WITH_EXISTING_SUFFIXES:
      Set s = (Set)args[0];
      availableSuffixes = new HashSet<SuffixDescriptor>();
      for (Object o: s)
      {
        availableSuffixes.add((SuffixDescriptor)o);
      }
      s = (Set)args[1];
      suffixesToReplicate = new HashSet<SuffixDescriptor>();
      for (Object o: s)
      {
        suffixesToReplicate.add((SuffixDescriptor)o);
      }
      break;
    default:
      // If there is something put it.
      if ((args != null) && (args.length > 0))
      {
        s = (Set)args[0];
        availableSuffixes = new HashSet<SuffixDescriptor>();
        for (Object o: s)
        {
          availableSuffixes.add((SuffixDescriptor)o);
        }
        s = (Set)args[1];
        suffixesToReplicate = new HashSet<SuffixDescriptor>();
        for (Object o: s)
        {
          suffixesToReplicate.add((SuffixDescriptor)o);
        }
      }
    }
  }
  /**
   * Returns the type of SuffixesToReplicateOptions represented by this object
   * (replicate or not).
   *
   * @return the type of SuffixesToReplicateOptions.
   */
  public Type getType()
  {
    return type;
  }
  /**
   * Returns the set of suffixes that we must replicate with.
   * If there are no suffixes to replicate with returns null.
   *
   * @return the set of suffixes that we must replicate with.
   */
  public Set<SuffixDescriptor> getAvailableSuffixes()
  {
    return availableSuffixes;
  }
  /**
   * Returns the set of suffixes that we must replicate with.
   * If there are no suffixes to replicate with returns null.
   *
   * @return the set of suffixes that we must replicate with.
   */
  public Set<SuffixDescriptor> getSuffixes()
  {
    return suffixesToReplicate;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -71,6 +71,7 @@
    initMaps();
    PrintStream origErr = System.err;
    PrintStream origOut = System.out;
    try
    {
      PrintStream err = new ErrorPrintStream();
@@ -78,56 +79,41 @@
      System.setErr(err);
      System.setOut(out);
      status = InstallProgressStep.CONFIGURING_SERVER;
      setStatus(InstallProgressStep.CONFIGURING_SERVER);
      configureServer();
      switch (getUserData().getDataOptions().getType())
      {
      case CREATE_BASE_ENTRY:
        status = InstallProgressStep.CREATING_BASE_ENTRY;
        notifyListeners(getTaskSeparator());
        createBaseEntry();
        break;
      case IMPORT_FROM_LDIF_FILE:
        status = InstallProgressStep.IMPORTING_LDIF;
        notifyListeners(getTaskSeparator());
        importLDIF();
        break;
      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
        notifyListeners(getTaskSeparator());
        importAutomaticallyGenerated();
        break;
      }
      createData();
      updateADS();
      writeJavaHome();
      if (Utils.isWindows())
      {
          notifyListeners(getTaskSeparator());
          status = InstallProgressStep.ENABLING_WINDOWS_SERVICE;
          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
          enableWindowsService();
      }
      if (getUserData().getStartServer())
      {
        notifyListeners(getTaskSeparator());
        status = InstallProgressStep.STARTING_SERVER;
        setStatus(InstallProgressStep.STARTING_SERVER);
        new ServerController(this).startServer();
      }
      status = InstallProgressStep.FINISHED_SUCCESSFULLY;
      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
      notifyListeners(null);
    } catch (QuickSetupException ex)
    {
      status = InstallProgressStep.FINISHED_WITH_ERROR;
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      String html = getFormattedError(ex, true);
      notifyListeners(html);
    }
    catch (Throwable t)
    {
      status = InstallProgressStep.FINISHED_WITH_ERROR;
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      QuickSetupException ex = new QuickSetupException(
          QuickSetupException.Type.BUG, getThrowableMsg("bug-msg", t), t);
      String msg = getFormattedError(ex, true);
@@ -182,7 +168,7 @@
        new ArrayList<InstallProgressStep>();
    totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
    steps.add(InstallProgressStep.CONFIGURING_SERVER);
    switch (getUserData().getDataOptions().getType())
    switch (getUserData().getNewSuffixOptions().getType())
    {
    case CREATE_BASE_ENTRY:
      steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
File was renamed from opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
@@ -25,11 +25,13 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.HashMap;
@@ -45,7 +47,13 @@
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.event.BrowseActionListener;
import org.opends.quicksetup.DataOptions;
import org.opends.quicksetup.installer.NewSuffixOptions;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.UserData;
/**
@@ -67,8 +75,8 @@
  private HashMap<FieldName, JTextComponent> hmFields =
      new HashMap<FieldName, JTextComponent>();
  private HashMap<DataOptions.Type, JRadioButton> hmRadioButtons =
      new HashMap<DataOptions.Type, JRadioButton>();
  private HashMap<NewSuffixOptions.Type, JRadioButton> hmRadioButtons =
      new HashMap<NewSuffixOptions.Type, JRadioButton>();
  private JButton ldifBrowseButton;
@@ -84,6 +92,7 @@
    populateComponentMaps();
    addDocumentListeners();
    addFocusListeners();
    addActionListeners();
  }
  /**
@@ -95,7 +104,7 @@
    if (fieldName == FieldName.DATA_OPTIONS)
    {
      for (DataOptions.Type type : hmRadioButtons.keySet())
      for (NewSuffixOptions.Type type : hmRadioButtons.keySet())
      {
        if (hmRadioButtons.get(type).isSelected())
        {
@@ -188,7 +197,7 @@
    panel.add(auxPanel, gbc);
    int h1 = getLabel(FieldName.DATA_OPTIONS).getPreferredSize().height;
    int h2 = getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY).
    int h2 = getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY).
    getPreferredSize().height;
    int additionalInset = Math.abs(h2 - h1) / 2;
    gbc.gridwidth = GridBagConstraints.RELATIVE;
@@ -224,10 +233,10 @@
    gbc.insets = UIFactory.getEmptyInsets();
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    panel.add(getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY), gbc);
    panel.add(getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY), gbc);
    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
    panel.add(getRadioButton(DataOptions.Type.LEAVE_DATABASE_EMPTY), gbc);
    panel.add(getRadioButton(DataOptions.Type.IMPORT_FROM_LDIF_FILE), gbc);
    panel.add(getRadioButton(NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY), gbc);
    panel.add(getRadioButton(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE), gbc);
    JPanel auxPanel =
        createBrowseButtonPanel(FieldName.LDIF_PATH, getLDIFBrowseButton());
@@ -239,7 +248,7 @@
    gbc.insets.left = 0;
    panel.add(getRadioButton(
            DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA),
            NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA),
        gbc);
    auxPanel = createNumberEntriesPanel();
@@ -336,19 +345,19 @@
    switch (fieldName)
    {
    case DIRECTORY_BASE_DN:
      value = defaultUserData.getDataOptions().getBaseDn();
      value = defaultUserData.getNewSuffixOptions().getBaseDn();
      break;
    case DATA_OPTIONS:
      value = defaultUserData.getDataOptions().getType();
      value = defaultUserData.getNewSuffixOptions().getType();
      break;
    case LDIF_PATH:
      value = defaultUserData.getDataOptions().getLDIFPath();
      value = defaultUserData.getNewSuffixOptions().getLDIFPath();
      break;
    case NUMBER_ENTRIES:
      value = defaultUserData.getDataOptions().getNumberEntries();
      value = defaultUserData.getNewSuffixOptions().getNumberEntries();
      break;
    default:
@@ -437,7 +446,7 @@
        UIFactory.makeJRadioButton(getMsg("create-base-entry-label", arg),
            getMsg("create-base-entry-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    hmRadioButtons.put(DataOptions.Type.CREATE_BASE_ENTRY, rb);
    hmRadioButtons.put(NewSuffixOptions.Type.CREATE_BASE_ENTRY, rb);
    dataLabel.setLabelFor(rb);
@@ -445,13 +454,13 @@
        UIFactory.makeJRadioButton(getMsg("leave-database-empty-label"),
            getMsg("leave-database-empty-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    hmRadioButtons.put(DataOptions.Type.LEAVE_DATABASE_EMPTY, rb);
    hmRadioButtons.put(NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, rb);
    rb =
        UIFactory.makeJRadioButton(getMsg("import-data-from-ldif-label"),
            getMsg("import-data-from-ldif-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    hmRadioButtons.put(DataOptions.Type.IMPORT_FROM_LDIF_FILE, rb);
    hmRadioButtons.put(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE, rb);
    rb =
        UIFactory.makeJRadioButton(
@@ -459,18 +468,19 @@
            getMsg("import-automatically-generated-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    hmRadioButtons
        .put(DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, rb);
        .put(NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, rb);
    DataOptions.Type defaultType =
        (DataOptions.Type) getDefaultValue(FieldName.DATA_OPTIONS);
    NewSuffixOptions.Type defaultType =
        (NewSuffixOptions.Type) getDefaultValue(FieldName.DATA_OPTIONS);
    ButtonGroup buttonGroup = new ButtonGroup();
    for (DataOptions.Type type : hmRadioButtons.keySet())
    for (NewSuffixOptions.Type type : hmRadioButtons.keySet())
    {
      rb = hmRadioButtons.get(type);
      rb.setSelected(type == defaultType);
      buttonGroup.add(rb);
    }
    checkEnablingState();
  }
  /**
@@ -510,7 +520,7 @@
        String newLabel = getMsg("create-base-entry-label", arg);
        JRadioButton rb =
          getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY);
          getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY);
        rb.setText(newLabel);
      }
@@ -538,12 +548,13 @@
        lastFocusComponent = e.getComponent();
        if (lastFocusComponent == getField(FieldName.LDIF_PATH))
        {
          getRadioButton(DataOptions.Type.IMPORT_FROM_LDIF_FILE).setSelected(
              true);
        } else if (lastFocusComponent == getField(FieldName.NUMBER_ENTRIES))
          getRadioButton(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE).
          setSelected(true);
        }
        else if (lastFocusComponent == getField(FieldName.NUMBER_ENTRIES))
        {
          getRadioButton(
              DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
              NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
              .setSelected(true);
        }
      }
@@ -567,6 +578,43 @@
  }
  /**
   * Adds the required focus listeners to the fields.
   */
  private void addActionListeners()
  {
    final ActionListener l = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        checkEnablingState();
      }
    };
    for (JRadioButton rb : hmRadioButtons.values())
    {
      rb.addActionListener(l);
    }
  }
  /**
   * Enables/disables the fields.
   */
  private void checkEnablingState()
  {
    boolean importLDIF = getRadioButton(
        NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE).isSelected();
    boolean automaticData = getRadioButton(
        NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA).
        isSelected();
    getField(FieldName.LDIF_PATH).setEnabled(importLDIF);
    getLDIFBrowseButton().setEnabled(importLDIF);
    getField(FieldName.NUMBER_ENTRIES).setEnabled(automaticData);
    getLabel(FieldName.LDIF_PATH).setEnabled(importLDIF);
    getLabel(FieldName.NUMBER_ENTRIES).setEnabled(automaticData);
  }
  /**
   * Returns the label associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the JLabel.
   * @return the label associated with the given field name.
@@ -593,7 +641,7 @@
   * JRadioButton.
   * @return the JRadioButton associated with the given DataOptions.Type object.
   */
  private JRadioButton getRadioButton(DataOptions.Type type)
  private JRadioButton getRadioButton(NewSuffixOptions.Type type)
  {
    return hmRadioButtons.get(type);
  }
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
New file
@@ -0,0 +1,540 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.HashMap;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.AuthenticationData;
import org.opends.quicksetup.installer.DataReplicationOptions;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
/**
 * This class is used to display the replication options for the server
 * that is being installed.
 */
public class DataReplicationPanel extends QuickSetupStepPanel
{
  private static final long serialVersionUID = -1721551487477733587L;
  private Component lastFocusComponent;
  private UserData defaultUserData;
  private JRadioButton rbStandalone;
  private JRadioButton rbReplicated;
  private JCheckBox cbTopologyExists;
  private HashMap<FieldName, JLabel> hmLabels =
    new HashMap<FieldName, JLabel>();
  private HashMap<FieldName, JTextComponent> hmFields =
    new HashMap<FieldName, JTextComponent>();
  /**
   * Constructor of the panel.
   * @param application Application represented by this panel and used to
   * initialize the fields of the panel.
   */
  public DataReplicationPanel(GuiApplication application)
  {
    super(application);
    this.defaultUserData = application.getUserData();
    populateComponentMaps();
    addDocumentListeners();
    addFocusListeners();
    addActionListeners();
  }
  /**
   * {@inheritDoc}
   */
  public Object getFieldValue(FieldName fieldName)
  {
    Object value = null;
    if (fieldName == FieldName.REPLICATION_OPTIONS)
    {
      if (rbStandalone.isSelected())
      {
        value = DataReplicationOptions.Type.STANDALONE;
      }
      else if (cbTopologyExists.isSelected())
      {
        value =
          DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
      }
      else
      {
        value = DataReplicationOptions.Type.FIRST_IN_TOPOLOGY;
      }
    }
    else
    {
      JTextComponent field = getField(fieldName);
      if (field != null)
      {
        value = field.getText();
      }
    }
    return value;
  }
  /**
   * {@inheritDoc}
   */
  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
  {
    JLabel label = getLabel(fieldName);
    if (label != null)
    {
      UIFactory.TextStyle style;
      if (invalid)
      {
        style = UIFactory.TextStyle.SECONDARY_FIELD_INVALID;
      } else
      {
        style = UIFactory.TextStyle.SECONDARY_FIELD_VALID;
      }
      UIFactory.setTextStyle(label, style);
    }
  }
  /**
   * {@inheritDoc}
   */
  protected Component createInputPanel()
  {
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setOpaque(false);
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets = UIFactory.getEmptyInsets();
    panel.add(rbStandalone, gbc);
    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
    panel.add(rbReplicated, gbc);
    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
    gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
    panel.add(cbTopologyExists, gbc);
    JPanel auxPanel = new JPanel(new GridBagLayout());
    auxPanel.setOpaque(false);
    gbc.insets.left = 2 * UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
    panel.add(auxPanel, gbc);
    // Add the server location widgets
    FieldName[] fields =
    {
      FieldName.REMOTE_SERVER_HOST,
      FieldName.REMOTE_SERVER_PORT,
      FieldName.REMOTE_SERVER_DN,
      FieldName.REMOTE_SERVER_PWD
    };
    gbc.insets = UIFactory.getEmptyInsets();
    for (int i=0; i<fields.length; i++)
    {
      if (i != 0)
      {
        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
      }
      else
      {
        gbc.insets.top = 0;
      }
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      gbc.weightx = 0.0;
      gbc.insets.left = 0;
      gbc.anchor = GridBagConstraints.WEST;
      auxPanel.add(getLabel(fields[i]), gbc);
      JPanel aux2Panel = new JPanel(new GridBagLayout());
      aux2Panel.setOpaque(false);
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.weightx = 0.0;
      aux2Panel.add(getField(fields[i]), gbc);
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.insets.left = 0;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      aux2Panel.add(Box.createHorizontalGlue(), gbc);
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.insets = UIFactory.getEmptyInsets();
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      auxPanel.add(aux2Panel, gbc);
    }
    addVerticalGlue(panel);
    return panel;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstructions()
  {
    return getMsg("data-replication-options-panel-instructions");
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle()
  {
    return getMsg("data-replication-options-panel-title");
  }
  /**
   * {@inheritDoc}
   */
  public void endDisplay()
  {
    if (lastFocusComponent != null)
    {
      lastFocusComponent.requestFocusInWindow();
    }
  }
  /**
   * Returns the default value for the provided field Name.
   * @param fieldName the field name for which we want to get the default
   * value.
   * @return the default value for the provided field Name.
   */
  private Object getDefaultValue(FieldName fieldName)
  {
    Object value = null;
    AuthenticationData auth =
      defaultUserData.getReplicationOptions().getAuthenticationData();
    switch (fieldName)
    {
    case REMOTE_SERVER_DN:
      value = auth.getDn();
      break;
    case REMOTE_SERVER_PWD:
      value = auth.getPwd();
      break;
    case REMOTE_SERVER_HOST:
      value = auth.getHostName();
      break;
    case REMOTE_SERVER_PORT:
      value = auth.getPort();
      break;
    case REPLICATION_OPTIONS:
      value = defaultUserData.getReplicationOptions().getType();
      break;
    default:
      throw new IllegalArgumentException("Unknown field name: " +
          fieldName);
    }
    return value;
  }
  /**
   * Returns the default string value for the provided field Name.
   * @param fieldName the field name for which we want to get the default
   * string value.
   * @return the default value for the provided field Name.
   */
  private String getDefaultStringValue(FieldName fieldName)
  {
    String value = null;
    Object v = getDefaultValue(fieldName);
    if (v != null)
    {
      if (v instanceof String)
      {
        value = (String) v;
      } else
      {
        value = String.valueOf(v);
      }
    }
    return value;
  }
  /**
   * Creates the components and populates the Maps with them.
   */
  private void populateComponentMaps()
  {
    HashMap<FieldName, LabelFieldDescriptor> hm =
        new HashMap<FieldName, LabelFieldDescriptor>();
    hm.put(FieldName.REMOTE_SERVER_DN, new LabelFieldDescriptor(
        getMsg("remote-server-dn-label"), getMsg("remote-server-dn-tooltip"),
        LabelFieldDescriptor.FieldType.TEXTFIELD,
        LabelFieldDescriptor.LabelType.SECONDARY, UIFactory.DN_FIELD_SIZE));
    hm.put(FieldName.REMOTE_SERVER_PWD, new LabelFieldDescriptor(
        getMsg("remote-server-pwd-label"), getMsg("remote-server-pwd-tooltip"),
        LabelFieldDescriptor.FieldType.PASSWORD,
        LabelFieldDescriptor.LabelType.SECONDARY,
        UIFactory.PASSWORD_FIELD_SIZE));
    hm.put(FieldName.REMOTE_SERVER_HOST, new LabelFieldDescriptor(
        getMsg("remote-server-host-label"),
        getMsg("remote-server-host-tooltip"),
        LabelFieldDescriptor.FieldType.TEXTFIELD,
        LabelFieldDescriptor.LabelType.SECONDARY,
        UIFactory.HOST_FIELD_SIZE));
    hm.put(FieldName.REMOTE_SERVER_PORT, new LabelFieldDescriptor(
        getMsg("remote-server-port-label"),
        getMsg("remote-server-port-tooltip"),
        LabelFieldDescriptor.FieldType.TEXTFIELD,
        LabelFieldDescriptor.LabelType.SECONDARY,
        UIFactory.PORT_FIELD_SIZE));
    for (FieldName fieldName : hm.keySet())
    {
      JTextComponent field;
      LabelFieldDescriptor desc = hm.get(fieldName);
      String defaultValue = getDefaultStringValue(fieldName);
      field = UIFactory.makeJTextComponent(desc, defaultValue);
      hmFields.put(fieldName, field);
      JLabel l = UIFactory.makeJLabel(desc);
      l.setLabelFor(field);
      hmLabels.put(fieldName, l);
    }
    ButtonGroup buttonGroup = new ButtonGroup();
    rbStandalone =
      UIFactory.makeJRadioButton(getMsg("standalone-server-label"),
          getMsg("standalone-server-tooltip"),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbStandalone.setOpaque(false);
    rbReplicated =
      UIFactory.makeJRadioButton(getMsg("replicated-server-label"),
          getMsg("replicated-server-tooltip"),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbReplicated.setOpaque(false);
    buttonGroup.add(rbStandalone);
    buttonGroup.add(rbReplicated);
    DataReplicationOptions.Type type =
      defaultUserData.getReplicationOptions().getType();
    cbTopologyExists = UIFactory.makeJCheckBox(getMsg("topology-exists-label"),
        getMsg("topology-exists-tooltip"),
        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    cbTopologyExists.setOpaque(false);
    rbStandalone.setSelected(type ==
      DataReplicationOptions.Type.STANDALONE);
    rbReplicated.setSelected(type !=
      DataReplicationOptions.Type.STANDALONE);
    cbTopologyExists.setSelected(type ==
      DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
    checkEnablingState();
  }
  /**
   * Adds all the required document listeners to the fields.
   */
  private void addDocumentListeners()
  {
    FieldName[] fields = {
        FieldName.REMOTE_SERVER_DN,
        FieldName.REMOTE_SERVER_PWD,
        FieldName.REMOTE_SERVER_HOST,
        FieldName.REMOTE_SERVER_PORT
    };
    for (int i=0; i<fields.length; i++)
    {
      JTextComponent tf = getField(fields[i]);
      tf.getDocument().addDocumentListener(new DocumentListener()
      {
        public void changedUpdate(DocumentEvent ev)
        {
          if (!rbReplicated.isSelected())
          {
            rbReplicated.setSelected(true);
          }
          if (!cbTopologyExists.isSelected())
          {
            cbTopologyExists.setSelected(true);
          }
        }
        public void insertUpdate(DocumentEvent ev)
        {
          changedUpdate(ev);
        }
        public void removeUpdate(DocumentEvent ev)
        {
          changedUpdate(ev);
        }
      });
    }
  }
  /**
   * Adds the required focus listeners to the fields.
   */
  private void addFocusListeners()
  {
    final FocusListener l = new FocusListener()
    {
      public void focusGained(FocusEvent e)
      {
        lastFocusComponent = e.getComponent();
        if (lastFocusComponent instanceof JTextComponent)
        {
          rbReplicated.setSelected(true);
          cbTopologyExists.setSelected(true);
        }
      }
      public void focusLost(FocusEvent e)
      {
      }
    };
    for (JTextComponent tf : hmFields.values())
    {
      tf.addFocusListener(l);
    }
    rbReplicated.addFocusListener(l);
    rbStandalone.addFocusListener(l);
    cbTopologyExists.addFocusListener(l);
    lastFocusComponent = rbStandalone;
  }
  /**
   * Adds the required focus listeners to the fields.
   */
  private void addActionListeners()
  {
    final ActionListener l = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
        checkEnablingState();
      }
    };
    rbReplicated.addActionListener(l);
    rbStandalone.addActionListener(l);
    cbTopologyExists.addActionListener(l);
    cbTopologyExists.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent ev)
      {
        if (cbTopologyExists.isSelected())
        {
          rbReplicated.setSelected(true);
        }
      }
    });
  }
  /**
   * Enables/disables the fields.
   */
  private void checkEnablingState()
  {
    boolean enableFields = rbReplicated.isSelected() &&
    cbTopologyExists.isSelected();
    for (JTextComponent tf : hmFields.values())
    {
      tf.setEnabled(enableFields);
    }
    for (JLabel l : hmLabels.values())
    {
      l.setEnabled(enableFields);
    }
    cbTopologyExists.setEnabled(rbReplicated.isSelected());
  }
  /**
   * Returns the label associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the JLabel.
   * @return the label associated with the given field name.
   */
  private JLabel getLabel(FieldName fieldName)
  {
    return hmLabels.get(fieldName);
  }
  /**
   * Returns the JTextComponent associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the
   * JTextComponent.
   * @return the JTextComponent associated with the given field name.
   */
  private JTextComponent getField(FieldName fieldName)
  {
    return hmFields.get(fieldName);
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java
New file
@@ -0,0 +1,324 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.HashMap;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
/**
 * This class is used to set the global administrator parameters.
 */
public class GlobalAdministratorPanel extends QuickSetupStepPanel
{
  private static final long serialVersionUID = 4266485298770553875L;
  private UserData defaultUserData;
  private Component lastFocusComponent;
  private HashMap<FieldName, JLabel> hmLabels =
      new HashMap<FieldName, JLabel>();
  private HashMap<FieldName, JTextComponent> hmFields =
      new HashMap<FieldName, JTextComponent>();
  /**
   * Constructor of the panel.
   * @param application Application represented by this panel and used to
   * initialize the fields of the panel.
   */
  public GlobalAdministratorPanel(GuiApplication application)
  {
    super(application);
    this.defaultUserData = application.getUserData();
    populateLabelAndFieldMaps();
    addFocusListeners();
  }
  /**
   * {@inheritDoc}
   */
  public Object getFieldValue(FieldName fieldName)
  {
    Object value = null;
    JTextComponent field = getField(fieldName);
    if (field != null)
    {
      value = field.getText();
    }
    return value;
  }
  /**
   * {@inheritDoc}
   */
  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
  {
    JLabel label = getLabel(fieldName);
    if (label != null)
    {
      if (invalid)
      {
        UIFactory.setTextStyle(label,
            UIFactory.TextStyle.PRIMARY_FIELD_INVALID);
      } else
      {
        UIFactory
            .setTextStyle(label, UIFactory.TextStyle.PRIMARY_FIELD_VALID);
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  protected Component createInputPanel()
  {
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setOpaque(false);
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.weightx = 1.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets = UIFactory.getEmptyInsets();
    // Add the server location widgets
    FieldName[] fields =
    {
      FieldName.GLOBAL_ADMINISTRATOR_UID,
      FieldName.GLOBAL_ADMINISTRATOR_PWD,
      FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM
    };
    gbc.insets = UIFactory.getEmptyInsets();
    for (int i=0; i<fields.length; i++)
    {
      if (i != 0)
      {
        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
      }
      else
      {
        gbc.insets.top = 0;
      }
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      gbc.weightx = 0.0;
      gbc.insets.left = 0;
      gbc.anchor = GridBagConstraints.WEST;
      panel.add(getLabel(fields[i]), gbc);
      JPanel auxPanel = new JPanel(new GridBagLayout());
      auxPanel.setOpaque(false);
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.weightx = 0.0;
      auxPanel.add(getField(fields[i]), gbc);
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.insets.left = 0;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      auxPanel.add(Box.createHorizontalGlue(), gbc);
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.insets = UIFactory.getEmptyInsets();
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      panel.add(auxPanel, gbc);
    }
    addVerticalGlue(panel);
    return panel;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstructions()
  {
    return getMsg("global-administrator-panel-instructions");
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle()
  {
    return getMsg("global-administrator-panel-title");
  }
  /**
   * {@inheritDoc}
   */
  public void endDisplay()
  {
    if (lastFocusComponent != null)
    {
      lastFocusComponent.requestFocusInWindow();
    }
  }
  /**
   * Returns the default value for the provided field Name.
   * @param fieldName the field name for which we want to get the default
   * value.
   * @return the default value for the provided field Name.
   */
  private String getDefaultValue(FieldName fieldName)
  {
    String value = null;
    switch (fieldName)
    {
    case GLOBAL_ADMINISTRATOR_UID:
      value = defaultUserData.getGlobalAdministratorUID();
      break;
    case GLOBAL_ADMINISTRATOR_PWD:
      value = defaultUserData.getGlobalAdministratorPassword();
      break;
    case GLOBAL_ADMINISTRATOR_PWD_CONFIRM:
      value = defaultUserData.getGlobalAdministratorPassword();
      break;
    default:
      throw new IllegalArgumentException("Unknown field name: " +
          fieldName);
    }
    return value;
  }
  /**
   * Creates the components and populates the Maps with them.
   */
  private void populateLabelAndFieldMaps()
  {
    HashMap<FieldName, LabelFieldDescriptor> hm =
        new HashMap<FieldName, LabelFieldDescriptor>();
    hm.put(FieldName.GLOBAL_ADMINISTRATOR_UID, new LabelFieldDescriptor(
        getMsg("global-administrator-uid-label"),
        getMsg("global-administrator-uid-tooltip"),
        LabelFieldDescriptor.FieldType.TEXTFIELD,
        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.UID_FIELD_SIZE));
    hm.put(FieldName.GLOBAL_ADMINISTRATOR_PWD, new LabelFieldDescriptor(
        getMsg("global-administrator-pwd-label"),
        getMsg("global-administrator-pwd-tooltip"),
        LabelFieldDescriptor.FieldType.PASSWORD,
        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PASSWORD_FIELD_SIZE));
    hm.put(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
        new LabelFieldDescriptor(
        getMsg("global-administrator-pwd-confirm-label"),
        getMsg("global-administrator-pwd-confirm-tooltip"),
        LabelFieldDescriptor.FieldType.PASSWORD,
        LabelFieldDescriptor.LabelType.PRIMARY,
        UIFactory.PASSWORD_FIELD_SIZE));
    for (FieldName fieldName : hm.keySet())
    {
      LabelFieldDescriptor desc = hm.get(fieldName);
      String defaultValue = getDefaultValue(fieldName);
      JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
      JLabel label = UIFactory.makeJLabel(desc);
      hmFields.put(fieldName, field);
      label.setLabelFor(field);
      hmLabels.put(fieldName, label);
    }
  }
  /**
   * Returns the label associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the JLabel.
   * @return the label associated with the given field name.
   */
  private JLabel getLabel(FieldName fieldName)
  {
    return hmLabels.get(fieldName);
  }
  /**
   * Returns the JTextComponent associated with the given field name.
   * @param fieldName the field name for which we want to retrieve the
   * JTextComponent.
   * @return the JTextComponent associated with the given field name.
   */
  private JTextComponent getField(FieldName fieldName)
  {
    return hmFields.get(fieldName);
  }
  /**
   * Adds the required focus listeners to the fields.
   */
  private void addFocusListeners()
  {
    final FocusListener l = new FocusListener()
    {
      public void focusGained(FocusEvent e)
      {
        lastFocusComponent = e.getComponent();
      }
      public void focusLost(FocusEvent e)
      {
      }
    };
    for (JTextComponent tf : hmFields.values())
    {
      tf.addFocusListener(l);
    }
    lastFocusComponent = getField(FieldName.GLOBAL_ADMINISTRATOR_PWD);
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -27,14 +27,18 @@
package org.opends.quicksetup.installer.ui;
import org.opends.quicksetup.DataOptions;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.DataReplicationOptions;
import org.opends.quicksetup.installer.NewSuffixOptions;
import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
import org.opends.quicksetup.ui.*;
import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.util.HashMap;
import java.util.Set;
/**
 * This is the panel that contains the Review Panel.
@@ -80,10 +84,19 @@
        getSecurityOptionsString(userData.getSecurityOptions(), false));
    setFieldValue(FieldName.DIRECTORY_MANAGER_DN, userData
        .getDirectoryManagerDn());
    setFieldValue(FieldName.DIRECTORY_BASE_DN, userData.getDataOptions()
        .getBaseDn());
    setFieldValue(FieldName.DATA_OPTIONS, getDisplayString(userData
        .getDataOptions()));
    setFieldValue(FieldName.DATA_OPTIONS, getDataDisplayString(userData));
    if (userData.mustCreateAdministrator())
    {
      setFieldValue(FieldName.GLOBAL_ADMINISTRATOR_UID,
          String.valueOf(userData.getGlobalAdministratorUID()));
      getField(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(true);
      getLabel(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(true);
    }
    else
    {
      getField(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
      getLabel(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
    }
  }
  /**
@@ -147,8 +160,8 @@
        LabelFieldDescriptor.FieldType.READ_ONLY,
        LabelFieldDescriptor.LabelType.PRIMARY, 0));
    hm.put(FieldName.DIRECTORY_BASE_DN, new LabelFieldDescriptor(
        getMsg("base-dn-label"), getMsg("base-dn-tooltip"),
    hm.put(FieldName.GLOBAL_ADMINISTRATOR_UID, new LabelFieldDescriptor(
        getMsg("global-administrator-uid-label"), null,
        LabelFieldDescriptor.FieldType.READ_ONLY,
        LabelFieldDescriptor.LabelType.PRIMARY, 0));
@@ -208,35 +221,70 @@
   * @param options the DataOptions of the user.
   * @return the localized string describing the DataOptions chosen by the user.
   */
  private String getDisplayString(DataOptions options)
  private String getDataDisplayString(UserData userInstallData)
  {
    String msg;
    switch (options.getType())
    boolean createSuffix = false;
    DataReplicationOptions repl =
      userInstallData.getReplicationOptions();
    SuffixesToReplicateOptions suf =
      userInstallData.getSuffixesToReplicateOptions();
    createSuffix =
      repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY ||
      repl.getType() == DataReplicationOptions.Type.STANDALONE ||
      suf.getType() == SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
    if (createSuffix)
    {
    case CREATE_BASE_ENTRY:
      msg = getMsg("review-create-base-entry-label", new String[]
        { options.getBaseDn() });
      String arg2;
      break;
      NewSuffixOptions options = userInstallData.getNewSuffixOptions();
      switch (options.getType())
      {
      case CREATE_BASE_ENTRY:
        arg2 = getMsg("review-create-base-entry-label",
            new String[] { options.getBaseDn() });
    case LEAVE_DATABASE_EMPTY:
      msg = getMsg("review-leave-database-empty-label");
      break;
        break;
    case IMPORT_FROM_LDIF_FILE:
      msg = getMsg("review-import-ldif", new String[]
        { options.getLDIFPath() });
      break;
      case LEAVE_DATABASE_EMPTY:
        arg2 = getMsg("review-leave-database-empty-label");
        break;
    case IMPORT_AUTOMATICALLY_GENERATED_DATA:
      msg = getMsg("review-import-automatically-generated", new String[]
        { String.valueOf(options.getNumberEntries()) });
      break;
      case IMPORT_FROM_LDIF_FILE:
        arg2 = getMsg("review-import-ldif",
            new String[] { options.getLDIFPath() });
        break;
    default:
      throw new IllegalArgumentException("Unknow type: " + options.getType());
      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
        arg2 = getMsg("review-import-automatically-generated",
            new String[] { String.valueOf(options.getNumberEntries()) });
        break;
      default:
        throw new IllegalArgumentException("Unknow type: " + options.getType());
      }
      msg = getMsg("review-create-suffix",
          new String[] {options.getBaseDn(), arg2});
    }
    else
    {
      StringBuilder buf = new StringBuilder();
      Set<SuffixDescriptor> suffixes = suf.getSuffixes();
      for (SuffixDescriptor suffix : suffixes)
      {
        if (buf.length() > 0)
        {
          buf.append("\n");
        }
        buf.append(suffix.getDN());
      }
      msg = getMsg("review-replicate-suffix", new String[] {buf.toString()});
    }
    return msg;
@@ -260,8 +308,7 @@
          {
            FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
            FieldName.SECURITY_OPTIONS, FieldName.DIRECTORY_MANAGER_DN,
            FieldName.DIRECTORY_BASE_DN,
            FieldName.DATA_OPTIONS
            FieldName.GLOBAL_ADMINISTRATOR_UID, FieldName.DATA_OPTIONS
          };
    }
    else
@@ -270,8 +317,8 @@
        new FieldName[]
          {
            FieldName.SERVER_PORT, FieldName.SECURITY_OPTIONS,
            FieldName.DIRECTORY_MANAGER_DN,
            FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS
            FieldName.DIRECTORY_MANAGER_DN, FieldName.GLOBAL_ADMINISTRATOR_UID,
            FieldName.DATA_OPTIONS
          };
    }
@@ -304,13 +351,7 @@
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      panel.add(auxPanel, gbc);
      gbc.insets = UIFactory.getEmptyInsets();
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      gbc.weightx = 1.0;
      auxPanel.add(getField(fieldNames[i]), gbc);
    }
      panel.add(getField(fieldNames[i]), gbc);    }
    return panel;
  }
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java
File was renamed from opends/src/quicksetup/org/opends/quicksetup/ui/InstallWelcomePanel.java
@@ -25,10 +25,13 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.Installation;
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
File was renamed from opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
@@ -25,7 +25,7 @@
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
@@ -59,6 +59,7 @@
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.installer.Installer;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.util.BackgroundTask;
import org.opends.quicksetup.util.Utils;
import org.opends.server.util.CertificateManager;
@@ -133,15 +134,7 @@
      }
    });
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    UIFactory.IconType ic;
    if (Utils.isMacOS())
    {
      ic = UIFactory.IconType.MINIMIZED_MAC;
    }
    else
    {
      ic = UIFactory.IconType.MINIMIZED;
    }
    Utils.centerOnComponent(this, parent);
  }
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java
File was renamed from opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
@@ -22,10 +22,10 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
package org.opends.quicksetup.installer.ui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
@@ -46,6 +46,7 @@
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.util.Utils;
/**
opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
File was renamed from opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
@@ -25,7 +25,7 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.ui;
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
@@ -45,6 +45,11 @@
import javax.swing.text.JTextComponent;
import org.opends.quicksetup.event.BrowseActionListener;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.LabelFieldDescriptor;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.UserData;
opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
New file
@@ -0,0 +1,530 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.installer.ui;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ReplicaDescriptor;
import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
import org.opends.quicksetup.ui.FieldName;
import org.opends.quicksetup.ui.GuiApplication;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.UIFactory;
/**
 * This class is used to provide a data model for the list of suffixes that
 * we have to replicate on the new server.
 */
public class SuffixesToReplicatePanel extends QuickSetupStepPanel
implements Comparator<SuffixDescriptor>
{
  private static final long serialVersionUID = -8051367953737385327L;
  private Component lastFocusComponent;
  private UserData defaultUserData;
  private TreeSet<SuffixDescriptor> orderedSuffixes =
    new TreeSet<SuffixDescriptor>(this);
  private HashMap<SuffixDescriptor, JCheckBox> hmCheckBoxes =
    new HashMap<SuffixDescriptor, JCheckBox>();
  private Set<JEditorPane> suffixLabels = new HashSet<JEditorPane>();
  private JRadioButton rbCreateNewSuffix;
  private JRadioButton rbReplicate;
  private JLabel noSuffixLabel;
  private Component labelGlue;
  private JPanel checkBoxPanel;
  private JScrollPane scroll;
  /**
   * Constructor of the panel.
   * @param application Application represented by this panel and used to
   * initialize the fields of the panel.
   */
  public SuffixesToReplicatePanel(GuiApplication application)
  {
    super(application);
    this.defaultUserData = application.getUserData();
    createComponents();
    addFocusListeners();
  }
  /**
   * {@inheritDoc}
   */
  public Object getFieldValue(FieldName fieldName)
  {
    Object value = null;
    if (fieldName == FieldName.SUFFIXES_TO_REPLICATE_OPTIONS)
    {
      if (rbCreateNewSuffix.isSelected())
      {
        value = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
      }
      else
      {
        value =
          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES;
      }
    }
    else if (fieldName == FieldName.SUFFIXES_TO_REPLICATE)
    {
      Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
      for (SuffixDescriptor suffix:orderedSuffixes)
      {
        if (hmCheckBoxes.get(suffix).isSelected())
        {
          suffixes.add(suffix);
        }
      }
      value = suffixes;
    }
    return value;
  }
  /**
   * {@inheritDoc}
   */
  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
  {
    if (fieldName == FieldName.SUFFIXES_TO_REPLICATE)
    {
      UIFactory.TextStyle style;
      if (invalid)
      {
        style = UIFactory.TextStyle.SECONDARY_FIELD_INVALID;
      } else
      {
        style = UIFactory.TextStyle.SECONDARY_FIELD_VALID;
      }
      UIFactory.setTextStyle(rbReplicate, style);
    }
  }
  /**
   * {@inheritDoc}
   */
  public int compare(SuffixDescriptor desc1, SuffixDescriptor desc2)
  {
    int result = 0;
    result = compareSuffixDN(desc1, desc2);
    if (result == 0)
    {
      result = compareSuffixStrings(desc1, desc2);
    }
    return result;
  }
  /**
   * {@inheritDoc}
   */
  protected Component createInputPanel()
  {
    JPanel panel = new JPanel(new GridBagLayout());
    panel.setOpaque(false);
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.weightx = 1.0;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.insets = UIFactory.getEmptyInsets();
    panel.add(rbCreateNewSuffix, gbc);
    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
    panel.add(rbReplicate, gbc);
    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
    gbc.insets.left = UIFactory.LEFT_INSET_SUBPANEL_SUBORDINATE;
    // Add the checkboxes
    checkBoxPanel = new JPanel(new GridBagLayout());
    checkBoxPanel.setOpaque(false);
    gbc.insets.top = 0;
    gbc.anchor = GridBagConstraints.NORTH;
    gbc.weighty = 1.0;
    gbc.fill = GridBagConstraints.BOTH;
    scroll = new JScrollPane(checkBoxPanel);
    scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
    scroll.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
    scroll.setOpaque(false);
    scroll.getViewport().setOpaque(false);
    panel.add(scroll, gbc);
    gbc.weighty = 0.0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
    gbc.anchor = GridBagConstraints.NORTHEAST;
    panel.add(noSuffixLabel, gbc);
    noSuffixLabel.setVisible(false);
    labelGlue = Box.createVerticalGlue();
    gbc.fill = GridBagConstraints.VERTICAL;
    gbc.weighty = 1.0;
    panel.add(labelGlue, gbc);
    labelGlue.setVisible(false);
    return panel;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstructions()
  {
    return getMsg("suffixes-to-replicate-panel-instructions");
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle()
  {
    return getMsg("suffixes-to-replicate-panel-title");
  }
  /**
   * {@inheritDoc}
   */
  public void beginDisplay(UserData data)
  {
    TreeSet<SuffixDescriptor> array = orderSuffixes(
        data.getSuffixesToReplicateOptions().getAvailableSuffixes());
    Set<SuffixDescriptor> chosen =
      data.getSuffixesToReplicateOptions().getSuffixes();
    if (!array.equals(orderedSuffixes))
    {
      orderedSuffixes.clear();
      orderedSuffixes.addAll(array);
      hmCheckBoxes.clear();
      for (SuffixDescriptor suffix : orderedSuffixes)
      {
        JCheckBox cb = UIFactory.makeJCheckBox(suffix.getDN(),
            getMsg("suffixes-to-replicate-dn-tooltip"),
            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
        cb.setOpaque(false);
        cb.setSelected(chosen.contains(suffix));
        cb.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent ev)
          {
            if (((JCheckBox)ev.getSource()).isSelected())
            {
              rbReplicate.setSelected(true);
            }
          }
        });
        hmCheckBoxes.put(suffix, cb);
      }
      populateCheckBoxPanel();
      boolean display = orderedSuffixes.size() > 0;
      noSuffixLabel.setVisible(!display);
      labelGlue.setVisible(!display);
      scroll.setVisible(display);
    }
    checkEnablingState();
  }
  /**
   * {@inheritDoc}
   */
  public void endDisplay()
  {
    if (lastFocusComponent != null)
    {
      lastFocusComponent.requestFocusInWindow();
    }
  }
  /**
   * Creates the components of this panel.
   */
  private void createComponents()
  {
    ButtonGroup buttonGroup = new ButtonGroup();
    rbCreateNewSuffix =
      UIFactory.makeJRadioButton(getMsg("create-new-suffix-label"),
          getMsg("create-new-suffix-tooltip"),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbCreateNewSuffix.setOpaque(false);
    rbReplicate =
      UIFactory.makeJRadioButton(getMsg("replicate-with-suffixes-label"),
          getMsg("replicate-with-suffixes-tooltip"),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    rbReplicate.setOpaque(false);
    buttonGroup.add(rbCreateNewSuffix);
    buttonGroup.add(rbReplicate);
    SuffixesToReplicateOptions.Type type =
      defaultUserData.getSuffixesToReplicateOptions().getType();
    rbCreateNewSuffix.setSelected(type ==
      SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
    rbReplicate.setSelected(type ==
      SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES);
    noSuffixLabel = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
        getMsg("suffix-list-empty"),
        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
    ActionListener l = new ActionListener()
    {
      public void actionPerformed(ActionEvent ev)
      {
        checkEnablingState();
      }
    };
    rbCreateNewSuffix.addActionListener(l);
    rbReplicate.addActionListener(l);
  }
  /**
   * Adds the required focus listeners to the fields.
   */
  private void addFocusListeners()
  {
    final FocusListener l = new FocusListener()
    {
      public void focusGained(FocusEvent e)
      {
        lastFocusComponent = e.getComponent();
      }
      public void focusLost(FocusEvent e)
      {
      }
    };
    rbReplicate.addFocusListener(l);
    rbCreateNewSuffix.addFocusListener(l);
    lastFocusComponent = rbReplicate;
  }
  private void populateCheckBoxPanel()
  {
    checkBoxPanel.removeAll();
    suffixLabels.clear();
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.NORTH;
    boolean first = true;
    for (SuffixDescriptor suffix : orderedSuffixes)
    {
      gbc.insets.left = 0;
      gbc.weightx = 0.0;
      if (!first)
      {
        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
      }
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      JCheckBox cb = hmCheckBoxes.get(suffix);
      cb.setVerticalAlignment(SwingConstants.TOP);
      checkBoxPanel.add(cb, gbc);
      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
      gbc.weightx = 1.0;
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      JEditorPane l = UIFactory.makeTextPane(getSuffixString(suffix),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
      l.setOpaque(false);
      suffixLabels.add(l);
      /* Use a prototype label to get the additional insets */
      JEditorPane proto = UIFactory.makeTextPane(suffix.getDN(),
          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
      gbc.insets.top += Math.abs(cb.getPreferredSize().height -
          proto.getPreferredSize().height) / 2;
      checkBoxPanel.add(l, gbc);
      first = false;
    }
    addVerticalGlue(checkBoxPanel);
  }
  private String getSuffixString(SuffixDescriptor desc)
  {
    TreeSet<String> replicaDisplays = new TreeSet<String>();
    for (ReplicaDescriptor rep: desc.getReplicas())
    {
      replicaDisplays.add(getReplicaDisplay(rep));
    }
    StringBuilder buf = new StringBuilder();
    for (String display: replicaDisplays)
    {
      if (buf.length() > 0)
      {
        buf.append("\n");
      }
      buf.append(display);
    }
    return buf.toString();
  }
  private String getReplicaDisplay(ReplicaDescriptor replica)
  {
    String display;
    ServerDescriptor server = replica.getServer();
    String serverDisplay = getServerDisplay(server);
    int nEntries = replica.getEntries();
    if (nEntries > 0)
    {
      String[] args = {serverDisplay, String.valueOf(nEntries)};
      display = getMsg("suffix-list-replica-display-entries", args);
    }
    else
    {
      String[] arg = {serverDisplay};
      display = getMsg("suffix-list-replica-display-no-entries", arg);
    }
    return display;
  }
  //TODO: only handles server that have ADSProperties.
  private String getServerDisplay(ServerDescriptor server)
  {
    String display;
    String hostName = (String)server.getAdsProperties().get(
        ADSContext.ServerProperty.HOSTNAME);
    boolean secure = false;
    int port = -1;
    if (hostName == null)
    {
      hostName = getMsg("suffix-list-unknown-label");
    }
    if (!"true".equalsIgnoreCase((String)server.getAdsProperties().get(
        ADSContext.ServerProperty.LDAP_ENABLED)))
    {
      if ("true".equalsIgnoreCase((String)server.getAdsProperties().get(
          ADSContext.ServerProperty.LDAPS_ENABLED)))
      {
        secure = true;
      }
    }
    try
    {
      if (secure)
      {
        port = Integer.parseInt((String)server.getAdsProperties().get(
            ADSContext.ServerProperty.SECURE_PORT));
      }
      else
      {
        port = Integer.parseInt((String)server.getAdsProperties().get(
            ADSContext.ServerProperty.PORT));
      }
    }
    catch (Throwable t)
    {
    }
    if (port == -1)
    {
      display = hostName+":"+getMsg("suffix-list-unknown-label");
    }
    else
    {
      display = hostName+":"+port;
    }
    return display;
  }
  private TreeSet<SuffixDescriptor> orderSuffixes(
  Set<SuffixDescriptor> suffixes)
  {
    TreeSet<SuffixDescriptor> ordered = new TreeSet<SuffixDescriptor>(this);
    ordered.addAll(suffixes);
    return ordered;
  }
  private int compareSuffixDN(SuffixDescriptor desc1, SuffixDescriptor desc2)
  {
    return desc1.getDN().compareTo(desc2.getDN());
  }
  private int compareSuffixStrings(SuffixDescriptor desc1,
      SuffixDescriptor desc2)
  {
    return getSuffixString(desc1).compareTo(getSuffixString(desc2));
  }
  private void checkEnablingState()
  {
    boolean enable = rbReplicate.isSelected();
    for (JCheckBox cb : hmCheckBoxes.values())
    {
      cb.setEnabled(enable);
    }
    for (JEditorPane p : suffixLabels)
    {
      p.setEnabled(enable);
    }
    noSuffixLabel.setEnabled(enable);
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -83,7 +83,7 @@
  public WebStartInstaller()
  {
    initLoader();
    status = InstallProgressStep.NOT_STARTED;
    setStatus(InstallProgressStep.NOT_STARTED);
  }
  /**
@@ -102,13 +102,13 @@
      System.setErr(err);
      System.setOut(out);
      status = InstallProgressStep.DOWNLOADING;
      setStatus(InstallProgressStep.DOWNLOADING);
      InputStream in =
          getZipInputStream(getRatio(InstallProgressStep.EXTRACTING));
      notifyListeners(getTaskSeparator());
      status = InstallProgressStep.EXTRACTING;
      setStatus(InstallProgressStep.EXTRACTING);
      createParentDirectoryIfRequired();
      extractZipFiles(in, getRatio(InstallProgressStep.EXTRACTING),
          getRatio(InstallProgressStep.CONFIGURING_SERVER));
@@ -116,56 +116,41 @@
      setInstallation(new Installation(getUserData().getServerLocation()));
      status = InstallProgressStep.CONFIGURING_SERVER;
      setStatus(InstallProgressStep.CONFIGURING_SERVER);
      configureServer();
      switch (getUserData().getDataOptions().getType())
      {
      case CREATE_BASE_ENTRY:
        status = InstallProgressStep.CREATING_BASE_ENTRY;
        notifyListeners(getTaskSeparator());
        createBaseEntry();
        break;
      case IMPORT_FROM_LDIF_FILE:
        status = InstallProgressStep.IMPORTING_LDIF;
        notifyListeners(getTaskSeparator());
        importLDIF();
        break;
      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
        notifyListeners(getTaskSeparator());
        importAutomaticallyGenerated();
        break;
      }
      createData();
      updateADS();
      writeJavaHome();
      if (Utils.isWindows())
      {
          notifyListeners(getTaskSeparator());
          status = InstallProgressStep.ENABLING_WINDOWS_SERVICE;
          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
          enableWindowsService();
      }
      if (getUserData().getStartServer())
      {
        notifyListeners(getTaskSeparator());
        status = InstallProgressStep.STARTING_SERVER;
        setStatus(InstallProgressStep.STARTING_SERVER);
        new ServerController(this).startServer();
      }
      status = InstallProgressStep.FINISHED_SUCCESSFULLY;
      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
      notifyListeners(null);
    } catch (QuickSetupException ex)
    {
      status = InstallProgressStep.FINISHED_WITH_ERROR;
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      String html = getFormattedError(ex, true);
      notifyListeners(html);
    }
    catch (Throwable t)
    {
      status = InstallProgressStep.FINISHED_WITH_ERROR;
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      QuickSetupException ex = new QuickSetupException(
          QuickSetupException.Type.BUG, getThrowableMsg("bug-msg", t), t);
      String msg = getFormattedError(ex, true);
@@ -233,7 +218,7 @@
    totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
    steps.add(InstallProgressStep.CONFIGURING_SERVER);
    switch (getUserData().getDataOptions().getType())
    switch (getUserData().getNewSuffixOptions().getType())
    {
    case CREATE_BASE_ENTRY:
      steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
@@ -354,7 +339,7 @@
   */
  protected String getOpenDSClassPath()
  {
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    String[] jars = getOpenDSJarPaths();
    for (int i = 0; i < jars.length; i++)
    {
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -127,8 +127,8 @@
cli-uninstall-confirm-prompt={0}\n[{1}]:
cli-uninstall-string-prompt={0}\n[{1}]:
cli-uninstall-error-reading-stdin=Unexpected error reading standard input.
cli-uninstall-what-to-delete=Do you want to remove all components of OpenDS or \
select the components to remove?\n\
cli-uninstall-what-to-delete=Do you want to remove all components of \
OpenDS or select the components to remove?\n\
1. Remove all components\n\
2. Select the components to be removed\n\
3. Neither; Quit the uninstaller
@@ -307,7 +307,24 @@
not-equal-pwd=The passwords you have provided do not match.
pwd-too-short=The minimum length required for the Administrative User \
password is {0} characters.
# Data Options Panel
# Data Replication Panel
empty-remote-host=You must provide the fully qualified name of the host.
invalid-remote-port=The provided port is not valid.
empty-remote-dn=You must provide a value for the Administrative User.
empty-remote-pwd=You must provide an Admin User password.
cannot-connect-to-remote-permissions=You do not have enough access rights \
to read the configuration in {0}. \nProvide credentials with enough rights.
cannot-connect-to-remote-generic=Could not connect to {0}. \nCheck that the \
server is running and that the provided credentials are valid.
remote-ads-exception=An unexpected error occurred reading the \
configuration in {0}.\nThe error is: {1}
no-suffixes-chosen-to-replicate=You must select at least one suffix to \
replicate contents with.
# Create Global Administrator Panel
empty-administrator-uid=You must provide a Global Administrative User ID.
empty-administrator-pwd=You must provide a Global Administrative User \
Password.
# New Suffix Options Panel
empty-base-dn=You must provide a Directory Base DN.
not-a-base-dn=The provided Directory Base DN is not a valid DN.
base-dn-is-configuration-dn=The provided Directory Base DN is used for \
@@ -338,7 +355,10 @@
#
welcome-step=Welcome
server-settings-step=Server Settings
data-options-step=Data Options
data-replication-step=Topology Options
create-global-administrator-step=Global Administrator
suffixes-step=Data Replication
data-options-step=Directory Data
review-step=Review
progress-step=Progress
confirm-uninstall-step=Uninstall Options
@@ -468,6 +488,70 @@
pkcs12-certificate=Use existing PKCS#12 File
#
# Data Replication Panel specific labels
#
data-replication-options-panel-title=Topology Options
data-replication-options-panel-instructions=Choose the Data \
Replication Options.
remote-server-dn-label=Admin User:
remote-server-dn-tooltip=The DN or the UID of an administrator in the OpenDS \
you want to replicate data with.
remote-server-pwd-label=Admin Password:
remote-server-pwd-tooltip=The password of an administrator in the OpenDS \
you want to replicate data with.
remote-server-host-label=Host Name:
remote-server-host-tooltip=The fully qualified name of the host where the \
OpenDS you want to replicate data with is located.
remote-server-port-label=Port:
remote-server-port-tooltip=The LDAP port of the OpenDS you want to \
replicate data with.
standalone-server-label=This will be a standalone server
standalone-server-tooltip=Check this if you do not want to replicate the \
data on the server that you are creating with other servers.
replicated-server-label=This server will be part of a replication \
topology
replicated-server-tooltip=Check this if you want to replicate the data on \
the server that you are creating with other servers.
topology-exists-label=There is already a server in the topology
topology-exists-tooltip=Check this if you already created a server that you \
want to replicate data with.
#
# Global Administrator specific labels
#
global-administrator-panel-instructions=Provide the informaton to create a \
Global Administrator that will able to manage your whole replication \
topology.
global-administrator-panel-title=Create Global Administrator
global-administrator-uid-label=Global Administrator ID:
global-administrator-uid-tooltip=The Global Administrator ID.
global-administrator-pwd-label=Global Administrator Password:
global-administrator-pwd-tooltip=The Global Administrator Password.
global-administrator-pwd-confirm-label=Global Administrator Password \
(confirm):
global-administrator-pwd-confirm-tooltip=Confirm the password of the \
Global Administrator.
#
# Suffixes to Replicate Panel specific labels
#
suffixes-to-replicate-panel-instructions=Choose whether to create suffixes \
as defined on remote servers or to create a new suffix.
suffixes-to-replicate-panel-title=Data Replication
create-new-suffix-label=Create first instance of suffix to be replicated
create-new-suffix-tooltip=Check this to create a new suffix.
replicate-with-suffixes-label=Create local instance of existing suffixes and \
configure replication:
replicate-with-suffixes-tooltip=Check this to Create Suffixes whose \
Contents are replicated with Existing Suffixes.
suffixes-to-replicate-dn-tooltip=The Distinguished Name (DN) of the suffix \
to replicate.
suffix-list-replica-display-entries={0}  ({1} entries)
suffix-list-replica-display-no-entries={0}  (no entries)
suffix-list-unknown-label=<unknown>
suffix-list-empty=-No Suffixes Found-
#
# Security Options dialog specific labels
#
security-options-dialog-title=OpenDS QuickSetup
@@ -546,7 +630,7 @@
#
# Data Options Panel specific labels
#
data-options-panel-title=Data Options
data-options-panel-title=Directory Data
data-options-panel-instructions=Choose options for the LDAP data to be hosted \
by OpenDS.
base-dn-label=Directory Base DN:
@@ -580,6 +664,8 @@
review-import-ldif=Import Data from LDIF File ({0})
review-import-automatically-generated=Import Automatically-Generated Data ({0} \
Entries)
review-create-suffix=Create New Suffix {0}.\nSuffix Data: {1}
review-replicate-suffix=Replicate contents with suffixes:\n{0}
start-server-label=Start Server when Configuration has Completed
start-server-tooltip=Check this check box if you want to start the server once \
the installation and configuration has completed
opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java
@@ -120,7 +120,6 @@
   */
  private void createLayout(GuiApplication app)
  {
    Set<? extends WizardStep> steps = app.getWizardSteps();
    if (steps != null) {
      for (WizardStep step : steps) {
@@ -194,21 +193,30 @@
  {
    final CardLayout cl = (CardLayout) (getLayout());
    // Show the 'loading...' panel and invoke begin
    // display in another thread in case the panel
    // taske a while to initialize.
    cl.show(this, LOADING_PANEL);
    new Thread(new Runnable() {
      public void run() {
        getPanel(step).beginDisplay(userData);
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            cl.show(CurrentStepPanel.this, step.toString());
            getPanel(step).endDisplay();
          }
        });
      }
    },"panel begin display thread").start();
    if (getPanel(step).blockingBeginDisplay())
    {
      // Show the 'loading...' panel and invoke begin
      // display in another thread in case the panel
      // taske a while to initialize.
      cl.show(this, LOADING_PANEL);
      new Thread(new Runnable() {
        public void run() {
          getPanel(step).beginDisplay(userData);
          SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              cl.show(CurrentStepPanel.this, step.toString());
              getPanel(step).endDisplay();
            }
          });
        }
      },"panel begin display thread").start();
    }
    else
    {
      getPanel(step).beginDisplay(userData);
      cl.show(CurrentStepPanel.this, step.toString());
      getPanel(step).endDisplay();
    }
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
@@ -342,7 +342,7 @@
        {
          InitialLdapContext ctx =
            Utils.createLdapContext(installStatus.getLdapUrl(), tfDn.getText(),
              tfPwd.getText(), 3000, null);
              tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
          /*
           * Search for the config to check that it is the directory manager.
opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -82,6 +82,46 @@
   */
  NUMBER_ENTRIES,
  /**
   * The value associated with this is a DataReplicationOptions.Type.
   */
  REPLICATION_OPTIONS,
  /**
   * The value associated with this is a SuffixesToReplicateOptions.Type.
   */
  SUFFIXES_TO_REPLICATE_OPTIONS,
  /**
   * The value associated with this is a Set of SuffixDescriptor.
   */
  SUFFIXES_TO_REPLICATE,
  /**
   * The value associated with this is a String.
   */
  REMOTE_SERVER_DN,
  /**
   * The value associated with this is a String.
   */
  REMOTE_SERVER_PWD,
  /**
   * The value associated with this is a String.
   */
  REMOTE_SERVER_HOST,
  /**
   * The value associated with this is a String.
   */
  REMOTE_SERVER_PORT,
  /**
   * The value associated with this is a String.
   */
  GLOBAL_ADMINISTRATOR_UID,
  /**
   * The value associated with this is a String.
   */
  GLOBAL_ADMINISTRATOR_PWD,
  /**
   * The value associated with this is a String.
   */
  GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
  /**
   * The value associated with this is a Boolean.
   */
  SERVER_START,
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -32,6 +32,7 @@
import javax.swing.*;
import java.awt.event.WindowEvent;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Logger;
@@ -178,6 +179,52 @@
  abstract public WizardStep getPreviousWizardStep(WizardStep step);
  /**
   * Indicates whether or not the provided <code>step</code> is a sub step or
   * not.
   * @param step WizardStep for which the return value indicates whether
   * or not is a sub step.
   * @return boolean where true indicates the provided <code>step</code> is a
   * substep.
   */
  public boolean isSubStep(WizardStep step)
  {
    return false;
  }
  /**
   * Indicates whether or not the provided <code>step</code> is visible or
   * not.
   * @param step WizardStep for which the return value indicates whether
   * or not is visible.
   * @return boolean where true indicates the provided <code>step</code> is
   * visible.
   */
  public boolean isVisible(WizardStep step)
  {
    return false;
  }
  /**
   * Returns the list of all the steps in an ordered manner.  This is required
   * because in the case of an application with substeps the user of the other
   * interfaces is not enough.  This is a default implementation that uses
   * the getNextWizardStep method to calculate the list that work for
   * applications with no substeps.
   * @return a list containing ALL the steps (including substeps) in an ordered
   * manner.
   */
  public LinkedHashSet<WizardStep> getOrderedSteps()
  {
    LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
    WizardStep step = getFirstWizardStep();
    orderedSteps.add(step);
    while (null != (step = getNextWizardStep(step))) {
      orderedSteps.add(step);
    }
    return orderedSteps;
  }
  /**
   * Indicates whether or not the user is allowed to return to a previous
   * step from <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
@@ -44,7 +44,6 @@
import org.opends.quicksetup.event.ButtonActionListener;
import org.opends.quicksetup.event.ButtonEvent;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.ProgressDescriptor;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
@@ -176,10 +175,9 @@
  public void setDisplayedStep(WizardStep step, UserData userData)
  {
    displayedStep = step;
    // First call the panels to do the required updates on their layout
    //  First call the panels to do the required updates on their layout
    getButtonsPanel().setDisplayedStep(step);
    getStepsPanel().setDisplayedStep(step);
    getStepsPanel().setDisplayedStep(step, userData);
    getCurrentStepPanel().setDisplayedStep(step, userData);
  }
@@ -426,17 +424,6 @@
    return buttonsPanel;
  }
  /* Different commodity methods to retrieve localized messages */
  private String getMsg(String key)
  {
    return getI18n().getMsg(key);
  }
  private ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
  /**
   * Returns the button corresponding to the buttonName.
   * @param buttonName the ButtonName for which we want to get the button.
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -108,6 +108,17 @@
  }
  /**
   * Tells whether the method beginDisplay can be long and so should be called
   * outside the event thread.
   * @return <CODE>true</CODE> if the method beginDisplay can be long and so
   * should be called outside the event thread and <CODE>true</CODE> otherwise.
   */
  public boolean blockingBeginDisplay()
  {
    return false;
  }
  /**
   * Called when a progress change must be reflected in the panels.  Only
   * ProgressPanel overwrites this method and for all the others it stays empty.
   * @param descriptor the descriptor of the Installation progress.
opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java
@@ -30,13 +30,14 @@
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.WizardStep;
/**
@@ -55,6 +56,8 @@
  HashMap<WizardStep, JLabel> hmIcons = new HashMap<WizardStep, JLabel>();
  HashMap<WizardStep, JPanel> hmSubPanels = new HashMap<WizardStep, JPanel>();
  /**
   * Creates a StepsPanel.
   * @param app Application whose steps this class represents
@@ -70,8 +73,9 @@
   * as parameter.
   *
   * @param step the step in the wizard.
   * @param userData the data provided by the user.
   */
  public void setDisplayedStep(WizardStep step)
  public void setDisplayedStep(WizardStep step, UserData userData)
  {
    for (WizardStep s : getApplication().getWizardSteps())
    {
@@ -79,7 +83,8 @@
      {
        getIcon(s).setVisible(true);
        UIFactory.setTextStyle(getLabel(s), UIFactory.TextStyle.CURRENT_STEP);
      } else
      }
      else
      {
        if (getIcon(s) != null)
        {
@@ -91,6 +96,11 @@
              UIFactory.TextStyle.NOT_CURRENT_STEP);
        }
      }
      if (getApplication().isSubStep(s))
      {
        setStepVisible(s, getApplication().isVisible(s));
      }
    }
  }
@@ -112,19 +122,15 @@
    gbc.anchor = GridBagConstraints.WEST;
    HashMap<WizardStep, String> hmText = new HashMap<WizardStep, String>();
    ArrayList<WizardStep> orderedSteps = new ArrayList<WizardStep>();
    WizardStep step = app.getFirstWizardStep();
    hmText.put(step, getMsg(step.getMessageKey()));
    orderedSteps.add(step);
    while (null != (step = app.getNextWizardStep(step))) {
      hmText.put(step, getMsg(step.getMessageKey()));
      orderedSteps.add(step);
    }
    LinkedHashSet<WizardStep> orderedSteps = app.getOrderedSteps();
    boolean first = true;
    for (WizardStep s : orderedSteps)
    {
      if (s != orderedSteps.get(0))
      hmText.put(s, getMsg(s.getMessageKey()));
      JPanel subPanel = new JPanel(new GridBagLayout());
      subPanel.setOpaque(false);
      if (!first)
      {
        gbc.insets.top = UIFactory.TOP_INSET_STEP;
      }
@@ -137,25 +143,49 @@
      JLabel iconLabel =
          UIFactory.makeJLabel(UIFactory.IconType.CURRENT_STEP, null,
              UIFactory.TextStyle.NO_STYLE);
      if (getApplication().isSubStep(s))
      {
        gbcAux.insets.left = UIFactory.LEFT_INSET_SUBSTEP;
      }
      else
      {
        gbcAux.insets.left = 0;
      }
      auxPanel.add(iconLabel, gbcAux);
      int width = (int) iconLabel.getPreferredSize().getWidth();
      if (getApplication().isSubStep(s))
      {
        width += UIFactory.LEFT_INSET_SUBSTEP;
      }
      gbcAux.insets.left = 0;
      auxPanel.add(Box.createHorizontalStrut(width), gbcAux);
      hmIcons.put(s, iconLabel);
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      mainPanel.add(auxPanel, gbc);
      gbc.gridwidth = 3;
      gbc.weightx = 0.0;
      subPanel.add(auxPanel, gbc);
      JLabel stepLabel =
          UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, hmText.get(s),
              UIFactory.TextStyle.CURRENT_STEP);
      hmLabels.put(s, stepLabel);
      gbc.insets.left = UIFactory.LEFT_INSET_STEP;
      gbc.gridwidth = GridBagConstraints.RELATIVE;
      subPanel.add(stepLabel, gbc);
      gbc.insets = UIFactory.getEmptyInsets();
      gbc.gridwidth = GridBagConstraints.REMAINDER;
      mainPanel.add(stepLabel, gbc);
      gbc.weightx = 1.0;
      subPanel.add(Box.createHorizontalGlue(), gbc);
      mainPanel.add(subPanel, gbc);
      hmSubPanels.put(s, subPanel);
      stepLabel.setLabelFor(this);
      iconLabel.setLabelFor(stepLabel);
      first = false;
    }
    gbc.insets.left = 0;
@@ -201,4 +231,24 @@
  {
    return hmIcons.get(step);
  }
  /**
   * Returns the sub-panel associated with the given step.
   * @param step the step for which we want to retrieve the sub-panel.
   * @return the sub-panel associated with the given step.
   */
  private JPanel getSubPanel(WizardStep step)
  {
    return hmSubPanels.get(step);
  }
  private void setStepVisible(WizardStep step, boolean visible)
  {
    JPanel subPanel = getSubPanel(step);
    // Check done to minimize possible flickering.
    if (visible != subPanel.isVisible())
    {
      subPanel.setVisible(visible);
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -1184,6 +1184,7 @@
    return buf.toString();
  }
  /**
   * Returns a table created with the provided model and renderers.
   * @param tableModel the table model.
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java
@@ -76,6 +76,14 @@
  /**
   * {@inheritDoc}
   */
  public boolean blockingBeginDisplay()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public void beginDisplay(UserData data) {
    super.beginDisplay(data);
    if (!loadBuildListAttempted) {
opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -78,6 +78,14 @@
  /**
   * {@inheritDoc}
   */
  public boolean blockingBeginDisplay()
  {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  protected String getTitle() {
    return getMsg("upgrade-review-panel-title");
  }
@@ -93,8 +101,6 @@
   * {@inheritDoc}
   */
  protected JPanel createFieldsPanel() {
    UpgradeUserData uud = (UpgradeUserData)getUserData();
    JPanel p = UIFactory.makeJPanel();
    LabelFieldDescriptor serverDescriptor = new LabelFieldDescriptor(
opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java
@@ -208,7 +208,7 @@
    String html = getHtml(text);
    String points = SPACE + getHtml(getMsg("progress-points")) + SPACE;
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    buf.append(UIFactory.applyFontToHtml(html, UIFactory.PROGRESS_FONT))
        .append(
            UIFactory.applyFontToHtml(points, UIFactory.PROGRESS_POINTS_FONT));
@@ -251,7 +251,7 @@
            UIFactory.PROGRESS_FONT);
    String closeDiv = "</div>";
    StringBuffer stackBuf = new StringBuffer();
    StringBuilder stackBuf = new StringBuilder();
    stackBuf.append(getHtmlStack(ex));
    Throwable root = ex.getCause();
    while (root != null)
@@ -263,7 +263,7 @@
    String stackText =
        UIFactory.applyFontToHtml(stackBuf.toString(), UIFactory.STACK_FONT);
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    String msg = ex.getMessage();
    if (msg != null)
@@ -361,7 +361,7 @@
   */
  private String getHtml(String text)
  {
    StringBuffer buffer = new StringBuffer();
    StringBuilder buffer = new StringBuilder();
    if (text != null) {
      text = text.replaceAll("\r\n", "\n");
      String[] lines = text.split("[\n\r\u0085\u2028\u2029]");
@@ -388,7 +388,7 @@
   */
  private String escape(String rawString)
  {
    StringBuffer buffer = new StringBuffer();
    StringBuilder buffer = new StringBuilder();
    for (int i = 0; i < rawString.length(); i++)
    {
      char c = rawString.charAt(i);
@@ -451,7 +451,7 @@
   */
  private String getHtmlStack(Throwable ex)
  {
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    StackTraceElement[] stack = ex.getStackTrace();
    for (int i = 0; i < stack.length; i++)
    {
@@ -500,7 +500,7 @@
  private String getErrorWithStackHtml(String openDiv, String hideText,
      String showText, String stackText, String closeDiv, boolean hide)
  {
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    String params =
        getUrlParams(openDiv, hideText, showText, stackText, closeDiv, hide);
@@ -539,7 +539,7 @@
  private String getUrlParams(String openDiv, String hideText,
      String showText, String stackText, String closeDiv, boolean hide)
  {
    StringBuffer buf = new StringBuffer();
    StringBuilder buf = new StringBuilder();
    buf.append(openDiv + PARAM_SEPARATOR);
    buf.append(hideText + PARAM_SEPARATOR);
    buf.append(showText + PARAM_SEPARATOR);
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -1170,6 +1170,7 @@
  }
  /**
   * Returns the max size in character of a line to be displayed in the command
   * line.
   * @return the max size in character of a line to be displayed in the command
opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
@@ -42,13 +42,13 @@
  public enum Type
  {
    /**
     * The base DN is not synchronized.
     * The base DN is not replicated.
     */
    NOT_SYNCHRONIZED,
    NOT_REPLICATED,
    /**
     * The base DN is synchronized.
     * The base DN is replicated.
     */
    SYNCHRONIZED
    REPLICATED
  };
  private int missingChanges;
@@ -59,8 +59,8 @@
  /**
   * Constructor for this class.
   * @param type the type of synchronization.
   * @param baseDn the base DN associated with the Synchronization.
   * @param type the type of replication.
   * @param baseDn the base DN associated with the Replication.
   * @param db the database containing this base DN.
   * @param ageOfOldestMissingChange the number of missing changes.
   * @param missingChanges the number of missing changes.
@@ -118,9 +118,9 @@
  }
  /**
   * Returns the number of missing changes in the synchronization topology for
   * Returns the number of missing changes in the replication topology for
   * this base DN.
   * @return the number of missing changes in the synchronization topology for
   * @return the number of missing changes in the replication topology for
   * this base DN.
   */
  public int getMissingChanges()
@@ -130,9 +130,9 @@
  /**
   * Returns the age of the oldest missing change in seconds in the
   * synchronization topology for this base DN.
   * replication topology for this base DN.
   * @return the age of the oldest missing change in seconds in the
   * synchronization topology for this base DN.
   * replication topology for this base DN.
   */
  public int getAgeOfOldestMissingChange()
  {
opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
@@ -39,6 +39,7 @@
import org.opends.server.util.LDIFReader;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.ObjectClass;
@@ -65,9 +66,9 @@
    DirectoryServer.getObjectClass("ds-cfg-root-dn", true);
  private final ObjectClass syncProviderOc =
    DirectoryServer.getObjectClass("ds-cfg-synchronization-provider", true);
  private final ObjectClass syncConfigOc =
    DirectoryServer.getObjectClass("ds-cfg-synchronization-provider-config",
    true);
  private final ObjectClass replicationConfigOc =
    DirectoryServer.getObjectClass("ds-cfg-replication-domain-config", true);
  private DN replicationDomainDN;
  private HashSet<ListenerDescriptor> listeners =
    new HashSet<ListenerDescriptor>();
@@ -75,8 +76,8 @@
    new HashSet<DatabaseDescriptor>();
  private HashSet<String> administrativeUsers = new HashSet<String>();
  private String errorMessage;
  private boolean synchronizationConfigured = false;
  private HashSet<String> synchronizedSuffixes = new HashSet<String>();
  private boolean replicationConfigured = false;
  private HashSet<String> replicatedSuffixes = new HashSet<String>();
  /**
   * Default constructor.
@@ -97,8 +98,8 @@
    listeners.clear();
    databases.clear();
    administrativeUsers.clear();
    synchronizationConfigured = false;
    synchronizedSuffixes.clear();
    replicationConfigured = false;
    replicatedSuffixes.clear();
    try
    {
      Installation installation =
@@ -111,7 +112,7 @@
      {
        updateConfig(entry);
      }
      updateSynchronization();
      updateReplication();
    }
    catch (IOException ioe)
    {
@@ -263,9 +264,9 @@
   {
     updateConfigWithSyncProviderEntry(entry);
   }
   else if (entry.hasObjectClass(syncConfigOc))
   else if (entry.hasObjectClass(replicationConfigOc))
   {
     updateConfigWithSyncConfig(entry);
     updateConfigWithReplConfig(entry);
   }
  }
@@ -405,7 +406,7 @@
  }
  /**
   * Updates the synchronization configuration data we expose to the user with
   * Updates the replication configuration data we expose to the user with
   * the provided entry object.
   * @param entry the entry to analyze.
   */
@@ -414,24 +415,24 @@
    if ("true".equalsIgnoreCase(getFirstValue(entry,
        "ds-cfg-synchronization-provider-enabled")))
    {
      synchronizationConfigured = true;
      replicationConfigured = true;
    }
    else
    {
      synchronizationConfigured = false;
      replicationConfigured = false;
    }
  }
  /**
   * Updates the databases suffixes with the list of synchronized suffixes
   * Updates the databases suffixes with the list of replicated suffixes
   * found.
   */
  private void updateSynchronization()
  private void updateReplication()
  {
    if (synchronizationConfigured)
    if (replicationConfigured)
    {
      for (String suffixDn: synchronizedSuffixes)
      for (String suffixDn: replicatedSuffixes)
      {
        BaseDNDescriptor replica = null;
        for (DatabaseDescriptor db: databases)
@@ -452,20 +453,37 @@
        }
        if (replica != null)
        {
          replica.setType(BaseDNDescriptor.Type.SYNCHRONIZED);
          replica.setType(BaseDNDescriptor.Type.REPLICATED);
        }
      }
    }
  }
  /**
   * Updates the synchronization configuration data we expose to the user with
   * Updates the replication configuration data we expose to the user with
   * the provided entry object.
   * @param entry the entry to analyze.
   */
  private void updateConfigWithSyncConfig(Entry entry)
  private void updateConfigWithReplConfig(Entry entry)
  {
    synchronizedSuffixes.addAll(getValues(entry, "ds-cfg-synchronization-dn"));
    if (replicationDomainDN == null)
    {
      try
      {
        replicationDomainDN = DN.decode(
            "cn=domains,cn=Multimaster Synchronization,"+
            "cn=Synchronization Providers,cn=config");
      }
      catch (Throwable t)
      {
        // Bug
        throw new IllegalStateException("Bug: "+t, t);
      }
    }
    if (entry.getDN().isDescendantOf(replicationDomainDN))
    {
      replicatedSuffixes.addAll(getValues(entry, "ds-cfg-replication-dn"));
    }
  }
  /**
@@ -517,11 +535,11 @@
  }
  /**
   * Create a non synchronized base DN descriptor.
   * Create a non replicated base DN descriptor.
   */
  private BaseDNDescriptor getBaseDNDescriptor(Entry entry, String baseDn)
  {
    return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_SYNCHRONIZED,
    return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED,
        baseDn, null, -1, -1);
  }
}
opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
@@ -59,8 +59,8 @@
    new HashSet<DatabaseDescriptor>();
  private HashSet<String> administrativeUsers = new HashSet<String>();
  private String errorMessage;
  private boolean synchronizationConfigured = false;
  private HashSet<String> synchronizedSuffixes = new HashSet<String>();
  private boolean replicationConfigured = false;
  private HashSet<String> replicatedSuffixes = new HashSet<String>();
  private HashMap<String, Integer> hmMissingChanges =
    new HashMap<String, Integer>();
  private HashMap<String, Integer> hmAgeOfOldestMissingChanges =
@@ -157,8 +157,8 @@
    listeners.clear();
    databases.clear();
    administrativeUsers.clear();
    synchronizationConfigured = false;
    synchronizedSuffixes.clear();
    replicationConfigured = false;
    replicatedSuffixes.clear();
    hmMissingChanges.clear();
    hmAgeOfOldestMissingChanges.clear();
    javaVersion = null;
@@ -169,7 +169,7 @@
      InitialLdapContext ctx = getDirContext();
      updateAdministrativeUsers(ctx);
      updateListeners(ctx);
      updateSynchronization(ctx);
      updateReplication(ctx);
      updateDatabases(ctx);
      javaVersion = getJavaVersion(ctx);
      openConnections = getOpenConnections(ctx);
@@ -341,12 +341,12 @@
  }
  /**
   * Updates the synchronization configuration data we expose to the user with
   * Updates the replication configuration data we expose to the user with
   * the provided InitialLdapContext.
   * @param ctx the InitialLdapContext to use to update the configuration.
   * @throws NamingException if there was an error.
   */
  private void updateSynchronization(InitialLdapContext ctx)
  private void updateReplication(InitialLdapContext ctx)
  throws NamingException
  {
    SearchControls ctls = new SearchControls();
@@ -371,7 +371,7 @@
        if ("true".equalsIgnoreCase(getFirstValue(sr,
          "ds-cfg-synchronization-provider-enabled")))
        {
          synchronizationConfigured = true;
          replicationConfigured = true;
        }
      }
    }
@@ -383,9 +383,9 @@
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(
        new String[] {
            "ds-cfg-synchronization-dn"
            "ds-cfg-replication-dn"
        });
    filter = "(objectclass=ds-cfg-synchronization-provider-config)";
    filter = "(objectclass=ds-cfg-replication-domain-config)";
    jndiName = new LdapName(
      "cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config");
@@ -398,7 +398,7 @@
      {
        SearchResult sr = (SearchResult)syncProviders.next();
        synchronizedSuffixes.addAll(getValues(sr, "ds-cfg-synchronization-dn"));
        replicatedSuffixes.addAll(getValues(sr, "ds-cfg-replication-dn"));
      }
    }
    catch (NameNotFoundException nse)
@@ -415,7 +415,7 @@
    jndiName = new LdapName("cn=monitor");
    if (synchronizedSuffixes.size() > 0)
    if (replicatedSuffixes.size() > 0)
    {
      try
      {
@@ -427,7 +427,7 @@
          String dn = getFirstValue(sr, "base-dn");
          for (String baseDn: synchronizedSuffixes)
          for (String baseDn: replicatedSuffixes)
          {
            if (Utils.areDnsEqual(dn, baseDn))
@@ -632,8 +632,8 @@
  }
  /**
   * Create the base DN descriptor.  Assumes that the synchronizedSuffixes Set
   * and synchronizationConfigured have already been initialized.
   * Create the base DN descriptor.  Assumes that the replicatedSuffixes Set
   * and replicationConfigured have already been initialized.
   */
  private BaseDNDescriptor getBaseDNDescriptor(InitialLdapContext ctx,
      String baseDn)
@@ -645,9 +645,9 @@
    String mapSuffixDn = null;
    boolean replicated = false;
    if (synchronizationConfigured)
    if (replicationConfigured)
    {
      for (String suffixDn: synchronizedSuffixes)
      for (String suffixDn: replicatedSuffixes)
      {
        if (Utils.areDnsEqual(baseDn, suffixDn))
        {
@@ -659,7 +659,7 @@
    }
    if (replicated)
    {
      type = BaseDNDescriptor.Type.SYNCHRONIZED;
      type = BaseDNDescriptor.Type.REPLICATED;
      Integer missing = hmMissingChanges.get(mapSuffixDn);
      Integer age = hmAgeOfOldestMissingChanges.get(mapSuffixDn);
@@ -676,7 +676,7 @@
    }
    else
    {
      type = BaseDNDescriptor.Type.NOT_SYNCHRONIZED;
      type = BaseDNDescriptor.Type.NOT_REPLICATED;
    }
    return new BaseDNDescriptor(type, baseDn, null, ageOfOldestMissingChange,
opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
@@ -940,7 +940,7 @@
      labelWidth = Math.max(labelWidth, labels[i].length());
    }
    String synchronizedLabel = getMsg("suffix-synchronized-label", false);
    String replicatedLabel = getMsg("suffix-replicated-label", false);
    for (int i=0; i<tableModel.getRowCount(); i++)
    {
      if (i > 0)
@@ -1007,7 +1007,7 @@
        {
          // If the suffix is not replicated we do not have to display these
          // lines.
          if (!synchronizedLabel.equals(tableModel.getValueAt(i, 3)))
          if (!replicatedLabel.equals(tableModel.getValueAt(i, 3)))
          {
            doWrite = false;
          }
opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -86,7 +86,7 @@
backendid-column=Backend ID
basedn-column=Base DN
number-entries-column=Entries
synchronized-column=Synchronization
replicated-column=Replication
missing-changes-column=Missing Changes
age-of-oldest-missing-change-column=<html>Age of Oldest<br>Missing \
Change (hh:mm:ss)
@@ -110,8 +110,8 @@
re-authenticating.\nDetails: {0}
no-dbs-found=-No LDAP Databases Found-
no-listeners-found=-No Listener Ports Found-
suffix-synchronized-label=Enabled
suffix-not-synchronized-label=Disabled
suffix-replicated-label=Enabled
suffix-not-replicated-label=Disabled
#
# Progress Dialog
opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java
@@ -55,7 +55,7 @@
    getMsg("basedn-column"),
    getMsg("backendid-column"),
    getMsg("number-entries-column"),
    getMsg("synchronized-column"),
    getMsg("replicated-column"),
    getMsg("missing-changes-column"),
    getMsg("age-of-oldest-missing-change-column")
  };
@@ -123,7 +123,7 @@
      if (result == 0)
      {
        result = compareSync(desc1, desc2);
        result = compareRepl(desc1, desc2);
      }
      if (result == 0)
@@ -153,7 +153,7 @@
      if (result == 0)
      {
        result = compareSync(desc1, desc2);
        result = compareRepl(desc1, desc2);
      }
      if (result == 0)
@@ -182,7 +182,7 @@
      if (result == 0)
      {
        result = compareSync(desc1, desc2);
        result = compareRepl(desc1, desc2);
      }
      if (result == 0)
@@ -197,7 +197,7 @@
    }
    else if (sortColumn == 3)
    {
      result = compareSync(desc1, desc2);
      result = compareRepl(desc1, desc2);
      if (result == 0)
      {
@@ -245,7 +245,7 @@
      if (result == 0)
      {
        result = compareSync(desc1, desc2);
        result = compareRepl(desc1, desc2);
      }
      if (result == 0)
@@ -274,7 +274,7 @@
      if (result == 0)
      {
        result = compareSync(desc1, desc2);
        result = compareRepl(desc1, desc2);
      }
      if (result == 0)
@@ -328,7 +328,7 @@
    }
    else if (col == 3)
    {
      v = getStringForSyncState(desc);
      v = getStringForReplState(desc);
    }
    else if (col == 4)
    {
@@ -423,7 +423,7 @@
    return desc1.getDn().compareTo(desc2.getDn());
  }
  private int compareSync(BaseDNDescriptor desc1, BaseDNDescriptor desc2)
  private int compareRepl(BaseDNDescriptor desc1, BaseDNDescriptor desc2)
  {
    return (String.valueOf(desc1.getType()).compareTo(
        String.valueOf(desc2.getType())));
@@ -473,7 +473,7 @@
  /**
   * Returns the Object describing the number of missing changes of a given Base
   * DN.  The Object will be a String unless the base DN is
   * synchronized and we could not find a valid value (in this case we return
   * replicated and we could not find a valid value (in this case we return
   * an Integer with the invalid value).
   * @param rep the Base DN object to handle.
   * @return the Object describing the number of missing changes of
@@ -482,7 +482,7 @@
  private Object getValueForMissingChanges(BaseDNDescriptor rep)
  {
    Object v;
    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
    {
      v = new Integer(rep.getMissingChanges());
    }
@@ -496,7 +496,7 @@
  /**
   * Returns the Object describing the age of oldest missing change of
   * a given Base DN.  The Object will be a String unless the base DN is
   * synchronized and we could not find a valid value (in this case we return
   * replicated and we could not find a valid value (in this case we return
   * an Integer with the invalid value).
   * @param rep the Base DN object to handle.
   * @return the Object describing the age of oldest missing change of
@@ -505,7 +505,7 @@
  private Object getValueForOldestMissingChange(BaseDNDescriptor rep)
  {
    Object v;
    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
    {
      int age = rep.getAgeOfOldestMissingChange();
      if (age >= 0)
@@ -538,22 +538,22 @@
  }
  /**
   * Returns the localized String describing the synchronization state of
   * Returns the localized String describing the replication state of
   * a given Base DN.
   * @param rep the Base DN object to handle.
   * @return the localized String describing the synchronization state of
   * @return the localized String describing the replication state of
   * a given Base DN.
   */
  private String getStringForSyncState(BaseDNDescriptor rep)
  private String getStringForReplState(BaseDNDescriptor rep)
  {
    String s;
    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
    {
      s = getMsg("suffix-synchronized-label");
      s = getMsg("suffix-replicated-label");
    }
    else
    {
      s = getMsg("suffix-not-synchronized-label");
      s = getMsg("suffix-not-replicated-label");
    }
    return s;
  }