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

kenneth_suter
31.43.2007 6df6635f1250c399a2f39d87d0534301ce4c22d7
Exposes the reversion functionality of the upgrader (issue 2169).  Originally it was intended to be exposed as a new script but in order to avoid the negativity of having a command devoted to undoing the upgrade and to avoid more scripts in the top-level directory, I've exposed the functionality as 2 new options in the existing upgrade script.  I will update the Wiki with documentation for these new options soon.

In order to support custom return codes for quicksetup applications I've overhauled the class formerly called ApplicationReturnCode, converting the inner enum to static instances of a new class ReturnCode. This change touched lots of file in a minor way.

Also addressed here:

- Interactivity for both the upgrade and reversion operations

- Additional work needed to tie the reverter into the version issue (flag day) notification framework.

- issue 2170 - upgrader emits NoClassDefFoundError following usage
2 files deleted
2 files added
42 files modified
2390 ■■■■■ changed files
opends/resource/revert 155 ●●●●● patch | view | raw | blame | history
opends/resource/upgrade 33 ●●●●● patch | view | raw | blame | history
opends/resource/upgrade.bat 17 ●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/uninstaller/UninstallGuiLauncher.java 7 ●●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/uninstaller/Uninstaller.java 17 ●●●● patch | view | raw | blame | history
opends/src/guitools/org/opends/guitools/uninstaller/ui/LoginDialog.java 2 ●●● patch | view | raw | blame | history
opends/src/messages/messages/quicksetup.properties 53 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/tools.properties 5 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Application.java 5 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java 1 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ApplicationReturnCode.java 143 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java 6 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java 46 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java 9 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Installation.java 10 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Launcher.java 65 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java 39 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ReturnCode.java 139 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 3 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserInteraction.java 9 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 48 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java 20 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java 6 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java 12 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/GuiUserInteraction.java 12 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java 118 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java 72 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/MigrationManager.java 10 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionIssueNotifier.java 232 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionLauncher.java 147 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionProgressStep.java 6 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Reverter.java 469 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReverterUserData.java 30 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeIssueNotifier.java 8 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java 203 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeUserData.java 25 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java 64 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java 61 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java 10 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/InProcessServerController.java 33 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java 12 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/ServerHealthChecker.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java 6 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/webstart/WebStartDownloader.java 10 ●●●● patch | view | raw | blame | history
opends/resource/revert
File was deleted
opends/resource/upgrade
@@ -135,9 +135,16 @@
  CLASSPATH=${CLASSPATH}:${JAR}
done
export CLASSPATH
# Run the build extractor first.  An exit code of 99 from the extractor
# means that this is indeed an upgrade (as opposed to a reversion) and
# that the upgrade should continue.  An exit code of 98 means that this
# operation is a reversion.  An exit code of 50 means that the usage
# statement was printed and there is nothing else to do
"${JAVA_BIN}" org.opends.quicksetup.upgrader.BuildExtractor "${@}"
RETURN_CODE=$?
if test ${RETURN_CODE} -eq 0
if test ${RETURN_CODE} -eq 99
then
  # Configure the appropriate CLASSPATH.
  # Unlike BuildExtractor, the Upgrader uses
@@ -149,10 +156,34 @@
  done
  # Launch the upgrade process.
  "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
elif test ${RETURN_CODE} -eq 98
then
  # 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}" org.opends.quicksetup.upgrader.ReversionLauncher "${@}"
  fi
elif test ${RETURN_CODE} -eq 50
then
  # Version info was on requested
  exit 0
elif test ${RETURN_CODE} -eq 0
then
  # Usage printed
  exit 0
else
  # Some unknown return code returned
  exit 101
fi
opends/resource/upgrade.bat
@@ -70,9 +70,11 @@
FOR %%x in ("%INSTANCE_ROOT%\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" %%x
set CLASSPATH=%DIR_HOME%\classes;%CLASSPATH%
"%JAVA_BIN%" org.opends.quicksetup.upgrader.BuildExtractor %*
if %errorlevel% == 99 goto upgrader
if %errorlevel% == 98 goto reverter
if %errorlevel% == 50 goto version
if not %errorlevel% == 0 goto end
goto upgrader
if %errorlevel% == 0 goto end
goto error
:upgrader
set CLASSPATH=""
@@ -80,8 +82,19 @@
"%JAVA_BIN%" org.opends.quicksetup.upgrader.UpgradeLauncher %*
goto end
:reverter
if EXIST "%INSTANCE_ROOT%\tmp\revert" rd "%INSTANCE_ROOT%\tmp\revert" /s /q
xcopy "%INSTANCE_ROOT%\lib\*.*" "%INSTANCE_ROOT%\tmp\revert" /E /D /Y
set CLASSPATH=""
FOR %%x in ("%INSTANCE_ROOT%\tmp\revert\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" %%x
"%JAVA_BIN%" org.opends.quicksetup.upgrader.ReversionLauncher %*
goto end
:version
rem version information was requested. Return code should be 0.
exit /B 0
:error
exit /B 101
:end
opends/src/guitools/org/opends/guitools/uninstaller/UninstallGuiLauncher.java
@@ -34,7 +34,7 @@
import java.io.File;
import java.util.logging.Logger;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.util.Utils;
@@ -136,15 +136,14 @@
      {
        printVersion();
      }
      System.exit(ApplicationReturnCode.ReturnCode.PRINT_VERSION
          .getReturnCode());
      System.exit(ReturnCode.PRINT_VERSION.getReturnCode());
    }
    else if (shouldPrintUsage()) {
      if (!argParser.usageOrVersionDisplayed())
      {
        printUsage(false);
      }
      System.exit(ApplicationReturnCode.ReturnCode.SUCCESSFUL.getReturnCode());
      System.exit(ReturnCode.SUCCESSFUL.getReturnCode());
    } else {
      willLaunchGui();
      int exitCode = launchGui(args);
opends/src/guitools/org/opends/guitools/uninstaller/Uninstaller.java
@@ -592,6 +592,13 @@
  }
  /**
   * {@inheritDoc}
   */
  public ReturnCode getReturnCode() {
    return null;
  }
  /**
   * Initialize the different map used in this class.
   */
  private void initMaps() {
@@ -828,7 +835,7 @@
    }
    catch (Throwable t) {
      ue = new ApplicationException(
              ApplicationReturnCode.ReturnCode.BUG,
              ReturnCode.BUG,
              getThrowableMsg(INFO_BUG_MSG.get(), t), t);
      status = UninstallProgressStep.FINISHED_WITH_ERROR;
      Message msg = getFormattedError(ue, true);
@@ -1137,7 +1144,7 @@
        errMsg = INFO_ERROR_DELETING_DIRECTORY.get(file.getAbsolutePath());
      }
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          errMsg, null);
    }
@@ -1250,7 +1257,7 @@
        break;
      default:
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.WINDOWS_SERVICE_ERROR,
            ReturnCode.WINDOWS_SERVICE_ERROR,
                errorMessage, null);
    }
  }
@@ -1869,7 +1876,7 @@
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, errorMessage,
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
    ADSContext adsContext = new ADSContext(ctx);
@@ -1887,7 +1894,7 @@
        ADSContextException.ErrorType.NOT_YET_REGISTERED)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
            ReturnCode.CONFIGURATION_ERROR,
            INFO_REMOTE_ADS_EXCEPTION.get(
                    serverDisplay, ace.toString()), ace);
      }
opends/src/guitools/org/opends/guitools/uninstaller/ui/LoginDialog.java
@@ -59,7 +59,7 @@
import org.opends.quicksetup.Step;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.UserDataCertificateException;
import org.opends.quicksetup.ApplicationReturnCode.ReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
import org.opends.quicksetup.ui.CertificateDialog;
import org.opends.quicksetup.ui.UIFactory;
opends/src/messages/messages/quicksetup.properties
@@ -315,6 +315,8 @@
INFO_ERROR_DETERMINING_SERVER_STATE=Failed to determine the server's state.
INFO_ERROR_DETERMINING_SVN_REV=Error determining installation's Subversion \
 revision number.
INFO_ERROR_DETERMINING_REVERSION_BUILD=Error determining upgrade build \
 information.
INFO_ERROR_DETERMINING_UPGRADE_BUILD=Error determining upgrade build \
 information.
INFO_ERROR_DISABLING_WINDOWS_SERVICE=Error Disabling Windows service.  Try to \
@@ -364,7 +366,9 @@
INFO_ERROR_LOGGING_OPERATION=Error writting operation details to log.
INFO_ERROR_OPTION_REQUIRED=Option %s is required.
INFO_ERROR_OPTION_REQUIRED_OR_INTERACTIVE=Option %s is required when invoking \
 this command in non-interactive mode.  See the usage statement.
 this command in non-prompting mode.  See the usage statement.
INFO_ERROR_OPTIONS_REQUIRED_OR_INTERACTIVE=Additional options are required \
 when invoking this command in non-prompting mode.  See the usage statement.
INFO_ERROR_PARSING_OPTIONS=Error parsing options.
INFO_ERROR_POOLING_INITIALIZATION=Error reading the progress of the \
 initialization with contents from server %s.
@@ -452,6 +456,7 @@
INFO_GENERAL_SEE_FOR_HISTORY=See %s for a history installation history.
INFO_GENERAL_SERVER_STARTED=started
INFO_GENERAL_SERVER_STOPPED=stopped
INFO_GENERAL_UNKNOWN=Unknown
INFO_GENERAL_UNSET=Unset
INFO_GENERAL_UNSPECIFIED=Unspecified
INFO_GENERAL_UNSUPPORTED=Unsupported
@@ -747,19 +752,22 @@
 supported.
INFO_REVERT_ERROR_EMPTY_HISTORY_DIR=There are no existing backup locations \
 from prior upgrades.  The 'history' directory is empty.
INFO_REVERT_ERROR_INVALID_FILES_DIR=The upgrade backup directory does not \
INFO_REVERT_ERROR_INVALID_FILES_DIR=The reversion archive directory does not \
 appear to contain files backed up from an invocation of the upgrade tool.
INFO_REVERT_ERROR_NO_DIR=ERROR:  No reversion directory specified.  You must \
 specify one of %s
INFO_REVERT_ERROR_NO_DIR=ERROR:  No reversion archive directory specified.  \
 You must specify one of %s
INFO_REVERT_ERROR_NO_HISTORY_DIR=There are no existing backup locations from \
 prior upgrades.  The 'history' directory does not exist.
INFO_REVERT_ERROR_NOT_DIR_FILES_DIR=The upgrade backup directory is not a \
INFO_REVERT_ERROR_NOT_DIR_FILES_DIR=The reversion archive directory is not a \
 directory.
INFO_REVERT_ERROR_NULL_FILES_DIR=The upgrade backup directory is invalid or \
INFO_REVERT_ERROR_NULL_FILES_DIR=The reversion archive directory is invalid or \
 could not be determined.
INFO_REVERT_LAUNCHER_USAGE_DESCRIPTION=This utility reverts the current \
 installation of the Directory Server to a version prior to running the \
 upgrade utility.
INFO_REVERT_CONFIRM_TITLE=Confirm Reversion
INFO_REVERT_CONFIRM_PROMPT=This installation will be reverted to version \
 %s using the files in %s.
INFO_REVIEW_CREATE_BASE_ENTRY_LABEL=Only Create Base Entry (%s)
INFO_REVIEW_CREATE_SUFFIX=Create New Base DN %s.Base DN Data: %s
INFO_REVIEW_IMPORT_AUTOMATICALLY_GENERATED=Import Automatically-Generated \
@@ -1028,6 +1036,12 @@
INFO_UPGRADE_CHOOSE_VERSION_REMOTE_WEEKLY=Weekly Builds
INFO_UPGRADE_CHOOSE_VERSION_UNABLE_TO_ACCESS_BUILD_INFO=Unable to access \
 remote build information.
INFO_UPGRADE_OPERATION_PROMPT=Would you like to upgrade this installation to \
  a newer version or revert to an older version?
INFO_UPGRADE_OPERATION_REVERSION=Revert to a previous version
INFO_UPGRADE_OPERATION_UPGRADE=Upgrade to a newer version
INFO_UPGRADE_OPERATION_REVERSION_RESPONSE=Please rerun this command specifying \
  options that indicate a reversion operation.  See the usage guide for details.
INFO_UPGRADE_FILE_PROMPT=Enter the name and path of the OpenDS install file \
 (.zip):
INFO_UPGRADE_LAUNCHER_DESCRIPTION=This utility may be used to upgrade the \
@@ -1040,10 +1054,16 @@
INFO_UPGRADE_LAUNCHER_LAUNCHING_CLI=Launching command line upgrade...
INFO_UPGRADE_LAUNCHER_LAUNCHING_GUI=Launching graphical upgrade...
INFO_UPGRADE_LAUNCHER_USAGE_DESCRIPTION=This utility may be used to upgrade \
 the Directory Server to a newer version.  Use of this tool assumes that you \
 have already downloaded an OpenDS install package (.zip) file.  You can also \
 upgrade your server using the Java Web Start version of this tool by visiting \
 the OpenDS web site at www.opends.org.
 the Directory Server to a newer version or revert to a previous version.%n%n\
 When using this tool to upgrade OpenDS you should first downloaded an OpenDS \
 install package (.zip) file and specify its location using the -f/--file \
 option.  You can also upgrade your server using the Java \
 Web Start version of this tool by visiting the OpenDS web site at \
 www.opends.org.%n%n\
 When using the tool to revert to a previous version you must either indicate \
 that you want to revert to version before the most recent upgrade using the \
 -r/--revertMostRecent option or specify the location of a reversion archive \
 using the -a/--reversionArchive option.%n
INFO_UPGRADE_LOCATION_LABEL=Server to Upgrade:
INFO_UPGRADE_LOCATION_TOOLTIP=File system location of the build that will be \
 upgraded
@@ -1061,6 +1081,19 @@
INFO_UPGRADE_MOD_IGNORE=Attribute or value already exists: %s
INFO_UPGRADE_MOD_NO_SCHEMA=Processed server modifications (schema checking \
 disabled): %s
INFO_REVERSION_ORACLE_WARNING=Reversion warning
INFO_REVERSION_ORACLE_ACTION=Upgrade requires manual action
INFO_REVERSION_ORACLE_INFO=Upgrade information
INFO_REVERSION_ORACLE_UNSUPPORTED=Upgrade not supportedfrom version %s to \
 version %s is not supported.  To upgrade You must uninstall the current \
 server, install the new server, and manually migrate your data.
INFO_REVERSION_TYPE_PROMPT=How would you like to specify the archive used \
 to revert this instance?
INFO_REVERSION_TYPE_PROMPT_RECENT=Use the most recent versioned archive
INFO_REVERSION_TYPE_PROMPT_FILE=Manually specify a reversion archive directory
INFO_REVERSION_DIR_PROMPT=Select a reversion archive directory:
INFO_REVERSION_DIR_WAIT=Initializing archives...
INFO_REVERSION_DIR_FROM_UPGRADE=%s archived on %s
INFO_UPGRADE_ORACLE_ACTION=Upgrade requires manual action
INFO_UPGRADE_ORACLE_INFO=Upgrade information
INFO_UPGRADE_ORACLE_SUCCESS=Upgrade from version %s to version %s is \
opends/src/messages/messages/tools.properties
@@ -1808,7 +1808,7 @@
 line version of this tool
INFO_UPGRADE_DESCRIPTION_NO_PROMPT_1191=Use non-interactive mode.  Prompt for \
 any required information rather than fail
INFO_UPGRADE_DESCRIPTION_SILENT_1192=Perform a quiet upgrade
INFO_UPGRADE_DESCRIPTION_SILENT_1192=Perform a quiet upgrade or reversion
INFO_LDIFIMPORT_DESCRIPTION_COUNT_REJECTS_1195=Count the number of entries \
 rejected by the server and return that value as the exit code (values > 255 \
 will be reduced to 255 due to exit code restrictions)
@@ -2007,3 +2007,6 @@
 passed to the JVM when running the server
SEVERE_ERR_CREATERC_JAVA_HOME_DOESNT_EXIST_1378=The directory %s specified \
 as the JAVA_HOME path does not exist or is not a directory
SEVERE_ERR_UPGRADE_INCOMPATIBLE_ARGS_1379=The argument '%s' is incompatible \
 with '%s'
opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -605,7 +605,8 @@
  public UserInteraction userInteraction() {
    // Note:  overridden in GuiApplication
    UserInteraction ui = null;
    if (!getUserData().isQuiet()) {
    UserData ud = getUserData();
    if (ud != null && ud.isInteractive()) {
      ui = new CliUserInteraction();
    }
    return ui;
@@ -721,7 +722,7 @@
      Message errorMessage = INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get(
          server.getHostPort(true), ne.toString(true));
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, errorMessage,
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          ne);
    }
    return ctx;
opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
@@ -29,7 +29,6 @@
import org.opends.messages.Message;
import org.opends.server.types.OpenDsException;
import static org.opends.quicksetup.ApplicationReturnCode.ReturnCode;
/**
 * This exception is used to encapsulate all the error that we might have
opends/src/quicksetup/org/opends/quicksetup/ApplicationReturnCode.java
File was deleted
opends/src/quicksetup/org/opends/quicksetup/BuildInformation.java
@@ -115,7 +115,7 @@
      }
    } catch (IOException e) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.START_ERROR,
          ReturnCode.START_ERROR,
          INFO_ERROR_CREATING_BUILD_INFO.get(), e);
    } finally {
      if (is != null) {
@@ -389,7 +389,7 @@
    for (String prop : props) {
      if (null == values.get(prop)) {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.TOOL_ERROR,
                ReturnCode.TOOL_ERROR,
                INFO_ERROR_PROP_VALUE.get(prop), null);
      }
    }
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
@@ -72,4 +72,10 @@
   */
  ApplicationException getRunError();
  /**
   * Gets the return code to return to the console.
   * @return return code to return;  if null the return code indicated in the
   *         error returned by <code>getRunError</code> will be used.
   */
  ReturnCode getReturnCode();
}
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
@@ -52,6 +52,7 @@
import java.security.cert.X509Certificate;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.util.logging.Level;
@@ -154,6 +155,47 @@
  }
  /**
   * Interactively prompts (on standard output) the user to provide select
   * one option from a set of options.
   *
   * @param  prompt        The prompt to present to the user.
   * @param  defaultOption The default value returned if the user clicks enter.
   * @param  options       The valid values that can be accepted as user input.
   *
   * @return index of options that was chosen or -1 if none where chosen
   */
  public int promptOptions(Message prompt,
                           Message defaultOption,
                           Message[] options) {
    Message choiceDefault = null;
    List<Message> choiceList = new ArrayList<Message>();
    MessageBuilder mb = new MessageBuilder(prompt);
    for (int i = 0; i < options.length; i++) {
      Message choice = Message.raw(Integer.toString(i + 1));
      choiceList.add(choice);
      if (options[i].equals(defaultOption)) {
        choiceDefault = choice;
      }
      mb.append("\n");
      mb.append(choice);
      mb.append(". ");
      mb.append(options[i]);
    }
    int ret = -1;
    Message resp = promptConfirm(mb.toMessage(), choiceDefault,
            choiceList.toArray(new Message[0]));
    if (resp != null) {
      for (int i = 0; i < choiceList.size(); i++) {
        if (resp.equals(choiceList.get(i))) {
          ret = i;
          break;
        }
      }
    }
    return ret;
  }
  /**
   * Interactively prompts (on standard output) the user to provide a string
   * value.  Any non-empty string will be allowed (the empty string will
   * indicate that the default should be used, if there is one).
@@ -166,7 +208,7 @@
   *
   * @return  The string value read from the user.
   */
  protected String promptForString(Message prompt, String defaultValue) {
  public String promptForString(Message prompt, String defaultValue) {
    String wrappedPrompt = StaticUtils.wrapText(prompt,
            Utils.getCommandLineMaxLineWidth());
@@ -391,6 +433,8 @@
  }
  /**
<<<<<<< .mine
=======
   * Returns <CODE>true</CODE> if this is a quiet session and
   * <CODE>false</CODE> otherwise.  This method relies on the a previous
   * call to createArgumentParser having been made and the parser
opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java
@@ -144,6 +144,15 @@
    return sb.toString();
  }
  /**
   * {@inheritDoc}
   */
  public String promptForString(Message prompt, Message title,
                                String defaultValue) {
    return promptForString(prompt, defaultValue);
  }
  private String createOption(int index, String option) {
    return new StringBuilder().
            append(Integer.toString(index)).
opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -170,16 +170,6 @@
  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";
opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -100,6 +100,46 @@
  }
  /**
   * Indicates whether or not the launcher should print a usage
   * statement based on the content of the arguments passed into
   * the constructor.
   * @return boolean where true indicates usage should be printed
   */
  protected boolean isQuiet() {
    boolean printUsage = false;
    if ((args != null) && (args.length > 0)) {
      for (String arg : args) {
        if (arg.equals("-?") ||
          arg.equalsIgnoreCase("-Q") ||
          arg.equalsIgnoreCase("--quiet")) {
          printUsage = true;
        }
      }
    }
    return printUsage;
  }
  /**
   * Indicates whether or not the launcher should print a usage
   * statement based on the content of the arguments passed into
   * the constructor.
   * @return boolean where true indicates usage should be printed
   */
  protected boolean isNoPrompt() {
    boolean printUsage = false;
    if ((args != null) && (args.length > 0)) {
      for (String arg : args) {
        if (arg.equals("-?") ||
          arg.equalsIgnoreCase("-n") ||
          arg.equalsIgnoreCase("--no-prompt")) {
          printUsage = true;
        }
      }
    }
    return printUsage;
  }
  /**
   * Indicates whether or not the launcher should print a version
   * statement based on the content of the arguments passed into
   * the constructor.
@@ -249,12 +289,11 @@
  {
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
    QuickSetupCli cli = new QuickSetupCli(cliApp, this);
    ApplicationReturnCode.ReturnCode returnValue = cli.run();
    if (returnValue.equals(ApplicationReturnCode.ReturnCode.USER_DATA_ERROR))
    ReturnCode returnValue = cli.run();
    if (returnValue.equals(ReturnCode.USER_DATA_ERROR))
    {
      printUsage(true);
      System.exit(ApplicationReturnCode.ReturnCode.USER_DATA_ERROR
          .getReturnCode());
      System.exit(ReturnCode.USER_DATA_ERROR.getReturnCode());
    }
    return returnValue.getReturnCode();
  }
@@ -317,15 +356,19 @@
   * The main method which is called by the command lines.
   */
  public void launch() {
    if (shouldPrintVersion())
    {
      printVersion();
      System.exit(ApplicationReturnCode.ReturnCode.PRINT_VERSION
          .getReturnCode());
    if (shouldPrintVersion()) {
      ArgumentParser parser = getArgumentParser();
      if (parser == null || !parser.usageOrVersionDisplayed()) {
        printVersion();
      }
      System.exit(ReturnCode.PRINT_VERSION.getReturnCode());
    }
    else if (shouldPrintUsage()) {
      printUsage(false);
      System.exit(ApplicationReturnCode.ReturnCode.SUCCESSFUL.getReturnCode());
      ArgumentParser parser = getArgumentParser();
      if (parser == null || !parser.usageOrVersionDisplayed()) {
        printUsage(false);
      }
      System.exit(ReturnCode.SUCCESSFUL.getReturnCode());
    } else if (isCli()) {
      CliApplication cliApp = createCliApplication();
      int exitCode = launchCli(cliApp);
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
@@ -30,10 +30,10 @@
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.ApplicationReturnCode.ReturnCode;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.server.util.StaticUtils;
import org.opends.messages.Message;
/**
 * This enum contains the different type of ApplicationException that we can
@@ -91,10 +91,13 @@
          cliApp.addProgressUpdateListener(
                  new ProgressUpdateListener() {
                    public void progressUpdate(ProgressUpdateEvent ev) {
                      System.out.print(
                              org.opends.server.util.StaticUtils.wrapText(
                                      ev.getNewLogs(),
                                      Utils.getCommandLineMaxLineWidth()));
                      Message newLogs = ev.getNewLogs();
                      if (newLogs != null) {
                        System.out.print(
                                StaticUtils.wrapText(
                                        newLogs,
                                        Utils.getCommandLineMaxLineWidth()));
                      }
                    }
                  });
        }
@@ -107,21 +110,23 @@
            // do nothing;
          }
        }
        ApplicationException ue = cliApp.getRunError();
        if (ue != null)
        {
          returnValue = ue.getType();
        }
        else
        {
          returnValue = ApplicationReturnCode.ReturnCode.SUCCESSFUL;
        returnValue = cliApp.getReturnCode();
        if (returnValue == null) {
          ApplicationException ue = cliApp.getRunError();
          if (ue != null)
          {
            returnValue = ue.getType();
          }
          else
          {
            returnValue = ReturnCode.SUCCESSFUL;
          }
        }
      }
      else
      {
    else
    {
        // User cancelled installation.
        returnValue = ApplicationReturnCode.ReturnCode.CANCELLED;
        returnValue = ReturnCode.CANCELLED;
      }
    }
    catch (UserDataException uude)
opends/src/quicksetup/org/opends/quicksetup/ReturnCode.java
New file
@@ -0,0 +1,139 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
/**
 * This class defines enumeration of application return code.
 */
public class ReturnCode {
  /**
   * Return code: Application successful.
   */
  public static final ReturnCode SUCCESSFUL = new ReturnCode(0);
  /**
   * Return code: User Cancelled uninstall.
   */
  public static final ReturnCode CANCELLED = new ReturnCode(0);
  /**
   * Return code: User provided invalid data.
   */
  public static final ReturnCode USER_DATA_ERROR = new ReturnCode(2);
  /**
   * Return code: Error accessing file system (reading/writing).
   */
  public static final ReturnCode FILE_SYSTEM_ACCESS_ERROR = new ReturnCode(3);
  /**
   * Error downloading jar files from web start server.  This is specific
   * to the web start installation.
   */
  public static final ReturnCode DOWNLOAD_ERROR = new ReturnCode(4);
  /**
   * Error during the configuration of the Directory Server.
   */
  public static final ReturnCode CONFIGURATION_ERROR = new ReturnCode(5);
  /**
   * Error during the import of data (base entry, from LDIF file or
   * automatically generated data).
   */
  public static final ReturnCode IMPORT_ERROR = new ReturnCode(6);
  /**
   * Error starting the Open DS server.
   */
  public static final ReturnCode START_ERROR = new ReturnCode(7);
  /**
   * Error stopping the Open DS server.
   */
  public static final ReturnCode STOP_ERROR = new ReturnCode(8);
  /**
   * Error enabling the Windows service.
   */
  public static final ReturnCode WINDOWS_SERVICE_ERROR = new ReturnCode(9);
  /**
   * Application specific error.
   */
  public static final ReturnCode APPLICATION_ERROR = new ReturnCode(10);
  /**
   * Error invoking an OpenDS tool.
   */
  public static final ReturnCode TOOL_ERROR = new ReturnCode(11);
  /**
   * Return code: Bug.
   */
  public static final ReturnCode BUG = new ReturnCode(12);
  /**
   * Return code: Bug.
   */
  public static final ReturnCode PRINT_VERSION = new ReturnCode(50);
  /**
   * Return code: Bug.
   */
  public static final ReturnCode PRINT_USAGE = new ReturnCode(51);
  /**
   * Return code for errors that are non-specified.
   */
  public static final ReturnCode UNKNOWN = new ReturnCode(100);
  private int code;
  /**
   * Creates a new parameterized instance.
   *
   * @param code to return
   */
  public ReturnCode(int code) {
    this.code = code;
  }
  /**
   * Gets the return code to return to the console.
   *
   * @return int code
   */
  public int getReturnCode() {
    return code;
  }
}
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -91,6 +91,7 @@
   * Creates a user data object with default values.
   */
  public UserData() {
    interactive = true;
    startServer = true;
    enableWindowsService = false;
    forceOnError = true;
@@ -509,7 +510,7 @@
   * @return boolean where true indicates this session should be interactive
   */
  public boolean isInteractive() {
    return !this.quiet && this.interactive;
    return this.interactive;
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/UserInteraction.java
@@ -106,4 +106,13 @@
   */
  String createUnorderedList(List list);
  /**
   * Promt the user for a string.
   * @param prompt for string
   * @param title of prompt dialog
   * @param defaultValue for default
   * @return String typed by user
   */
  String promptForString(Message prompt, Message title, String defaultValue);
}
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -728,7 +728,7 @@
      Message failedMsg = getThrowableMsg(
              INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          failedMsg, ioe);
    }
  }
@@ -851,13 +851,13 @@
      if (result != 0)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
            ReturnCode.CONFIGURATION_ERROR,
            INFO_ERROR_CONFIGURING.get(), null);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_CONFIGURING.get(), t), t);
    }
@@ -964,7 +964,7 @@
    catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_CONFIGURING_CERTIFICATE.get(),
                  t), t);
    }
@@ -1011,13 +1011,13 @@
      if (result != 0)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
            ReturnCode.CONFIGURATION_ERROR,
            INFO_ERROR_CREATING_BASE_ENTRY.get(), null);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_CREATING_BASE_ENTRY.get(), t), t);
    }
    finally
@@ -1062,13 +1062,13 @@
      if (result != 0)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
            ReturnCode.CONFIGURATION_ERROR,
            INFO_ERROR_IMPORTING_LDIF.get(), null);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_IMPORTING_LDIF.get(), t), t);
    }
  }
@@ -1112,14 +1112,14 @@
      if (result != 0)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
            ReturnCode.CONFIGURATION_ERROR,
            INFO_ERROR_IMPORT_LDIF_TOOL_RETURN_CODE.get(
                    Integer.toString(result)), null);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_IMPORT_AUTOMATICALLY_GENERATED.get(
                  listToString(argList, " "), t.getLocalizedMessage()), t), t);
    }
@@ -1367,7 +1367,7 @@
      Message failedMsg = getThrowableMsg(
              INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, failedMsg, ne);
          ReturnCode.CONFIGURATION_ERROR, failedMsg, ne);
    }
    finally
    {
@@ -1564,7 +1564,7 @@
      setCurrentProgressStep(InstallProgressStep.CANCELING);
      notifyListeners(null);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CANCELLED,
          ReturnCode.CANCELLED,
            INFO_UPGRADE_CANCELED.get(), null);
    }
  }
@@ -1709,7 +1709,7 @@
      {
      }
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, failedMsg, t);
          ReturnCode.CONFIGURATION_ERROR, failedMsg, t);
    }
    Set<SuffixDescriptor> suffixes =
@@ -1737,7 +1737,7 @@
      catch (NamingException ne)
      {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get(
                        server.getHostPort(true),
                        ne.getLocalizedMessage()), ne);
@@ -1784,7 +1784,7 @@
          catch (NamingException ne)
          {
            throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get(
                        server.getHostPort(true),
                        ne.getLocalizedMessage()), ne);
@@ -1820,7 +1820,7 @@
            if (nTries == 1)
            {
              throw new ApplicationException(
                  ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
                  ReturnCode.APPLICATION_ERROR,
                  pnfe.getMessageObject(), null);
            }
            try
@@ -1985,7 +1985,7 @@
      if (remoteServer)
      {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                INFO_CANNOT_CONNECT_TO_REMOTE_PERMISSIONS.get(
                        getHostDisplay(auth)), ne);
      }
@@ -1995,7 +1995,7 @@
        Message failedMsg = getThrowableMsg(
                INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne);
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                failedMsg, ne);
      }
    }
@@ -2004,21 +2004,21 @@
      if (remoteServer)
      {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                INFO_CANNOT_CONNECT_TO_REMOTE_GENERIC.get(
                        getHostDisplay(auth), ne.getLocalizedMessage()), ne);
      }
      else
      {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
                ReturnCode.CONFIGURATION_ERROR,
                getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), ne), ne);
      }
    }
    catch (ADSContextException ace)
    {
      throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
              ReturnCode.CONFIGURATION_ERROR,
              ((remoteServer)
                      ? INFO_REMOTE_ADS_EXCEPTION.get(
                      getHostDisplay(auth), ace.getReason())
@@ -3669,7 +3669,7 @@
      {
        LOG.log(Level.SEVERE, "Error creating task "+attrs, ne);
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
            ReturnCode.APPLICATION_ERROR,
                getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(
                        sourceServerDisplay
                ), ne), ne);
@@ -3822,7 +3822,7 @@
              helper.isStoppedByError(state))
          {
            ApplicationException ae = new ApplicationException(
                ApplicationReturnCode.ReturnCode.APPLICATION_ERROR, errorMsg,
                ReturnCode.APPLICATION_ERROR, errorMsg,
                null);
            if ((lastLogMsg == null) ||
                helper.isPeersNotFoundError(lastLogMsg))
@@ -3851,7 +3851,7 @@
      catch (NamingException ne)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
            ReturnCode.APPLICATION_ERROR,
                getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get(
                        sourceServerDisplay),
                        ne), ne);
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -40,7 +40,7 @@
import javax.naming.ldap.InitialLdapContext;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import static org.opends.quicksetup.util.Utils.*;
import org.opends.server.admin.DefaultBehaviorException;
import org.opends.server.admin.ManagedObjectNotFoundException;
@@ -133,7 +133,7 @@
        break;
      default:
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.WINDOWS_SERVICE_ERROR,
            ReturnCode.WINDOWS_SERVICE_ERROR,
                errorMessage, null);
    }
  }
@@ -148,7 +148,7 @@
    if (code == ConfigureWindowsService.SERVICE_DISABLE_ERROR) {
      throw new ApplicationException(
          // TODO: fix this message's format string
          ApplicationReturnCode.ReturnCode.WINDOWS_SERVICE_ERROR,
          ReturnCode.WINDOWS_SERVICE_ERROR,
              INFO_ERROR_DISABLING_WINDOWS_SERVICE.get(""), null);
    }
  }
@@ -172,7 +172,7 @@
      Message failedMsg =
              getThrowableMsg(INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          failedMsg, ioe);
    }
@@ -190,19 +190,19 @@
      writer.close();
    } catch (DirectoryException de) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
              getThrowableMsg(INFO_ERROR_IMPORTING_LDIF.get(), de), de);
    } catch (LDIFException le) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
              getThrowableMsg(INFO_ERROR_IMPORTING_LDIF.get(), le), le);
    } catch (IOException ioe) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR,
          ReturnCode.CONFIGURATION_ERROR,
              getThrowableMsg(INFO_ERROR_IMPORTING_LDIF.get(), ioe), ioe);
    } catch (Throwable t) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.BUG, getThrowableMsg(
          ReturnCode.BUG, getThrowableMsg(
              INFO_BUG_MSG.get(), t), t);
    }
    return ldifFile;
@@ -398,7 +398,7 @@
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, errorMessage,
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
  }
@@ -502,7 +502,7 @@
      Message errorMessage = INFO_ERROR_CONFIGURING_REMOTE_GENERIC.get(
              serverDisplay, t.toString());
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.CONFIGURATION_ERROR, errorMessage,
          ReturnCode.CONFIGURATION_ERROR, errorMessage,
          t);
    }
  }
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -39,7 +39,7 @@
import java.security.KeyStoreException;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.ProgressStep;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.SecurityOptions;
@@ -159,7 +159,7 @@
    } catch (ApplicationException ex)
    {
      if (ApplicationReturnCode.ReturnCode.CANCELLED.equals(ex.getType())) {
      if (ReturnCode.CANCELLED.equals(ex.getType())) {
        uninstall();
        setCurrentProgressStep(InstallProgressStep.FINISHED_CANCELED);
        notifyListeners(null);
@@ -198,7 +198,7 @@
      updateSummaryWithServerState(hmSummary);
      setCurrentProgressStep(InstallProgressStep.FINISHED_WITH_ERROR);
      ApplicationException ex = new ApplicationException(
          ApplicationReturnCode.ReturnCode.BUG,
          ReturnCode.BUG,
          Utils.getThrowableMsg(INFO_BUG_MSG.get(), t), t);
      Message msg = getFormattedError(ex, true);
      notifyListeners(msg);
opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -37,7 +37,7 @@
import java.util.logging.Logger;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.ProgressStep;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.installer.Installer;
@@ -211,7 +211,7 @@
    } catch (ApplicationException ex)
    {
      if (ApplicationReturnCode.ReturnCode.CANCELLED.equals(ex.getType())) {
      if (ReturnCode.CANCELLED.equals(ex.getType())) {
        uninstall();
        setCurrentProgressStep(InstallProgressStep.FINISHED_CANCELED);
        notifyListeners(null);
@@ -250,7 +250,7 @@
      updateSummaryWithServerState(hmSummary);
      setCurrentProgressStep(InstallProgressStep.FINISHED_WITH_ERROR);
      ApplicationException ex = new ApplicationException(
          ApplicationReturnCode.ReturnCode.BUG,
          ReturnCode.BUG,
          Utils.getThrowableMsg(INFO_BUG_MSG.get(), t), t);
      Message msg = getFormattedError(ex, true);
      notifyListeners(msg);
@@ -407,7 +407,7 @@
    if (in == null)
    {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.DOWNLOAD_ERROR,
          ReturnCode.DOWNLOAD_ERROR,
              INFO_ERROR_ZIPINPUTSTREAMNULL.get(zipName), null);
    }
@@ -431,14 +431,14 @@
        if (!Utils.createDirectory(parent))
        {
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
              ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
              INFO_ERROR_COULD_NOT_CREATE_PARENT_DIR.get(parent), null);
        }
      }
      catch (IOException ioe)
      {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
            ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
            INFO_ERROR_COULD_NOT_CREATE_PARENT_DIR.get(parent),
            ioe);
      }
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -569,7 +569,7 @@
              (t.getMessage() == null) ? t.toString() : t.getMessage());
      LOG.log(Level.INFO, msg.toString(), t);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.IMPORT_ERROR, msg, t);
          ReturnCode.IMPORT_ERROR, msg, t);
    }
  }
@@ -578,7 +578,7 @@
   */
  public UserInteraction userInteraction() {
    UserInteraction ui = null;
    if (!getUserData().isQuiet()) {
    if (!getUserData().isInteractive()) {
      if (Utils.isCli()) {
        ui = new CliUserInteraction();
      } else {
opends/src/quicksetup/org/opends/quicksetup/ui/GuiUserInteraction.java
@@ -148,6 +148,18 @@
  }
  /**
   * {@inheritDoc}
   */
  public String promptForString(Message prompt, Message title,
                                String defaultValue) {
    Object o = JOptionPane.showInputDialog(
            parent, prompt.toString(), title.toString(),
            JOptionPane.QUESTION_MESSAGE,
            null, null, defaultValue);
    return o != null ? o.toString() : null;
  }
  /**
   * JOptionPane that controls the number of characters that are allowed
   * to appear on a single line in the input area of the dialog.
   */
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
@@ -43,10 +43,17 @@
import java.util.logging.Logger;
/**
 * BuildExtractor unzips an OpenDS installation package (.zip file) from a user
 * specified location into the current builds staging directory.  This Java
 * program handles this task so that we don't need to rely on the operating
 * system's tools for managing zip files.
 * BuildExtractor runs prior to an upgrade or reversion operation.  Its main
 * purpose is to unzip an OpenDS installation package (.zip file) from a user
 * specified location into the current builds staging directory.  However,
 * this program is also responsible for determining whether or not this
 * invocation is intended to be an upgrade or reversion operation.  If this
 * is a reversion, this program just exists with the appropriate exit code
 * indicating reversion.  If this is an upgrade this program unzips the
 * installation package.
 *
 * This Java program handles unzipping files so that we don't need to rely on
 * the operating system's tools for managing zip files.
 *
 * This tool is a stand-alone program since it is run in preparation for a
 * off line upgrade and runs using the current program's jars rather than
@@ -60,6 +67,12 @@
  static private final Logger LOG =
          Logger.getLogger(BuildExtractor.class.getName());
  /** Return code indicating that this invocation is an upgrade. */
  private static final int RC_CONTINUE_WITH_UPGRADE = 99;
  /** Return code indicating that this invocation is a reversion. */
  private static final int RC_CONTINUE_WITH_REVERSION = 98;
  /**
   * Creates and run a BuildExtractor using command line arguments.
   * @param args String[] command line arguments
@@ -78,14 +91,14 @@
    new BuildExtractor(args).launch();
  }
  private BuildExtractorCliHelper helper = new BuildExtractorCliHelper();
  private UpgradeUserData userData;
  private boolean finished;
  private ApplicationException error;
  private ReturnCode rc;
  private BuildExtractor(String[] args) {
    super(args);
  }
@@ -101,37 +114,49 @@
   * contents into the current build's staging are and exits with return code 0.
   */
  public void run() {
    try {
      UpgradeUserData uud = (UpgradeUserData)getUserData();
      File buildFile = uud.getInstallPackage();
      if (buildFile != null) {
        LOG.log(Level.INFO, "expanding zip file " + buildFile.getPath());
        File stageDirectory = initStageDirectory();
        ZipExtractor extractor = new ZipExtractor(buildFile);
        extractor.extract(stageDirectory);
        LOG.log(Level.INFO, "extraction finished");
        Installation installation = new Installation(stageDirectory);
        if (!installation.isValid()) {
          LOG.log(Level.INFO, "extraction produed an invalid OpenDS" +
                  "installation: " + installation.getInvalidityReason());
          Message invalidMsg = INFO_BUILD_EXTRACTOR_FILE_INVALID.get(
                  Utils.getPath(buildFile),
                  installation.getInvalidityReason());
          error = new ApplicationException(
              ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
                  invalidMsg, null);
          System.err.println(invalidMsg);
    UpgradeUserData uud = (UpgradeUserData)getUserData();
    if (UpgradeUserData.Operation.REVERSION.equals(uud.getOperation())) {
      rc = new ReturnCode(RC_CONTINUE_WITH_REVERSION);
    } else {
      try {
        File buildFile = uud.getInstallPackage();
        if (buildFile != null) {
          LOG.log(Level.INFO, "Expanding zip file " + buildFile.getPath());
          File stageDirectory = initStageDirectory();
          ZipExtractor extractor = new ZipExtractor(buildFile);
          extractor.extract(stageDirectory);
          LOG.log(Level.INFO, "Extraction finished");
          Installation installation = new Installation(stageDirectory);
          if (!installation.isValid()) {
            LOG.log(Level.INFO, "Extraction produed an invalid OpenDS" +
                    "installation: " + installation.getInvalidityReason());
            Message invalidMsg = INFO_BUILD_EXTRACTOR_FILE_INVALID.get(
                    Utils.getPath(buildFile),
                    installation.getInvalidityReason());
            error = new ApplicationException(
                ReturnCode.APPLICATION_ERROR,
                    invalidMsg, null);
            System.err.println(invalidMsg);
          }
          rc = new ReturnCode(RC_CONTINUE_WITH_UPGRADE);
        } else {
          // This should never happen assuming createUserData did the
          // right thing
          LOG.log(Level.INFO, "Build extractor failed to " +
                  "specify valid installation zip file");
          throw new IllegalStateException("Build extractor failed to " +
                  "specify valid installation zip file");
        }
      } catch (Throwable t) {
        LOG.log(Level.INFO, "Unexpected error extracting build", t);
        String reason = t.getLocalizedMessage();
        error = new ApplicationException(
                ReturnCode.APPLICATION_ERROR,
                INFO_BUILD_EXTRACTOR_ERROR.get(reason), t);
        System.err.println(reason);
      } finally   {
        finished = true;
      }
    } catch (Throwable t) {
      LOG.log(Level.INFO, "unexpected error extracting build", t);
      String reason = t.getLocalizedMessage();
      error = new ApplicationException(
              ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
              INFO_BUILD_EXTRACTOR_ERROR.get(reason), t);
      System.err.println(reason);
    } finally   {
      finished = true;
    }
  }
@@ -173,7 +198,21 @@
  public UserData createUserData(Launcher launcher)
          throws UserDataException
  {
    return helper.createUserData(args);
    BuildExtractorCliHelper helper =
            new BuildExtractorCliHelper((UpgradeLauncher)launcher);
    UpgradeUserData uud = helper.createUserData(args);
    // Build Extractor is always quiet
    uud.setQuiet(true);
    // The user may have indicated the operation via interactivity
    if (UpgradeUserData.Operation.UPGRADE.equals(uud.getOperation())) {
      isUpgrade = true;
    } else if (UpgradeUserData.Operation.REVERSION.equals(uud.getOperation())) {
      isReversion = true;
    }
    return uud;
  }
  /**
@@ -216,6 +255,13 @@
  /**
   * {@inheritDoc}
   */
  public ReturnCode getReturnCode() {
    return rc;
  }
  /**
   * {@inheritDoc}
   */
  public void addProgressUpdateListener(ProgressUpdateListener l) {
    // ignored;  no progress messages
  }
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java
@@ -28,6 +28,7 @@
package org.opends.quicksetup.upgrader;
import static org.opends.messages.QuickSetupMessages.*;
import org.opends.messages.Message;
import org.opends.quicksetup.UserDataException;
@@ -44,6 +45,14 @@
          Logger.getLogger(BuildExtractorCliHelper.class.getName());
  /**
   * Create a parameterized instance.
   * @param launcher for this CLI
   */
  public BuildExtractorCliHelper(UpgradeLauncher launcher) {
    super(launcher);
  }
  /**
   * Creates a set of user data from command line arguments and installation
   * status.
   * @param args String[] of arguments passed in from the command line
@@ -53,37 +62,44 @@
  public UpgradeUserData createUserData(String[] args)
    throws UserDataException {
    UpgradeUserData uud = super.createUserData(args);
    // Build extractor is always quiet whether user
    // has specified this or not.
    uud.setQuiet(true);
    if (localInstallPackFileNameArg.isPresent()) {
      String localInstallPackFileName =
              localInstallPackFileNameArg.getValue();
      LOG.log(Level.INFO, "file specified on command line: " +
              localInstallPackFileName);
      uud.setInstallPackage(
              validateInstallPackFile(localInstallPackFileName));
    } else if (isInteractive()) {
      LOG.log(Level.INFO, "obtaining file information interactively");
      while(true) {
        String fileName = promptForString(
                INFO_UPGRADE_FILE_PROMPT.get(), null);
        try {
          uud.setInstallPackage(validateInstallPackFile(fileName));
          LOG.log(Level.INFO, "file specified interactively: " +
                  fileName);
          break;
        } catch (UserDataException ude) {
          System.out.println(ude.getMessage());
    if (launcher.isInteractive()) {
      if (!launcher.isNoPrompt()) {
        LOG.log(Level.INFO, "obtaining file information interactively");
        Message[] options = new Message[] {
                INFO_UPGRADE_OPERATION_UPGRADE.get(),
                INFO_UPGRADE_OPERATION_REVERSION.get()
        };
        int response = promptOptions(
                INFO_UPGRADE_OPERATION_PROMPT.get(),
                options[0],
                options);
        if (response == 0) {
          uud.setOperation(UpgradeUserData.Operation.UPGRADE);
          while(true) {
            String fileName = promptForString(
                    INFO_UPGRADE_FILE_PROMPT.get(), null);
            try {
              uud.setInstallPackage(validateInstallPackFile(fileName));
              LOG.log(Level.INFO, "file specified interactively: " +
                      fileName);
              break;
            } catch (UserDataException ude) {
              System.out.println(ude.getMessage());
            }
          }
        } else {
          uud.setOperation(UpgradeUserData.Operation.REVERSION);
        }
      } else {
        throw new UserDataException(null,
                INFO_ERROR_OPTIONS_REQUIRED_OR_INTERACTIVE.get());
      }
    } else {
      throw new UserDataException(null,
              INFO_ERROR_OPTION_REQUIRED_OR_INTERACTIVE.get("-" +
                      UpgradeLauncher.FILE_OPTION_SHORT + "/--" +
                              UpgradeLauncher.FILE_OPTION_LONG));
      String upgradeFile = launcher.getUpgradeFileName();
      if (upgradeFile != null) {
        uud.setInstallPackage(
                validateInstallPackFile(upgradeFile));
      }
    }
    return uud;
  }
opends/src/quicksetup/org/opends/quicksetup/upgrader/MigrationManager.java
@@ -32,7 +32,7 @@
import static org.opends.messages.QuickSetupMessages.*;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.UserInteraction;
import org.opends.quicksetup.Constants;
@@ -179,7 +179,7 @@
      Message msg = INFO_ERROR_APPLYING_CUSTOM_CONFIG.get();
      LOG.log(Level.INFO, msg.toString(), e);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.IMPORT_ERROR, msg, e);
          ReturnCode.IMPORT_ERROR, msg, e);
    }
  }
@@ -201,7 +201,7 @@
      Message msg = INFO_ERROR_APPLYING_CUSTOM_SCHEMA.get();
      LOG.log(Level.INFO, msg.toString(), e);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.IMPORT_ERROR, msg, e);
          ReturnCode.IMPORT_ERROR, msg, e);
    }
  }
@@ -274,7 +274,7 @@
            // do nothing; will retry;
          } else {
            throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.CANCELLED,
                ReturnCode.CANCELLED,
                INFO_UPGRADE_CANCELED.get(), e);
          }
        } else {
@@ -341,7 +341,7 @@
    int ret = oo.getReturnCode();
    if (ret != 0) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.TOOL_ERROR,
          ReturnCode.TOOL_ERROR,
              INFO_ERROR_LDIF_DIFF_TOOL_RETURN_CODE.get(Integer.toString(ret)),
              null);
    }
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionIssueNotifier.java
New file
@@ -0,0 +1,232 @@
/*
 * 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.UserInteraction;
import org.opends.quicksetup.BuildInformation;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.Constants;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import static org.opends.messages.QuickSetupMessages.*;
import org.opends.server.util.VersionCompatibilityIssue;
import static org.opends.server.util.VersionCompatibilityIssue.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.util.List;
import java.util.Set;
/**
 * {@link VersionIssueNotifier} specific
 * to upgrade tools.
 */
public class ReversionIssueNotifier extends VersionIssueNotifier {
  static private final Logger LOG =
          Logger.getLogger(ReversionIssueNotifier.class.getName());
  /**
   * Creates a new instance that can analyze a hypothetical upgrade/reversion
   * operation from one version to another.
   * @param ui UserInteraction for relaying information to the user
   * @param current BuildInformation representing the current version
   * @param neu BuildInformation representing the proposed next version
   */
  public ReversionIssueNotifier(UserInteraction ui,
                       BuildInformation current,
                       BuildInformation neu) {
    super(ui, current, neu);
  }
  /**
   * {@inheritDoc}
   */
  public void notifyUser() throws ApplicationException {
    Message cont = INFO_ORACLE_ACTION_PROMPT_CONTINUE.get();
    Message cancel = INFO_ORACLE_ACTION_PROMPT_CANCEL.get();
    if (hasIssues()) {
      List<Directive> issues = getIssues();
      if (!isSupported()) {
        if (issues != null) {
          for (Directive directive : issues) {
            LOG.log(Level.INFO, "Unsupported reversion details: " +
                    directive.getMessage());
          }
        }
        throw new ApplicationException(
            ReturnCode.APPLICATION_ERROR,
                INFO_REVERSION_ORACLE_UNSUPPORTED.get(
                        currentBuildInfo.toString(),
                        newBuildInfo.toString()),
                null);
      } else {
        if (ui != null) {
          for (Directive directive : issues) {
            Message title;
            Message summary;
            Message details;
            Message defaultAction;
            UserInteraction.MessageType msgType;
            switch (directive.getType()) {
              case ACTION:
                title = INFO_GENERAL_ACTION_REQUIRED.get();
                summary = INFO_REVERSION_ORACLE_ACTION.get();
                details = new MessageBuilder(directive.getMessage())
                        .append(Constants.HTML_LINE_BREAK)
                        .append(Constants.HTML_LINE_BREAK)
                        .append(INFO_ORACLE_ACTION_PROMPT.get())
                        .toMessage();
                msgType = UserInteraction.MessageType.WARNING;
                defaultAction = cancel;
                break;
              case INFO:
                title = INFO_GENERAL_INFO.get();
                summary = INFO_REVERSION_ORACLE_INFO.get();
                details = new MessageBuilder(directive.getMessage())
                        .append(Constants.HTML_LINE_BREAK)
                        .append(Constants.HTML_LINE_BREAK)
                        .append(INFO_ORACLE_INFO_PROMPT.get())
                        .toMessage();
                msgType = UserInteraction.MessageType.INFORMATION;
                defaultAction = cont;
                break;
              case WARNING:
                title = INFO_GENERAL_WARNING.get();
                summary = INFO_REVERSION_ORACLE_WARNING.get();
                details = new MessageBuilder(directive.getMessage())
                        .append(Constants.HTML_LINE_BREAK)
                        .append(Constants.HTML_LINE_BREAK)
                        .append(INFO_ORACLE_INFO_PROMPT.get())
                        .toMessage();
                msgType = UserInteraction.MessageType.WARNING;
                defaultAction = cont;
                break;
              default:
                LOG.log(Level.INFO, "Unexpected issue type " +
                        directive.getType());
                title = Message.EMPTY;
                summary = Message.EMPTY;
                details = directive.getMessage();
                msgType = UserInteraction.MessageType.WARNING;
                defaultAction = cont;
            }
            if (cancel.equals(ui.confirm(
                    summary,
                    details,
                    title,
                    msgType,
                    new Message[]{cont, cancel},
                    defaultAction))) {
              throw new ApplicationException(
                  ReturnCode.CANCELLED,
                      INFO_REVERSION_CANCELED.get(), null);
            }
          }
        } else {
          throw new ApplicationException(
              ReturnCode.APPLICATION_ERROR,
              INFO_ORACLE_NO_SILENT.get(), null);
        }
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  protected Message getLocalizedDetailMessage(
          VersionCompatibilityIssue.Cause cause)
  {
    Message msg = cause.getLocalizedUpgradeMessage();
    // See if we need to supply a generic message
    Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects();
    // If the import/export effect is present, append the detailed
    // instructions.
    if (effects.contains(Effect.REVERSION_DATA_EXPORT_AND_REIMPORT_REQUIRED)) {
      msg = new MessageBuilder(msg)
              .append(Constants.HTML_LINE_BREAK)
              .append(ui.createUnorderedList(getExportImportInstructions()))
              .toMessage();
    }
    return msg;
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isActionRequired(VersionCompatibilityIssue.Cause cause) {
    boolean isAction = false;
    if (cause != null) {
      Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects();
      isAction =
              effects.contains(
                      Effect.REVERSION_DATA_EXPORT_AND_REIMPORT_REQUIRED) ||
                      (effects.contains(
                              Effect.REVERSION_MANUAL_ACTION_REQUIRED) &&
                              cause.getLocalizedUpgradeMessage() != null);
    }
    return isAction;
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isWarning(VersionCompatibilityIssue.Cause cause) {
    boolean isWarning = false;
    if (cause != null && !isActionRequired(cause)) {
      Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects();
      isWarning = effects.contains(Effect.REVERSION_SHOW_WARNING_MESSAGE) &&
              cause.getLocalizedUpgradeMessage() != null;
    }
    return isWarning;
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isUnsupported(VersionCompatibilityIssue.Cause cause) {
    boolean isUnsupported = false;
    if (cause != null) {
      Set<VersionCompatibilityIssue.Effect> effects = cause.getEffects();
      for (VersionCompatibilityIssue.Effect effect : effects) {
        switch (effect) {
          case REVERSION_NOT_POSSIBLE:
            isUnsupported = true; break;
          default:
            // assume not an tion;
        }
      }
    }
    return isUnsupported;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionLauncher.java
@@ -27,42 +27,19 @@
package org.opends.quicksetup.upgrader;
import org.opends.messages.Message;
import static org.opends.messages.QuickSetupMessages.*;
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.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.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
import java.io.File;
/**
 * Launches a reversion operation.
 * Launches a reversion operation.  This class just extends UpgradeLauncher
 * which really contains all the smarts for launching reversion/upgrade
 * operations.
 */
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-";
public class ReversionLauncher extends UpgradeLauncher {
  /**
   * Creates and launches a reversion operation.
@@ -80,140 +57,26 @@
    new ReversionLauncher(args).launch();
  }
  private ArgumentParser argParser;
  private BooleanArgument showUsage;
  private FileBasedArgument dir;
  private BooleanArgument mostRecent;
  private BooleanArgument quiet;
  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
  public boolean isReversion() {
    return true;
  }
  /**
   * {@inheritDoc}
   */
  protected Message 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(),
        INFO_REVERT_LAUNCHER_USAGE_DESCRIPTION.get(), false);
    try
    {
      dir = new FileBasedArgument("directory",
              DIRECTORY_OPTION_SHORT,
              DIRECTORY_OPTION_LONG,
              false, false,
              "{directory}",
              null, null, INFO_REVERT_DESCRIPTION_DIRECTORY.get());
      argParser.addArgument(dir);
      mostRecent = new BooleanArgument("mostRecent",
              MOST_RECENT_OPTION_SHORT,
              MOST_RECENT_OPTION_LONG,
              INFO_REVERT_DESCRIPTION_RECENT.get());
      argParser.addArgument(mostRecent);
      interactive = new BooleanArgument("interactive", 'i', "interactive",
          INFO_REVERT_DESCRIPTION_INTERACTIVE.get());
      argParser.addArgument(interactive);
      quiet = new BooleanArgument("quiet",
              OPTION_SHORT_QUIET,
              OPTION_LONG_QUIET,
              INFO_REVERT_DESCRIPTION_SILENT.get());
      argParser.addArgument(quiet);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        INFO_DESCRIPTION_USAGE.get());
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      argParser.parseArguments(args);
    }
    catch (Throwable t)
    {
      System.out.println("ERROR: "+t);
      t.printStackTrace();
    }
  }
  private void validate(ArgumentParser argParser) {
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReversionProgressStep.java
@@ -45,7 +45,9 @@
  REVERTING_FILESYSTEM(INFO_SUMMARY_REVERT_REVERTING_COMPONENTS.get(), 60),
  VERIFYING(INFO_SUMMARY_REVERT_VERIFYING.get(), 80),
  VERIFYING(INFO_SUMMARY_REVERT_VERIFYING.get(), 70),
  STARTING_SERVER(INFO_SUMMARY_STARTING.get(), 80),
  RECORDING_HISTORY(INFO_SUMMARY_REVERT_HISTORY.get(), 90),
@@ -65,7 +67,7 @@
  private Message summaryMsg;
  private int progress;
  private ReversionProgressStep(Message summaryMsgKey, int progress) {
  private ReversionProgressStep(Message summaryMsg, int progress) {
    this.summaryMsg = summaryMsg;
    this.progress = progress;
  }
opends/src/quicksetup/org/opends/quicksetup/upgrader/Reverter.java
@@ -31,7 +31,7 @@
import org.opends.messages.MessageBuilder;
import static org.opends.messages.QuickSetupMessages.*;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.UserDataException;
@@ -45,6 +45,7 @@
import org.opends.quicksetup.Application;
import org.opends.quicksetup.HistoricalRecord;
import org.opends.quicksetup.UserInteraction;
import org.opends.quicksetup.CliUserInteraction;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
@@ -59,8 +60,12 @@
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.text.DateFormat;
/**
 * Reverts an installation from its current version to a prior version.
@@ -74,27 +79,141 @@
          ReversionProgressStep.NOT_STARTED;
  private ReverterUserData userData;
  private ProgressMessageFormatter formatter;
  private ProgressUpdateListenerDelegate listenerDelegate;
  private ApplicationException runError;
  private ApplicationException runWarning;
  private Installation installation;
  private Installation archiveInstallation;
  private File tempBackupDir;
  private long historicalOperationId;
  private BuildInformation fromBuildInfo;
  private BuildInformation toBuildInfo;
  private BuildInformation archiveBuildInfo;
  private boolean abort = false;
  private boolean restartServer = false;
  /**
   * {@inheritDoc}
   */
  public UserData createUserData(Launcher launcher) throws UserDataException {
    ReverterUserData ud = null;
    if (launcher instanceof ReversionLauncher) {
    if (launcher instanceof UpgradeLauncher) {
      ud = new ReverterUserData();
      ReversionLauncher rl = (ReversionLauncher)launcher;
      UpgradeLauncher rl = (UpgradeLauncher)launcher;
      File filesDir = null;
      if (rl.useMostRecentUpgrade()) {
      if (rl.isInteractive()) {
        if (rl.isNoPrompt()) {
          StringBuilder sb = new StringBuilder()
                  .append("-")
                  .append(UpgradeLauncher.REVERT_ARCHIVE_OPTION_SHORT)
                  .append("/--")
                  .append(ReversionLauncher.REVERT_ARCHIVE_OPTION_LONG)
                  .append(", -")
                  .append(ReversionLauncher.REVERT_MOST_RECENT_OPTION_SHORT)
                  .append("/--")
                  .append(ReversionLauncher.REVERT_MOST_RECENT_OPTION_LONG);
          throw new UserDataException(null,
                  INFO_REVERT_ERROR_NO_DIR.get(sb.toString()));
        } else {
          CliUserInteraction ui = new CliUserInteraction();
          Message[] options = new Message[] {
                  INFO_REVERSION_TYPE_PROMPT_RECENT.get(),
                  INFO_REVERSION_TYPE_PROMPT_FILE.get()};
          if (options[0].equals(ui.confirm(
                  INFO_REVERT_CONFIRM_TITLE.get(),
                  INFO_REVERSION_TYPE_PROMPT.get(),
                  INFO_REVERT_CONFIRM_TITLE.get(),
                  UserInteraction.MessageType.QUESTION,
                  options, options[0])))
          {
            ud.setRevertMostRecent(true);
          } else {
            ud.setRevertMostRecent(false);
            // Present a list of reversion archive choices to the user.
            // In the future perhaps we might also allow them to type
            // freehand.
            File historyDir = getInstallation().getHistoryDirectory();
            if (historyDir != null && historyDir.exists()) {
              // Print a wait message, this could take a while
              System.out.println(INFO_REVERSION_DIR_WAIT.get());
              String[] historyChildren = historyDir.list();
              Arrays.sort(historyChildren);
              List<File> raDirList = new ArrayList<File>();
              for (int i = historyChildren.length - 1; i >=0; i--) {
                File raDirCandidate = new File(historyDir, historyChildren[i]);
                if (isReversionFilesDirectory(raDirCandidate)) {
                  raDirList.add(raDirCandidate);
                }
              }
              File[] raDirs = raDirList.toArray(new File[raDirList.size()]);
              List<Message> raDirChoiceList = new ArrayList<Message>();
              for (File raDir : raDirs) {
                String name = raDir.getName();
                Message buildInfo = INFO_UPGRADE_BUILD_ID_UNKNOWN.get();
                Message date = INFO_GENERAL_UNKNOWN.get();
                try {
                  Installation i =
                          new Installation(appendFilesDirIfNeccessary(raDir));
                  BuildInformation bi = i.getBuildInformation();
                  buildInfo = Message.raw(bi.toString());
                } catch (Exception e) {
                  LOG.log(Level.INFO,
                          "Error determining archive version for " + name);
                }
                try {
                  Date d = new Date(Long.valueOf(name));
                  DateFormat df = DateFormat.getInstance();
                  date = Message.raw(df.format(d));
                } catch (Exception e) {
                  LOG.log(Level.INFO, "Error converting reversion archive " +
                          "name " + name + " to date helper");
                }
                MessageBuilder mb = new MessageBuilder(name);
                mb.append(" (");
                mb.append(INFO_REVERSION_DIR_FROM_UPGRADE.get(buildInfo, date));
                mb.append(")");
                raDirChoiceList.add(mb.toMessage());
              }
              Message[] raDirChoices =
                      raDirChoiceList.toArray(new Message[0]);
              if (raDirChoices.length > 0) {
                int resp = ui.promptOptions(
                        INFO_REVERSION_DIR_PROMPT.get(),
                        raDirChoices[0],
                        raDirChoices);
                File raDir = raDirs[resp];
                raDir = appendFilesDirIfNeccessary(raDir);
                try {
                  ud.setReversionArchiveDirectory(
                          validateReversionArchiveDirectory(raDir));
                } catch (UserDataException ude) {
                  System.err.println(ude.getMessageObject());
                }
              } else {
                LOG.log(Level.INFO, "No archives in history dir");
                throw new UserDataException(null,
                        INFO_REVERT_ERROR_NO_HISTORY_DIR.get());
              }
            } else {
              LOG.log(Level.INFO, "History dir does not exist");
              throw new UserDataException(null,
                      INFO_REVERT_ERROR_NO_HISTORY_DIR.get());
            }
          }
        }
      } else if (rl.isRevertMostRecent()) {
        ud.setRevertMostRecent(true);
      } else {
        filesDir = rl.getReversionArchiveDirectory();
        filesDir = appendFilesDirIfNeccessary(filesDir);
        ud.setReversionArchiveDirectory(
                validateReversionArchiveDirectory(filesDir));
      }
      if (ud.isRevertMostRecent()) {
        Installation install = getInstallation();
        File historyDir = install.getHistoryDirectory();
        if (historyDir.exists()) {
@@ -115,8 +234,8 @@
            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;
              if (isReversionFilesDirectory(d)) {
                ud.setReversionArchiveDirectory(d);
                break;
              }
            }
@@ -129,33 +248,9 @@
          throw new UserDataException(null,
                  INFO_REVERT_ERROR_NO_HISTORY_DIR.get());
        }
      } 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,
                  INFO_REVERT_ERROR_NO_DIR.get(sb.toString()));
        }
      }
      if (validateFilesDirectory(filesDir)) {
        ud.setFilesDirectory(filesDir);
      }
      ud.setQuiet(rl.isQuiet());
      ud.setInteractive(!rl.isNoPrompt());
    }
    return ud;
  }
@@ -194,6 +289,13 @@
  /**
   * {@inheritDoc}
   */
  public ReturnCode getReturnCode() {
    return null;
  }
  /**
   * {@inheritDoc}
   */
  public void addProgressUpdateListener(ProgressUpdateListener l) {
    listenerDelegate.addProgressUpdateListener(l);
  }
@@ -324,44 +426,95 @@
  public void run() {
    try {
      initialize();
      // Get the user to confirm if possible
      UserInteraction ui = userInteraction();
      if (ui != null) {
        Message cont = INFO_CONTINUE_BUTTON_LABEL.get();
        Message cancel = INFO_CANCEL_BUTTON_LABEL.get();
        String toBuildString = null;
        BuildInformation toBi = getToBuildInformation();
        String toBuildString;
        BuildInformation toBi = getArchiveBuildInformation();
        if (toBi != null) {
          toBuildString = toBi.toString();
        } else {
          toBuildString = INFO_UPGRADE_BUILD_ID_UNKNOWN.get().toString();
        }
        if (cancel.equals(ui.confirm( // TODO: i18n
                Message.raw("Confirm Reversion"),
                Message.raw("This installation will be reverted to version " +
                        toBuildString +
                        " using the files in " + getFilesDirectory() + "."),
                Message.raw("Confirm"),
        if (cancel.equals(ui.confirm(
                INFO_REVERT_CONFIRM_TITLE.get(),
                INFO_REVERT_CONFIRM_PROMPT.get(
                        toBuildString,
                        Utils.getPath(getReversionFilesDirectory())),
                INFO_REVERT_CONFIRM_TITLE.get(),
                UserInteraction.MessageType.WARNING,
                new Message[] { cont, cancel },
                cont))) {
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.CANCELLED,
              ReturnCode.CANCELLED,
              INFO_REVERSION_CANCELED.get(), null);
        }
      }
      stopServer();
      revertFiles();
      // Stop the server if necessary.  Task note as to whether the server
      // is running since we will leave it in that state when we are done.
      Installation installation = getInstallation();
      Status status = installation.getStatus();
      ServerController sc = new ServerController(installation);
      if (status.isServerRunning()) {
        restartServer = true;
        sc = new ServerController(installation);
        try {
          setCurrentProgressStep(ReversionProgressStep.STOPPING_SERVER);
          LOG.log(Level.INFO, "Stopping server");
          sc.stopServer(true);
          notifyListeners(getFormattedDoneWithLineBreak());
        } catch (ApplicationException ae) {
          notifyListeners(getFormattedErrorWithLineBreak());
        }
      }
      try {
        setCurrentProgressStep(ReversionProgressStep.INITIALIZING);
        initialize();
        notifyListeners(getFormattedDoneWithLineBreak());
      } catch (ApplicationException ae) {
        LOG.log(Level.INFO, "Error initializing reversion", ae);
        notifyListeners(getFormattedErrorWithLineBreak());
        throw ae;
      }
      try {
        LOG.log(Level.INFO, "Reverting components");
        setCurrentProgressStep(ReversionProgressStep.REVERTING_FILESYSTEM);
        revertComponents();
        LOG.log(Level.INFO, "Finished reverting components");
        notifyListeners(getFormattedDoneWithLineBreak());
      } catch (ApplicationException ae) {
        LOG.log(Level.INFO, "Error reverting components", ae);
        notifyListeners(getFormattedErrorWithLineBreak());
        throw ae;
      }
      if (restartServer) {
        try {
          LOG.log(Level.INFO, "Restarting server");
          setCurrentProgressStep(ReversionProgressStep.STARTING_SERVER);
          sc.startServer();
          notifyListeners(getFormattedDoneWithLineBreak());
        } catch (ApplicationException ae) {
          notifyListeners(getFormattedErrorWithLineBreak());
        }
      }
    } catch (Throwable e) {
      if (!(e instanceof ApplicationException)) {
        runError = new ApplicationException(
            ApplicationReturnCode.ReturnCode.BUG,
            ReturnCode.BUG,
                Message.raw(e.getLocalizedMessage()), e);
      } else {
        runError = (ApplicationException)e;
        abort = ReturnCode.CANCELLED.equals(
                ((ApplicationException)e).getType());
      }
    } finally {
      end();
@@ -379,25 +532,13 @@
    this.historicalOperationId =
      writeInitialHistoricalRecord(
              getFromBuildInformation(),
              getToBuildInformation());
              getArchiveBuildInformation());
    insureRevertability();
    backupCurrentInstallation();
  }
  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 {
  private void backupCurrentInstallation() throws ApplicationException {
    LOG.log(Level.INFO, "Backing up filesystem");
    try {
      File filesBackupDirectory = getTempBackupDirectory();
      FileManager fm = new FileManager();
@@ -408,11 +549,14 @@
        //fm.copyRecursively(f, filesBackupDirectory,
        fm.move(f, filesBackupDirectory, filter);
      }
      LOG.log(Level.INFO, "Finished backing up filesystem");
    } catch (ApplicationException ae) {
      LOG.log(Level.INFO, "Error backing up filesystem", ae);
      throw ae;
    } catch (Exception e) {
      LOG.log(Level.INFO, "Error backing up filesystem", e);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
              INFO_ERROR_BACKUP_FILESYSTEM.get(),
              e);
    }
@@ -420,7 +564,7 @@
  private void revertComponents() throws ApplicationException {
    try {
      File stageDir = getFilesDirectory();
      File stageDir = getReversionFilesDirectory();
      Installation installation = getInstallation();
      File root = installation.getRootDirectory();
      FileManager fm = new FileManager();
@@ -434,7 +578,7 @@
      // 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 " +
      LOG.log(Level.INFO, "Reverted bits to " +
              installation.getBuildInformation(false));
    } catch (IOException e) {
@@ -443,12 +587,12 @@
    }
  }
  private File getFilesDirectory()
  private File getReversionFilesDirectory()
          throws ApplicationException, IOException {
    return userData.getFilesDirectory();
    return userData.getReversionArchiveDirectory();
  }
  private boolean validateFilesDirectory(File filesDir)
  private File validateReversionArchiveDirectory(File filesDir)
          throws UserDataException
  {
    if (filesDir == null) {
@@ -457,16 +601,17 @@
    } else if (!filesDir.isDirectory()) {
      throw new UserDataException(null,
              INFO_REVERT_ERROR_NOT_DIR_FILES_DIR.get());
    } else if (!isFilesDirectory(filesDir)) {
    } else if (!isReversionFilesDirectory(filesDir)) {
      throw new UserDataException(null,
              INFO_REVERT_ERROR_NOT_DIR_FILES_DIR.get());
    }
    return true;
    return filesDir;
  }
  private boolean isFilesDirectory(File filesDir) {
  private boolean isReversionFilesDirectory(File filesDir) {
    filesDir = appendFilesDirIfNeccessary(filesDir);
    boolean isFilesDir = false;
    if (filesDir != null && filesDir.isDirectory()) {
    if (filesDir != null && filesDir.exists() && filesDir.isDirectory()) {
      String[] children = filesDir.list();
      Set<String> cs = new HashSet<String>(Arrays.asList(children));
@@ -483,6 +628,15 @@
      String note = null;
      if (runError == null && !abort) {
        status = HistoricalRecord.Status.SUCCESS;
        // Since everything went OK, delete the archive
        LOG.log(Level.INFO, "Cleaning up after reversion");
        setCurrentProgressStep(ReversionProgressStep.CLEANUP);
        deleteArchive();
        deleteBackup();
        notifyListeners(getFormattedDoneWithLineBreak());
        LOG.log(Level.INFO, "Clean up complete");
      } else {
        if (abort) {
          status = HistoricalRecord.Status.CANCEL;
@@ -492,32 +646,29 @@
        }
        // Abort the reversion and put things back like we found it
        LOG.log(Level.INFO, "canceling reversion");
        LOG.log(Level.INFO, "Canceling reversion");
        ProgressStep lastProgressStep = currentProgressStep;
        setCurrentProgressStep(ReversionProgressStep.ABORT);
        abort(lastProgressStep);
        notifyListeners(getFormattedDoneWithLineBreak());
        LOG.log(Level.INFO, "cancelation complete");
        LOG.log(Level.INFO, "Cancelation complete");
      }
      LOG.log(Level.INFO, "cleaning up after reversion");
      setCurrentProgressStep(ReversionProgressStep.CLEANUP);
      cleanup();
      notifyListeners(getFormattedDoneWithLineBreak());
      LOG.log(Level.INFO, "clean up complete");
      // Remove the lib directory temporarily created by the
      // launch script with which the program is running
      deleteReversionLib();
      // Write a record in the log file indicating success/failure
      LOG.log(Level.INFO, "recording history");
      LOG.log(Level.INFO, "Recording history");
      setCurrentProgressStep(ReversionProgressStep.RECORDING_HISTORY);
      writeHistoricalRecord(historicalOperationId,
              getFromBuildInformation(),
              getToBuildInformation(),
              getArchiveBuildInformation(),
              status,
              note);
      notifyListeners(getFormattedDoneWithLineBreak());
      LOG.log(Level.INFO, "history recorded");
      LOG.log(Level.INFO, "History recorded");
      notifyListeners(
              new MessageBuilder(
                INFO_GENERAL_SEE_FOR_HISTORY.get(
@@ -525,7 +676,7 @@
              .append(getLineBreak()).toMessage());
    } catch (ApplicationException e) {
      notifyListeners(getFormattedDoneWithLineBreak());
      LOG.log(Level.INFO, "Error cleaning up after upgrade.", e);
      LOG.log(Level.INFO, "Error cleaning up after reversion.", e);
    }
    // Decide final status based on presense of error
@@ -538,16 +689,16 @@
    // processing messages has finished.  Need to resolve these
    // issues.
    if (abort) {
      LOG.log(Level.INFO, "upgrade canceled by user");
      LOG.log(Level.INFO, "reversion canceled by user");
      setCurrentProgressStep(ReversionProgressStep.FINISHED_CANCELED);
    } else if (runError != null) {
      LOG.log(Level.INFO, "upgrade completed with errors", runError);
      LOG.log(Level.INFO, "reversion completed with errors", runError);
      notifyListeners(getFormattedErrorWithLineBreak(runError,true));
      notifyListeners(getLineBreak());
      setCurrentProgressStep(ReversionProgressStep.FINISHED_WITH_ERRORS);
      notifyListeners(getLineBreak());
    } else if (runWarning != null) {
      LOG.log(Level.INFO, "upgrade completed with warnings");
      LOG.log(Level.INFO, "reversion completed with warnings");
      Message warningText = runWarning.getMessageObject();
      // By design, the warnings are written as errors to the details section
@@ -615,12 +766,6 @@
          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);
      }
@@ -628,8 +773,45 @@
  }
  private void cleanup() {
    // TODO:
  /**
   * Deletes the archived backup to which we reverted.
   */
  private void deleteArchive() {
    FileManager fm = new FileManager();
    try {
      fm.deleteRecursively(getReversionFilesDirectory());
    } catch (Exception e) {
      // ignore; this is best effort
    }
  }
  /**
   * Deletes the backup of the current installation.
   */
  private void deleteBackup() {
    FileManager fm = new FileManager();
    try {
      fm.deleteRecursively(getTempBackupDirectory());
    } catch (Exception e) {
      // ignore; this is best effort
    }
  }
  /**
   * Delete the library with which this reversion is currently
   * running.
   */
  private void deleteReversionLib() {
    FileManager fm = new FileManager();
    try {
      File tmpDir = getInstallation().getTemporaryDirectory();
      File revertLibDir = new File(tmpDir, "revert");
      fm.deleteRecursively(
              revertLibDir, null,
              FileManager.DeletionPolicy.DELETE_ON_EXIT);
    } catch (Exception e) {
      // ignore; this is best effort
    }
  }
  /**
@@ -638,6 +820,8 @@
   * is a problem with this reversion in which case they can be restored.
   *
   * @return File directory where the unreverted bits will be stored.
   * @throws java.io.IOException if something goes wrong
   * @throws org.opends.quicksetup.ApplicationException if something goes wrong
   */
  private File getTempBackupDirectory()
          throws IOException, ApplicationException
@@ -670,20 +854,29 @@
    return fromBuildInfo;
  }
  private BuildInformation getToBuildInformation() {
    if (toBuildInfo == null) {
  private BuildInformation getArchiveBuildInformation() {
    if (archiveBuildInfo == null) {
      if (currentProgressStep.ordinal() >
              ReversionProgressStep.REVERTING_FILESYSTEM.ordinal()) {
        try {
          toBuildInfo = installation.getBuildInformation(false);
          archiveBuildInfo = installation.getBuildInformation(false);
        } catch (ApplicationException e) {
          LOG.log(Level.INFO, "Failed to obtain 'from' build information", e);
          LOG.log(Level.INFO, "Failed to obtain archived build information " +
                  "from reverted files", e);
        }
      } else {
        // TODO: try to determine build info from backed up bits
        Installation archiveInstall = null;
        try {
          archiveInstall = getArchiveInstallation();
          archiveBuildInfo = archiveInstall.getBuildInformation();
        } catch (Exception e) {
          LOG.log(Level.INFO, "Failed to obtain archived build information " +
                  "from archived files", e);
        }
      }
    }
    return toBuildInfo;
    return archiveBuildInfo;
  }
  private Message getFinalSuccessMessage() {
@@ -706,5 +899,75 @@
    return txt;
  }
  /**
   * Given the current information, determines whether or not
   * a reversion from the current version to the archived version
   * is possible.  Reversion may not be possible due to 'flag
   * day' types of changes to the codebase.
   * @throws org.opends.quicksetup.ApplicationException if revertability
   *         cannot be insured.
   */
  private void insureRevertability() throws ApplicationException {
    BuildInformation currentVersion;
    BuildInformation newVersion;
    try {
      currentVersion = getInstallation().getBuildInformation();
    } catch (ApplicationException e) {
      LOG.log(Level.INFO, "Error getting build information for " +
              "current installation", e);
      throw ApplicationException.createFileSystemException(
              INFO_ERROR_DETERMINING_CURRENT_BUILD.get(), e);
    }
    try {
      Installation revInstallation = getArchiveInstallation();
      newVersion = revInstallation.getBuildInformation();
    } catch (ApplicationException ae) {
      throw ae;
    } catch (Exception e) {
      LOG.log(Level.INFO, "Error getting build information for " +
              "staged installation", e);
      throw ApplicationException.createFileSystemException(
              INFO_ERROR_DETERMINING_REVERSION_BUILD.get(), e);
    }
    if (currentVersion != null && newVersion != null) {
      ReversionIssueNotifier uo = new ReversionIssueNotifier(
              userInteraction(), currentVersion, newVersion);
      uo.notifyUser();
      if (uo.noServerStartFollowingOperation()) {
        // Some issue dicatates that we don't try and restart the server
        // after this operation.  It may be that the databases are no
        // longer readable after the reversion or something equally earth
        // shattering.
        getUserData().setStartServer(false);
      }
    } else {
      LOG.log(Level.INFO, "Did not run reversion issue notifier due to " +
              "incomplete build information");
    }
  }
  private Installation getArchiveInstallation()
          throws ApplicationException, IOException
  {
    if (archiveInstallation == null) {
      File revFiles = getReversionFilesDirectory();
      archiveInstallation = new Installation(revFiles);
    }
    return archiveInstallation;
  }
  private File appendFilesDirIfNeccessary(File archiveDir) {
    if (archiveDir != null) {
      // Automatically append the 'filesDir' subdirectory if necessary
      if (!archiveDir.getName().
              endsWith(Installation.HISTORY_BACKUP_FILES_DIR_NAME)) {
        archiveDir = new File(archiveDir,
                Installation.HISTORY_BACKUP_FILES_DIR_NAME);
      }
    }
    return archiveDir;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/ReverterUserData.java
@@ -36,22 +36,42 @@
 */
class ReverterUserData extends UserData {
  File filesDir = null;
  /** Directory where the reversion archive lives. */
  private File reversionArchiveDir = null;
  /** Indicates that we are reverting to the most recent version. */
  private boolean mostRecent;
  /**
   * Gets the directory where the files are stored for the reversion.
   * @return File where the reversion files are kept
   */
  public File getFilesDirectory() {
    return filesDir;
  public File getReversionArchiveDirectory() {
    return reversionArchiveDir;
  }
  /**
   * 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;
  public void setReversionArchiveDirectory(File files) {
    this.reversionArchiveDir = files;
  }
  /**
   * Sets whether or not we will be reverting to the most recent version.
   * @param mostRecent version or not
   */
  public void setRevertMostRecent(boolean mostRecent) {
    this.mostRecent = mostRecent;
  }
  /**
   * Indicates whether or not we will be reverting to the most recent version.
   * @return boolean where true means revert to the most recent version
   */
  public boolean isRevertMostRecent() {
    return this.mostRecent;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeIssueNotifier.java
@@ -30,7 +30,7 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.BuildInformation;
import org.opends.quicksetup.UserInteraction;
import org.opends.quicksetup.ApplicationException;
@@ -83,7 +83,7 @@
          }
        }
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
            ReturnCode.APPLICATION_ERROR,
                INFO_UPGRADE_ORACLE_UNSUPPORTED.get(
                        currentBuildInfo.toString(),
                        newBuildInfo.toString()),
@@ -147,13 +147,13 @@
                    new Message[]{cont, cancel},
                    defaultAction))) {
              throw new ApplicationException(
                  ApplicationReturnCode.ReturnCode.CANCELLED,
                  ReturnCode.CANCELLED,
                      INFO_UPGRADE_CANCELED.get(), null);
            }
          }
        } else {
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
              ReturnCode.APPLICATION_ERROR,
              INFO_ORACLE_NO_SILENT.get(), null);
        }
      }
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
@@ -37,12 +37,14 @@
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.util.Utils;
import org.opends.server.util.ServerConstants;
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.args.ArgumentException;
import org.opends.server.util.args.StringArgument;
import java.util.logging.Logger;
import java.io.File;
@@ -65,6 +67,24 @@
  /** Long form of the option for specifying the installation package file. */
  static public final String FILE_OPTION_LONG = "file";
  /** Short form of the option for specifying the reversion files directory. */
  static public final Character REVERT_ARCHIVE_OPTION_SHORT = 'a';
  /** Long form of the option for specifying the reversion files directory. */
  static public final String REVERT_ARCHIVE_OPTION_LONG = "reversionArchive";
  /** Short form of the option for specifying the 'most recent' option. */
  static public final Character REVERT_MOST_RECENT_OPTION_SHORT = 'r';
  /** Long form of the option for specifying the 'most recent' option. */
  static public final String REVERT_MOST_RECENT_OPTION_LONG ="revertMostRecent";
  /** Indicates that this operation is an upgrade as opposed to reversion. */
  protected boolean isUpgrade;
  /** Indicates that this operation is a reversion as opposed to an upgrade. */
  protected boolean isReversion;
  /**
   * The main method which is called by the setup command lines.
   *
@@ -84,6 +104,14 @@
  private ArgumentParser argParser;
  private BooleanArgument showUsage;
  private StringArgument file;
  private BooleanArgument quiet;
  private BooleanArgument noPrompt;
  private BooleanArgument revertMostRecent;
  private StringArgument reversionArchive;
  /**
   * {@inheritDoc}
   */
@@ -158,6 +186,94 @@
  }
  /**
   * Indicates whether or not this operation is silent.
   * @return boolean where true indicates silence
   */
  public boolean isQuiet() {
    return quiet.isPresent();
  }
  /**
   * Indicates whether or not this operation is interactive.
   * @return boolean where true indicates noninteractive
   */
  public boolean isNoPrompt() {
    return noPrompt.isPresent();
  }
  /**
   * Indicates whether this invocation is intended to upgrade the current
   * build as opposed to revert.
   * @return boolean where true indicates upgrade
   */
  public boolean isUpgrade() {
    return isUpgrade;
  }
  /**
   * Indicates whether this invocation is intended to revert the current
   * build as opposed to upgrade.
   * @return boolean where true indicates revert
   */
  public boolean isReversion() {
    return isReversion;
  }
  /**
   * Indicates that none of the options that indicate an upgrade
   * or reversion where specified on the command line so we are going
   * to have to prompt for the information or fail.
   *
   * @return boolean where true means this application needs to ask
   *         the user which operation they would like to perform; false
   *         means no further input is required
   */
  public boolean isInteractive() {
    return !file.isPresent() &&
            !reversionArchive.isPresent() &&
            !revertMostRecent.isPresent();
  }
  /**
   * Gets the name of the file to be used for upgrade.
   * @return name of the upgrade file
   */
  public String getUpgradeFileName() {
    return file.getValue();
  }
  /**
   * Gets the name of the directory to be used for reversion.
   * @return name of the reversion directory
   */
  public String getReversionArchiveDirectoryName() {
    return reversionArchive.getValue();
  }
  /**
   * Gets the file's directory if specified on the command line.
   * @return File representing the directory where the reversion files are
   * stored.
   */
  public File getReversionArchiveDirectory() {
    File f = null;
    String s = reversionArchive.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 isRevertMostRecent() {
    return revertMostRecent.isPresent();
  }
  /**
   * Creates an instance.
   *
   * @param args specified on command line
@@ -175,37 +291,86 @@
    argParser = new ArgumentParser(getClass().getName(),
        INFO_UPGRADE_LAUNCHER_USAGE_DESCRIPTION.get(), false);
    BooleanArgument showUsage;
    FileBasedArgument file;
    BooleanArgument quiet;
    BooleanArgument noPrompt;
    try
    {
      file = new FileBasedArgument(
              "file",
      file = new StringArgument(
              FILE_OPTION_LONG,
              FILE_OPTION_SHORT,
              FILE_OPTION_LONG,
              false, false,
              false, false, true,
              "{file}",
              null, null, INFO_UPGRADE_DESCRIPTION_FILE.get());
      argParser.addArgument(file);
      revertMostRecent = new BooleanArgument(
              REVERT_MOST_RECENT_OPTION_LONG,
              REVERT_MOST_RECENT_OPTION_SHORT,
              REVERT_MOST_RECENT_OPTION_LONG,
              INFO_REVERT_DESCRIPTION_RECENT.get());
      argParser.addArgument(revertMostRecent);
      reversionArchive = new StringArgument(
              REVERT_ARCHIVE_OPTION_LONG,
              REVERT_ARCHIVE_OPTION_SHORT,
              REVERT_ARCHIVE_OPTION_LONG,
              false, false, true,
              "{directory}",
              null, null, INFO_REVERT_DESCRIPTION_DIRECTORY.get());
      argParser.addArgument(reversionArchive);
      noPrompt = new BooleanArgument(
          OPTION_LONG_NO_PROMPT,
          OPTION_SHORT_NO_PROMPT,
          OPTION_LONG_NO_PROMPT,
          INFO_UPGRADE_DESCRIPTION_NO_PROMPT.get());
              OPTION_LONG_NO_PROMPT,
              OPTION_SHORT_NO_PROMPT,
              OPTION_LONG_NO_PROMPT,
              INFO_UPGRADE_DESCRIPTION_NO_PROMPT.get());
      argParser.addArgument(noPrompt);
      quiet = new BooleanArgument(
          OPTION_LONG_QUIET,
          OPTION_SHORT_QUIET,
          OPTION_LONG_QUIET,
          INFO_UPGRADE_DESCRIPTION_SILENT.get());
              OPTION_LONG_QUIET,
              OPTION_SHORT_QUIET,
              OPTION_LONG_QUIET,
              INFO_UPGRADE_DESCRIPTION_SILENT.get());
      argParser.addArgument(quiet);
      showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        INFO_DESCRIPTION_USAGE.get());
      showUsage = new BooleanArgument(
              "showusage",
              OPTION_SHORT_HELP,
              OPTION_LONG_HELP,
              INFO_DESCRIPTION_USAGE.get());
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      try {
        argParser.parseArguments(args);
        // Set fields indicating reversion or upgrade.  This may change
        // later if interaction is required to make the determination.
        isUpgrade = file.isPresent();
        isReversion =
                reversionArchive.isPresent() || revertMostRecent.isPresent();
        if (showUsage.isPresent()) {
          argParser.getUsage(System.out);
          System.exit(ReturnCode.PRINT_USAGE.getReturnCode());
        } else if (isUpgrade) {
          if (reversionArchive.isPresent()) {
            System.err.println(ERR_UPGRADE_INCOMPATIBLE_ARGS.get(
                    file.getName(), reversionArchive.getName()));
            System.exit(ReturnCode.
                    APPLICATION_ERROR.getReturnCode());
          } else if (revertMostRecent.isPresent()) {
            System.err.println(ERR_UPGRADE_INCOMPATIBLE_ARGS.get(
                    file.getName(), revertMostRecent.getName()));
            System.exit(ReturnCode.
                    APPLICATION_ERROR.getReturnCode());
          }
        }
      } catch (ArgumentException ae) {
        System.err.println(ae.getMessageObject());
        System.exit(ReturnCode.
                APPLICATION_ERROR.getReturnCode());
      }
    }
    catch (Throwable t)
    {
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeUserData.java
@@ -36,9 +36,14 @@
 */
public class UpgradeUserData extends UserData {
  File installPackage;
  /** Describes upgrade operation type. */
  public enum Operation { UPGRADE, REVERSION };
  Build buildToDownload;
  private File installPackage;
  private Build buildToDownload;
  private Operation operation;
  /**
   * Gets the OpenDS package (.zip) file whose contents will
@@ -87,4 +92,20 @@
    return false;
  }
  /**
   * Sets the operation the user would like to perform.
   * @param operation upgrade or reversion
   */
  public void setOperation(Operation operation) {
    this.operation = operation;
  }
  /**
   * Gets the operation the user would like to perform.
   * @return operation upgrade or reversion
   */
  public Operation getOperation() {
    return this.operation;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -33,7 +33,7 @@
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.WizardStep;
import org.opends.quicksetup.ProgressStep;
import org.opends.quicksetup.ApplicationException;
@@ -782,7 +782,7 @@
                  "Error starting server in order to apply custom" +
                          "schema and/or configuration", e);
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
              ReturnCode.APPLICATION_ERROR,
              INFO_ERROR_STARTING_SERVER.get(), e);
        }
@@ -833,7 +833,7 @@
          LOG.log(Level.INFO, "server stopped");
        } catch (Throwable t) {
          LOG.log(Level.INFO, "Error stopping server", t);
          throw new ApplicationException(ApplicationReturnCode.ReturnCode.BUG,
          throw new ApplicationException(ReturnCode.BUG,
                  INFO_ERROR_STOPPING_SERVER.get(), t);
        }
      }
@@ -850,12 +850,20 @@
                null, INFO_ERROR_ARTIFICIAL.get(), null);
      }
      LOG.log(Level.INFO, "verifying upgrade");
      setCurrentProgressStep(UpgradeProgressStep.VERIFYING);
      Installation installation = getInstallation();
      ServerHealthChecker healthChecker = new ServerHealthChecker(installation);
      healthChecker.checkServer();
      List<Message> errors = healthChecker.getProblemMessages();
      List<Message> errors;
      try {
        LOG.log(Level.INFO, "verifying upgrade");
        setCurrentProgressStep(UpgradeProgressStep.VERIFYING);
        Installation installation = getInstallation();
        ServerHealthChecker healthChecker =
                new ServerHealthChecker(installation);
        healthChecker.checkServer();
        errors = healthChecker.getProblemMessages();
      } catch (Exception e) {
        LOG.log(Level.INFO, "error performing server health check", e);
        notifyListeners(getFormattedErrorWithLineBreak());
        throw e;
      }
      // For testing
      if ("true".equals(
@@ -873,7 +881,7 @@
                Utils.listToMessage(errors,
                        Constants.LINE_SEPARATOR, /*bullet=*/"\u2022 ", "");
        ApplicationException ae = new ApplicationException(
                ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
                ReturnCode.APPLICATION_ERROR,
                INFO_ERROR_UPGRADED_SERVER_STARTS_WITH_ERRORS.get(
                        Constants.LINE_SEPARATOR + formattedDetails), null);
        UserInteraction ui = userInteraction();
@@ -928,7 +936,7 @@
            int port = getInstallation().getCurrentConfiguration().getPort();
            if (port != -1 && !Utils.canUseAsPort(port)) {
              throw new ApplicationException(
                  ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
                  ReturnCode.APPLICATION_ERROR,
                      INFO_ERROR_PORT_IN_USE.get(Integer.toString(port)),
                      null);
            }
@@ -954,7 +962,7 @@
      } catch (IOException ioe) {
        LOG.log(Level.INFO, "error determining if server running");
        this.runWarning = new ApplicationException(
            ApplicationReturnCode.ReturnCode.TOOL_ERROR,
            ReturnCode.TOOL_ERROR,
                INFO_ERROR_SERVER_STATUS.get(), ioe);
      }
@@ -962,7 +970,7 @@
      // We don't consider a  user cancelation exception
      // to be an error.
      if (ae.getType() != ApplicationReturnCode.ReturnCode.CANCELLED) {
      if (ae.getType() != ReturnCode.CANCELLED) {
        this.runError = ae;
      } else {
        this.abort = true;
@@ -970,7 +978,7 @@
    } catch (Throwable t) {
      this.runError =
              new ApplicationException(ApplicationReturnCode.ReturnCode.BUG,
              new ApplicationException(ReturnCode.BUG,
                      INFO_BUG_MSG.get(), t);
    } finally {
      try {
@@ -1087,7 +1095,7 @@
  private void checkAbort() throws ApplicationException {
    if (abort) throw new ApplicationException(
        ApplicationReturnCode.ReturnCode.CANCELLED,
        ReturnCode.CANCELLED,
            INFO_UPGRADE_CANCELED.get(), null);
  }
@@ -1222,7 +1230,7 @@
      throw ae;
    } catch (Exception e) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
              INFO_ERROR_BACKUP_FILESYSTEM.get(),
              e);
    }
@@ -1235,7 +1243,7 @@
      int ret = output.getReturnCode();
      if (ret != 0) {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.TOOL_ERROR,
            ReturnCode.TOOL_ERROR,
                INFO_ERROR_BACKUP_DB_TOOL_RETURN_CODE.get(
                        Integer.toString(ret)),
                null);
@@ -1245,7 +1253,7 @@
      throw ae;
    } catch (Exception e) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.TOOL_ERROR,
          ReturnCode.TOOL_ERROR,
              INFO_ERROR_BACKUP_DB.get(), e);
    }
  }
@@ -1292,7 +1300,7 @@
      throw ae;
    } catch (Exception e) {
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
              INFO_ERROR_INITIALIZING_UPGRADE.get(), e);
    }
  }
@@ -1370,11 +1378,11 @@
  /**
   * {@inheritDoc}
   * @param launcher
   */
  public UserData createUserData(Launcher launcher)
          throws UserDataException {
    return getCliHelper().createUserData(launcher.getArguments());
    return new UpgraderCliHelper((UpgradeLauncher) launcher).
            createUserData(launcher.getArguments());
  }
  /**
@@ -1384,6 +1392,13 @@
    return runError;
  }
  /**
   * {@inheritDoc}
   */
  public ReturnCode getReturnCode() {
    return null;
  }
  private void setCurrentProgressStep(UpgradeProgressStep step) {
    this.currentProgressStep = step;
    int progress = step.getProgress();
@@ -1391,13 +1406,6 @@
    notifyListeners(progress, msg, getFormattedProgress(msg));
  }
  private UpgraderCliHelper getCliHelper() {
    if (cliHelper == null) {
      cliHelper = new UpgraderCliHelper();
    }
    return cliHelper;
  }
  private Message getFinalSuccessMessage() {
    Message txt;
    String installPath = Utils.getPath(getInstallation().getRootDirectory());
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
@@ -27,16 +27,9 @@
package org.opends.quicksetup.upgrader;
import org.opends.messages.Message;
import static org.opends.messages.QuickSetupMessages.*;
import org.opends.quicksetup.CliApplicationHelper;
import org.opends.quicksetup.UserDataException;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.ArgumentException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
@@ -47,14 +40,17 @@
  static private final Logger LOG =
          Logger.getLogger(UpgraderCliHelper.class.getName());
  StringArgument localInstallPackFileNameArg = null;
  /** Launcher for this CLI invocation. */
  protected UpgradeLauncher launcher;
  /**
   * Default constructor.
   * Creates a parameterized instance.
   * @param launcher for this CLI
   */
  public UpgraderCliHelper()
  public UpgraderCliHelper(UpgradeLauncher launcher)
  {
    super(System.out, System.err, System.in);
    this.launcher = launcher;
  }
  /**
@@ -66,47 +62,14 @@
   */
  public UpgradeUserData createUserData(String[] args)
    throws UserDataException {
    // It is assumed that if we got here that the build
    // exptractor took care of extracting the file and
    // putting it in tmp/upgrade for us.  So there's
    // not too much to do at this point.
    UpgradeUserData uud = new UpgradeUserData();
    ArgumentParser ap = createArgumentParser();
    try {
      ap.parseArguments(args);
      uud.setQuiet(isQuiet());
      uud.setInteractive(isInteractive());
      // There is no need to check/validate the file argument
      // since this is done by the BuildExtractor
    } catch (ArgumentException e) {
      throw new UserDataException(null, INFO_ERROR_PARSING_OPTIONS.get());
    }
    uud.setQuiet(launcher.isQuiet());
    uud.setInteractive(!launcher.isNoPrompt());
    return uud;
  }
  private ArgumentParser createArgumentParser() {
    // TODO: get rid of this method and user launcher.getArgumentParser
    Message toolDescription = INFO_UPGRADE_LAUNCHER_DESCRIPTION.get();
    ArgumentParser argParser = createArgumentParser(
            "org.opends.quicksetup.upgrader.Upgrader",
            toolDescription,
            false);
    // Initialize all the app specific command-line argument types
    // and register them with the parser.
    try {
      localInstallPackFileNameArg =
              new StringArgument("install package file",
                      UpgradeLauncher.FILE_OPTION_SHORT,
                      UpgradeLauncher.FILE_OPTION_LONG,
                      false, true, "{install package file}", null);
      argParser.addArgument(localInstallPackFileNameArg);
    } catch (ArgumentException e) {
      LOG.log(Level.INFO, "error", e);
    }
    return argParser;
  }
}
opends/src/quicksetup/org/opends/quicksetup/util/FileManager.java
@@ -162,14 +162,14 @@
        if (target.exists()) {
          if (!target.delete()) {
            throw new ApplicationException(
                    ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                    ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                    INFO_ERROR_DELETING_FILE.get(Utils.getPath(target)), null);
          }
        }
      }
      if (!fileToRename.renameTo(target)) {
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                INFO_ERROR_RENAMING_FILE.get(Utils.getPath(fileToRename),
                        Utils.getPath(target)), null);
      }
@@ -525,7 +525,7 @@
                      objectFile.getAbsolutePath(),
                      destination.getAbsolutePath());
              throw new ApplicationException(
                      ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                      ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                      errMsg, null);
            } finally {
              if (fis != null) {
@@ -548,7 +548,7 @@
                    objectFile.getAbsolutePath(),
                    destination.getAbsolutePath());
            throw new ApplicationException(
                    ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                    ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                    errMsg, null);
          }
        } else {
@@ -654,7 +654,7 @@
          errMsg = INFO_ERROR_DELETING_DIRECTORY.get(file.getAbsolutePath());
        }
        throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                errMsg, null);
      }
opends/src/quicksetup/org/opends/quicksetup/util/InProcessServerController.java
@@ -60,10 +60,12 @@
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPAttribute;
import org.opends.server.protocols.asn1.ASN1OctetString;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.AddOperation;
import org.opends.server.core.DeleteOperation;
import org.opends.server.core.CompareOperation;
import org.opends.server.config.ConfigException;
import java.util.logging.Logger;
@@ -416,7 +418,7 @@
          // report the error to the user
          MessageBuilder error = op.getErrorMessage();
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.IMPORT_ERROR,
              ReturnCode.IMPORT_ERROR,
                  INFO_ERROR_APPLY_LDIF_MODIFY.get(dnByteString.toString(),
                          error != null ? error.toString() : ""),
                  null);
@@ -435,6 +437,29 @@
        rc = addOp.getResultCode();
        if (rc.equals(ResultCode.SUCCESS)) {
          LOG.log(Level.INFO, "processed server add " + addOp.getEntryDN());
        } else if (rc.equals(ResultCode.ENTRY_ALREADY_EXISTS)) {
          // Compare the attributes with the existing entry to see if we
          // can ignore this add.
          boolean ignore = true;
          for (RawAttribute attr : rawAttrs) {
            ArrayList<ASN1OctetString> values = attr.getValues();
            for (ASN1OctetString value : values) {
              CompareOperation compOp =
                cc.processCompare(dnByteString, attr.getAttributeType(), value);
              if (ResultCode.ASSERTION_FAILED.equals(compOp.getResultCode())) {
                ignore = false;
                break;
              }
            }
          }
          if (!ignore) {
            MessageBuilder error = addOp.getErrorMessage();
            throw new ApplicationException(
                ReturnCode.IMPORT_ERROR,
                    INFO_ERROR_APPLY_LDIF_ADD.get(dnByteString.toString(),
                            error != null ? error.toString() : ""),
                    null);
          }
        } else {
          boolean ignore = false;
@@ -471,7 +496,7 @@
          if (!ignore) {
            MessageBuilder error = addOp.getErrorMessage();
            throw new ApplicationException(
                    ApplicationReturnCode.ReturnCode.IMPORT_ERROR,
                    ReturnCode.IMPORT_ERROR,
                    INFO_ERROR_APPLY_LDIF_ADD.get(dnByteString.toString(),
                            error != null ? error.toString() : ""),
                    null);
@@ -489,7 +514,7 @@
          // report the error to the user
          MessageBuilder error = delOp.getErrorMessage();
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.IMPORT_ERROR,
              ReturnCode.IMPORT_ERROR,
                  INFO_ERROR_APPLY_LDIF_DELETE.get(dnByteString.toString(),
                          error != null ? error.toString() : ""),
                  null);
@@ -497,7 +522,7 @@
        break;
      default:
        LOG.log(Level.SEVERE, "Unexpected record type " + cre.getClass());
        throw new ApplicationException(ApplicationReturnCode.ReturnCode.BUG,
        throw new ApplicationException(ReturnCode.BUG,
                INFO_BUG_MSG.get(),
                null);
    }
opends/src/quicksetup/org/opends/quicksetup/util/ServerController.java
@@ -209,7 +209,7 @@
          * not be stopped.
          */
          throw new ApplicationException(
              ApplicationReturnCode.ReturnCode.STOP_ERROR,
              ReturnCode.STOP_ERROR,
                  INFO_ERROR_STOPPING_SERVER_CODE.get(
                          String.valueOf(returnValue)),
                  null);
@@ -223,7 +223,7 @@
      } catch (Exception e) {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.STOP_ERROR, getThrowableMsg(
            ReturnCode.STOP_ERROR, getThrowableMsg(
                INFO_ERROR_STOPPING_SERVER.get(), e), e);
      }
    } finally {
@@ -442,7 +442,7 @@
          if (Utils.isWindows())
          {
            throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.START_ERROR,
                ReturnCode.START_ERROR,
                    INFO_ERROR_STARTING_SERVER_IN_WINDOWS.get(
                            String.valueOf(port)),
                    null);
@@ -450,7 +450,7 @@
          else
          {
            throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.START_ERROR,
                ReturnCode.START_ERROR,
                    INFO_ERROR_STARTING_SERVER_IN_UNIX.get(
                            String.valueOf(port)),
                    null);
@@ -461,7 +461,7 @@
    } catch (IOException ioe)
    {
      throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.START_ERROR,
            ReturnCode.START_ERROR,
              getThrowableMsg(INFO_ERROR_STARTING_SERVER.get(), ioe), ioe);
    }
  } finally {
@@ -625,7 +625,7 @@
          } catch (Throwable t)
          {
            ex = new ApplicationException(
                ApplicationReturnCode.ReturnCode.START_ERROR,
                ReturnCode.START_ERROR,
                getThrowableMsg(errorTag, t), t);
          }
opends/src/quicksetup/org/opends/quicksetup/util/ServerHealthChecker.java
@@ -29,7 +29,7 @@
import org.opends.messages.Message;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.ApplicationException;
@@ -90,7 +90,7 @@
        throw (ApplicationException)e;
      } else {
        throw new ApplicationException(
            ApplicationReturnCode.ReturnCode.APPLICATION_ERROR,
            ReturnCode.APPLICATION_ERROR,
                INFO_ERROR_SERVER_HEALTH_CHECK_FAILURE.get(), e);
      }
    } finally {
opends/src/quicksetup/org/opends/quicksetup/util/ZipExtractor.java
@@ -32,7 +32,7 @@
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.Application;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import java.io.*;
import java.util.zip.ZipInputStream;
@@ -210,7 +210,7 @@
                            INFO_ERROR_COPYING.get(entry.getName()), ioe);
            throw new ApplicationException(
                ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
                    errorMsg, ioe);
          }
        }
@@ -246,7 +246,7 @@
              Utils.getThrowableMsg(
                      INFO_ERROR_ZIP_STREAM.get(zipFileName), ioe);
      throw new ApplicationException(
          ApplicationReturnCode.ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          errorMsg, ioe);
    }
  }
opends/src/quicksetup/org/opends/quicksetup/webstart/WebStartDownloader.java
@@ -39,7 +39,7 @@
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.ApplicationReturnCode;
import org.opends.quicksetup.ReturnCode;
import org.opends.server.util.SetupUtils;
import static org.opends.quicksetup.util.Utils.*;
@@ -138,7 +138,7 @@
        {
          // This is a bug
          ex =
              new ApplicationException(ApplicationReturnCode.ReturnCode.BUG,
              new ApplicationException(ReturnCode.BUG,
                      getThrowableMsg(INFO_BUG_MSG.get(),mfe), mfe);
        } catch (IOException ioe)
        {
@@ -154,14 +154,14 @@
          }
          ex =
              new ApplicationException(
              ApplicationReturnCode.ReturnCode.DOWNLOAD_ERROR,
              ReturnCode.DOWNLOAD_ERROR,
              getThrowableMsg(
                      INFO_DOWNLOADING_ERROR.get(buf.toString()), ioe), ioe);
        } catch (Throwable t)
        {
          // This is a bug
          ex =
              new ApplicationException(ApplicationReturnCode.ReturnCode.BUG,
              new ApplicationException(ReturnCode.BUG,
                      getThrowableMsg(INFO_BUG_MSG.get(), t), t);
        }
      }
@@ -366,7 +366,7 @@
  {
    ex =
        new ApplicationException(
        ApplicationReturnCode.ReturnCode.DOWNLOAD_ERROR,
        ReturnCode.DOWNLOAD_ERROR,
                INFO_DOWNLOADING_ERROR.get(url.toString()), null);
  }