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

kenneth_suter
28.39.2007 72a49cdc969eed0d2a46c6ec37390a351e360015
This commit address issue 1674 <https://opends.dev.java.net/issues/show_bug.cgi?id=1674> to make the webstart and offline installers cancelable.  The plumbing for cancelability is already in place since the upgrader makes use of it.  This commit for the most part implements the actions that the installers must perform when the operation is canceled.

Note that I have not implemented steps necessary to unregister a server from replication but have left this as 'todo' for the time being.

For the Web Start installer:
- Stop the server if running.
- If the install has registered this application as a windows service unregister it.
- Delete the files that have been installed.

For the offline installer there are more steps since we can't just wipe out all the files:

- Stop the server if running.
- If the install has registered this application as a windows service unregister it.
- Revert the configuration to the base configuration.
- If SSL was configured delete the self-signed cert (if necessary), delete keystore, keystore.pin and truststore.
- Delete the database files.
9 files modified
428 ■■■■■ changed files
opends/src/quicksetup/org/opends/quicksetup/Application.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java 17 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 106 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java 13 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java 123 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java 71 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 14 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ProgressPanel.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java 78 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -169,7 +169,7 @@
   * Sets the application's installation.
   * @param installation describing the application's OpenDS installation
   */
  protected void setInstallation(Installation installation) {
  public void setInstallation(Installation installation) {
    this.installation = installation;
  }
opends/src/quicksetup/org/opends/quicksetup/installer/InstallProgressStep.java
@@ -102,11 +102,27 @@
  ENABLING_WINDOWS_SERVICE,
  /**
   * User is waiting for current task to finish
   * so that the operation can be canceled.
   */
  WAITING_TO_CANCEL,
  /**
   * Canceling install.
   */
  CANCELING,
  /**
   * Installation finished successfully.
   */
  FINISHED_SUCCESSFULLY,
  /**
   * User canceled installation.
   */
  FINISHED_CANCELED,
  /**
   * Installation finished with an error.
   */
  FINISHED_WITH_ERROR;
@@ -116,6 +132,7 @@
   */
  public boolean isLast() {
    return this == FINISHED_SUCCESSFULLY ||
            this == FINISHED_CANCELED ||
    this == FINISHED_WITH_ERROR;
  }
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -100,9 +100,12 @@
public abstract class Installer extends GuiApplication {
  private TopologyCache lastLoadedCache;
  /* Indicates that we've detected that there is something installed */
  /** Indicates that we've detected that there is something installed. */
  boolean forceToDisplaySetup = false;
  /** When true indicates that the user has canceled this operation. */
  protected boolean canceled = false;
  // Constants used to do checks
  private static final int MIN_DIRECTORY_MANAGER_PWD = 1;
@@ -122,6 +125,10 @@
  private static final int MAX_NUMBER_ENTRIES = 10000;
  /** Set of progress steps that have been completed. */
  protected Set<InstallProgressStep>
          completedProgress = new HashSet<InstallProgressStep>();
  private List<WizardStep> lstSteps = new ArrayList<WizardStep>();
  private final HashSet<WizardStep> SUBSTEPS = new HashSet<WizardStep>();
@@ -137,12 +144,17 @@
  private HashMap<WizardStep, WizardStep> hmPreviousSteps =
    new HashMap<WizardStep, WizardStep>();
  private char[] selfSignedCertPw = null;
  /**
   * An static String that contains the class name of ConfigFileHandler.
   */
  protected static final String CONFIG_CLASS_NAME =
      "org.opends.server.extensions.ConfigFileHandler";
  /** Alias of a self-signed certificate. */
  protected static final String SELF_SIGNED_CERT_ALIAS = "server-cert";
  /**
   * Creates a default instance.
   */
@@ -175,7 +187,7 @@
   * {@inheritDoc}
   */
  public boolean isCancellable() {
    return false; // TODO: have installer delete installed files upon cancel
    return true;
  }
  /**
@@ -338,6 +350,7 @@
  public boolean isFinished()
  {
    return getCurrentProgressStep() == InstallProgressStep.FINISHED_SUCCESSFULLY
            || getCurrentProgressStep() == InstallProgressStep.FINISHED_CANCELED
        || getCurrentProgressStep() == InstallProgressStep.FINISHED_WITH_ERROR;
  }
@@ -345,7 +358,9 @@
   * {@inheritDoc}
   */
  public void cancel() {
    // do nothing; not cancellable
    setStatus(InstallProgressStep.WAITING_TO_CANCEL);
    notifyListeners(null);
    this.canceled = true;
  }
  /**
@@ -644,6 +659,26 @@
  }
  /**
   * Uninstalls installed services.  This is to be used when the user
   * has elected to cancel an installation.
   */
  protected void uninstallServices() {
    if (completedProgress.contains(
            InstallProgressStep.ENABLING_WINDOWS_SERVICE)) {
      try {
        new InstallerHelper().disableWindowsService();
      } catch (ApplicationException ae) {
        LOG.log(Level.INFO, "Error disabling Windows service", ae);
      }
    }
    if (completedProgress.contains(
            InstallProgressStep.CONFIGURING_REPLICATION)) {
      // TODO:  undo replication
    }
  }
  /**
   * Creates a template file based in the contents of the UserData object.
   * This template file is used to generate automatically data.  To generate
   * the template file the code will basically take into account the value of
@@ -815,17 +850,17 @@
            getSelfSignedKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            pwd);
        certManager.generateSelfSignedCertificate("server-cert",
        certManager.generateSelfSignedCertificate(SELF_SIGNED_CERT_ALIAS,
            getSelfSignedCertificateSubjectDN(),
            getSelfSignedCertificateValidity());
        exportCertificate(certManager, "server-cert",
        exportCertificate(certManager, SELF_SIGNED_CERT_ALIAS,
            getTemporaryCertificatePath());
        trustManager = new CertificateManager(
            getTrustManagerPath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            pwd);
        trustManager.addCertificate("server-cert",
        trustManager.addCertificate(SELF_SIGNED_CERT_ALIAS,
            new File(getTemporaryCertificatePath()));
        Utils.createFile(getKeystorePinPath(), pwd);
        f = new File(getTemporaryCertificatePath());
@@ -1034,16 +1069,18 @@
      if (result != 0)
      {
        String[] msgArgs = { Utils.stringArrayToString(args, " ") };
        throw new ApplicationException(
            ApplicationException.Type.CONFIGURATION_ERROR,
            getMsg("error-import-automatically-generated", msgArgs), null);
            getMsg("error-import-ldif-tool-return-code",
                    Integer.toString(result)), null);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationException.Type.CONFIGURATION_ERROR,
          getThrowableMsg("error-import-automatically-generated", null, t), t);
          getThrowableMsg("error-import-automatically-generated",
                  new String[] { Utils.listToString(argList, " "),
                          t.getLocalizedMessage()}, t), t);
    }
  }
@@ -1278,6 +1315,10 @@
        getFormattedSummary(getMsg("summary-initialize-replicated-suffixes")));
    hmSummary.put(InstallProgressStep.ENABLING_WINDOWS_SERVICE,
        getFormattedSummary(getMsg("summary-enabling-windows-service")));
    hmSummary.put(InstallProgressStep.WAITING_TO_CANCEL,
        getFormattedSummary(getMsg("summary-waiting-to-cancel")));
    hmSummary.put(InstallProgressStep.CANCELING,
        getFormattedSummary(getMsg("summary-canceling")));
    Installation installation = getInstallation();
    String cmd = Utils.getPath(installation.getStatusPanelCommandFile());
@@ -1286,11 +1327,32 @@
    hmSummary.put(InstallProgressStep.FINISHED_SUCCESSFULLY,
        getFormattedSuccess(
            getMsg("summary-install-finished-successfully", args)));
    hmSummary.put(InstallProgressStep.FINISHED_CANCELED,
        getFormattedSuccess(
            getMsg("summary-install-finished-canceled", args)));
    hmSummary.put(InstallProgressStep.FINISHED_WITH_ERROR,
        getFormattedError(getMsg("summary-install-finished-with-error", args)));
  }
  /**
   * Checks the value of <code>canceled</code> field and throws an
   * ApplicationException if true.  This indicates that the user has
   * canceled this operation and the process of aborting should begin
   * as soon as possible.
   *
   * @throws ApplicationException thrown if <code>canceled</code>
   */
  protected void checkAbort() throws ApplicationException {
    if (canceled) {
      setStatus(InstallProgressStep.CANCELING);
      notifyListeners(null);
      throw new ApplicationException(
            ApplicationException.Type.CANCEL,
            getMsg("upgrade-canceled"), null);
    }
  }
  /**
   * Writes the java home that we are using for the setup in a file.
   * This way we can use this java home even if the user has not set JAVA_HOME
   * when running the different scripts.
@@ -1365,6 +1427,9 @@
   */
  protected void setStatus(InstallProgressStep status)
  {
    if (status != null) {
      this.completedProgress.add(status);
    }
    this.status = status;
  }
@@ -3339,7 +3404,7 @@
   * @return the keystore path to be used for generating a self-signed
   * certificate.
   */
  private String getSelfSignedKeystorePath()
  protected String getSelfSignedKeystorePath()
  {
    String parentFile = Utils.getPath(getInstallationPath(),
        Installation.CONFIG_PATH_RELATIVE);
@@ -3405,13 +3470,26 @@
  }
  /**
   * Returns the self-signed certificate password used for this session.  This
   * method calls <code>createSelfSignedCertificatePwd()</code> the first time
   * this method is called.
   * @return the self-signed certificate password used for this session.
   */
  protected String getSelfSignedCertificatePwd()
  {
    if (selfSignedCertPw == null) {
      selfSignedCertPw = createSelfSignedCertificatePwd();
    }
    return new String(selfSignedCertPw);
  }
  /**
   * Returns a randomly generated password for the self-signed certificate
   * keystore.
   * @return a randomly generated password for the self-signed certificate
   * keystore.
   */
  private String getSelfSignedCertificatePwd()
  {
  private char[] createSelfSignedCertificatePwd() {
    int pwdLength = 50;
    char[] pwd = new char[pwdLength];
    Random random = new Random();
@@ -3420,9 +3498,7 @@
        char nextChar = getRandomChar(random,type);
        pwd[pos] = nextChar;
    }
    String pwdString = new String(pwd);
    return pwdString;
    return pwd;
  }
  private void exportCertificate(CertificateManager certManager, String alias,
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -145,6 +145,19 @@
    }
  }
  /**
   * This method disables this server as a Windows service.
   * @throws ApplicationException if something goes worong.
   */
  public void disableWindowsService() throws ApplicationException
  {
    int code = ConfigureWindowsService.disableService(System.out, System.err);
    if (code == ConfigureWindowsService.SERVICE_DISABLE_ERROR) {
      throw new ApplicationException(
              ApplicationException.Type.WINDOWS_SERVICE_ERROR,
              getMsg("error-disabling-windows-service"), null);
    }
  }
  private String getThrowableMsg(String key, Throwable t)
  {
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -28,17 +28,23 @@
package org.opends.quicksetup.installer.offline;
import java.io.PrintStream;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.security.KeyStoreException;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ProgressStep;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.installer.Installer;
import org.opends.quicksetup.installer.InstallProgressStep;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.FileManager;
import org.opends.server.util.CertificateManager;
/**
 * This is an implementation of the Installer class that is used to install
@@ -83,11 +89,17 @@
      System.setErr(err);
      System.setOut(out);
      checkAbort();
      setStatus(InstallProgressStep.CONFIGURING_SERVER);
      configureServer();
      checkAbort();
      createData();
      checkAbort();
      writeJavaHome();
      if (Utils.isWindows() && getUserData().getEnableWindowsService())
@@ -95,6 +107,7 @@
          notifyListeners(getTaskSeparator());
          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
          enableWindowsService();
          checkAbort();
      }
      if (mustStart())
@@ -102,6 +115,7 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.STARTING_SERVER);
        new ServerController(this).startServer();
        checkAbort();
      }
      if (mustConfigureReplication())
@@ -110,6 +124,7 @@
        notifyListeners(getTaskSeparator());
        configureReplication();
        checkAbort();
      }
      if (mustInitializeSuffixes())
@@ -117,6 +132,7 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
        initializeSuffixes();
        checkAbort();
      }
      if (mustCreateAds())
@@ -124,6 +140,7 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.CONFIGURING_ADS);
        updateADS();
        checkAbort();
      }
      if (mustStop())
@@ -133,17 +150,24 @@
        new ServerController(this).stopServer();
      }
      checkAbort();
      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
      notifyListeners(null);
    } catch (ApplicationException ex)
    {
      notifyListeners(getLineBreak());
      notifyListenersOfLog();
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      String html = getFormattedError(ex, true);
      notifyListeners(html);
      LOG.log(Level.SEVERE, "Error installing.", ex);
      if (ApplicationException.Type.CANCEL.equals(ex.getType())) {
        uninstall();
        setStatus(InstallProgressStep.FINISHED_CANCELED);
        notifyListeners(null);
      } else {
        notifyListeners(getLineBreak());
        notifyListenersOfLog();
        setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
        String html = getFormattedError(ex, true);
        notifyListeners(html);
        LOG.log(Level.SEVERE, "Error installing.", ex);
      }
    }
    catch (Throwable t)
    {
@@ -177,6 +201,92 @@
  }
  /**
   * Called when the user elects to cancel this operation.
   */
  protected void uninstall() {
    Installation installation = getInstallation();
    FileManager fm = new FileManager(this);
    // Stop the server if necessary
    if (installation.getStatus().isServerRunning()) {
      try {
        new ServerController(installation).stopServer(true);
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error stopping server", e);
      }
    }
    uninstallServices();
    // Revert to the base configuration
    try {
      File newConfig = fm.copy(installation.getBaseConfigurationFile(),
                               installation.getConfigurationDirectory(),
                               /*overwrite=*/true);
      fm.rename(newConfig, installation.getCurrentConfigurationFile());
    } catch (ApplicationException ae) {
      LOG.log(Level.INFO, "failed to restore base configuration", ae);
    }
    // Cleanup SSL if necessary
    SecurityOptions sec = getUserData().getSecurityOptions();
    if (sec.getEnableSSL() || sec.getEnableStartTLS()) {
      if (SecurityOptions.CertificateType.SELF_SIGNED_CERTIFICATE.equals(
              sec.getCertificateType())) {
        CertificateManager cm = new CertificateManager(
            getSelfSignedKeystorePath(),
            CertificateManager.KEY_STORE_TYPE_JKS,
            getSelfSignedCertificatePwd());
        try {
          cm.removeCertificate(SELF_SIGNED_CERT_ALIAS);
        } catch (KeyStoreException e) {
          LOG.log(Level.INFO, "Error deleting self signed certification", e);
        }
      }
      File keystore = new File(installation.getConfigurationDirectory(),
              "keystore");
      if (keystore.exists()) {
        try {
          fm.delete(keystore);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to delete keystore", e);
        }
      }
      File keystorePin = new File(installation.getConfigurationDirectory(),
              "keystore.pin");
      if (keystorePin.exists()) {
        try {
          fm.delete(keystorePin);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to delete keystore.pin", e);
        }
      }
      File truststore = new File(installation.getConfigurationDirectory(),
              "truststore");
      if (truststore.exists()) {
        try {
          fm.delete(truststore);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to delete truststore", e);
        }
      }
    }
    // Remove the databases
    try {
      fm.deleteChildren(installation.getDatabasesDirectory());
    } catch (ApplicationException e) {
      LOG.log(Level.INFO, "Error deleting databases", e);
    }
  }
  /**
   * Initialize the different map used in this class.
   *
   */
@@ -277,6 +387,7 @@
    }
    hmRatio.put(InstallProgressStep.FINISHED_SUCCESSFULLY, 100);
    hmRatio.put(InstallProgressStep.FINISHED_WITH_ERROR, 100);
    hmRatio.put(InstallProgressStep.FINISHED_CANCELED, 100);
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -45,6 +45,7 @@
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ZipExtractor;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.FileManager;
/**
 * This is an implementation of the Installer class that is used to install
@@ -109,12 +110,16 @@
      setStatus(InstallProgressStep.DOWNLOADING);
      checkAbort();
      InputStream in =
          getZipInputStream(getRatio(InstallProgressStep.EXTRACTING));
      setStatus(InstallProgressStep.EXTRACTING);
      notifyListeners(getTaskSeparator());
      checkAbort();
      createParentDirectoryIfRequired();
      extractZipFiles(in, getRatio(InstallProgressStep.EXTRACTING),
          getRatio(InstallProgressStep.CONFIGURING_SERVER));
@@ -127,6 +132,9 @@
      {
        LOG.log(Level.INFO, "Error closing zip input stream: "+t, t);
      }
      checkAbort();
      setStatus(InstallProgressStep.CONFIGURING_SERVER);
      notifyListeners(getTaskSeparator());
@@ -135,15 +143,24 @@
      writeJavaHome();
      setInstallation(new Installation(getUserData().getServerLocation()));
      checkAbort();
      setStatus(InstallProgressStep.CONFIGURING_SERVER);
      configureServer();
      checkAbort();
      createData();
      checkAbort();
      if (Utils.isWindows() && getUserData().getEnableWindowsService())
      {
          notifyListeners(getTaskSeparator());
          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
          enableWindowsService();
          checkAbort();
      }
      if (mustStart())
@@ -151,6 +168,8 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.STARTING_SERVER);
        new ServerController(this).startServer();
        checkAbort();
      }
      if (mustConfigureReplication())
@@ -159,6 +178,8 @@
        notifyListeners(getTaskSeparator());
        configureReplication();
        checkAbort();
      }
      if (mustInitializeSuffixes())
@@ -166,6 +187,8 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.INITIALIZE_REPLICATED_SUFFIXES);
        initializeSuffixes();
        checkAbort();
      }
      if (mustCreateAds())
@@ -173,6 +196,8 @@
        notifyListeners(getTaskSeparator());
        setStatus(InstallProgressStep.CONFIGURING_ADS);
        updateADS();
        checkAbort();
      }
      if (mustStop())
@@ -182,17 +207,24 @@
        new ServerController(this).stopServer();
      }
      checkAbort();
      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
      notifyListeners(null);
    } catch (ApplicationException ex)
    {
      notifyListeners(getLineBreak());
      notifyListenersOfLog();
      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
      String html = getFormattedError(ex, true);
      notifyListeners(html);
      LOG.log(Level.SEVERE, "Error installing.", ex);
      if (ApplicationException.Type.CANCEL.equals(ex.getType())) {
        uninstall();
        setStatus(InstallProgressStep.FINISHED_CANCELED);
        notifyListeners(null);
      } else {
        notifyListeners(getLineBreak());
        notifyListenersOfLog();
        setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
        String html = getFormattedError(ex, true);
        notifyListeners(html);
        LOG.log(Level.SEVERE, "Error installing.", ex);
      }
    }
    catch (Throwable t)
    {
@@ -338,6 +370,7 @@
    }
    hmRatio.put(InstallProgressStep.FINISHED_SUCCESSFULLY, 100);
    hmRatio.put(InstallProgressStep.FINISHED_CANCELED, 100);
    hmRatio.put(InstallProgressStep.FINISHED_WITH_ERROR, 100);
  }
@@ -462,6 +495,32 @@
  }
  /**
   * Uninstall what has already been installed.
   */
  private void uninstall() {
    Installation installation = getInstallation();
    FileManager fm = new FileManager(this);
    // Stop the server if necessary
    if (installation.getStatus().isServerRunning()) {
      try {
        new ServerController(installation).stopServer(true);
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error stopping server", e);
      }
    }
    uninstallServices();
    try {
      fm.deleteRecursively(installation.getRootDirectory(), null,
              FileManager.DeletionPolicy.DELETE_ON_EXIT_IF_UNSUCCESSFUL);
    } catch (ApplicationException e) {
      LOG.log(Level.INFO, "error deleting files", e);
    }
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstallationPath()
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -918,6 +918,8 @@
summary-configuring-replication=Configuring Replication...
summary-starting=Starting Directory Server...
summary-enabling-windows-service=Enabling Windows Service...
summary-waiting-to-cancel=Waiting to Cancel...
summary-canceling=Canceling...
summary-configuring-ads=Creating Registration Configuration...
summary-initialize-replicated-suffixes=Initializing Contents of Replicated \
Suffixes...
@@ -928,6 +930,9 @@
configuration.<br>To see basic server configuration status and to start/stop \
the server, click Launch Status Panel.  Note that you can launch this tool \
later using {1}.<br><INPUT type="submit" value="Launch Status Panel"></INPUT>
summary-install-finished-canceled=<b>OpenDS QuickSetup Canceled.</b> \
  <br>The upgrade operation was canceled and any files installed to your system \
  during this operation have been removed.
summary-install-finished-with-error=An error occurred.  Check 'Details' text \
area for more information.<br>To see basic server configuration status, click \
Launch Status Panel.  Note that you can launch this tool \
@@ -1022,6 +1027,7 @@
progress-creating-base-entry=Creating Base Entry {0}
progress-importing-ldif=Importing LDIF file {0}:
progress-configuring-replication=Configuring Replication
progress-cancel=Waiting to cancel operation.
progress-configuring-replication-remote=Configuring Replication on {0}
progress-import-automatically-generated=Importing Automatically-Generated Data \
@@ -1037,7 +1043,7 @@
progress-deleting-installation-files=Deleting Files under the Installation Path:
progress-deleting-file=Deleting file {0}
progress-deleting-directory=Deleting directory {0}
progress-deleting-file-does-not-exist=Ignoring file {0} since it does not exist.
progress-deleting-file-does-not-exist=Ignoring file {0} since it does not exist.
progress-copying-file=Copying file {0} to {1}
progress-server-already-stopped=The Directory Server is already stopped.
@@ -1080,8 +1086,8 @@
{0}\\bat\\windows-service.bat -d command-line to disable the service manually. 
error-creating-base-entry=Error Creating Base Entry.
error-importing-ldif=Error Importing LDIF File.
error-import-automatically-generated=Error Importing Automatically- Generated \
Data when invoked with arguments: {0}.
error-import-automatically-generated=Error Importing Automatically-Generated \
Data when invoked with arguments {0}:  {1}.
error-starting-server-with-no-connection-handlers=Error Starting Server with \
no connection handlers: {0}.
error-starting-server=Error Starting Directory Server.
@@ -1098,6 +1104,7 @@
exception-root-cause=Root Cause:
error-deleting-file=Error deleting file {0}.  Check that you have the rights \
to delete this file and that there is no other application using it.
error-renaming-file=Error renaming file {0} to {1}.
error-deleting-directory=Error deleting directory {0}.  Check that you have \
the rights to delete this directory and that there is no other application \
using it.
@@ -1155,6 +1162,7 @@
error-determining-server-state=Failed to determine the server's state.
error-backup-db-tool-return-code=The backup tool returned error code {0}.
error-ldif-diff-tool-return-code=The LDIF diff tool returned error code {0}.
error-import-ldif-tool-return-code=The import LDIF tool returned error code {0}.
error-apply-ldif-modify=Error processing modification operation of {0}: {1}
error-apply-ldif-add=Error processing add operation of {0}: {1}
error-apply-ldif-delete=Error processing delete operation of {0}: {1}
opends/src/quicksetup/org/opends/quicksetup/ui/ProgressPanel.java
@@ -202,8 +202,8 @@
    }
    progressBarLabel.setText(summaryText);
    int v = descriptor.getProgressBarRatio();
    if (v > 0)
    Integer v = descriptor.getProgressBarRatio();
    if (v != null && v > 0)
    {
      progressBar.setIndeterminate(false);
      progressBar.setValue(v);
opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
@@ -112,6 +112,44 @@
  }
  /**
   * Renames the source file to the target file.  If the target file exists
   * it is first deleted.  The rename and delete operation return values
   * are checked for success and if unsuccessful, this method throws an
   * exception.
   *
   * @param fileToRename The file to rename.
   * @param target       The file to which <code>fileToRename</code> will be
   *                     moved.
   * @throws ApplicationException If a problem occurs while attempting to rename
   *                     the file.  On the Windows platform, this typically
   *                     indicates that the file is in use by this or another
   *                     application.
   */
  public void rename(File fileToRename, File target)
          throws ApplicationException {
    if (fileToRename != null && target != null) {
      synchronized (target) {
        if (target.exists()) {
          if (!target.delete()) {
            throw new ApplicationException(
                    ApplicationException.Type.FILE_SYSTEM_ERROR,
                    getMsg("error-deleting-file",
                            Utils.getPath(target)), null);
          }
        }
      }
      if (!fileToRename.renameTo(target)) {
        throw new ApplicationException(
                ApplicationException.Type.FILE_SYSTEM_ERROR,
                getMsg("error-renaming-file",
                        Utils.getPath(fileToRename),
                        Utils.getPath(target)), null);
      }
    }
  }
  /**
   * Move a file.
   * @param object File to move
   * @param newParent File representing new parent directory
@@ -167,6 +205,23 @@
  }
  /**
   * Deletes the children of a directory.
   *
   * @param parentDir the directory whose children is deleted
   * @throws ApplicationException if there is a problem deleting children
   */
  public void deleteChildren(File parentDir) throws ApplicationException {
    if (parentDir != null && parentDir.exists() && parentDir.isDirectory()) {
      File[] children = parentDir.listFiles();
      if (children != null) {
        for (File child : children) {
          delete(child);
        }
      }
    }
  }
  /**
   * Deletes everything below the specified file.
   *
   * @param file the path to be deleted.
@@ -198,12 +253,15 @@
   *
   * @param objectFile   the file to be copied.
   * @param destDir      the directory to copy the file to
   * @return File representing the destination
   * @throws ApplicationException if something goes wrong.
   */
  public void copy(File objectFile, File destDir)
  public File copy(File objectFile, File destDir)
          throws ApplicationException
  {
    new CopyOperation(objectFile, destDir, false).apply();
    CopyOperation co = new CopyOperation(objectFile, destDir, false);
    co.apply();
    return co.getDestination();
  }
  /**
@@ -211,13 +269,16 @@
   *
   * @param objectFile   the file to be copied.
   * @param destDir      the directory to copy the file to
   * @return File representing the destination
   * @param overwrite    overwrite destination files.
   * @throws ApplicationException if something goes wrong.
   */
  public void copy(File objectFile, File destDir, boolean overwrite)
  public File copy(File objectFile, File destDir, boolean overwrite)
          throws ApplicationException
  {
    new CopyOperation(objectFile, destDir, overwrite).apply();
    CopyOperation co = new CopyOperation(objectFile, destDir, overwrite);
    co.apply();
    return co.getDestination();
  }
  /**
@@ -372,6 +433,15 @@
    }
    /**
     * Returns the destination file that is the result of copying
     * <code>objectFile</code> to <code>destDir</code>.
     * @return
     */
    public File getDestination() {
      return this.destination;
    }
    /**
     * {@inheritDoc}
     */
    public void apply() throws ApplicationException {