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

kenneth_suter
12.17.2007 f54aeb79b0f90d550c8cdcac5bfc22d4fc4579ce
- The upgrader now contains a small companion program BuildExtractor that is run prior to Upgrader that extacts the user specified build file.  This is done to allow upgrader to run from the new builds bits as opposed to the current build's bits.

- Improved error notification
2 files added
14 files modified
1273 ■■■■■ changed files
opends/resource/upgrade 19 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Application.java 340 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/GuiApplication.java 333 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Installation.java 105 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java 3 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/ButtonsPanel.java 6 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java 8 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java 177 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java 198 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java 19 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java 51 ●●●● patch | view | raw | blame | history
opends/resource/upgrade
@@ -82,7 +82,11 @@
# Configure the appropriate CLASSPATH to test.
CLASSPATH=${INSTANCE_ROOT}/classes
for JAR in ${INSTANCE_ROOT}/tmp/upgrade/lib/*.jar
do
  CLASSPATH=${CLASSPATH}:${JAR}
done
CLASSPATH=${CLASSPATH}:${INSTANCE_ROOT}/classes
for JAR in ${INSTANCE_ROOT}/lib/*.jar
do
  CLASSPATH=${CLASSPATH}:${JAR}
@@ -115,6 +119,15 @@
  fi
fi
if [ -r "./tmp/upgrade" ]
then
  rm -fr "./tmp/upgrade"
fi
# Launch the build extractor.
"${JAVA_BIN}" org.opends.quicksetup.upgrader.BuildExtractor "${@}"
# Launch the uninstall process.
"${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
if test ${?} -eq 0
then
  # Launch the upgrade process.
  "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
fi
opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -30,54 +30,60 @@
import org.opends.quicksetup.event.ProgressNotifier;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.ui.QuickSetupDialog;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import org.opends.quicksetup.ui.FramePanel;
import javax.swing.*;
import java.io.*;
import java.util.*;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.event.WindowEvent;
import java.util.HashSet;
/**
 * This class represents an application that can be run in the context
 * of QuickSetup.  Examples of applications might be 'installer',
 * 'uninstaller' and 'upgrader'.
 * This class represents an application that can be run in the context of
 * QuickSetup.  Examples of applications might be 'installer', 'uninstaller'
 * and 'upgrader'.
 */
public abstract class Application implements ProgressNotifier, Runnable {
  static private final Logger LOG =
          Logger.getLogger(Application.class.getName());
  /** The currently displayed wizard step. */
  private WizardStep displayedStep;
  /** Represents current install state. */
  protected CurrentInstallStatus installStatus;
  private HashSet<ProgressUpdateListener> listeners =
      new HashSet<ProgressUpdateListener>();
  private UserData userData;
  private Installation installation;
  private ServerController serverController;
  /** Formats progress messages. */
  protected ProgressMessageFormatter formatter;
  /**
   * Creates an application by instantiating the Application class
   * denoted by the System property
   * <code>org.opends.quicksetup.Application.class</code>.
   * @return Application object that was newly instantiated
   * @throws ApplicationException if there was a problem creating
   *         the new Application object
   * @throws org.opends.quicksetup.ApplicationException if there was a problem
   *  creating the new Application object
   */
  static public Application create()
  static public GuiApplication create()
          throws ApplicationException {
    Application app;
    GuiApplication app;
    String appClassName =
            System.getProperty("org.opends.quicksetup.Application.class");
    if (appClassName != null) {
      Class appClass = null;
      try {
        appClass = Class.forName(appClassName);
        app = (Application) appClass.newInstance();
        app = (GuiApplication) appClass.newInstance();
      } catch (ClassNotFoundException e) {
        LOG.log(Level.INFO, "error creating quicksetup application", e);
        String msg = "Application class " + appClass + " not found";
@@ -104,33 +110,6 @@
    return app;
  }
  private HashSet<ProgressUpdateListener> listeners =
      new HashSet<ProgressUpdateListener>();
  private UserData userData;
  private Installation installation;
  private ServerController serverController;
  /** Formats progress messages. */
  protected ProgressMessageFormatter formatter;
  /**
   * Constructs an instance of an application.  Subclasses
   * of this application must have a default constructor.
   */
  public Application() {
    this.displayedStep = getFirstWizardStep();
  }
  /**
   * Gets the frame title of the GUI application that will be used
   * in some operating systems.
   * @return internationalized String representing the frame title
   */
  abstract public String getFrameTitle();
  /**
   * Sets this instances user data.
   * @param userData UserData this application will use
@@ -168,16 +147,6 @@
  }
  /**
   * Returns whether the installer has finished or not.
   * @return <CODE>true</CODE> if the install is finished or <CODE>false
   * </CODE> if not.
   */
  public boolean isFinished()
  {
    return getCurrentProgressStep().isLast();
  }
  /**
   * Gets the OpenDS installation associated with the execution of this
   * command.
   * @return Installation object representing the current OpenDS installation
@@ -512,58 +481,12 @@
  }
  /**
   * Returns the initial wizard step.
   * @return Step representing the first step to show in the wizard
   */
  public abstract WizardStep getFirstWizardStep();
  /**
   * Called by the quicksetup controller when the user advances to
   * a new step in the wizard.  Applications are expected to manipulate
   * the QuickSetupDialog to reflect the current step.
   *
   * @param step     Step indicating the new current step
   * @param userData UserData representing the data specified by the user
   * @param dlg      QuickSetupDialog hosting the wizard
   */
  protected void setDisplayedWizardStep(WizardStep step,
                                        UserData userData,
                                        QuickSetupDialog dlg) {
    this.displayedStep = step;
    // First call the panels to do the required updates on their layout
    dlg.setDisplayedStep(step, userData);
    setWizardDialogState(dlg, userData, step);
  }
  /**
   * Called when the user advances to new step in the wizard.  Applications
   * are expected to manipulate the QuickSetupDialog to reflect the current
   * step.
   * @param dlg QuickSetupDialog hosting the wizard
   * @param userData UserData representing the data specified by the user
   * @param step Step indicating the new current step
   */
  protected abstract void setWizardDialogState(QuickSetupDialog dlg,
                                               UserData userData,
                                               WizardStep step);
  /**
   * Returns the installation path.
   * @return the installation path.
   */
  protected abstract String getInstallationPath();
  /**
   * Returns the tab formatted.
   * @return the tab formatted.
   */
  protected String getTab()
  {
    return formatter.getTab();
  }
  /**
   * Gets the current step.
   * @return ProgressStep representing the current step
   */
@@ -595,216 +518,6 @@
  }
  /**
   * Called by the controller when the window is closing.  The application
   * can take application specific actions here.
   * @param dlg QuickSetupDialog that will be closing
   * @param evt The event from the Window indicating closing
   */
  abstract public void windowClosing(QuickSetupDialog dlg, WindowEvent evt);
  /**
   * This method is called when we detected that there is something installed
   * we inform of this to the user and the user wants to proceed with the
   * installation destroying the contents of the data and the configuration
   * in the current installation.
   */
  public void forceToDisplay() {
    // This is really only appropriate for Installer.
    // The default implementation is to do nothing.
    // The Installer application overrides this with
    // whatever it needs.
  }
  /**
   * Get the name of the button that will receive initial focus.
   * @return ButtonName of the button to receive initial focus
   */
  abstract public ButtonName getInitialFocusButtonName();
  /**
   * Creates the main panel for the wizard dialog.
   * @param dlg QuickSetupDialog used
   * @return JPanel frame panel
   */
  public JPanel createFramePanel(QuickSetupDialog dlg) {
    return new FramePanel(dlg.getStepsPanel(),
            dlg.getCurrentStepPanel(),
            dlg.getButtonsPanel());
  }
  /**
   * Returns the set of wizard steps used in this application's wizard.
   * @return Set of Step objects representing wizard steps
   */
  abstract public Set<? extends WizardStep> getWizardSteps();
  /**
   * Creates a wizard panel given a specific step.
   * @param step for which a panel representation should be created
   * @return QuickSetupStepPanel for representing the <code>step</code>
   */
  abstract public QuickSetupStepPanel createWizardStepPanel(WizardStep step);
  /**
   * Gets the next step in the wizard given a current step.
   * @param step Step the current step
   * @return Step the next step
   */
  abstract public WizardStep getNextWizardStep(WizardStep step);
  /**
   * Gets the previous step in the wizard given a current step.
   * @param step Step the current step
   * @return Step the previous step
   */
  abstract public WizardStep getPreviousWizardStep(WizardStep step);
  /**
   * 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
   * or not the user can return to a previous step
   * @return boolean where true indicates the user can return to a previous
   * step from <code>step</code>
   */
  public boolean canGoBack(WizardStep step) {
    return !getFirstWizardStep().equals(step);
  }
  /**
   * Indicates whether or not the user is allowed to move to a new
   * step from <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can move to a new step
   * @return boolean where true indicates the user can move to a new
   * step from <code>step</code>
   */
  public boolean canGoForward(WizardStep step) {
    return getNextWizardStep(step) != null;
  }
  /**
   * Inidicates whether or not the user is allowed to finish the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can finish the wizard
   * @return boolean where true indicates the user can finish the wizard
   */
  public boolean canFinish(WizardStep step) {
    return getNextWizardStep(step) != null;
  }
  /**
   * Inidicates whether or not the user is allowed to quit the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can quit the wizard
   * @return boolean where true indicates the user can quit the wizard
   */
  public boolean canQuit(WizardStep step) {
    return false;
  }
  /**
   * Inidicates whether or not the user is allowed to close the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can close the wizard
   * @return boolean where true indicates the user can close the wizard
   */
  public boolean canClose(WizardStep step) {
    return false;
  }
  /**
   * Inidicates whether or not the user is allowed to cancel the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can cancel the wizard
   * @return boolean where true indicates the user can cancel the wizard
   */
  public boolean canCancel(WizardStep step) {
    return false;
  }
  /**
   * Called when the user has clicked the 'previous' button.
   * @param cStep WizardStep at which the user clicked the previous button
   * @param qs QuickSetup controller
   */
  public abstract void previousClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'finish' button.
   * @param cStep WizardStep at which the user clicked the previous button
   * @param qs QuickSetup controller
   */
  public abstract void finishClicked(final WizardStep cStep,
                                     final QuickSetup qs);
  /**
   * Called when the user has clicked the 'next' button.
   * @param cStep WizardStep at which the user clicked the next button
   * @param qs QuickSetup controller
   */
  public abstract void nextClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'close' button.
   * @param cStep WizardStep at which the user clicked the close button
   * @param qs QuickSetup controller
   */
  public abstract void closeClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'cancel' button.
   * @param cStep WizardStep at which the user clicked the cancel button
   * @param qs QuickSetup controller
   */
  public abstract void cancelClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'quit' button.
   * @param step WizardStep at which the user clicked the quit button
   * @param qs QuickSetup controller
   */
  abstract public void quitClicked(WizardStep step, QuickSetup qs);
  /**
   * Called whenever this application should update its user data from
   * values found in QuickSetup.
   * @param cStep current wizard step
   * @param qs QuickSetup controller
   * @throws UserDataException if there is a problem with the data
   */
  abstract protected void updateUserData(WizardStep cStep, QuickSetup qs)
          throws UserDataException;
  /**
   * Gets the key for the close button's tool tip text.
   * @return String key of the text in the resource bundle
   */
  public String getCloseButtonToolTip() {
    return "close-button-tooltip";
  }
  /**
   * Gets the key for the finish button's tool tip text.
   * @return String key of the text in the resource bundle
   */
  public String getFinishButtonToolTip() {
    return "finish-button-tooltip";
  }
  /**
   * Gets the key for the finish button's label.
   * @return String key of the text in the resource bundle
   */
  public String getFinishButtonLabel() {
    return "finish-button-label";
  }
  /**
   * This class is used to notify the ProgressUpdateListeners of events
   * that are written to the standard error.  It is used in WebStartInstaller
   * and in OfflineInstaller.  These classes just create a ErrorPrintStream and
@@ -921,5 +634,4 @@
      println(new String(b, off, len));
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/GuiApplication.java
New file
@@ -0,0 +1,333 @@
/*
 * 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;
import org.opends.quicksetup.ui.FramePanel;
import org.opends.quicksetup.ui.QuickSetupDialog;
import org.opends.quicksetup.ui.QuickSetupStepPanel;
import javax.swing.*;
import java.awt.event.WindowEvent;
import java.util.Set;
import java.util.logging.Logger;
/**
 * This class represents an application with a wizard GUI that can be run in the
 * context of QuickSetup.  Examples of applications might be 'installer',
 * 'uninstaller' and 'upgrader'.
 */
public abstract class GuiApplication extends Application {
  static private final Logger LOG =
          Logger.getLogger(GuiApplication.class.getName());
  /** The currently displayed wizard step. */
  private WizardStep displayedStep;
  /**
   * Constructs an instance of an application.  Subclasses
   * of this application must have a default constructor.
   */
  public GuiApplication() {
    this.displayedStep = getFirstWizardStep();
  }
  /**
   * Gets the frame title of the GUI application that will be used
   * in some operating systems.
   * @return internationalized String representing the frame title
   */
  abstract public String getFrameTitle();
  /**
   * Returns whether the installer has finished or not.
   * @return <CODE>true</CODE> if the install is finished or <CODE>false
   * </CODE> if not.
   */
  public boolean isFinished()
  {
    return getCurrentProgressStep().isLast();
  }
  /**
   * Returns the initial wizard step.
   * @return Step representing the first step to show in the wizard
   */
  public abstract WizardStep getFirstWizardStep();
  /**
   * Called by the quicksetup controller when the user advances to
   * a new step in the wizard.  Applications are expected to manipulate
   * the QuickSetupDialog to reflect the current step.
   *
   * @param step     Step indicating the new current step
   * @param userData UserData representing the data specified by the user
   * @param dlg      QuickSetupDialog hosting the wizard
   */
  protected void setDisplayedWizardStep(WizardStep step,
                                        UserData userData,
                                        QuickSetupDialog dlg) {
    this.displayedStep = step;
    // First call the panels to do the required updates on their layout
    dlg.setDisplayedStep(step, userData);
    setWizardDialogState(dlg, userData, step);
  }
  /**
   * Called when the user advances to new step in the wizard.  Applications
   * are expected to manipulate the QuickSetupDialog to reflect the current
   * step.
   * @param dlg QuickSetupDialog hosting the wizard
   * @param userData UserData representing the data specified by the user
   * @param step Step indicating the new current step
   */
  protected abstract void setWizardDialogState(QuickSetupDialog dlg,
                                               UserData userData,
                                               WizardStep step);
  /**
   * Returns the tab formatted.
   * @return the tab formatted.
   */
  protected String getTab()
  {
    return formatter.getTab();
  }
  /**
   * Called by the controller when the window is closing.  The application
   * can take application specific actions here.
   * @param dlg QuickSetupDialog that will be closing
   * @param evt The event from the Window indicating closing
   */
  abstract public void windowClosing(QuickSetupDialog dlg, WindowEvent evt);
  /**
   * This method is called when we detected that there is something installed
   * we inform of this to the user and the user wants to proceed with the
   * installation destroying the contents of the data and the configuration
   * in the current installation.
   */
  public void forceToDisplay() {
    // This is really only appropriate for Installer.
    // The default implementation is to do nothing.
    // The Installer application overrides this with
    // whatever it needs.
  }
  /**
   * Get the name of the button that will receive initial focus.
   * @return ButtonName of the button to receive initial focus
   */
  abstract public ButtonName getInitialFocusButtonName();
  /**
   * Creates the main panel for the wizard dialog.
   * @param dlg QuickSetupDialog used
   * @return JPanel frame panel
   */
  public JPanel createFramePanel(QuickSetupDialog dlg) {
    return new FramePanel(dlg.getStepsPanel(),
            dlg.getCurrentStepPanel(),
            dlg.getButtonsPanel());
  }
  /**
   * Returns the set of wizard steps used in this application's wizard.
   * @return Set of Step objects representing wizard steps
   */
  abstract public Set<? extends WizardStep> getWizardSteps();
  /**
   * Creates a wizard panel given a specific step.
   * @param step for which a panel representation should be created
   * @return QuickSetupStepPanel for representing the <code>step</code>
   */
  abstract public QuickSetupStepPanel createWizardStepPanel(WizardStep step);
  /**
   * Gets the next step in the wizard given a current step.
   * @param step Step the current step
   * @return Step the next step
   */
  abstract public WizardStep getNextWizardStep(WizardStep step);
  /**
   * Gets the previous step in the wizard given a current step.
   * @param step Step the current step
   * @return Step the previous step
   */
  abstract public WizardStep getPreviousWizardStep(WizardStep step);
  /**
   * 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
   * or not the user can return to a previous step
   * @return boolean where true indicates the user can return to a previous
   * step from <code>step</code>
   */
  public boolean canGoBack(WizardStep step) {
    return !getFirstWizardStep().equals(step);
  }
  /**
   * Indicates whether or not the user is allowed to move to a new
   * step from <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can move to a new step
   * @return boolean where true indicates the user can move to a new
   * step from <code>step</code>
   */
  public boolean canGoForward(WizardStep step) {
    return getNextWizardStep(step) != null;
  }
  /**
   * Inidicates whether or not the user is allowed to finish the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can finish the wizard
   * @return boolean where true indicates the user can finish the wizard
   */
  public boolean canFinish(WizardStep step) {
    return getNextWizardStep(step) != null;
  }
  /**
   * Inidicates whether or not the user is allowed to quit the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can quit the wizard
   * @return boolean where true indicates the user can quit the wizard
   */
  public boolean canQuit(WizardStep step) {
    return false;
  }
  /**
   * Inidicates whether or not the user is allowed to close the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can close the wizard
   * @return boolean where true indicates the user can close the wizard
   */
  public boolean canClose(WizardStep step) {
    return false;
  }
  /**
   * Inidicates whether or not the user is allowed to cancel the wizard from
   * <code>step</code>.
   * @param step WizardStep for which the the return value indicates whether
   * or not the user can cancel the wizard
   * @return boolean where true indicates the user can cancel the wizard
   */
  public boolean canCancel(WizardStep step) {
    return false;
  }
  /**
   * Called when the user has clicked the 'previous' button.
   * @param cStep WizardStep at which the user clicked the previous button
   * @param qs QuickSetup controller
   */
  public abstract void previousClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'finish' button.
   * @param cStep WizardStep at which the user clicked the previous button
   * @param qs QuickSetup controller
   */
  public abstract void finishClicked(final WizardStep cStep,
                                     final QuickSetup qs);
  /**
   * Called when the user has clicked the 'next' button.
   * @param cStep WizardStep at which the user clicked the next button
   * @param qs QuickSetup controller
   */
  public abstract void nextClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'close' button.
   * @param cStep WizardStep at which the user clicked the close button
   * @param qs QuickSetup controller
   */
  public abstract void closeClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'cancel' button.
   * @param cStep WizardStep at which the user clicked the cancel button
   * @param qs QuickSetup controller
   */
  public abstract void cancelClicked(WizardStep cStep, QuickSetup qs);
  /**
   * Called when the user has clicked the 'quit' button.
   * @param step WizardStep at which the user clicked the quit button
   * @param qs QuickSetup controller
   */
  abstract public void quitClicked(WizardStep step, QuickSetup qs);
  /**
   * Called whenever this application should update its user data from
   * values found in QuickSetup.
   * @param cStep current wizard step
   * @param qs QuickSetup controller
   * @throws UserDataException if there is a problem with the data
   */
  abstract protected void updateUserData(WizardStep cStep, QuickSetup qs)
          throws UserDataException;
  /**
   * Gets the key for the close button's tool tip text.
   * @return String key of the text in the resource bundle
   */
  public String getCloseButtonToolTip() {
    return "close-button-tooltip";
  }
  /**
   * Gets the key for the finish button's tool tip text.
   * @return String key of the text in the resource bundle
   */
  public String getFinishButtonToolTip() {
    return "finish-button-tooltip";
  }
  /**
   * Gets the key for the finish button's label.
   * @return String key of the text in the resource bundle
   */
  public String getFinishButtonLabel() {
    return "finish-button-label";
  }
}
opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -29,6 +29,9 @@
import java.io.File;
import java.io.IOException;
import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import org.opends.quicksetup.util.Utils;
@@ -93,7 +96,7 @@
  /**
   * Path to the config/upgrade directory where upgrade base files are stored.
   */
  public static final String CONFIG_UPGRADE_PATH = "upgrade";
  public static final String UPGRADE_PATH = "upgrade";
  /**
   * Relative path to the change log database directory.
@@ -106,6 +109,11 @@
  public static final String LOCKS_PATH_RELATIVE = "locks";
  /**
   * Relative path to the locks directory.
   */
  public static final String TMP_PATH_RELATIVE = "tmp";
  /**
   * The relative path to the current Configuration LDIF file.
   */
  public static final String CURRENT_CONFIG_FILE_NAME = "config.ldif";
@@ -191,6 +199,44 @@
   */
  public static final String HISTORY_LOG_FILE_NAME = "log";
  /**
   * Performs validation on the specified file to make sure that it is
   * an actual OpenDS installation.
   * @param rootDirectory File directory candidate
   * @throws IllegalArgumentException if root directory does not appear to
   * be an OpenDS installation root.
   */
  static public void validateRootDirectory(File rootDirectory)
          throws IllegalArgumentException {
    // TODO:  i18n
    String failureReason = null;
    if (!rootDirectory.exists()) {
      failureReason = "is not a directory";
    } else if (!rootDirectory.isDirectory()) {
      failureReason = "does not exist";
    } else {
      String[] children = rootDirectory.list();
      Set<String> childrenSet = new HashSet<String>(Arrays.asList(children));
      String[] dirsToCheck = new String[] {
              CONFIG_PATH_RELATIVE,
              DATABASES_PATH_RELATIVE,
              LIBRARIES_PATH_RELATIVE,
              // perhaps we should check more
      };
      for (String dir : dirsToCheck) {
        if (!childrenSet.contains(dir)) {
          failureReason = "does not contain directory '" + dir + "'";
        }
      }
    }
    if (failureReason != null) {
      throw new IllegalArgumentException("Install root '" +
              Utils.getPath(rootDirectory) +
              "' is not an OpenDS installation root: " +
              " " + failureReason);
    }
  }
  private File rootDirectory;
  private Status status;
@@ -235,12 +281,49 @@
   */
  public void setRootDirectory(File rootDirectory) throws NullPointerException {
    if (rootDirectory == null) {
      throw new NullPointerException("install root cannot be null");
      throw new NullPointerException("Install root cannot be null");
    }
    // Hold off on doing more validation of rootDirectory since
    // some applications (like the Installer) create an Installation
    // before the actual bits have been laid down on the filesyste.
    this.rootDirectory = rootDirectory;
  }
  /**
   * Indicates whether or not this installation appears to be an actual
   * OpenDS installation.
   * @return boolean where true indicates that this does indeed appear to be
   * a valid OpenDS installation; false otherwise
   */
  public boolean isValid() {
    boolean valid = true;
    try {
      validateRootDirectory(rootDirectory);
    } catch (IllegalArgumentException e) {
      valid = false;
    }
    return valid;
  }
  /**
   * Creates a string explaining why this is not a legitimate OpenDS
   * installation.  Null if this is in fact a vaild installation.
   * @return localized message indicating the reason this is not an
   * OpenDS installation
   */
  public String getInvalidityReason() {
    String reason = null;
    try {
      validateRootDirectory(rootDirectory);
    } catch (IllegalArgumentException e) {
      reason = e.getLocalizedMessage();
    }
    return reason;
  }
  /**
   * Gets the Configuration object representing this file.  The
   * current configuration is stored in config/config.ldif.
   *
@@ -453,6 +536,14 @@
  }
  /**
   * Gets the directory used to store files temporarily.
   * @return File temporary directory
   */
  public File getTemporaryDirectory() {
    return new File(getRootDirectory(), TMP_PATH_RELATIVE);
  }
  /**
   * Returns the directory where the lock files are stored.
   *
   * @return the path to the lock files.
@@ -495,7 +586,15 @@
   * @return File representing the config/upgrade directory
   */
  public File getConfigurationUpgradeDirectory() {
    return new File(getConfigurationDirectory(), CONFIG_UPGRADE_PATH);
    return new File(getConfigurationDirectory(), UPGRADE_PATH);
  }
  /**
   * Gets the directory where the upgrader stores files temporarily.
   * @return File representing the upgrader's temporary directory
   */
  public File getTemporaryUpgradeDirectory() {
    return new File(getTemporaryDirectory(), UPGRADE_PATH);
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java
@@ -71,7 +71,7 @@
  static private final Logger LOG =
          Logger.getLogger(QuickSetup.class.getName());
  private Application application;
  private GuiApplication application;
  private CurrentInstallStatus installStatus;
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -57,7 +57,7 @@
 * it is included in quicksetup.jar.
 *
 */
public abstract class Installer extends Application {
public abstract class Installer extends GuiApplication {
  /* Indicates that we've detected that there is something installed */
  boolean forceToDisplaySetup = false;
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -374,11 +374,10 @@
      throws QuickSetupException {
    ZipExtractor extractor =
            new ZipExtractor(is, minRatio, maxRatio,
            getUserData().getServerLocation(),
            Utils.getNumberZipEntries(),
            getZipFileName(),
            this);
    extractor.extract();
    extractor.extract(getUserData().getServerLocation());
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/ui/ButtonsPanel.java
@@ -40,7 +40,7 @@
import org.opends.quicksetup.ButtonName;
import org.opends.quicksetup.WizardStep;
import org.opends.quicksetup.Application;
import org.opends.quicksetup.GuiApplication;
import org.opends.quicksetup.uninstaller.Uninstaller;
import org.opends.quicksetup.installer.Installer;
import org.opends.quicksetup.event.ButtonActionListener;
@@ -71,14 +71,14 @@
  private JButton cancelButton;
  private Application application;
  private GuiApplication application;
  /**
   * Default constructor.
   * @param application Application running in QuickSetup
   *
   */
  public ButtonsPanel(Application application)
  public ButtonsPanel(GuiApplication application)
  {
    this.application = application;
    createButtons();
opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java
@@ -64,7 +64,7 @@
   * The constructor of this class.
   * @param app Application used to create panels for populating the layout
   */
  public CurrentStepPanel(Application app)
  public CurrentStepPanel(GuiApplication app)
  {
    this.application = app;
    createLayout(app);
@@ -119,7 +119,7 @@
   * Create the layout of the panel.
   * @param app Application used to create panels for populating the layout
   */
  private void createLayout(Application app)
  private void createLayout(GuiApplication app)
  {
    Set<? extends WizardStep> steps = app.getWizardSteps();
opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
@@ -80,7 +80,7 @@
  private HashSet<ButtonActionListener> buttonListeners =
      new HashSet<ButtonActionListener>();
  private Application application;
  private GuiApplication application;
  private boolean forceToDisplay;
@@ -89,7 +89,7 @@
   * @param app Application to run in as a wizard
   * @param installStatus of the current environment
   */
  public QuickSetupDialog(Application app,
  public QuickSetupDialog(GuiApplication app,
      CurrentInstallStatus installStatus)
  {
    if (app == null) {
opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java
@@ -37,7 +37,7 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.opends.quicksetup.Application;
import org.opends.quicksetup.GuiApplication;
import org.opends.quicksetup.WizardStep;
/**
@@ -56,13 +56,13 @@
  HashMap<WizardStep, JLabel> hmIcons = new HashMap<WizardStep, JLabel>();
  Application application = null;
  GuiApplication application = null;
  /**
   * Creates a StepsPanel.
   * @param app Application whose steps this class represents
   */
  public StepsPanel(Application app)
  public StepsPanel(GuiApplication app)
  {
    this.application = app;
    createLayout(app);
@@ -101,7 +101,7 @@
   * Creates the layout of the panel.
   * @param app Application whose steps this class represents
   */
  private void createLayout(Application app)
  private void createLayout(GuiApplication app)
  {
    setLayout(new GridBagLayout());
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
@@ -44,7 +44,7 @@
/**
 * This class is in charge of performing the uninstallation of Open DS.
 */
public class Uninstaller extends Application implements CliApplication {
public class Uninstaller extends GuiApplication implements CliApplication {
  private ProgressStep status = UninstallProgressStep.NOT_STARTED;
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
New file
@@ -0,0 +1,177 @@
/*
 * 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.upgrader;
import org.opends.quicksetup.*;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ZipExtractor;
import org.opends.quicksetup.util.FileManager;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
/**
 * BuildExtractor unzips an OpenDS installation package (.zip file) from a user
 * specified location into the current builds staging directory.  This Java
 * program handles this task so that we don't need to rely on the operating
 * system's tools for managing zip files.
 *
 * This tool is a stand-alone program since it is run in preparation for a
 * off line upgrade and runs using the current program's jars rather than
 * the new build's jars as is manditory for the Upgrader itself.  Since this
 * tool itself is run using the old bits prior to upgrade and the upgrade
 * itself is dependent upon this tool, it should be kept simple and stable
 * to insure that the upgrade will work.
 */
public class BuildExtractor extends Application implements Runnable {
  /**
   * Creates and run a BuildExtractor using command line arguments.
   * @param args String[] command line arguments
   */
  public static void main(String[] args) {
    new BuildExtractor(args).run();
  }
  private String[] args = null;
  private BuildExtractor(String[] args) {
    this.args = args;
    setProgressMessageFormatter(new PlainTextProgressMessageFormatter());
    addProgressUpdateListener(new ProgressUpdateListener() {
      public void progressUpdate(ProgressUpdateEvent ev) {
        System.out.println(ev.getNewLogs());
      }
    });
  }
  /**
   * Executes this build extractor.  First and attempt is made to extract the
   * build file name from the command line arguments.  If no such file has been
   * specified this program simply exits with a return code of 0.  If such a
   * file has been specified this program performs a certain amount of
   * verification on the file.  If the verification fails this program prints
   * a message and exits with with a return code of 1 meaning that the upgrade
   * process should end.  If verification succeeeds this program unzips its
   * contents into the current build's staging are and exits with return code 0.
   */
  public void run() {
    int retCode = 0;
    try {
      File buildFile = getBuildFile(args);
      if (buildFile != null) {
        if (!buildFile.exists()) {
          // TODO: i18n
          throw new FileNotFoundException(
                  buildFile.getName() + " does not exist");
        }
        expandZipFile(buildFile);
      }
    } catch (Throwable t) {
      retCode = 1;
      notifyListeners(t.getLocalizedMessage() + getLineBreak());
    }
    System.exit(retCode);
  }
  private File getBuildFile(String[] args) {
    File buildFile = null;
    String buildFileName = null;
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        if (args[i].equals("--" + UpgraderCliHelper.FILE_OPTION_LONG) ||
                args[i].equals("-" + UpgraderCliHelper.FILE_OPTION_SHORT)) {
          if (i < args.length - 1) {
            buildFileName = args[i+ 1];
          }
        }
      }
    }
    if (buildFileName != null) {
      buildFile = new File(buildFileName);
    }
    return buildFile;
  }
  private void expandZipFile(File buildFile)
          throws ApplicationException, IOException, QuickSetupException {
    ZipExtractor extractor = new ZipExtractor(buildFile,
            1, 10, // TODO figure out these values
            Utils.getNumberZipEntries(), this);
    extractor.extract(getStageDirectory());
  }
  private File getStageDirectory() throws ApplicationException {
    File stageDir;
    Installation installation = new Installation(getInstallationPath());
    stageDir = installation.getTemporaryUpgradeDirectory();
    if (stageDir.exists()) {
      FileManager fm = new FileManager(this);
      fm.deleteRecursively(stageDir);
    }
    if (!stageDir.mkdirs()) {
      // TODO: i18n
      throw ApplicationException.createFileSystemException(
              "failed to create staging directory " + stageDir, null);
    }
    return stageDir;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstallationPath() {
    return Utils.getInstallPathFromClasspath();
  }
  /**
   * {@inheritDoc}
   */
  public ProgressStep getCurrentProgressStep() {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  public Integer getRatio(ProgressStep step) {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  public String getSummary(ProgressStep step) {
    return null;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -29,7 +29,6 @@
import org.opends.quicksetup.*;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ZipExtractor;
import org.opends.quicksetup.util.FileManager;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.ui.QuickSetupDialog;
@@ -55,7 +54,7 @@
 * QuickSetup application of ugrading the bits of an installation of
 * OpenDS.
 */
public class Upgrader extends Application implements CliApplication {
public class Upgrader extends GuiApplication implements CliApplication {
  /**
   * Steps in the Upgrade wizard.
@@ -93,6 +92,8 @@
    INITIALIZING("summary-upgrade-initializing"),
    STARTING_SERVER("summary-starting"),
    STOPPING_SERVER("summary-stopping"),
    CALCULATING_SCHEMA_CUSTOMIZATIONS(
@@ -164,7 +165,8 @@
          DATABASES_PATH_RELATIVE, // db
          LOGS_PATH_RELATIVE, // logs
          LOCKS_PATH_RELATIVE, // locks
          HISTORY_PATH_RELATIVE // history
          HISTORY_PATH_RELATIVE, // history
          TMP_PATH_RELATIVE // tmp
  };
  private ProgressStep currentProgressStep = UpgradeProgressStep.NOT_STARTED;
@@ -198,6 +200,9 @@
  /** SVN rev number of the current build. */
  private Integer currentVersion = null;
  /** New OpenDS bits. */
  private Installation stagedInstallation = null;
  /** SVN rev number of the build in the stage directory. */
  private Integer stagedVersion = null;
@@ -352,16 +357,28 @@
        setCurrentProgressStep(UpgradeProgressStep.INITIALIZING);
        initialize();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error initializing upgrader", e);
        LOG.log(Level.INFO, "Error initializing upgrader", e);
        throw e;
      }
      if (!getInstallation().getStatus().isServerRunning()) {
        try {
          setCurrentProgressStep(UpgradeProgressStep.STARTING_SERVER);
          startServerWithoutConnectionHandlers();
          getServerController().stopServerInProcess();
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Error starting server to insure configuration" +
                  " changes have been written to the filesystem", e);
          throw e;
        }
      }
      if (getInstallation().getStatus().isServerRunning()) {
        try {
          setCurrentProgressStep(UpgradeProgressStep.STOPPING_SERVER);
          new ServerController(this).stopServer();
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "error stopping server", e);
          LOG.log(Level.INFO, "Error stopping server", e);
          throw e;
        }
      }
@@ -371,7 +388,7 @@
                UpgradeProgressStep.CALCULATING_SCHEMA_CUSTOMIZATIONS);
        calculateSchemaCustomizations();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error calculating schema customizations", e);
        LOG.log(Level.INFO, "Error calculating schema customizations", e);
        throw e;
      }
@@ -381,7 +398,7 @@
        calculateConfigCustomizations();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO,
                "error calculating config customizations", e);
                "Error calculating config customizations", e);
        throw e;
      }
@@ -389,7 +406,7 @@
        setCurrentProgressStep(UpgradeProgressStep.BACKING_UP_DATABASES);
        backupDatabases();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error backing up databases", e);
        LOG.log(Level.INFO, "Error backing up databases", e);
        throw e;
      }
@@ -397,7 +414,7 @@
        setCurrentProgressStep(UpgradeProgressStep.BACKING_UP_FILESYSTEM);
        backupFilesytem();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO, "error backing up files", e);
        LOG.log(Level.INFO, "Error backing up files", e);
        throw e;
      }
@@ -407,7 +424,7 @@
        upgradeComponents();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO,
                "error upgrading components", e);
                "Error upgrading components", e);
        throw e;
      }
@@ -417,7 +434,7 @@
        applySchemaCustomizations();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO,
                "error applying schema customizations", e);
                "Error applying schema customizations", e);
        throw e;
      }
@@ -427,10 +444,13 @@
        applyConfigurationCustomizations();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO,
                "error applying configuration customizations", e);
                "Error applying configuration customizations", e);
        throw e;
      }
      // This allows you to test whether or not he upgrader can successfully
      // abort an upgrade once changes have been made to the installation
      // path's filesystem.
      if ("true".equals(
              System.getProperty(
                      "org.opends.upgrader.Upgrader.CreateError.CreateError")))
@@ -444,7 +464,7 @@
        verifyUpgrade();
      } catch (ApplicationException e) {
        LOG.log(Level.INFO,
                "error verifying upgrade", e);
                "Error verifying upgrade", e);
        throw e;
      }
@@ -453,7 +473,7 @@
    } catch (Throwable t) {
      this.runException =
              new ApplicationException(ApplicationException.Type.BUG,
                      t.getLocalizedMessage(),
                      "Unexpected error: " + t.getLocalizedMessage(),
                      t);
    } finally {
      try {
@@ -476,6 +496,9 @@
        // Write a record in the log file indicating success/failure
        setCurrentProgressStep(UpgradeProgressStep.RECORDING_HISTORY);
        notifyListeners("See '" +
                Utils.getPath(getInstallation().getHistoryLogFile()) +
                "'" + formatter.getLineBreak());
        writeHistoricalRecord(historicalOperationId,
                getCurrentVersion(),
                getStagedVersion(),
@@ -483,10 +506,8 @@
                note);
      } catch (ApplicationException e) {
        System.err.print("error cleaning up after upgrade: " +
        System.err.print("Error cleaning up after upgrade: " +
                e.getLocalizedMessage());
      } finally {
      }
    }
@@ -536,12 +557,12 @@
          } catch (Throwable t) {
            notifyListeners("The following could not be restored after the" +
                    "failed upgrade attempt.  You should restore this " +
                    "file/directory manually: " + f + " to " + root);
                    "file/directory manually: '" + f + "' to '" + root + "'");
          }
        }
        fm.deleteRecursively(backupDirectory);
      } catch (IOException e) {
        LOG.log(Level.INFO, "error getting backup directory", e);
        LOG.log(Level.INFO, "Error getting backup directory", e);
      }
    }
@@ -552,7 +573,8 @@
    try {
      new ServerController(this).startServer();
    } catch (QuickSetupException e) {
      LOG.log(Level.INFO, "error starting server", e);
      LOG.log(Level.INFO, "Error starting server: " +
              e.getLocalizedMessage(), e);
    }
  }
@@ -563,13 +585,17 @@
        applyCustomizationLdifFile(configDiff);
      }
    } catch (IOException e) {
      LOG.log(Level.INFO, "error getting schema diff file", e);
      String msg = "IO Error applying configuration customization: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "error applying configuration customization", e);
              msg, e);
    } catch (LDIFException e) {
      LOG.log(Level.INFO, "error reading change record", e);
      String msg = "LDIF error applying configuration customization: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "error applying configuration customization", e);
              msg, e);
    }
  }
@@ -580,13 +606,17 @@
        applyCustomizationLdifFile(schemaDiff);
      }
    } catch (IOException e) {
      LOG.log(Level.INFO, "error getting schema diff file", e);
      String msg = "IO Error applying schema customization: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "error applying schema customization", e);
              msg, e);
    } catch (LDIFException e) {
      LOG.log(Level.INFO, "error reading change record", e);
      String msg = "LDIF error applying schema customization: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "error applying schema customization", e);
              msg, e);
    }
  }
@@ -599,17 +629,23 @@
      }
      control.startServerInProcess(true);
    } catch (IOException e) {
      LOG.log(Level.INFO, "could not determine server state", e);
      String msg = "Failed to determine server state: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "error trying to determine server state", e);
              msg, e);
    } catch (InitializationException e) {
      LOG.log(Level.INFO, "could not start server", e);
      String msg = "Failed to start server due to initialization error:" +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "could not start server with handlers", e);
              msg, e);
    } catch (ConfigException e) {
      LOG.log(Level.INFO, "configuration error starting server", e);
      String msg = "Failed to start server due to configuration error: " +
              e.getLocalizedMessage();
      LOG.log(Level.INFO, msg, e);
      throw new ApplicationException(ApplicationException.Type.IMPORT_ERROR,
              "configuration error starting server", e);
              msg, e);
    }
  }
@@ -675,7 +711,6 @@
        }
      }
    } catch (Throwable t) {
      // t.printStackTrace(System.out);
      throw new ApplicationException(ApplicationException.Type.BUG,
              t.getMessage(), t);
    } finally {
@@ -705,8 +740,9 @@
      id = log.append(fromVersion, toVersion,
              HistoricalRecord.Status.STARTED, null);
    } catch (IOException e) {
      String msg = "IO Error logging operation: " + e.getLocalizedMessage();
      throw ApplicationException.createFileSystemException(
              "error logging operation", e);
              msg, e);
    }
    return id;
  }
@@ -723,8 +759,8 @@
              new HistoricalLog(getInstallation().getHistoryLogFile());
      log.append(id, from, to, status, note);
    } catch (IOException e) {
      throw ApplicationException.createFileSystemException(
              "error logging operation", e);
      String msg = "Error logging operation: " + e.getLocalizedMessage();
      throw ApplicationException.createFileSystemException(msg, e);
    }
  }
@@ -741,7 +777,7 @@
      }
    } catch (IOException e) {
      throw ApplicationException.createFileSystemException(
              "I/0 error upgrading components", e);
              "I/0 error upgrading components: " + e.getLocalizedMessage(), e);
    }
  }
@@ -754,7 +790,8 @@
                   getCustomConfigDiffFile());
        } catch (Exception e) {
          throw ApplicationException.createFileSystemException(
                  "error determining configuration customizations", e);
                  "Error determining configuration customizations: "
                  + e.getLocalizedMessage(), e);
        }
      } else {
        // TODO i18n
@@ -764,7 +801,8 @@
    } catch (IOException e) {
      // TODO i18n
      throw ApplicationException.createFileSystemException(
              "could not determine configuration modifications", e);
              "Could not determine configuration modifications: " +
              e.getLocalizedMessage(), e);
    }
  }
@@ -809,14 +847,16 @@
      // TODO i18n
      notifyListeners(
              "Schema contains customizations and needs to be migrated\n");
              "Schema contains customizations and needs to be migrated" +
              formatter.getLineBreak());
      try {
        ldifDiff(getInstallation().getBaseSchemaFile(),
                 getInstallation().getSchemaConcatFile(),
                 getCustomSchemaDiffFile());
      } catch (Exception e) {
        throw ApplicationException.createFileSystemException(
                "error determining schema customizations", e);
                "Error determining schema customizations: " +
                e.getLocalizedMessage(), e);
      }
    } else {
      // TODO i18n
@@ -891,18 +931,17 @@
    } catch (IOException e) {
      // TODO i18n
      throw ApplicationException.createFileSystemException(
              "error attempting to clean up tmp directory " +
                      stagingDir != null ? stagingDir.getName() : "null",
              "Error attempting to clean up tmp directory " +
                      stagingDir != null ? stagingDir.getName() : "null" +
              ": " + e.getLocalizedMessage(),
              e);
    }
  }
  private void initialize() throws ApplicationException {
    try {
      expandZipFile();
      Integer fromVersion = getStagedVersion();
      Integer toVersion = getCurrentVersion();
      Integer fromVersion = getCurrentVersion();
      Integer toVersion = getStagedVersion();
      this.historicalOperationId =
              writeInitialHistoricalRecord(fromVersion, toVersion);
@@ -930,7 +969,8 @@
    } catch (QuickSetupException e) {
      LOG.log(Level.INFO, "error", e);
      throw ApplicationException.createFileSystemException(
              "could not determine current version number", e);
              "Could not determine current version number: " +
              e.getLocalizedMessage(), e);
    }
    try {
@@ -938,7 +978,8 @@
    } catch (Exception e) {
      LOG.log(Level.INFO, "error", e);
      throw ApplicationException.createFileSystemException(
              "could not determine upgrade version number", e);
              "Could not determine upgrade version number: " +
              e.getLocalizedMessage(), e);
    }
    UpgradeOracle uo = new UpgradeOracle(currentVersion, newVersion);
@@ -951,30 +992,20 @@
  private Installation getStagedInstallation()
          throws IOException, ApplicationException {
    return new Installation(getStageDirectory());
  }
  private void expandZipFile()
          throws ApplicationException, IOException, QuickSetupException {
    File installPackage = getUpgradeUserData().getInstallPackage();
    FileInputStream fis = new FileInputStream(installPackage);
    ZipExtractor extractor = new ZipExtractor(fis,
            1, 10, // TODO figure out these values
            getStageDirectory().getCanonicalPath(),
            Utils.getNumberZipEntries(),
            installPackage.getName(), this);
    extractor.extract();
  }
  /**
   * Delays for a time FOR TESTING ONLY.
   */
  private void sleepFor1() {
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
    if (stagedInstallation == null) {
      File stageDir = getStageDirectory();
      try {
        Installation.validateRootDirectory(stageDir);
        stagedInstallation = new Installation(getStageDirectory());
      } catch (IllegalArgumentException e) {
        throw ApplicationException.createFileSystemException(
                "Directory '" + getStageDirectory() +
                        "' does not contain a staged installation of OpenDS" +
                        " as was expected.  Verify that the new installation" +
                        " package (.zip) is an OpenDS installation file", null);
      }
    }
    return stagedInstallation;
  }
  /**
@@ -1005,24 +1036,9 @@
    return cliHelper;
  }
  private File getTempDirectory() {
    return new File(System.getProperty("java.io.tmpdir"));
  }
  private File getStageDirectory()
          throws ApplicationException, IOException {
    if (stagingDirectory == null) {
      File tmpDir = getTempDirectory();
      stagingDirectory =
              new File(tmpDir, "opends-upgrade-tmp-" +
                      System.currentTimeMillis());
      if (stagingDirectory.exists()) {
        FileManager fm = new FileManager(this);
        fm.deleteRecursively(stagingDirectory);
      }
      stagingDirectory.mkdirs();
    }
    return stagingDirectory;
    return getInstallation().getTemporaryUpgradeDirectory();
  }
  private UpgradeUserData getUpgradeUserData() {
@@ -1076,8 +1092,6 @@
    return stagedVersion;
  }
  /**
   * Filter defining files we want to manage in the upgrade
   * process.
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
@@ -44,12 +44,17 @@
 */
public class UpgraderCliHelper extends CliApplicationHelper {
  /** Short form of the option for specifying the installation package file. */
  static public final Character FILE_OPTION_SHORT = 'F';
  /** Long form of the option for specifying the installation package file. */
  static public final String FILE_OPTION_LONG = "file";
  static private final Logger LOG =
          Logger.getLogger(UpgraderCliHelper.class.getName());
  BooleanArgument cliArg = null;
  BooleanArgument dryRunArg = null;
  StringArgument localInstallPackFileNameArg = null;
  StringArgument remoteBuildNameArg = null;
  /**
   * Creates a set of user data from command line arguments and installation
@@ -77,12 +82,10 @@
        } else {
          uud.setInstallPackage(installPackFile);
        }
      } else if (remoteBuildNameArg.isPresent()) {
        // TODO download build
      } else {
        // TODO i18N
        throw new UserDataException(null,
                "either -F or -B option must be present");
                "-F must be present");
      }
    } catch (ArgumentException e) {
@@ -110,15 +113,11 @@
      argParser.addArgument(cliArg);
      localInstallPackFileNameArg =
           new StringArgument("install package file", 'F', "package file",
           new StringArgument("install package file",
                   FILE_OPTION_SHORT, FILE_OPTION_LONG,
                   false, true, "{install package file}", 0);
      argParser.addArgument(localInstallPackFileNameArg);
      remoteBuildNameArg =
           new StringArgument("build name", 'B', "build name",
                   false, false, "{build name}", 1);
      argParser.addArgument(remoteBuildNameArg);
    } catch (ArgumentException e) {
      LOG.log(Level.INFO, "error", e);
    }
opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java
@@ -31,8 +31,7 @@
import org.opends.quicksetup.Application;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.io.InputStream;
import java.io.IOException;
import java.io.*;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipEntry;
import java.util.ArrayList;
@@ -48,29 +47,53 @@
  private InputStream is;
  private int minRatio;
  private int maxRatio;
  private String basePath;
  private int numberZipEntries;
  private String zipFileName;
  private Application application;
  /**
   * Creates an instance of an ZipExtractor.
   * @param zipFile File the zip file to extract
   * @param minRatio int indicating the max ration
   * @param maxRatio int indicating the min ration
   * @param numberZipEntries number of entries in the input stream
   * @param app application to be notified about progress
   * @throws FileNotFoundException if the specified file does not exist
   * @throws IllegalArgumentException if the zip file is not a zip file
   */
  public ZipExtractor(File zipFile, int minRatio, int maxRatio,
                                      int numberZipEntries,
                                      Application app)
    throws FileNotFoundException, IllegalArgumentException
  {
    this(new FileInputStream(zipFile),
      minRatio,
      maxRatio,
      numberZipEntries,
      zipFile.getName(),
      app);
    if (!zipFile.getName().endsWith(".zip")) {
      // TODO i18n
      throw new IllegalArgumentException("File must have extension .zip");
    }
  }
  /**
   * Creates an instance of an ZipExtractor.
   * @param is InputStream of zip file content
   * @param minRatio int indicating the max ration
   * @param maxRatio int indicating the min ration
   * @param basePath filesystem location where content will be unzipped
   * @param numberZipEntries number of entries in the input stream
   * @param zipFileName name of the input zip file
   * @param app application to be notified about progress
   */
  public ZipExtractor(InputStream is, int minRatio, int maxRatio,
                                      String basePath, int numberZipEntries,
                                      int numberZipEntries,
                                      String zipFileName,
                                      Application app) {
    this.is = is;
    this.minRatio = minRatio;
    this.maxRatio = maxRatio;
    this.basePath = basePath;
    this.numberZipEntries = numberZipEntries;
    this.zipFileName = zipFileName;
    this.application = app;
@@ -78,9 +101,19 @@
  /**
   * Performs the zip extraction.
   * @param destination File where the zip file will be extracted
   * @throws QuickSetupException if something goes wrong
   */
  public void extract() throws QuickSetupException {
  public void extract(File destination) throws QuickSetupException {
    extract(Utils.getPath(destination));
  }
  /**
   * Performs the zip extraction.
   * @param destination File where the zip file will be extracted
   * @throws QuickSetupException if something goes wrong
   */
  public void extract(String destination) throws QuickSetupException {
    ZipInputStream zipIn = new ZipInputStream(is);
    int nEntries = 1;
@@ -112,7 +145,7 @@
        {
          try
          {
            copyZipEntry(entry, basePath, zipFirstPath, zipIn,
            copyZipEntry(entry, destination, zipFirstPath, zipIn,
            ratioBeforeCompleted, ratioWhenCompleted, permissions, application);
          } catch (IOException ioe)
@@ -201,7 +234,7 @@
    {
      entryName = entryName.substring(zipFirstPath.length());
    }
    String path = Utils.getPath(basePath, entryName);
    String path = Utils.getPath(new File(basePath, entryName));
    String progressSummary =
            ResourceProvider.getInstance().getMsg("progress-extracting",