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

kenneth_suter
23.25.2007 f0ecb612708c2fdd2ad21698701b5a04298750cd
This commit does some initial work in anticipation of the reverter tool:

- Defines new tool messages for the reverter CLI.

- Moved some common upgrader methods for writing to the historical log to Application for use by the reversion tool. Theoretically these also be called by the installers to record when the installation was installed.

- Makes the existing ArgumentParser's created for usage messages further available for the arg parsing.

- Creates a progress notification delegate class.

- Changes the name of VersionOracle and UpgradeOracle to VersionIssueNotifier and UpgradeVersionNotifier. Ludo's suggestion was interesting but a esoteric :)

- Removed the CurrentInstallStatus arg from the createUserData since it was not being used.

- Made QuickSetupCLI exit from event loop dependent upon termination of the CLI app thread rather than the isFinished method so that it more reliably exits properly.

8 files added
4 files renamed
20 files modified
2434 ■■■■ changed files
opendj-sdk/opends/resource/revert 155 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java 93 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java 13 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java 2 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/HistoricalLog.java 5 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/HistoricalRecord.java 10 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java 21 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java 42 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ProgressUpdateListenerDelegate.java 123 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java 54 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java 3 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installandupgrader/InstallAndUpgrader.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java 96 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 44 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java 15 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCliHelper.java 5 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java 82 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java 7 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java 8 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java 3 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionLauncher.java 216 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionProgressStep.java 103 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Reverter.java 709 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReverterUserData.java 57 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeFileFilter.java 72 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeIssueNotifier.java 12 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java 97 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeProgressStep.java 128 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java 199 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java 11 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/VersionIssueNotifier.java 6 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java 41 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/revert
New file
@@ -0,0 +1,155 @@
#!/bin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE
# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
# add the following below this CDDL HEADER, with the fields enclosed
# by brackets "[]" replaced with your own identifying information:
#      Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#      Portions Copyright 2006-2007 Sun Microsystems, Inc.
# See if JAVA_HOME is set.  If not, then see if there is a java executable in
# the path and try to figure it out.
if test -z "${JAVA_BIN}"
then
  if test -z "${JAVA_HOME}"
  then
    if test -f "${INSTANCE_ROOT}/lib/set-java-home"
    then
      . "${INSTANCE_ROOT}/lib/set-java-home"
      JAVA_BIN="${JAVA_HOME}/bin/java"
      export JAVA_BIN
    else
      JAVA_BIN=`which java 2> /dev/null`
      if test ${?} -eq 0
      then
        export JAVA_BIN
      else
        echo "Please set JAVA_HOME to the root of a Java 5 (or later) installation."
        exit 1
      fi
    fi
  else
    JAVA_BIN="${JAVA_HOME}/bin/java"
    export JAVA_BIN
    export JAVA_WS
  fi
fi
# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
# system environment variables for security and compatibility reasons.
PATH=/bin:/usr/bin
LD_LIBRARY_PATH=
LD_LIBRARY_PATH_32=
LD_LIBRARY_PATH_64=
LD_PRELOAD=
LD_PRELOAD_32=
LD_PRELOAD_64=
export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
# Capture the current working directory so that we can change to it later.
# Then capture the location of this script and the Directory Server instance
# root so that we can use them to create appropriate paths.
WORKING_DIR=`pwd`
cd `dirname "${0}"`
SCRIPT_DIR=`pwd`
INSTANCE_ROOT=${SCRIPT_DIR}
export INSTANCE_ROOT
cd "${WORKING_DIR}"
# Configure the appropriate CLASSPATH to test.
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}
done
export CLASSPATH
# Determine whether the detected Java environment is acceptable for use.
if test -z "${JAVA_ARGS}"
then
  "${JAVA_BIN}" -client org.opends.server.tools.InstallDS -t 2> /dev/null
  if test ${?} -eq 0
  then
    JAVA_ARGS="-client"
  else
    "${JAVA_BIN}" org.opends.server.tools.InstallDS -t 2> /dev/null
    if test ${?} -ne 0
    then
      echo "ERROR:  The detected Java version could not be used.  Please set "
      echo "        JAVA_HOME to the root of a Java 5 (or later) installation."
      exit 1
    fi
  fi
else
  "${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.InstallDS -t 2> /dev/null
  if test ${?} -ne 0
  then
    echo "ERROR:  The detected Java version could not be used.  Please set "
    echo "        JAVA_HOME to the root of a Java 5.0 installation."
    exit 1
  fi
fi
if [ -r "${INSTANCE_ROOT}/tmp/upgrade" ]
then
  rm -fr "${INSTANCE_ROOT}/tmp/upgrade"
fi
# Copy jars to a temporary place from which to run the reverter
# in order to avoid potential file lock issues.
mkdir -p tmp/revert
cp -R lib tmp/revert
if test ${?} -ne 0
then
  echo "ERROR:  Failed to initialize reversion."
  exit 101
else
  CLASSPATH=${INSTANCE_ROOT}/tmp/revert/classes
  for JAR in ${INSTANCE_ROOT}/tmp/revert/lib/*.jar
  do
    CLASSPATH=${JAR}:${CLASSPATH}
  done
  # Launch the upgrade process.
  "${JAVA_BIN}" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 org.opends.quicksetup.upgrader.ReversionLauncher "${@}"
  RETURN_CODE=$?
  if test ${RETURN_CODE} -eq 0
  then
    exit 0
  elif test ${RETURN_CODE} -eq 50
  then
    # Version info was on requested
    exit 0
  else
    exit 101
  fi
fi
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -30,7 +30,6 @@
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.event.ProgressNotifier;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ProgressMessageFormatter;
@@ -39,9 +38,10 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.HashSet;
/**
 * This class represents an application that can be run in the context of
@@ -56,9 +56,6 @@
  /** Represents current install state. */
  protected CurrentInstallStatus installStatus;
  private HashSet<ProgressUpdateListener> listeners =
      new HashSet<ProgressUpdateListener>();
  private UserData userData;
  private Installation installation;
@@ -70,6 +67,9 @@
  /** Formats progress messages. */
  protected ProgressMessageFormatter formatter;
  /** Handler for listeners and event firing. */
  protected ProgressUpdateListenerDelegate listenerDelegate;
  /**
   * Creates an application by instantiating the Application class
   * denoted by the System property
@@ -138,7 +138,7 @@
   */
  public void addProgressUpdateListener(ProgressUpdateListener l)
  {
    listeners.add(l);
    listenerDelegate.addProgressUpdateListener(l);
  }
  /**
@@ -147,7 +147,7 @@
   */
  public void removeProgressUpdateListener(ProgressUpdateListener l)
  {
    listeners.remove(l);
    listenerDelegate.removeProgressUpdateListener(l);
  }
  /**
@@ -224,13 +224,8 @@
  public void notifyListeners(Integer ratio, String currentPhaseSummary,
      String newLogDetail)
  {
    ProgressUpdateEvent ev =
        new ProgressUpdateEvent(getCurrentProgressStep(), ratio,
                currentPhaseSummary, newLogDetail);
    for (ProgressUpdateListener l : listeners)
    {
      l.progressUpdate(ev);
    }
    listenerDelegate.notifyListeners(getCurrentProgressStep(),
            ratio, currentPhaseSummary, newLogDetail);
  }
  /**
@@ -322,6 +317,7 @@
   */
  public void setProgressMessageFormatter(ProgressMessageFormatter formatter) {
    this.formatter = formatter;
    this.listenerDelegate = new ProgressUpdateListenerDelegate(formatter);
  }
  /**
@@ -585,8 +581,73 @@
    return ui;
  }
  static private String getMessage(String key, String... args) {
    return ResourceProvider.getInstance().getMsg(key, args);
  /**
   * Conditionally notifies listeners of the log file if it
   * has been initialized.
   */
  protected void notifyListenersOfLog() {
    File logFile = QuickSetupLog.getLogFile();
    if (logFile != null) {
      notifyListeners(
          getFormattedProgress(getMsg("general-see-for-details",
              logFile.getPath())) +
          formatter.getLineBreak());
    }
  }
  /**
   * Writes an initial record in the installation's historical
   * log describing moving from one version to another.
   * @param fromVersion from with install will be migrated
   * @param toVersion to which install will be migrated
   * @return Long ID for this session
   * @throws ApplicationException if something goes wrong
   */
  protected Long writeInitialHistoricalRecord(
          BuildInformation fromVersion,
          BuildInformation toVersion)
          throws ApplicationException {
    Long id;
    try {
      HistoricalLog log =
              new HistoricalLog(getInstallation().getHistoryLogFile());
      id = log.append(fromVersion, toVersion,
              HistoricalRecord.Status.STARTED,
              "log file '" + QuickSetupLog.getLogFile().getPath() + "'");
    } catch (IOException e) {
      String msg = getMsg("error-logging-operation");
      throw ApplicationException.createFileSystemException(
              msg, e);
    }
    return id;
  }
  /**
   * Writes a record into this installation's historical log.
   * @param id obtained from calling <code>writeInitialHistoricalRecord</code>
   * @param from version from with install will be migrated
   * @param to version to which install will be migrated
   * @param status of the operation
   * @param note string with additional information
   * @throws ApplicationException if something goes wrong
   * @see {@link #writeInitialHistoricalRecord(BuildInformation,
          BuildInformation)}
   */
  protected void writeHistoricalRecord(
          Long id,
          BuildInformation from,
          BuildInformation to,
          HistoricalRecord.Status status,
          String note)
          throws ApplicationException {
    try {
      HistoricalLog log =
              new HistoricalLog(getInstallation().getHistoryLogFile());
      log.append(id, from, to, status, note);
    } catch (IOException e) {
      String msg = getMsg("error-logging-operation");
      throw ApplicationException.createFileSystemException(msg, e);
    }
  }
  /**
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
@@ -38,12 +38,11 @@
  /**
   * Creates a set of user data from command line arguments and installation
   * status.
   * @param args String[] of arguments passed in from the command line
   * @param status the current installation status
   * @param launcher that launched this application
   * @return UserData object populated to reflect the input args and status
   * @throws UserDataException if something is wrong
   */
  UserData createUserData(String[] args, CurrentInstallStatus status)
  UserData createUserData(Launcher launcher)
          throws UserDataException;
  /**
@@ -66,17 +65,11 @@
  void setProgressMessageFormatter(ProgressMessageFormatter formatter);
  /**
   * Indicates whether or not this applicat is finished running.
   * @return boolean where true indicates we are not running
   */
  boolean isFinished();
  /**
   * Gets any exception that happened while this application was running.
   * A null value returned from this method indicates that the execution
   * of the CLI program is not complete or was successful.
   * @return an exception that happened while the CLI was running
   */
  ApplicationException getException();
  ApplicationException getRunError();
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
@@ -308,6 +308,8 @@
                                                String description,
                                                boolean caseSensitive) {
    // TODO: get rid of this method and user launcher.getArgumentParser
    // Create the command-line argument parser for use with this program.
    ArgumentParser argParser =
         new ArgumentParser(mainClass, description, caseSensitive);
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/HistoricalLog.java
File was renamed from opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalLog.java
@@ -25,10 +25,9 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.upgrader;
package org.opends.quicksetup;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.BuildInformation;
import java.util.List;
import java.util.ArrayList;
@@ -97,7 +96,7 @@
   * Creates a new historical log record and appends a new log record to the
   * log.
   * @param id Long ID obtained from a call to
            {@link org.opends.quicksetup.upgrader.HistoricalLog#
            {@link org.opends.quicksetup.HistoricalLog#
            append(Integer, Integer,
            org.opends.quicksetup.upgrader.HistoricalRecord.Status)}
   * @param from current version
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/HistoricalRecord.java
File was renamed from opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java
@@ -25,9 +25,8 @@
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.upgrader;
package org.opends.quicksetup;
import org.opends.quicksetup.BuildInformation;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.util.StringTokenizer;
@@ -71,14 +70,18 @@
  /**
   * State of an upgrade.
   */
  enum Status {
  public enum Status {
    /** Operation has started. */
    STARTED(getMsg("upgrade-log-status-started")),
    /** Operation completed successfully. */
    SUCCESS(getMsg("upgrade-log-status-success")),
    /** Operation failed. */
    FAILURE(getMsg("upgrade-log-status-failure")),
    /** Operation was canceled. */
    CANCEL(getMsg("upgrade-log-status-cancel"));
    private String representation;
@@ -229,6 +232,7 @@
   * @param note containing details of status; can be null
   * @param creationError Exception that occurred while this record was
   * being created
   * @param date of this operation
   */
  private HistoricalRecord(Long operationId, Date date, BuildInformation from,
                          BuildInformation to, Status status, String note,
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -147,16 +147,26 @@
  public static final String WINDOWS_UNINSTALL_FILE_NAME = "uninstall.bat";
  /**
   * The UNIX uninstall script file name.
   * The UNIX upgrade script file name.
   */
  public static final String UNIX_UPGRADE_FILE_NAME = "upgrade";
  /**
   * The Windows uninstall batch file name.
   * The Windows upgrade batch file name.
   */
  public static final String WINDOWS_UPGRADE_FILE_NAME = "upgrade.bat";
  /**
   * The UNIX revert script file name.
   */
  public static final String UNIX_REVERT_FILE_NAME = "revert";
  /**
   * The Windows revert batch file name.
   */
  public static final String WINDOWS_REVERT_FILE_NAME = "revert.bat";
  /**
   * The UNIX start script file name.
   */
  public static final String UNIX_START_FILE_NAME = "start-ds";
@@ -203,6 +213,13 @@
  public static final String HISTORY_LOG_FILE_NAME = "log";
  /**
   * The name of the directory in an upgrade backup directory (child
   * of the 'history' directory) that contains the files from a
   * previous version.
   */
  public static final String HISTORY_BACKUP_FILES_DIR_NAME = "files";
  /**
   * Generic name for the backup tool.
   */
  public static final String BACKUP = "backup";
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -28,6 +28,7 @@
package org.opends.quicksetup;
import static org.opends.server.util.DynamicConstants.PRINTABLE_VERSION_STRING;
import org.opends.server.util.args.ArgumentParser;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.i18n.ResourceProvider;
@@ -58,9 +59,25 @@
      throw new IllegalArgumentException("args cannot be null");
    }
    this.args = args;
  }
  /**
   * Gets the arguments with which this launcher was invoked.
   * @return String[] args from the CLI invocation
   */
  public String[] getArguments() {
    return this.args;
  }
  /**
   * Gets an argument parser appropriate for this CLI launcher.
   *
   * @return ArgumentParser for parsing args
   */
  public abstract ArgumentParser getArgumentParser();
  /**
   * Indicates whether or not the launcher should print a usage
   * statement based on the content of the arguments passed into
   * the constructor.
@@ -248,14 +265,13 @@
  /**
   * Launches the command line based uninstall.
   *
   * @param args the arguments passed
   * @param cliApp the CLI application to launch
   * @return 0 if everything worked fine, and an error code if something wrong
   *         occurred.
   */
  protected int launchCli(String[] args, CliApplication cliApp) {
  protected int launchCli(CliApplication cliApp) {
    System.setProperty("org.opends.quicksetup.cli", "true");
    QuickSetupCli cli = new QuickSetupCli(cliApp, args);
    QuickSetupCli cli = new QuickSetupCli(cliApp, this);
    int returnValue = cli.run();
    if (returnValue == QuickSetupCli.USER_DATA_ERROR) {
      printUsage(true);
@@ -278,7 +294,21 @@
   * @param toStdErr whether the message must be printed to the standard error
   * or the standard output.
   */
  protected abstract void printUsage(boolean toStdErr);
  protected void printUsage(boolean toStdErr) {
    try
    {
      ArgumentParser argParser = getArgumentParser();
      if (argParser != null) {
        String msg = argParser.getUsage();
        printUsage(msg, toStdErr);
      }
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
  /**
   * Creates a CLI application that will be run if the
@@ -318,7 +348,7 @@
      System.exit(QuickSetupCli.SUCCESSFUL);
    } else if (isCli()) {
      CliApplication cliApp = createCliApplication();
      int exitCode = launchCli(args, cliApp);
      int exitCode = launchCli(cliApp);
      preExit(cliApp);
      System.exit(exitCode);
    } else {
@@ -335,7 +365,7 @@
          guiLaunchFailed(null);
        }
        CliApplication cliApp = createCliApplication();
        exitCode = launchCli(args, cliApp);
        exitCode = launchCli(cliApp);
        if (exitCode != 0) {
          preExit(cliApp);
          System.exit(exitCode);
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ProgressUpdateListenerDelegate.java
New file
@@ -0,0 +1,123 @@
/*
 * 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.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.util.HashSet;
import java.io.File;
/**
 * Delegate class for handling progress notification listeners and events.
 */
public class ProgressUpdateListenerDelegate {
  private HashSet<ProgressUpdateListener> listeners =
          new HashSet<ProgressUpdateListener>();
  private ProgressMessageFormatter formatter;
  /**
   * Creates a parameterized instance.
   * @param formatter for formatting messages.
   */
  public ProgressUpdateListenerDelegate(ProgressMessageFormatter formatter) {
    this.formatter = formatter;
  }
  /**
   * Adds a ProgressUpdateListener that will be notified of updates in
   * the install progress.
   *
   * @param l the ProgressUpdateListener to be added.
   */
  public void addProgressUpdateListener(ProgressUpdateListener l) {
    listeners.add(l);
  }
  /**
   * Removes a ProgressUpdateListener.
   *
   * @param l the ProgressUpdateListener to be removed.
   */
  public void removeProgressUpdateListener(ProgressUpdateListener l) {
    listeners.remove(l);
  }
  /**
   * This method notifies the ProgressUpdateListeners that there was an
   * update in the installation progress.
   *
   * @param current             progress step
   * @param ratio               the integer that specifies which percentage of
   *                            the whole installation has been completed.
   * @param currentPhaseSummary the localized summary message for the
   *                            current installation progress in formatted form.
   * @param newLogDetail        the new log messages that we have for the
   *                            installation in formatted form.
   */
  public void notifyListeners(ProgressStep current, Integer ratio,
                              String currentPhaseSummary,
                              String newLogDetail) {
    ProgressUpdateEvent ev =
            new ProgressUpdateEvent(current, ratio,
                    currentPhaseSummary, newLogDetail);
    for (ProgressUpdateListener l : listeners) {
      l.progressUpdate(ev);
    }
  }
  /**
   * Conditionally notifies listeners of the log file if it
   * has been initialized.
   */
  public void notifyListenersOfLog() {
    File logFile = QuickSetupLog.getLogFile();
    if (logFile != null) {
      notifyListeners(
          formatter.getFormattedProgress(getMsg("general-see-for-details",
              logFile.getPath())) +
          formatter.getLineBreak());
    }
  }
  /**
   * Notify listeners about a change in log detail.
   * @param msg log detail
   */
  protected void notifyListeners(String msg) {
    notifyListeners(null, null, null, msg);
  }
  private String getMsg(String key, String... args) {
    return ResourceProvider.getInstance().getMsg(key, args);
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
@@ -33,6 +33,7 @@
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.server.util.StaticUtils;
/**
 * Controller for managing the execution of a CliApplication.
@@ -80,18 +81,28 @@
  static public int UNKNOWN = 100;
  /** Arguments passed in the command line. */
  protected String[] args;
  protected Launcher launcher;
  private CliApplication cliApp;
  private UserData userData;
  /**
   * Creates a QuickSetupCli instance.
   * @param cliApp the application to be run
   * @param args arguments passed in from the command line
   * @param launcher that launched the app
   */
  public QuickSetupCli(CliApplication cliApp, String[] args) {
  public QuickSetupCli(CliApplication cliApp, Launcher launcher) {
    this.cliApp = cliApp;
    this.args = args;
    this.launcher = launcher;
  }
  /**
   * Gets the user data this application will use when running.
   * @return UserData to use when running
   */
  public UserData getUserData() {
    return this.userData;
  }
  /**
@@ -107,8 +118,7 @@
    // Parse the arguments
    try
    {
      CurrentInstallStatus installStatus = new CurrentInstallStatus();
      UserData userData = cliApp.createUserData(args, installStatus);
      userData = cliApp.createUserData(launcher);
      if (userData != null)
      {
        ProgressMessageFormatter formatter =
@@ -117,15 +127,8 @@
        cliApp.setProgressMessageFormatter(formatter);
        if (!userData.isSilent()) {
          cliApp.addProgressUpdateListener(
              new ProgressUpdateListener()
              {
                /**
                 * ProgressUpdateListener implementation.
                 * @param ev the ProgressUpdateEvent we receive.
                 *
                 */
                public void progressUpdate(ProgressUpdateEvent ev)
                {
                  new ProgressUpdateListener() {
                    public void progressUpdate(ProgressUpdateEvent ev) {
                  System.out.print(
                          org.opends.server.util.StaticUtils.wrapText(
                                  ev.getNewLogs(),
@@ -133,20 +136,17 @@
                }
              });
        }
        new Thread(cliApp).start();
        while (!cliApp.isFinished())
        {
          try
          {
        Thread appThread = new Thread(cliApp, "CLI Application");
        appThread.start();
        while (!Thread.State.TERMINATED.equals(appThread.getState())) {
          try {
            Thread.sleep(100);
          }
          catch (Exception ex)
          {
          } catch (Exception ex) {
            // do nothing;
          }
        }
        ApplicationException ue = cliApp.getException();
        ApplicationException ue = cliApp.getRunError();
        if (ue != null)
        {
          ApplicationException.Type type = ue.getType();
@@ -186,8 +186,10 @@
    }
    catch (UserDataException uude)
    {
      System.err.println(Constants.LINE_SEPARATOR+uude.getLocalizedMessage()+
          Constants.LINE_SEPARATOR);
      System.err.println();
      System.err.println(StaticUtils.wrapText(uude.getLocalizedMessage(),
              Utils.getCommandLineMaxLineWidth()));
      System.err.println();
      returnValue = USER_DATA_ERROR;
    }
    return returnValue;
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupLog.java
@@ -41,6 +41,9 @@
 */
public class QuickSetupLog {
  /** Suffix for log files. */
  static public final String LOG_FILE_SUFFIX = ".log";
  static private File logFile = null;
  /**
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installandupgrader/InstallAndUpgrader.java
@@ -82,7 +82,7 @@
        QuickSetupLog.initLogFileHandler(
                File.createTempFile(
                        UpgradeLauncher.LOG_FILE_PREFIX,
                        UpgradeLauncher.LOG_FILE_SUFFIX));
                        QuickSetupLog.LOG_FILE_SUFFIX));
    } catch (IOException e) {
      System.err.println(
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
@@ -32,6 +32,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.util.logging.Level;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.CliApplication;
@@ -63,7 +64,6 @@
  static private final Logger LOG =
          Logger.getLogger(InstallLauncher.class.getName());
  /**
   * The main method which is called by the setup command lines.
   *
@@ -82,6 +82,8 @@
    new InstallLauncher(args).launch();
  }
  private ArgumentParser argParser;
  /**
   * Creates a launcher.
   *
@@ -89,43 +91,7 @@
   */
  public InstallLauncher(String[] args) {
    super(args);
  }
  /**
   * {@inheritDoc}
   */
  protected void guiLaunchFailed(String logFileName) {
    if (logFileName != null)
    {
      System.err.println(getMsg("setup-launcher-gui-launched-failed-details",
          logFileName));
    }
    else
    {
      System.err.println(getMsg("setup-launcher-gui-launched-failed"));
    }
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(getMsg("setup-launcher-launching-gui"));
    System.setProperty("org.opends.quicksetup.Application.class",
            "org.opends.quicksetup.installer.offline.OfflineInstaller");
  }
  /**
   * {@inheritDoc}
   */
  protected String getFrameTitle() {
    return getI18n().getMsg("frame-install-title");
  }
  /**
   * {@inheritDoc}
   */
  protected void printUsage(boolean toStdErr) {
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_SETUP_FILE_NAME;
@@ -133,7 +99,8 @@
      scriptName = Installation.UNIX_SETUP_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    ArgumentParser argParser = new ArgumentParser(getClass().getName(),
    argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("setup-launcher-usage-description"),
        false);
    BooleanArgument   addBaseEntry;
@@ -238,8 +205,6 @@
          MSGID_INSTALLDS_DESCRIPTION_HELP);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      String msg = argParser.getUsage();
      printUsage(msg, toStdErr);
    }
    catch (Throwable t)
    {
@@ -251,6 +216,44 @@
  /**
   * {@inheritDoc}
   */
  protected void guiLaunchFailed(String logFileName) {
    if (logFileName != null)
    {
      System.err.println(getMsg("setup-launcher-gui-launched-failed-details",
          logFileName));
    }
    else
    {
      System.err.println(getMsg("setup-launcher-gui-launched-failed"));
    }
  }
  /**
   * {@inheritDoc}
   */
  public ArgumentParser getArgumentParser() {
    return this.argParser;
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(getMsg("setup-launcher-launching-gui"));
    System.setProperty("org.opends.quicksetup.Application.class",
            "org.opends.quicksetup.installer.offline.OfflineInstaller");
  }
  /**
   * {@inheritDoc}
   */
  protected String getFrameTitle() {
    return getI18n().getMsg("frame-install-title");
  }
  /**
   * {@inheritDoc}
   */
  protected CliApplication createCliApplication() {
    // Setup currently has no implemented CliApplication
    // but rather relies on InstallDS from the server
@@ -264,7 +267,7 @@
   * {@inheritDoc}
   */
  @Override
  protected int launchCli(String[] args, CliApplication cliApp) {
  protected int launchCli(CliApplication cliApp) {
    System.setProperty("org.opends.quicksetup.cli", "true");
    if (Utils.isWindows()) {
@@ -276,10 +279,10 @@
    }
    ArrayList<String> newArgList = new ArrayList<String>();
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        if (!args[i].equalsIgnoreCase("--cli") &&
            !args[i].equalsIgnoreCase("-c")) {
          newArgList.add(args[i]);
      for (String arg : args) {
        if (!arg.equalsIgnoreCase("--cli") &&
                !arg.equalsIgnoreCase("-c")) {
          newArgList.add(arg);
        }
      }
    }
@@ -292,7 +295,8 @@
    String[] newArgs = new String[newArgList.size()];
    newArgList.toArray(newArgs);
    LOG.log(Level.INFO, "Launching 'installMain' with args " +
            Utils.listToString(newArgList, " "));
    return org.opends.server.tools.InstallDS.installMain(newArgs);
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -106,6 +106,20 @@
failed.  Check file {0} for more details.\n\nLaunching command line upgrade...
cli-upgrade-unknown-argument=Unknown argument {0}
revert-launcher-usage-description=This utility reverts the current installation \
  of the Directory Server to a version prior to running the upgrade utility.
revert-error-no-history-dir=There are no existing backup locations from \
  prior upgrades.  The 'history' directory does not exist.
revert-error-empty-history-dir=There are no existing backup locations from \
  prior upgrades.  The 'history' directory is empty.
revert-error-null-files-dir=The upgrade backup directory is invalid or could not \
  be determined.
revert-error-not-dir-files-dir=The upgrade backup directory is not a directory.
revert-error-invalid-files-dir=The upgrade backup directory does not appear to \
  contain files backed up from an invocation of the upgrade tool.
revert-error-no-dir=ERROR:  No reversion directory specified.  You must specify \
  one of {0}
#
# Dialog titles
@@ -939,7 +953,34 @@
summary-upgrade-finished-canceled-cli=OpenDS QuickUpgrade Canceled. \
  The upgrade operation was canceled and the installation has been \
  restored to the state it was in before the upgrade operation.
summary-revert-not-started=Starting Reversion...
summary-revert-initializing=Initializing Reversion...
summary-revert-reverting-components=Reverting Components...
summary-revert-verifying=Verifying revert...
summary-revert-history=Recording Reversion History...
summary-revert-cleanup=Cleaning Up...
summary-revert-abort=Canceling Reversion...
summary-revert-finished-successfully-cli=OpenDS Reversion Completed \
  Successfully.  The OpenDS installation at {0} has now been reverted \
  to version {1}.
summary-revert-finished-with-errors-cli=OpenDS Reversion Failed. \
  The reversion operation could not complete successfully due to errors and \
  the installation has been restored to the state it was in before the reversion \
  operation.  See the logs for details on why the reversion operation failed.
summary-revert-finished-with-warnings-cli=OpenDS Reversion Succeeded With \
  Warnings. The reversion operation completed successfully but the reverter \
  had problems that require attention. See the logs for details on the \
  problems.
summary-revert-finished-canceled-cli=OpenDS Reversion Canceled. \
  The upgrade operation was canceled and the installation has been \
  restored to the state it was in before the reversion operation.
#
#
#
#
##
# Progress messages
#
progress-downloading=Downloading
@@ -1190,6 +1231,8 @@
upgrade-verification-failure-view-details=View Error Details
upgrade-file-prompt=Enter the name and path of the OpenDS install file (.zip):
reversion-canceled=Reversion canceled.
#
# Upgrader Panels
#
@@ -1315,6 +1358,7 @@
general-checking-data=Checking Data...
general-loading=Loading...
general-see-for-details=See {0} for a detailed log of this operation.
general-see-for-history=See {0} for a history installation history.
not-available-label=<not available>
general-build-id=Build ID
general-unset=Unset
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -36,7 +36,6 @@
import javax.swing.*;
import java.awt.event.WindowEvent;
import java.io.File;
import java.security.cert.X509Certificate;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -579,20 +578,6 @@
  }
  /**
   * Conditionally notifies listeners of the log file if it
   * has been initialized.
   */
  protected void notifyListenersOfLog() {
    File logFile = QuickSetupLog.getLogFile();
    if (logFile != null) {
      notifyListeners(
          getFormattedProgress(getMsg("general-see-for-details",
              logFile.getPath())) +
          formatter.getLineBreak());
    }
  }
  /**
   * {@inheritDoc}
   */
  public UserInteraction userInteraction() {
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCliHelper.java
@@ -60,14 +60,13 @@
   * user for additional information if what is provided in the arguments is not
   * enough.
   * @param args the arguments provided in the command line.
   * @param installStatus the current install status.
   * @return the UserData object with what the user wants to uninstall
   * and null if the user cancels the uninstallation.
   * @throws UserDataException if there is an error parsing the data
   * in the arguments.
   */
  public UninstallUserData createUserData(String[] args,
      CurrentInstallStatus installStatus) throws UserDataException
  public UninstallUserData createUserData(String[] args
  ) throws UserDataException
  {
    UninstallUserData userData = new UninstallUserData();
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
@@ -77,6 +77,8 @@
    new UninstallLauncher(args).launch();
  }
  private ArgumentParser argParser;
  /**
   * Creates a launcher.
   *
@@ -84,6 +86,39 @@
   */
  public UninstallLauncher(String[] args) {
    super(args);
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_UNINSTALL_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_UNINSTALL_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("uninstall-launcher-usage-description"), false);
    BooleanArgument cli;
    BooleanArgument silent;
    BooleanArgument showUsage;
    try
    {
      cli = new BooleanArgument("cli", 'c', "cli",
          MSGID_UNINSTALLDS_DESCRIPTION_CLI);
      argParser.addArgument(cli);
      silent = new BooleanArgument("silent", 's', "silent",
          MSGID_UNINSTALLDS_DESCRIPTION_SILENT);
      argParser.addArgument(silent);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        MSGID_DESCRIPTION_USAGE);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
  /**
@@ -104,6 +139,13 @@
  /**
   * {@inheritDoc}
   */
  public ArgumentParser getArgumentParser() {
    return this.argParser;
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(getMsg("uninstall-launcher-launching-gui"));
    System.setProperty("org.opends.quicksetup.Application.class",
@@ -124,44 +166,4 @@
    return getI18n().getMsg("frame-uninstall-title");
  }
  /**
   * {@inheritDoc}
   */
  protected void printUsage(boolean toStdErr) {
    ArgumentParser argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("uninstall-launcher-usage-description"), false);
    BooleanArgument cli;
    BooleanArgument silent;
    BooleanArgument showUsage;
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_UNINSTALL_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_UNINSTALL_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    try
    {
      cli = new BooleanArgument("cli", 'c', "cli",
          MSGID_UNINSTALLDS_DESCRIPTION_CLI);
      argParser.addArgument(cli);
      silent = new BooleanArgument("silent", 's', "silent",
          MSGID_UNINSTALLDS_DESCRIPTION_SILENT);
      argParser.addArgument(silent);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        MSGID_DESCRIPTION_USAGE);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      String msg = argParser.getUsage();
      printUsage(msg, toStdErr);
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
@@ -388,10 +388,11 @@
  /**
   * {@inheritDoc}
   * @param launcher
   */
  public UserData createUserData(String[] args, CurrentInstallStatus status)
  public UserData createUserData(Launcher launcher)
          throws UserDataException {
    return cliHelper.createUserData(args, status);
    return cliHelper.createUserData(launcher.getArguments());
  }
  /**
@@ -408,7 +409,7 @@
   * @return the ApplicationException that might occur during installation or
   *         <CODE>null</CODE> if no exception occurred.
   */
  public ApplicationException getException() {
  public ApplicationException getRunError() {
    return ue;
  }
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
@@ -66,7 +66,7 @@
      QuickSetupLog.initLogFileHandler(
              File.createTempFile(
                      UpgradeLauncher.LOG_FILE_PREFIX + "ext-",
                      UpgradeLauncher.LOG_FILE_SUFFIX));
                      QuickSetupLog.LOG_FILE_SUFFIX));
    } catch (Throwable t) {
      System.err.println(
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
@@ -164,8 +164,9 @@
  /**
   * {@inheritDoc}
   * @param launcher
   */
  public UserData createUserData(String[] args, CurrentInstallStatus status)
  public UserData createUserData(Launcher launcher)
          throws UserDataException
  {
    return helper.createUserData(args);
@@ -204,7 +205,7 @@
  /**
   * {@inheritDoc}
   */
  public ApplicationException getException() {
  public ApplicationException getRunError() {
    return error;
  }
@@ -229,4 +230,5 @@
                              String newLogDetail) {
    // ignored;  no progress messages
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java
@@ -80,7 +80,8 @@
    } else {
      throw new UserDataException(null,
              getMsg("error-option-required-or-interactive",
                      "-" + FILE_OPTION_SHORT + "/--" + FILE_OPTION_LONG));
                      "-" + UpgradeLauncher.FILE_OPTION_SHORT + "/--" +
                              UpgradeLauncher.FILE_OPTION_LONG));
    }
    return uud;
  }
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionLauncher.java
New file
@@ -0,0 +1,216 @@
/*
 * 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.Launcher;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.ServerConstants;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.OPTION_SHORT_HELP;
import static org.opends.server.tools.ToolConstants.OPTION_LONG_HELP;
import java.io.File;
/**
 * Launches a reversion operation.
 */
public class ReversionLauncher extends Launcher {
  /** Short form of the option for specifying the reversion files directory. */
  static public final Character DIRECTORY_OPTION_SHORT = 'd';
  /** Long form of the option for specifying the reversion files directory. */
  static public final String DIRECTORY_OPTION_LONG = "directory";
  /** Short form of the option for specifying the 'most recent' option. */
  static public final Character MOST_RECENT_OPTION_SHORT = 'm';
  /** Long form of the option for specifying the 'most recent' option. */
  static public final String MOST_RECENT_OPTION_LONG = "mostRecent";
  static private final String LOG_FILE_PREFIX = "opends-revert-";
  /**
   * Creates and launches a reversion operation.
   * @param args from the command line
   */
  static public void main(String[] args) {
    try {
      QuickSetupLog.initLogFileHandler(
              File.createTempFile(LOG_FILE_PREFIX,
                      QuickSetupLog.LOG_FILE_SUFFIX));
    } catch (Throwable t) {
      System.err.println(
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
      t.printStackTrace();
    }
    new ReversionLauncher(args).launch();
  }
  private ArgumentParser argParser;
  private BooleanArgument showUsage;
  private FileBasedArgument dir;
  private BooleanArgument mostRecent;
  private BooleanArgument silent;
  private BooleanArgument interactive;
  /**
   * Gets the file's directory if specified on the command line.
   * @return File representing the directory where the reversion files are
   * stored.
   */
  public File getFilesDirectory() {
    File f = null;
    String s = dir.getValue();
    if (s != null) {
      f = new File(s);
    }
    return f;
  }
  /**
   * Indicates whether the user has specified the 'mostRecent' option.
   * @return boolean where true indicates use the most recent upgrade backup
   */
  public boolean useMostRecentUpgrade() {
    return mostRecent.isPresent();
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isCli() {
    // for now only CLI is supported via command line
    return true;
  }
  /**
   * {@inheritDoc}
   */
  protected String getFrameTitle() {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  protected CliApplication createCliApplication() {
    return new Reverter();
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    // not supported;
  }
  /**
   * {@inheritDoc}
   */
  protected void guiLaunchFailed(String logFileName) {
    // not supported;
  }
  /**
   * {@inheritDoc}
   */
  public ArgumentParser getArgumentParser() {
    return argParser;
  }
  /**
   * Creates a new launcher.
   * @param args from the command line
   */
  protected  ReversionLauncher(String[] args) {
    super(args);
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_REVERT_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_REVERT_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("revert-launcher-usage-description"), false);
    try
    {
      dir = new FileBasedArgument("directory",
              DIRECTORY_OPTION_SHORT,
              DIRECTORY_OPTION_LONG,
              false, false,
              "{directory}",
              null, null, MSGID_REVERT_DESCRIPTION_DIRECTORY);
      argParser.addArgument(dir);
      mostRecent = new BooleanArgument("mostRecent",
              MOST_RECENT_OPTION_SHORT,
              MOST_RECENT_OPTION_LONG,
              MSGID_REVERT_DESCRIPTION_RECENT);
      argParser.addArgument(mostRecent);
      interactive = new BooleanArgument("interactive", 'i', "interactive",
          MSGID_REVERT_DESCRIPTION_INTERACTIVE);
      argParser.addArgument(interactive);
      silent = new BooleanArgument("silent", 's', "silent",
          MSGID_REVERT_DESCRIPTION_SILENT);
      argParser.addArgument(silent);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        MSGID_DESCRIPTION_USAGE);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      argParser.parseArguments(args);
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
  private void validate(ArgumentParser argParser) {
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionProgressStep.java
New file
@@ -0,0 +1,103 @@
/*
 * 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.ProgressStep;
/**
 * Steps during the reversion process.
 */
enum ReversionProgressStep implements ProgressStep {
  NOT_STARTED("summary-revert-not-started", 0),
  INITIALIZING("summary-revert-initializing", 20),
  STOPPING_SERVER("summary-stopping", 40),
  REVERTING_FILESYSTEM("summary-revert-reverting-components", 60),
  VERIFYING("summary-revert-verifying", 80),
  RECORDING_HISTORY("summary-revert-history", 90),
  CLEANUP("summary-revert-cleanup", 95),
  ABORT("summary-revert-abort", 99),
  FINISHED_WITH_ERRORS("summary-revert-finished-with-errors-cli", 100),
  FINISHED_WITH_WARNINGS("summary-revert-finished-with-warnings-cli", 100),
  FINISHED_CANCELED("summary-revert-finished-canceled-cli", 100),
  FINISHED("summary-revert-finished-successfully-cli", 100);
  private String summaryMsgKey;
  private int progress;
  private ReversionProgressStep(String summaryMsgKey, int progress) {
    this.summaryMsgKey = summaryMsgKey;
    this.progress = progress;
  }
  /**
   * Return a key for access a summary message.
   *
   * @return String representing key for access summary in resource bundle
   */
  public String getSummaryMesssageKey() {
    return summaryMsgKey;
  }
  /**
   * Gets the amount of progress to show in the progress meter for this step.
   *
   * @return int representing progress
   */
  public int getProgress() {
    return this.progress;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isLast() {
    return this == FINISHED ||
            this == FINISHED_WITH_ERRORS ||
            this == FINISHED_WITH_WARNINGS ||
            this == FINISHED_CANCELED;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isError() {
    return this == FINISHED_WITH_ERRORS;
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Reverter.java
New file
@@ -0,0 +1,709 @@
/*
 * 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.CliApplication;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.UserDataException;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ProgressUpdateListenerDelegate;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.Status;
import org.opends.quicksetup.ProgressStep;
import org.opends.quicksetup.BuildInformation;
import org.opends.quicksetup.Application;
import org.opends.quicksetup.HistoricalRecord;
import org.opends.quicksetup.UserInteraction;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ServerController;
import org.opends.quicksetup.util.FileManager;
import java.io.File;
import java.io.IOException;
import java.io.FilenameFilter;
import java.io.FileFilter;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * Reverts an installation from its current version to a prior version.
 */
public class Reverter extends Application implements CliApplication {
  static private final Logger LOG =
          Logger.getLogger(Reverter.class.getName());
  private ReversionProgressStep currentProgressStep =
          ReversionProgressStep.NOT_STARTED;
  private ReverterUserData userData;
  private ProgressMessageFormatter formatter;
  private ProgressUpdateListenerDelegate listenerDelegate;
  private ApplicationException runError;
  private ApplicationException runWarning;
  private Installation installation;
  private File tempBackupDir;
  private long historicalOperationId;
  private BuildInformation fromBuildInfo;
  private BuildInformation toBuildInfo;
  private boolean abort = false;
  /**
   * {@inheritDoc}
   */
  public UserData createUserData(Launcher launcher) throws UserDataException {
    ReverterUserData ud = null;
    if (launcher instanceof ReversionLauncher) {
      ud = new ReverterUserData();
      ReversionLauncher rl = (ReversionLauncher)launcher;
      File filesDir = null;
      if (rl.useMostRecentUpgrade()) {
        Installation install = getInstallation();
        File historyDir = install.getHistoryDirectory();
        if (historyDir.exists()) {
          FilenameFilter filter = new FilenameFilter() {
            public boolean accept(File dir, String name) {
              return !Installation.HISTORY_LOG_FILE_NAME.equals(name);
            }
          };
          String[] childNames = historyDir.list(filter);
          if (childNames != null && childNames.length > 0) {
            // The directories beneath 'history' are named according
            // to the system time at which they were generated.
            // Go through the directory names in order of most
            // recent to oldest looking for the first one that
            // looks like a backup directory
            Arrays.sort(childNames);
            for (String childName : childNames) {
              File b = new File(historyDir, childName);
              File d = new File(b, Installation.HISTORY_BACKUP_FILES_DIR_NAME);
              if (isFilesDirectory(d)) {
                filesDir = d;
                break;
              }
            }
          } else {
            throw new UserDataException(null,
                    getMsg("revert-error-empty-history-dir"));
          }
        } else {
          throw new UserDataException(null,
                  getMsg("revert-error-no-history-dir"));
        }
      } else {
        filesDir = rl.getFilesDirectory();
        if (filesDir != null) {
          // Automatically append the 'filesDir' subdirectory if necessary
          if (!filesDir.getName().
                  endsWith(Installation.HISTORY_BACKUP_FILES_DIR_NAME)) {
            filesDir = new File(filesDir,
                    Installation.HISTORY_BACKUP_FILES_DIR_NAME);
          }
        } else {
          StringBuilder sb = new StringBuilder()
                  .append("-")
                  .append(ReversionLauncher.DIRECTORY_OPTION_SHORT)
                  .append("/--")
                  .append(ReversionLauncher.DIRECTORY_OPTION_LONG)
                  .append(", -")
                  .append(ReversionLauncher.MOST_RECENT_OPTION_SHORT)
                  .append("/--")
                  .append(ReversionLauncher.MOST_RECENT_OPTION_LONG);
          throw new UserDataException(null,
                  getMsg("revert-error-no-dir", sb.toString()));
        }
      }
      if (validateFilesDirectory(filesDir)) {
        ud.setFilesDirectory(filesDir);
      }
    }
    return ud;
  }
  /**
   * {@inheritDoc}
   */
  public UserData getUserData() {
    return this.userData;
  }
  /**
   * {@inheritDoc}
   */
  public void setUserData(UserData userData) {
    if (userData instanceof ReverterUserData) {
      this.userData = (ReverterUserData)userData;
    }
  }
  /**
   * {@inheritDoc}
   */
  public void setProgressMessageFormatter(ProgressMessageFormatter formatter) {
    this.formatter = formatter;
    this.listenerDelegate = new ProgressUpdateListenerDelegate(formatter);
  }
  /**
   * {@inheritDoc}
   */
  public ApplicationException getRunError() {
    return this.runError;
  }
  /**
   * {@inheritDoc}
   */
  public void addProgressUpdateListener(ProgressUpdateListener l) {
    listenerDelegate.addProgressUpdateListener(l);
  }
  /**
   * {@inheritDoc}
   */
  public void removeProgressUpdateListener(ProgressUpdateListener l) {
    listenerDelegate.removeProgressUpdateListener(l);
  }
  /**
   * {@inheritDoc}
   */
  public void notifyListeners(Integer ratio,
                              String currentPhaseSummary,
                              String newLogDetail) {
    listenerDelegate.notifyListeners(null,
            ratio,
            currentPhaseSummary,
            newLogDetail);
  }
  /**
   * {@inheritDoc}
   */
  public String getInstallationPath() {
    String installationPath = null;
    String path = Utils.getInstallPathFromClasspath();
    if (path != null) {
      File f = new File(path);
      if (f.getParentFile() != null &&
              f.getParentFile().getParentFile() != null &&
              new File(f.getParentFile().getParentFile(),
                      Installation.LOCKS_PATH_RELATIVE).exists()) {
        installationPath = Utils.getPath(f.getParentFile().getParentFile());
      } else {
        installationPath = path;
      }
    }
    return installationPath;
  }
  /**
   * {@inheritDoc}
   */
  public ProgressStep getCurrentProgressStep() {
    return this.currentProgressStep;
  }
  /**
   * {@inheritDoc}
   */
  public Integer getRatio(ProgressStep step) {
    Integer ratio = null;
    if (step instanceof ReversionProgressStep) {
      ratio = ((ReversionProgressStep)step).getProgress();
    }
    return ratio;
  }
  /**
   * {@inheritDoc}
   */
  public String getSummary(ProgressStep step) {
    String txt;
    if (step == ReversionProgressStep.FINISHED) {
      txt = getFinalSuccessMessage();
//    } else if (step == ReversionProgressStep.FINISHED_CANCELED) {
//      txt = getFinalCanceledMessage();
//    } else if (step == ReversionProgressStep.FINISHED_WITH_ERRORS) {
//      txt = getFinalErrorMessage();
//    } else if (step == ReversionProgressStep.FINISHED_WITH_WARNINGS) {
//      txt = getFinalWarningMessage();
    }
    else {
      txt = getMsg(((ReversionProgressStep) step).getSummaryMesssageKey());
    }
    return txt;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isFinished() {
    return getCurrentProgressStep() ==
            ReversionProgressStep.FINISHED
            || getCurrentProgressStep() ==
            ReversionProgressStep.FINISHED_WITH_ERRORS
            || getCurrentProgressStep() ==
            ReversionProgressStep.FINISHED_WITH_WARNINGS
            || getCurrentProgressStep() ==
            ReversionProgressStep.FINISHED_CANCELED;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isCancellable() {
    return false;
  }
  /**
   * {@inheritDoc}
   */
  public void cancel() {
    // not supported
  }
  /**
   * Gets the OpenDS installation associated with the execution of this
   * command.
   * @return Installation object representing the current OpenDS installation
   */
  public Installation getInstallation() {
    if (installation == null) {
      String installPath = getInstallationPath();
      if (installPath != null) {
        installation = new Installation(installPath);
      }
    }
    return installation;
  }
  /**
   * {@inheritDoc}
   */
  public void run() {
    try {
      initialize();
      UserInteraction ui = userInteraction();
      if (ui != null) {
        String cont = "Continue";
        String cancel = "Cancel";
        String toBuildString = null;
        BuildInformation toBi = getToBuildInformation();
        if (toBi != null) {
          toBuildString = toBi.toString();
        } else {
          toBuildString = getMsg("upgrade-build-id-unknown");
        }
        if (cancel.equals(ui.confirm("Confirm Reversion",
                "This installation will be reverted to version " +
                        toBuildString +
                        " using the files in " + getFilesDirectory() + ".",
                "Confirm",
                UserInteraction.MessageType.WARNING,
                new String[] { cont, cancel },
                cont))) {
          throw new ApplicationException(ApplicationException.Type.CANCEL,
                  getMsg("reversion-canceled"), null);
        }
      }
      stopServer();
      revertFiles();
    } catch (Throwable e) {
      if (!(e instanceof ApplicationException)) {
        runError = new ApplicationException(
                ApplicationException.Type.BUG,
                e.getLocalizedMessage(), e);
      } else {
        runError = (ApplicationException)e;
      }
    } finally {
      end();
    }
  }
  private void setCurrentProgressStep(ReversionProgressStep step) {
    this.currentProgressStep = step;
    int progress = step.getProgress();
    String msg = getSummary(step);
    notifyListeners(progress, msg, formatter.getFormattedProgress(msg));
  }
  private void initialize() throws ApplicationException {
    this.historicalOperationId =
      writeInitialHistoricalRecord(
              getFromBuildInformation(),
              getToBuildInformation());
  }
  private void stopServer() throws ApplicationException {
    Installation installation = getInstallation();
    Status status = installation.getStatus();
    if (status.isServerRunning()) {
      setCurrentProgressStep(ReversionProgressStep.STOPPING_SERVER);
      ServerController sc = new ServerController(installation);
      sc.stopServer(true);
    }
  }
  private void revertFiles() throws ApplicationException {
    backupFilesytem();
    revertComponents();
  }
  private void backupFilesytem() throws ApplicationException {
    try {
      File filesBackupDirectory = getTempBackupDirectory();
      FileManager fm = new FileManager();
      File root = getInstallation().getRootDirectory();
      FileFilter filter = new UpgradeFileFilter(root);
      for (String fileName : root.list()) {
        File f = new File(root, fileName);
        //fm.copyRecursively(f, filesBackupDirectory,
        fm.move(f, filesBackupDirectory, filter);
      }
    } catch (ApplicationException ae) {
      throw ae;
    } catch (Exception e) {
      throw new ApplicationException(
              ApplicationException.Type.FILE_SYSTEM_ERROR,
              getMsg("error-backup-filesystem"),
              e);
    }
  }
  private void revertComponents() throws ApplicationException {
    try {
      File stageDir = getFilesDirectory();
      Installation installation = getInstallation();
      File root = installation.getRootDirectory();
      FileManager fm = new FileManager();
      for (String fileName : stageDir.list()) {
        File f = new File(stageDir, fileName);
        fm.copyRecursively(f, root,
                new UpgradeFileFilter(stageDir),
                /*overwrite=*/true);
      }
      // The bits should now be of the new version.  Have
      // the installation update the build information so
      // that it is correct.
      LOG.log(Level.INFO, "reverted bits to " +
              installation.getBuildInformation(false));
    } catch (IOException e) {
      throw ApplicationException.createFileSystemException(
              getMsg("error-upgrading-components"), e);
    }
  }
  private File getFilesDirectory()
          throws ApplicationException, IOException {
    return userData.getFilesDirectory();
  }
  private boolean validateFilesDirectory(File filesDir)
          throws UserDataException
  {
    if (filesDir == null) {
      throw new UserDataException(null,
              getMsg("revert-error-null-files-dir"));
    } else if (!filesDir.isDirectory()) {
      throw new UserDataException(null,
              getMsg("revert-error-not-dir-files-dir"));
    } else if (!isFilesDirectory(filesDir)) {
      throw new UserDataException(null,
              getMsg("revert-error-not-dir-files-dir"));
    }
    return true;
  }
  private boolean isFilesDirectory(File filesDir) {
    boolean isFilesDir = false;
    if (filesDir != null && filesDir.isDirectory()) {
      String[] children = filesDir.list();
      Set<String> cs = new HashSet<String>(Arrays.asList(children));
      // TODO:  more testing of file dir
      isFilesDir = cs.contains(Installation.CONFIG_PATH_RELATIVE) &&
              cs.contains(Installation.LIBRARIES_PATH_RELATIVE);
    }
    return isFilesDir;
  }
  private void end() {
    try {
      HistoricalRecord.Status status;
      String note = null;
      if (runError == null && !abort) {
        status = HistoricalRecord.Status.SUCCESS;
      } else {
        if (abort) {
          status = HistoricalRecord.Status.CANCEL;
        } else {
          status = HistoricalRecord.Status.FAILURE;
          note = runError.getLocalizedMessage();
        }
        // Abort the reversion and put things back like we found it
        LOG.log(Level.INFO, "canceling reversion");
        ProgressStep lastProgressStep = currentProgressStep;
        setCurrentProgressStep(ReversionProgressStep.ABORT);
        abort(lastProgressStep);
        notifyListeners(formatter.getFormattedDone() +
                formatter.getLineBreak());
        LOG.log(Level.INFO, "cancelation complete");
      }
      LOG.log(Level.INFO, "cleaning up after reversion");
      setCurrentProgressStep(ReversionProgressStep.CLEANUP);
      cleanup();
      notifyListeners(formatter.getFormattedDone() +
              formatter.getLineBreak());
      LOG.log(Level.INFO, "clean up complete");
      // Write a record in the log file indicating success/failure
      LOG.log(Level.INFO, "recording history");
      setCurrentProgressStep(ReversionProgressStep.RECORDING_HISTORY);
      writeHistoricalRecord(historicalOperationId,
              getFromBuildInformation(),
              getToBuildInformation(),
              status,
              note);
      notifyListeners(formatter.getFormattedDone() +
              formatter.getLineBreak());
      LOG.log(Level.INFO, "history recorded");
      notifyListeners(getMsg("general-see-for-history",
              Utils.getPath(getInstallation().getHistoryLogFile())) +
              formatter.getLineBreak());
    } catch (ApplicationException e) {
      notifyListeners(formatter.getFormattedError() +
              formatter.getLineBreak());
      LOG.log(Level.INFO, "Error cleaning up after upgrade.", e);
    }
    // Decide final status based on presense of error
    // WARNING: change this code at your own risk!  The ordering
    // of these statements is important.  There are differences
    // in how the CLI and GUI application's processes exit.
    // Changing the ordering here may result in messages being
    // skipped because the process has already exited by the time
    // processing messages has finished.  Need to resolve these
    // issues.
    if (abort) {
      LOG.log(Level.INFO, "upgrade canceled by user");
      setCurrentProgressStep(ReversionProgressStep.FINISHED_CANCELED);
    } else if (runError != null) {
      LOG.log(Level.INFO, "upgrade completed with errors", runError);
      notifyListeners(formatter.getFormattedError(runError, true) +
                      formatter.getLineBreak());
      notifyListeners(formatter.getLineBreak());
      setCurrentProgressStep(ReversionProgressStep.FINISHED_WITH_ERRORS);
      notifyListeners(formatter.getLineBreak());
    } else if (runWarning != null) {
      LOG.log(Level.INFO, "upgrade completed with warnings");
      String warningText = runWarning.getLocalizedMessage();
      // By design, the warnings are written as errors to the details section
      // as errors.  Warning markup is used surrounding the main message
      // at the end of progress.
      notifyListeners(formatter.getFormattedError(warningText, true) +
                      formatter.getLineBreak());
      notifyListeners(formatter.getLineBreak());
      setCurrentProgressStep(ReversionProgressStep.FINISHED_WITH_WARNINGS);
      notifyListeners(formatter.getLineBreak());
    } else {
      LOG.log(Level.INFO, "reversion completed successfully");
      setCurrentProgressStep(ReversionProgressStep.FINISHED);
    }
  }
  /**
   * Abort this reversion and repair the installation.
   *
   * @param lastStep ProgressStep indicating how much work we will have to
   *                 do to get the installation back like we left it
   * @throws ApplicationException of something goes wrong
   */
  private void abort(ProgressStep lastStep) throws ApplicationException {
    // This can be used to bypass the aborted reversion cleanup
    // process so that an autopsy can be performed on the
    // crippled server.
    if ("true".equals(System.getProperty(Upgrader.SYS_PROP_NO_ABORT))) {
      return;
    }
    ReversionProgressStep lastReversionStep = (ReversionProgressStep) lastStep;
    EnumSet<ReversionProgressStep> stepsStarted =
            EnumSet.range(ReversionProgressStep.NOT_STARTED, lastReversionStep);
    if (stepsStarted.contains(ReversionProgressStep.REVERTING_FILESYSTEM)) {
      // Files were copied from the reversion directory to the current
      // directory.  Repair things by overwriting file in the
      // root with those that were copied to the backup directory
      // during revertFiles()
      File root = getInstallation().getRootDirectory();
      File backupDirectory;
      try {
        backupDirectory = getTempBackupDirectory();
        FileManager fm = new FileManager();
        boolean restoreError = false;
        for (String fileName : backupDirectory.list()) {
          File f = new File(backupDirectory, fileName);
          // Do our best to restore the filesystem like
          // we found it.  Just report potential problems
          // to the user.
          try {
            fm.move(f, root, null);
          } catch (Throwable t) {
            restoreError = true;
            notifyListeners(getMsg("error-restoring-file",
                    Utils.getPath(f),
                    Utils.getPath(root)));
          }
        }
        if (!restoreError) {
          fm.deleteRecursively(backupDirectory);
        }
        // Restart the server after putting the files
        // back like we found them.
        ServerController sc = new ServerController(getInstallation());
        sc.stopServer(true);
        sc.startServer(true);
      } catch (IOException e) {
        LOG.log(Level.INFO, "Error getting backup directory", e);
      }
    }
  }
  private void cleanup() {
    // TODO:
  }
  /**
   * Gets the directory that will be used to store the bits that this
   * reversion operation will replace.  The bits are stored in case there
   * is a problem with this reversion in which case they can be restored.
   *
   * @return File directory where the unreverted bits will be stored.
   */
  private File getTempBackupDirectory()
          throws IOException, ApplicationException
  {
    if (tempBackupDir == null) {
      tempBackupDir = new File(getInstallation().getTemporaryDirectory(),
              Installation.HISTORY_BACKUP_FILES_DIR_NAME);
      if (tempBackupDir.exists()) {
        FileManager fm = new FileManager();
        fm.deleteRecursively(tempBackupDir);
      }
      if (!tempBackupDir.mkdirs()) {
        throw new IOException("error creating files backup directory");
      }
    }
    return tempBackupDir;
  }
  private BuildInformation getFromBuildInformation() {
    if (fromBuildInfo == null) {
      if (currentProgressStep.ordinal() <
              ReversionProgressStep.REVERTING_FILESYSTEM.ordinal()) {
        try {
          fromBuildInfo = installation.getBuildInformation(false);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to obtain 'from' build information", e);
        }
      }
    }
    return fromBuildInfo;
  }
  private BuildInformation getToBuildInformation() {
    if (toBuildInfo == null) {
      if (currentProgressStep.ordinal() >
              ReversionProgressStep.REVERTING_FILESYSTEM.ordinal()) {
        try {
          toBuildInfo = installation.getBuildInformation(false);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to obtain 'from' build information", e);
        }
      } else {
        // TODO: try to determine build info from backed up bits
      }
    }
    return toBuildInfo;
  }
  private String getFinalSuccessMessage() {
    String txt;
    String installPath = Utils.getPath(getInstallation().getRootDirectory());
    String newVersion;
    try {
      BuildInformation bi = getInstallation().getBuildInformation();
      if (bi != null) {
        newVersion = bi.toString();
      } else {
        newVersion = getMsg("reversion-build-id-unknown");
      }
    } catch (ApplicationException e) {
      newVersion = getMsg("reversion-build-id-unknown");
    }
    String[] args = {
            formatter.getFormattedText(installPath),
            newVersion};
    txt = getMsg("summary-revert-finished-successfully-cli", args);
    return txt;
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/ReverterUserData.java
New file
@@ -0,0 +1,57 @@
/*
 * 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.UserData;
import java.io.File;
/**
 * Holds state data specific to a reversion operation.
 */
class ReverterUserData extends UserData {
  File filesDir = null;
  /**
   * Gets the directory where the files are stored for the reversion.
   * @return File where the reversion files are kept
   */
  public File getFilesDirectory() {
    return filesDir;
  }
  /**
   * Sets the directory where the files are stored for the reversion.
   * @param files where the reversion files are kept
   */
  public void setFilesDirectory(File files) {
    this.filesDir = files;
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeFileFilter.java
New file
@@ -0,0 +1,72 @@
/*
 * 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.util.Utils;
import java.io.FileFilter;
import java.io.File;
import java.util.Set;
import java.util.HashSet;
/**
   * Filter defining files we want to manage in the upgrade
 * process.
 */
class UpgradeFileFilter implements FileFilter {
  Set<File> filesToIgnore;
  /**
   * Creates a filter for ignoring in an OpenDS installation at
   * <code>root</code>certain OpenDS files below root.
   * @param root the root of the installation
   */
  public UpgradeFileFilter(File root) { //throws IOException {
    this.filesToIgnore = new HashSet<File>();
    for (String rootFileNamesToIgnore :
            Upgrader.ROOT_FILES_TO_IGNORE_DURING_BACKUP) {
      filesToIgnore.add(new File(root, rootFileNamesToIgnore));
    }
  }
  /**
   * {@inheritDoc}
   */
  public boolean accept(File file) {
    boolean accept = true;
    for (File ignoreFile : filesToIgnore) {
      if (ignoreFile.equals(file) ||
              Utils.isParentOf(ignoreFile, file)) {
        accept = false;
        break;
      }
    }
    return accept;
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeIssueNotifier.java
File was renamed from opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeOracle.java
@@ -40,13 +40,13 @@
import java.util.logging.Level;
/**
 * {@link org.opends.quicksetup.upgrader.VersionOracle} specific
 * {@link org.opends.quicksetup.upgrader.VersionIssueNotifier} specific
 * to upgrade tools.
 */
public class UpgradeOracle extends VersionOracle {
public class UpgradeIssueNotifier extends VersionIssueNotifier {
  static private final Logger LOG =
          Logger.getLogger(UpgradeOracle.class.getName());
          Logger.getLogger(UpgradeIssueNotifier.class.getName());
  /**
   * Creates a new instance that can analyze a hypothetical upgrade/reversion
@@ -55,7 +55,7 @@
   * @param current BuildInformation representing the current version
   * @param neu BuildInformation representing the proposed next version
   */
  public UpgradeOracle(UserInteraction ui,
  public UpgradeIssueNotifier(UserInteraction ui,
                       BuildInformation current,
                       BuildInformation neu) {
    super(ui, current, neu);
@@ -72,7 +72,7 @@
      List<Directive> issues = getIssues();
      if (!isSupported()) {
        if (issues != null) {
          for (VersionOracle.Directive directive : issues) {
          for (VersionIssueNotifier.Directive directive : issues) {
            LOG.log(Level.INFO, "Unsupported upgrade details: " +
                    directive.getMessage());
          }
@@ -81,7 +81,7 @@
                getMsg("upgrade-oracle-unsupported", args), null);
      } else {
        if (ui != null) {
          for (VersionOracle.Directive directive : issues) {
          for (VersionIssueNotifier.Directive directive : issues) {
            String title;
            String summary;
            String details;
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
@@ -53,12 +53,15 @@
  /** Prefix for log files. */
  static public final String LOG_FILE_PREFIX = "opends-upgrade-";
  /** Suffix for log files. */
  static public final String LOG_FILE_SUFFIX = ".log";
  static private final Logger LOG =
          Logger.getLogger(UpgradeLauncher.class.getName());
  /** 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";
  /**
   * The main method which is called by the setup command lines.
   *
@@ -67,7 +70,8 @@
  public static void main(String[] args) {
    try {
      QuickSetupLog.initLogFileHandler(
              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
              File.createTempFile(LOG_FILE_PREFIX,
                      QuickSetupLog.LOG_FILE_SUFFIX));
    } catch (Throwable t) {
      System.err.println(
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
@@ -76,6 +80,8 @@
    new UpgradeLauncher(args).launch();
  }
  private ArgumentParser argParser;
  /**
   * {@inheritDoc}
   */
@@ -95,41 +101,14 @@
   * {@inheritDoc}
   */
  protected void printUsage(boolean toStdErr) {
    ArgumentParser argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("upgrade-launcher-usage-description"), false);
    BooleanArgument showUsage;
    FileBasedArgument file;
    BooleanArgument silent;
    BooleanArgument interactive;
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_UPGRADE_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_UPGRADE_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    try
    {
      file = new FileBasedArgument("file", 'f',
          "file", false, false,
          "{file}",
          null, null, MSGID_UPGRADE_DESCRIPTION_FILE);
      argParser.addArgument(file);
      interactive = new BooleanArgument("interactive", 'i', "interactive",
          MSGID_UPGRADE_DESCRIPTION_INTERACTIVE);
      argParser.addArgument(interactive);
      silent = new BooleanArgument("silent", 's', "silent",
          MSGID_UPGRADE_DESCRIPTION_SILENT);
      argParser.addArgument(silent);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        MSGID_DESCRIPTION_USAGE);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      ArgumentParser argParser = getArgumentParser();
      if (argParser != null) {
      String msg = argParser.getUsage();
      printUsage(msg, toStdErr);
    }
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
@@ -169,12 +148,62 @@
  }
  /**
   * {@inheritDoc}
   */
  public ArgumentParser getArgumentParser() {
    return argParser;
  }
  /**
   * Creates an instance.
   *
   * @param args specified on command line
   */
  protected UpgradeLauncher(String[] args) {
    super(args);
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_UPGRADE_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_UPGRADE_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    argParser = new ArgumentParser(getClass().getName(),
        getI18n().getMsg("upgrade-launcher-usage-description"), false);
    BooleanArgument showUsage;
    FileBasedArgument file;
    BooleanArgument silent;
    BooleanArgument interactive;
    try
    {
      file = new FileBasedArgument(
              "file",
              FILE_OPTION_SHORT,
              FILE_OPTION_LONG,
              false, false,
              "{file}",
              null, null, MSGID_UPGRADE_DESCRIPTION_FILE);
      argParser.addArgument(file);
      interactive = new BooleanArgument("interactive", 'i', "interactive",
          MSGID_UPGRADE_DESCRIPTION_INTERACTIVE);
      argParser.addArgument(interactive);
      silent = new BooleanArgument("silent", 's', "silent",
          MSGID_UPGRADE_DESCRIPTION_SILENT);
      argParser.addArgument(silent);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        MSGID_DESCRIPTION_USAGE);
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeProgressStep.java
New file
@@ -0,0 +1,128 @@
/*
 * 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.ProgressStep;
/**
   * Steps during the upgrade process.
 */
enum UpgradeProgressStep implements ProgressStep {
  NOT_STARTED("summary-upgrade-not-started", 0),
  DOWNLOADING("summary-upgrade-downloading", 10),
  EXTRACTING("summary-upgrade-extracting", 20),
  INITIALIZING("summary-upgrade-initializing", 30),
  CHECK_SERVER_HEALTH("summary-upgrade-check-server-health", 35),
  CALCULATING_SCHEMA_CUSTOMIZATIONS(
          "summary-upgrade-calculating-schema-customization", 40),
  CALCULATING_CONFIGURATION_CUSTOMIZATIONS(
          "summary-upgrade-calculating-config-customization", 48),
  BACKING_UP_DATABASES("summary-upgrade-backing-up-db", 50),
  BACKING_UP_FILESYSTEM("summary-upgrade-backing-up-files",52),
  UPGRADING_COMPONENTS("summary-upgrade-upgrading-components", 60),
  PREPARING_CUSTOMIZATIONS("summary-upgrade-preparing-customizations", 65),
  APPLYING_SCHEMA_CUSTOMIZATIONS(
          "summary-upgrade-applying-schema-customization", 70),
  APPLYING_CONFIGURATION_CUSTOMIZATIONS(
          "summary-upgrade-applying-config-customization", 75),
  VERIFYING("summary-upgrade-verifying", 80),
  STARTING_SERVER("summary-starting", 90),
  STOPPING_SERVER("summary-stopping", 90),
  RECORDING_HISTORY("summary-upgrade-history", 97),
  CLEANUP("summary-upgrade-cleanup", 99),
  ABORT("summary-upgrade-abort", 99),
  FINISHED_WITH_ERRORS("summary-upgrade-finished-with-errors", 100),
  FINISHED_WITH_WARNINGS("summary-upgrade-finished-with-warnings", 100),
  FINISHED_CANCELED("summary-upgrade-finished-canceled", 100),
  FINISHED("summary-upgrade-finished-successfully", 100);
  private String summaryMsgKey;
  private int progress;
  private UpgradeProgressStep(String summaryMsgKey, int progress) {
    this.summaryMsgKey = summaryMsgKey;
    this.progress = progress;
  }
  /**
   * Return a key for access a summary message.
   *
   * @return String representing key for access summary in resource bundle
   */
  public String getSummaryMesssageKey() {
    return summaryMsgKey;
  }
  /**
   * Gets the amount of progress to show in the progress meter for this step.
   * @return int representing progress
   */
  public int getProgress() {
    return this.progress;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isLast() {
    return this == FINISHED ||
            this == FINISHED_WITH_ERRORS ||
            this == FINISHED_WITH_WARNINGS ||
            this == FINISHED_CANCELED;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isError() {
    return this == FINISHED_WITH_ERRORS;
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -39,9 +39,10 @@
import org.opends.quicksetup.ButtonName;
import org.opends.quicksetup.UserDataException;
import org.opends.quicksetup.BuildInformation;
import org.opends.quicksetup.CurrentInstallStatus;
import org.opends.quicksetup.UserInteraction;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.HistoricalRecord;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.webstart.WebStartDownloader;
import org.opends.quicksetup.util.Utils;
@@ -76,7 +77,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
@@ -88,104 +88,6 @@
 */
public class Upgrader extends GuiApplication implements CliApplication {
  /**
   * Steps during the upgrade process.
   */
  enum UpgradeProgressStep implements ProgressStep {
    NOT_STARTED("summary-upgrade-not-started", 0),
    DOWNLOADING("summary-upgrade-downloading", 10),
    EXTRACTING("summary-upgrade-extracting", 20),
    INITIALIZING("summary-upgrade-initializing", 30),
    CHECK_SERVER_HEALTH("summary-upgrade-check-server-health", 35),
    CALCULATING_SCHEMA_CUSTOMIZATIONS(
            "summary-upgrade-calculating-schema-customization", 40),
    CALCULATING_CONFIGURATION_CUSTOMIZATIONS(
            "summary-upgrade-calculating-config-customization", 48),
    BACKING_UP_DATABASES("summary-upgrade-backing-up-db", 50),
    BACKING_UP_FILESYSTEM("summary-upgrade-backing-up-files",52),
    UPGRADING_COMPONENTS("summary-upgrade-upgrading-components", 60),
    PREPARING_CUSTOMIZATIONS("summary-upgrade-preparing-customizations", 65),
    APPLYING_SCHEMA_CUSTOMIZATIONS(
            "summary-upgrade-applying-schema-customization", 70),
    APPLYING_CONFIGURATION_CUSTOMIZATIONS(
            "summary-upgrade-applying-config-customization", 75),
    VERIFYING("summary-upgrade-verifying", 80),
    STARTING_SERVER("summary-starting", 90),
    STOPPING_SERVER("summary-stopping", 90),
    RECORDING_HISTORY("summary-upgrade-history", 97),
    CLEANUP("summary-upgrade-cleanup", 99),
    ABORT("summary-upgrade-abort", 99),
    FINISHED_WITH_ERRORS("summary-upgrade-finished-with-errors", 100),
    FINISHED_WITH_WARNINGS("summary-upgrade-finished-with-warnings", 100),
    FINISHED_CANCELED("summary-upgrade-finished-canceled", 100),
    FINISHED("summary-upgrade-finished-successfully", 100);
    private String summaryMsgKey;
    private int progress;
    private UpgradeProgressStep(String summaryMsgKey, int progress) {
      this.summaryMsgKey = summaryMsgKey;
      this.progress = progress;
    }
    /**
     * Return a key for access a summary message.
     *
     * @return String representing key for access summary in resource bundle
     */
    public String getSummaryMesssageKey() {
      return summaryMsgKey;
    }
    /**
     * Gets the amount of progress to show in the progress meter for this step.
     * @return int representing progress
     */
    public int getProgress() {
      return this.progress;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isLast() {
      return this == FINISHED ||
              this == FINISHED_WITH_ERRORS ||
              this == FINISHED_WITH_WARNINGS ||
              this == FINISHED_CANCELED;
    }
    /**
     * {@inheritDoc}
     */
    public boolean isError() {
      return this == FINISHED_WITH_ERRORS;
    }
  }
  static private final Logger LOG = Logger.getLogger(Upgrader.class.getName());
  /**
@@ -215,11 +117,11 @@
   * changes is made a no-op leaving the server in the
   * erroneous state.
   */
  static private final String SYS_PROP_NO_ABORT =
  static final String SYS_PROP_NO_ABORT =
          "org.opends.quicksetup.upgrader.NoAbort";
  // Root files that will be ignored during backup
  static private final String[] ROOT_FILES_TO_IGNORE_DURING_BACKUP = {
  static final String[] ROOT_FILES_TO_IGNORE_DURING_BACKUP = {
          CHANGELOG_PATH_RELATIVE, // changelogDb
          DATABASES_PATH_RELATIVE, // db
          LOGS_PATH_RELATIVE, // logs
@@ -288,7 +190,7 @@
        QuickSetupLog.initLogFileHandler(
                File.createTempFile(
                        UpgradeLauncher.LOG_FILE_PREFIX,
                        UpgradeLauncher.LOG_FILE_SUFFIX));
                        QuickSetupLog.LOG_FILE_SUFFIX));
    } catch (IOException e) {
      System.err.println(
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
@@ -1134,9 +1036,9 @@
        notifyListeners(formatter.getFormattedDone() +
                formatter.getLineBreak());
        LOG.log(Level.INFO, "history recorded");
        notifyListeners("See '" +
                Utils.getPath(getInstallation().getHistoryLogFile()) +
                " for upgrade history" + formatter.getLineBreak());
        notifyListeners(getMsg("general-see-for-history",
                Utils.getPath(getInstallation().getHistoryLogFile())) +
                formatter.getLineBreak());
      } catch (ApplicationException e) {
        notifyListeners(formatter.getFormattedError() +
                formatter.getLineBreak());
@@ -1279,45 +1181,6 @@
  }
  private Long writeInitialHistoricalRecord(
          BuildInformation fromVersion,
          BuildInformation toVersion)
          throws ApplicationException {
    Long id;
    try {
      HistoricalLog log =
              new HistoricalLog(getInstallation().getHistoryLogFile());
      id = log.append(fromVersion, toVersion,
              HistoricalRecord.Status.STARTED,
              "log file '" + QuickSetupLog.getLogFile().getPath() + "'");
    } catch (IOException e) {
      String msg = getMsg("error-logging-operation");
      throw ApplicationException.createFileSystemException(
              msg, e);
    }
    return id;
  }
  private void writeHistoricalRecord(
          Long id,
          BuildInformation from,
          BuildInformation to,
          HistoricalRecord.Status status,
          String note)
          throws ApplicationException {
    try {
      HistoricalLog log =
              new HistoricalLog(getInstallation().getHistoryLogFile());
      log.append(id, from, to, status, note);
    } catch (IOException e) {
      String msg = getMsg("error-logging-operation");
      throw ApplicationException.createFileSystemException(msg, e);
    }
  }
  private void upgradeComponents() throws ApplicationException {
    try {
      File stageDir = getStageDirectory();
@@ -1490,7 +1353,7 @@
              getMsg("error-determining-upgrade-build"), e);
    }
    UpgradeOracle uo = new UpgradeOracle(
    UpgradeIssueNotifier uo = new UpgradeIssueNotifier(
            userInteraction(), currentVersion, newVersion);
    uo.notifyUser();
    if (uo.noServerStartFollowingOperation()) {
@@ -1532,16 +1395,17 @@
  /**
   * {@inheritDoc}
   * @param launcher
   */
  public UserData createUserData(String[] args, CurrentInstallStatus cis)
  public UserData createUserData(Launcher launcher)
          throws UserDataException {
    return getCliHelper().createUserData(args);
    return getCliHelper().createUserData(launcher.getArguments());
  }
  /**
   * {@inheritDoc}
   */
  public ApplicationException getException() {
  public ApplicationException getRunError() {
    return runError;
  }
@@ -1629,7 +1493,8 @@
  }
  private File getFilesBackupDirectory() throws IOException {
    File files = new File(getUpgradeBackupDirectory(), "files");
    File files = new File(getUpgradeBackupDirectory(),
            Installation.HISTORY_BACKUP_FILES_DIR_NAME);
    if (!files.exists()) {
      if (!files.mkdirs()) {
        throw new IOException("error creating files backup directory");
@@ -1668,38 +1533,4 @@
    return stagedVersion;
  }
  /**
   * Filter defining files we want to manage in the upgrade
   * process.
   */
  private class UpgradeFileFilter implements FileFilter {
    Set<File> filesToIgnore;
    public UpgradeFileFilter(File root) throws IOException {
      this.filesToIgnore = new HashSet<File>();
      for (String rootFileNamesToIgnore : ROOT_FILES_TO_IGNORE_DURING_BACKUP) {
        filesToIgnore.add(new File(root, rootFileNamesToIgnore));
      }
      // Definitely want to not back this up since it would create
      // infinite recursion.  This may not be necessary if we are
      // ignoring the entire history directory but its added here for
      // safe measure.
      filesToIgnore.add(getUpgradeBackupDirectory());
    }
    public boolean accept(File file) {
      boolean accept = true;
      for (File ignoreFile : filesToIgnore) {
        if (ignoreFile.equals(file) ||
                Utils.isParentOf(ignoreFile, file)) {
          accept = false;
          break;
        }
      }
      return accept;
    }
  }
}
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
@@ -41,12 +41,6 @@
 */
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());
@@ -79,6 +73,8 @@
  private ArgumentParser createArgumentParser() {
    // TODO: get rid of this method and user launcher.getArgumentParser
    String toolDescription = getMsg("upgrade-launcher-description");
    ArgumentParser argParser = createArgumentParser(
            "org.opends.quicksetup.upgrader.Upgrader",
@@ -90,7 +86,8 @@
    try {
      localInstallPackFileNameArg =
              new StringArgument("install package file",
                      FILE_OPTION_SHORT, FILE_OPTION_LONG,
                      UpgradeLauncher.FILE_OPTION_SHORT,
                      UpgradeLauncher.FILE_OPTION_LONG,
                      false, true, "{install package file}", 0);
      argParser.addArgument(localInstallPackFileNameArg);
    } catch (ArgumentException e) {
opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/VersionIssueNotifier.java
File was renamed from opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/VersionOracle.java
@@ -50,10 +50,10 @@
 * interacting with the user to inform them of an actions or information
 * that they dictate.
 */
public abstract class VersionOracle {
public abstract class VersionIssueNotifier {
  static private final Logger LOG =
          Logger.getLogger(VersionOracle.class.getName());
          Logger.getLogger(VersionIssueNotifier.class.getName());
  /** Descriptor for a directive. */
  protected enum DirectiveType {
@@ -131,7 +131,7 @@
   * @param current build version
   * @param neu build version
   */
  public VersionOracle(UserInteraction ui,
  public VersionIssueNotifier(UserInteraction ui,
                       BuildInformation current,
                       BuildInformation neu) {
    this.ui = ui;
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -9181,6 +9181,13 @@
  public static final int MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1215;
<<<<<<< .mine
  /**
   * Message ID for reverter tool's directory option.
   */
  public static final int MSGID_REVERT_DESCRIPTION_DIRECTORY =
          CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1216;
=======
  /**
   * The message ID for the message that will be used as the
   * description of the advanced mode argument in get-xxx-prop
@@ -9189,8 +9196,29 @@
   */
  public static final int MSGID_DSCFG_DESCRIPTION_ADVANCED_GET =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1216;
>>>>>>> .r2457
  /**
<<<<<<< .mine
   * Message ID for reverter tool's directory option.
   */
  public static final int MSGID_REVERT_DESCRIPTION_RECENT =
          CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1217;
  /**
   * Message ID for reverter tool's directory option.
   */
  public static final int MSGID_REVERT_DESCRIPTION_INTERACTIVE =
          CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1218;
  /**
   * Message ID for reverter tool's directory option.
   */
  public static final int MSGID_REVERT_DESCRIPTION_SILENT =
          CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1219;
  /**
=======
   * The message ID for the message that will be used as the
   * description of the advanced mode argument in create-xxx and
   * set-xxx-prop sub-commands. This takes no arguments.
@@ -9208,6 +9236,7 @@
  /**
>>>>>>> .r2457
   * Associates a set of generic messages with the message IDs defined in this
   * class.
   */
@@ -12181,6 +12210,18 @@
                    "invalid");
    registerMessage(MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE,
                    "Default value");
    registerMessage(MSGID_REVERT_DESCRIPTION_DIRECTORY,
                    "Directory where reversion files are stored.  This " +
                    "should be one of the child directories of the 'history' " +
                    "directory that is created when the upgrade tool is run");
    registerMessage(MSGID_REVERT_DESCRIPTION_RECENT,
                    "Indicates that the installation will be reverted to the " +
                    "state before the most recent upgrade");
    registerMessage(MSGID_REVERT_DESCRIPTION_INTERACTIVE,
                    "Prompt for any required information rather than fail");
    registerMessage(MSGID_REVERT_DESCRIPTION_SILENT,
                    "Perform a silent reversion");
  }
}