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

kenneth_suter
08.15.2007 426f6fff96db9c07683e5a27b8b745b3e13c29ff
This commit address several related issues regarding the upgrader CLI:

- After discussing the previously noninteractive option with Brian, I changed the CLI options somewhat. The new CLI design is to specify an interactive option (if interactivity is desired) rather than to have to specify non-interactivity. Additionally interactivity is only supposed to apply to gathering of required information and not whether or not and application is allowed to prompt for such things as continuation following an error. To suppress these sort of prompts you should specify the silent option. So the common plumbing (currently not used by setup or uninstall) now operates as described above and the upgrader now has a both silent and interactive options as described.

- Make BuildExtractor a Launcher. BuildExtractor is a simple program used by the CLI for unzipping an OpenDS .zip file. Previously is was not very smart, relying on the Upgrader to report status and make sure the unzipping went OK. This had the unfortunate side-effect of making the scripts overly complicated resulting in issue 1772, and made it difficult to support interactivity. So the BuildExtractor has been made smarter so that it is capable of parsing the complete command line invocation, printing usage, and performing verification that it performed properly.

- Addresses issue 1772 by simplifying and correcting the upgrade and upgrade.bat scripts.

1 files added
17 files modified
562 ■■■■■ changed files
opends/resource/upgrade 13 ●●●● patch | view | raw | blame | history
opends/resource/upgrade.bat 12 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Application.java 4 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java 5 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java 7 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java 66 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java 2 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Launcher.java 32 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java 31 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 30 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties 17 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java 2 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java 147 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java 103 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java 4 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java 7 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java 53 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java 27 ●●●● patch | view | raw | blame | history
opends/resource/upgrade
@@ -136,8 +136,7 @@
done
export CLASSPATH
"${JAVA_BIN}" org.opends.quicksetup.upgrader.BuildExtractor "${@}"
if [ -r "${INSTANCE_ROOT}/tmp/upgrade" ]
if test $? -eq 0
then
  # Configure the appropriate CLASSPATH.
  # Unlike BuildExtractor, the Upgrader uses
@@ -149,14 +148,6 @@
  done
  # Launch the upgrade process.
  "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
  # Clean up if necessary
  if [ -r "${INSTANCE_ROOT}/tmp/upgrade" ]
  then
    rm -fr "${INSTANCE_ROOT}/tmp/upgrade"
  fi
else
  # Build extractor didn't work.  Invoke the upgrader
  # to report errors and usage.
  "${JAVA_BIN}" org.opends.quicksetup.upgrader.UpgradeLauncher "${@}"
  exit 101
fi
opends/resource/upgrade.bat
@@ -69,18 +69,12 @@
set CLASSPATH=""
FOR %%x in ("%INSTANCE_ROOT%\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" %%x
"%JAVA_BIN%" org.opends.quicksetup.upgrader.BuildExtractor %*
goto prepUpgrader
if not %errorlevel% == 0 goto end
goto upgrader
:prepUpgrader
if EXIST "%INSTANCE_ROOT%\tmp\upgrade" goto setClassPathToStageDir
goto callUpgrader
:setClassPathToStageDir
:upgrader
set CLASSPATH=""
FOR %%x in ("%INSTANCE_ROOT%\tmp\upgrade\lib\*.jar") DO call "%INSTANCE_ROOT%\lib\setcp.bat" %%x
goto callUpgrader
:callUpgrader
"%JAVA_BIN%" org.opends.quicksetup.upgrader.UpgradeLauncher %*
goto end
opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -573,13 +573,13 @@
  /**
   * Makes available a <code>UserInteraction</code> class that can be used
   * by the application to interact with the user.  If the user has requested
   * a noninteractive session this method returns null.
   * a silent session this method returns null.
   * @return UserInteraction object
   */
  protected UserInteraction userInteraction() {
    // Note:  overridden in GuiApplication
    UserInteraction ui = null;
    if (!getUserData().isNoninteractive()) {
    if (!getUserData().isSilent()) {
      ui = new CliUserInteraction();
    }
    return ui;
opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
@@ -96,6 +96,11 @@
    TOOL_ERROR,
    /**
     * User canceled operation.
     */
    CANCEL,
    /**
     * A bug (for instance when we throw an IllegalStateException).
     */
    BUG
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
@@ -47,6 +47,13 @@
          throws UserDataException;
  /**
   * Gets the user data this application will use when running.
   * @return UserData to use when running
   */
  UserData getUserData();
  /**
   * Sets the user data this application will use when running.
   * @param userData UserData to use when running
   */
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
@@ -32,6 +32,7 @@
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.StaticUtils;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@@ -57,12 +58,12 @@
  static public final String SILENT_OPTION_LONG = "silent";
  /** Short form of the option for specifying a noninteractive session. */
  static public final Character NONINTERACTIVE_OPTION_SHORT = 'n';
  static public final Character INTERACTIVE_OPTION_SHORT = 'i';
  /** Long form of the option for specifying a noninteractive session. */
  static public final String NONINTERACTIVE_OPTION_LONG = "noninteractive";
  static public final String INTERACTIVE_OPTION_LONG = "interactive";
  private BooleanArgument noninteractiveArg = null;
  private BooleanArgument interactiveArg = null;
  private BooleanArgument silentArg = null;
@@ -111,6 +112,53 @@
  }
  /**
   * 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).
   *
   * @param  prompt        The prompt to present to the user.
   * @param  defaultValue  The default value to assume if the user presses ENTER
   *                       without typing anything, or <CODE>null</CODE> if
   *                       there should not be a default and the user must
   *                       explicitly provide a value.
   *
   * @return  The string value read from the user.
   */
  protected String promptForString(String prompt, String defaultValue) {
    System.out.println();
    String wrappedPrompt = StaticUtils.wrapText(prompt,
            Utils.getCommandLineMaxLineWidth());
    while (true) {
      System.out.println(wrappedPrompt);
      if (defaultValue == null) {
        System.out.print(": ");
      } else {
        System.out.print("[");
        System.out.print(defaultValue);
        System.out.print("]: ");
      }
      System.out.flush();
      String response = readLine();
      if (response.equals("")) {
        if (defaultValue == null) {
          String message = getMsg("error-empty-response");
          System.err.println(StaticUtils.wrapText(message,
                  Utils.getCommandLineMaxLineWidth()));
        } else {
          return defaultValue;
        }
      } else {
        return response;
      }
    }
  }
  /**
   * Reads a line of text from standard input.
   * @return  The line of text read from standard input, or <CODE>null</CODE>
   *          if the end of the stream is reached or an error occurs while
@@ -243,8 +291,8 @@
   * @return <CODE>true</CODE> if this is a noninteractive session and
   * <CODE>false</CODE> otherwise.
   */
  protected boolean isNoninteractive() {
    return noninteractiveArg != null && noninteractiveArg.isPresent();
  protected boolean isInteractive() {
    return interactiveArg != null && interactiveArg.isPresent();
  }
  /**
@@ -267,12 +315,12 @@
    // Initialize all the common command-line argument types and register
    // them with the parser.
    try {
      noninteractiveArg =
      interactiveArg =
           new BooleanArgument("noninteractive session",
                   NONINTERACTIVE_OPTION_SHORT,
                   NONINTERACTIVE_OPTION_LONG,
                   INTERACTIVE_OPTION_SHORT,
                   INTERACTIVE_OPTION_LONG,
                   0);
      argParser.addArgument(noninteractiveArg);
      argParser.addArgument(interactiveArg);
      silentArg =
           new BooleanArgument("silent session",
opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java
@@ -133,6 +133,8 @@
    return returnValue;
  }
  private String createOption(int index, String option) {
    return new StringBuilder().
            append(Integer.toString(index)).
opends/src/quicksetup/org/opends/quicksetup/Launcher.java
@@ -252,16 +252,11 @@
   */
  protected int launchCli(String[] args, CliApplication cliApp) {
    System.setProperty("org.opends.quicksetup.cli", "true");
    QuickSetupCli cli = new QuickSetupCli(cliApp, args);
    int returnValue = cli.run();
    if (returnValue == QuickSetupCli.USER_DATA_ERROR) {
      printUsage();
    }
    // Add an extra space systematically
    System.out.println();
    return returnValue;
  }
@@ -315,8 +310,9 @@
    else if (shouldPrintUsage()) {
      printUsage();
    } else if (isCli()) {
      int exitCode = launchCli(args, createCliApplication());
      preExit();
      CliApplication cliApp = createCliApplication();
      int exitCode = launchCli(args, cliApp);
      preExit(cliApp);
      System.exit(exitCode);
    } else {
      willLaunchGui();
@@ -331,20 +327,28 @@
        {
          guiLaunchFailed(null);
        }
        exitCode = launchCli(args, createCliApplication());
        CliApplication cliApp = createCliApplication();
        exitCode = launchCli(args, cliApp);
        if (exitCode != 0) {
          preExit();
          preExit(cliApp);
          System.exit(exitCode);
        }
      }
    }
  }
  private void preExit() {
    File logFile = QuickSetupLog.getLogFile();
    if (logFile != null) {
      System.out.println(getMsg("general-see-for-details",
            QuickSetupLog.getLogFile().getPath()));
  private void preExit(CliApplication cliApp) {
    UserData ud = cliApp.getUserData();
    if (ud != null && !ud.isSilent()) {
      // Add an extra space systematically
      System.out.println();
      File logFile = QuickSetupLog.getLogFile();
      if (logFile != null) {
        System.out.println(getMsg("general-see-for-details",
              QuickSetupLog.getLogFile().getPath()));
      }
    }
  }
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
@@ -110,21 +110,24 @@
                new PlainTextProgressMessageFormatter();
        cliApp.setUserData(userData);
        cliApp.setProgressMessageFormatter(formatter);
        cliApp.addProgressUpdateListener(
            new ProgressUpdateListener()
            {
              /**
               * ProgressUpdateListener implementation.
               * @param ev the ProgressUpdateEvent we receive.
               *
               */
              public void progressUpdate(ProgressUpdateEvent ev)
        if (!userData.isSilent()) {
          cliApp.addProgressUpdateListener(
              new ProgressUpdateListener()
              {
                System.out.print(
                    org.opends.server.util.StaticUtils.wrapText(ev.getNewLogs(),
                        Utils.getCommandLineMaxLineWidth()));
              }
            });
                /**
                 * ProgressUpdateListener implementation.
                 * @param ev the ProgressUpdateEvent we receive.
                 *
                 */
                public void progressUpdate(ProgressUpdateEvent ev)
                {
                  System.out.print(
                          org.opends.server.util.StaticUtils.wrapText(
                                  ev.getNewLogs(),
                                  Utils.getCommandLineMaxLineWidth()));
                }
              });
        }
        new Thread(cliApp).start();
        while (!cliApp.isFinished())
        {
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -83,7 +83,7 @@
  private boolean silent;
  private boolean noninteractive;
  private boolean interactive;
  /**
   * Creates a user data object with default values.
@@ -454,6 +454,11 @@
  /**
   * Indicates whether or not the user has requested silent mode.
   * <p>
   * Silent mode in the CLI means that nothing is written to output including
   * prompts for information and whether or not to continue an operation
   * experiencing errors.
   *
   * @return boolean where true indicates this session should be silent.
   */
  public boolean isSilent() {
@@ -461,20 +466,27 @@
  }
  /**
   * Sets whether or not this session should solicite feedback from the user.
   * @param noninteractive boolean where true indicates this application
   * Sets whether or not this session should solicite feedback from the user
   * for missing information.
   * @param interactive boolean where true indicates this application
   *        should NOT solicite feedback from the user
   */
  public void setNoninteractive(boolean noninteractive) {
    this.noninteractive = noninteractive;
  public void setInteractive(boolean interactive) {
    this.interactive = interactive;
  }
  /**
   * Indicates whether or not the user has requested noninteractive mode.
   * @return boolean where true indicates this session should be noninteractive
   * Indicates whether or not the user has requested interactive mode.
   * <p>
   * Interactive mode in the CLI means that the CLI will prompt the user
   * for more information if it is required.  Interactivity does NOT
   * affect prompts to the user regarding actions like continuing an operation
   * that is experiencing errors.
   *
   * @return boolean where true indicates this session should be interactive
   */
  public boolean isNoninteractive() {
    return this.noninteractive;
  public boolean isInteractive() {
    return !this.silent && this.interactive;
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -176,9 +176,10 @@
     -V, --version\n    Display Directory Server version information.\n\
     -f, --file\n    Specifies an existing OpenDS package (.zip) \
   file to which the\n    current build will be upgraded using the command line \
   \n    version of this tool\n-n, --noninteractive\n    If this tool requires more \
   information to complete successfully\n    it will fail instead of prompting.\
   \n-?, -H , --help\n    Display this usage information.\n
   \n    version of this tool\n-i, --interactive\n    Prompt for any required \
   information rather than fail\
   \n-s, --silent\n    Perform a silent upgrade\n-?, -H , --help\n    Display \
   this usage information.\n
upgrade-launcher-launching-gui=Launching graphical upgrade...
upgrade-launcher-launching-cli=Launching command line upgrade...
upgrade-launcher-gui-launched-failed=\n\nThe graphical upgrade launch \
@@ -1162,6 +1163,9 @@
  Either the selected directory is not a valid OpenDS root installation\n\
  directory or you do not have access permissions for this directory.
error-option-required=Option {0} is required.
error-option-required-or-interactive=Option {0} is required when not invoking \
  this command in interactive mode.  See the usage statement.
error-parsing-options=Error parsing options.
error-install-root-dir-null=The root directory is null.
error-install-root-dir-not-dir=File {0} is not an OpenDS installation root.
@@ -1169,7 +1173,7 @@
error-install-root-dir-no-dir=Directory {0} does not contain directory {1}.
error-install-root-dir-empty=Directory {0} is either empty or you lack permissions\
  to access its contents.
error-empty-response=ERROR:  The response value may not be an empty string
#
# Install Status: messages displayed in the offline quick setup
@@ -1209,6 +1213,7 @@
  made to the server by this upgrade will be backed out.
upgrade-verification-failure-cancel=Cancel Upgrade
upgrade-verification-failure-view-details=View Error Details
upgrade-file-prompt=Enter the name and path of the OpenDS install file (.zip):
#
# Upgrader Panels
@@ -1282,6 +1287,9 @@
# Build extractor
build-extractor-error=Failed to extract build: {0}
build-extractor-error-file-no-exist=File {0} does not exist.
build-extractor-error-file-not-zip=File {0} is not a .zip file.
build-extractor-file-invalid=Could not extract a valid OpenDS installation from \
  {0} because: {1}
# Web Proxy dialog strings
web-proxy-dlg-title=Web Proxy Configuration
@@ -1302,6 +1310,7 @@
upgrade-log-status-started=Started
upgrade-log-status-success=Success
upgrade-log-status-failure=Failure
upgrade-log-status-cancel=Canceled
general-loading=Loading...
general-see-for-details=See {0} for a detailed log of this operation.
opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -561,7 +561,7 @@
   */
  protected UserInteraction userInteraction() {
    UserInteraction ui = null;
    if (!getUserData().isNoninteractive()) {
    if (!getUserData().isSilent()) {
      if (Utils.isCli()) {
        ui = new CliUserInteraction();
      } else {
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
@@ -28,17 +28,14 @@
package org.opends.quicksetup.upgrader;
import org.opends.quicksetup.*;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.util.ZipExtractor;
import org.opends.quicksetup.util.FileManager;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -55,7 +52,7 @@
 * itself is dependent upon this tool, it should be kept simple and stable
 * to insure that the upgrade will work.
 */
public class BuildExtractor extends Application implements Runnable {
public class BuildExtractor extends UpgradeLauncher implements CliApplication {
  static private final Logger LOG =
          Logger.getLogger(BuildExtractor.class.getName());
@@ -75,21 +72,19 @@
              ResourceProvider.getInstance().getMsg("error-initializing-log"));
      t.printStackTrace();
    }
    new BuildExtractor(args).run();
    new BuildExtractor(args).launch();
  }
  private String[] args = null;
  private BuildExtractorCliHelper helper = new BuildExtractorCliHelper();
  private boolean finished = false;
  private UpgradeUserData userData;
  private boolean finished;
  private ApplicationException error;
  private BuildExtractor(String[] args) {
    this.args = args;
    setProgressMessageFormatter(new PlainTextProgressMessageFormatter());
    addProgressUpdateListener(new ProgressUpdateListener() {
      public void progressUpdate(ProgressUpdateEvent ev) {
        System.out.println(ev.getNewLogs());
      }
    });
    super(args);
  }
  /**
@@ -103,60 +98,40 @@
   * contents into the current build's staging are and exits with return code 0.
   */
  public void run() {
    int retCode = 0;
    try {
      File buildFile = getBuildFile(args);
      UpgradeUserData uud = (UpgradeUserData)getUserData();
      File buildFile = uud.getInstallPackage();
      if (buildFile != null) {
        if (!buildFile.exists()) {
          throw new FileNotFoundException(
                  getMsg("build-extractor-error-file-no-exist",
                          Utils.getPath(buildFile)));
        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());
          String invalidMsg = getMsg("build-extractor-file-invalid",
                  Utils.getPath(buildFile),
                  installation.getInvalidityReason());
          error = new ApplicationException(
                ApplicationException.Type.APPLICATION,
                  invalidMsg, null);
          System.err.println(invalidMsg);
        }
        expandZipFile(buildFile);
      }
    } catch (Throwable t) {
      LOG.log(Level.INFO, "unexpected error extracting build", t);
      String reason = t.getLocalizedMessage();
      System.err.println(getMsg("build-extractor-error", reason));
      retCode = 1;
    }
    LOG.log(Level.INFO, "extractor exiting code=" + retCode);
    System.exit(retCode);
  }
  private File getBuildFile(String[] args) {
    File buildFile = null;
    String buildFileName = null;
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        if (args[i].equals("--" + UpgraderCliHelper.FILE_OPTION_LONG) ||
                args[i].equalsIgnoreCase(
                        "-" + UpgraderCliHelper.FILE_OPTION_SHORT)) {
          if (i < args.length - 1) {
            buildFileName = args[i+ 1];
          }
        }
      }
    }
    if (buildFileName != null) {
      buildFile = new File(buildFileName);
    }
    return buildFile;
  }
  private void expandZipFile(File buildFile)
          throws ApplicationException, IOException {
    try {
      LOG.log(Level.INFO, "expanding zip file " + buildFile.getPath());
      ZipExtractor extractor = new ZipExtractor(buildFile);
      extractor.extract(getStageDirectory());
      LOG.log(Level.INFO, "extraction finished");
    } finally {
      error = new ApplicationException(ApplicationException.Type.APPLICATION,
                getMsg("build-extractor-error", reason), t);
      System.err.println(reason);
    } finally   {
      finished = true;
    }
  }
  private File getStageDirectory() throws ApplicationException {
  private File initStageDirectory() throws ApplicationException {
    File stageDir;
    Installation installation = new Installation(getInstallationPath());
    stageDir = installation.getTemporaryUpgradeDirectory();
@@ -176,6 +151,13 @@
  /**
   * {@inheritDoc}
   */
  protected CliApplication createCliApplication() {
    return this;
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstallationPath() {
    return Utils.getInstallPathFromClasspath();
  }
@@ -183,23 +165,33 @@
  /**
   * {@inheritDoc}
   */
  public ProgressStep getCurrentProgressStep() {
    return null;
  public UserData createUserData(String[] args, CurrentInstallStatus status)
          throws UserDataException
  {
    return helper.createUserData(args);
  }
  /**
   * {@inheritDoc}
   */
  public Integer getRatio(ProgressStep step) {
    return null;
  public UserData getUserData() {
    return userData;
  }
  /**
   * {@inheritDoc}
   */
  public String getSummary(ProgressStep step) {
    return null;
  public void setUserData(UserData userData) {
    if (userData instanceof UpgradeUserData) {
      this.userData = (UpgradeUserData)userData;
    }
  }
  /**
   * {@inheritDoc}
   */
  public void setProgressMessageFormatter(ProgressMessageFormatter formatter) {
    // ignore
  }
  /**
@@ -212,14 +204,29 @@
  /**
   * {@inheritDoc}
   */
  public boolean isCancellable() {
    return false;
  public ApplicationException getException() {
    return error;
  }
  /**
   * {@inheritDoc}
   */
  public void cancel() {
    // do nothing; not cancellable
  public void addProgressUpdateListener(ProgressUpdateListener l) {
    // ignored;  no progress messages
  }
  /**
   * {@inheritDoc}
   */
  public void removeProgressUpdateListener(ProgressUpdateListener l) {
    // ignored;  no progress messages
  }
  /**
   * {@inheritDoc}
   */
  public void notifyListeners(Integer ratio, String currentPhaseSummary,
                              String newLogDetail) {
    // ignored;  no progress messages
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java
New file
@@ -0,0 +1,103 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.upgrader;
import org.opends.quicksetup.UserDataException;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.File;
/**
 * Assists Upgrader utility in CLI drudgery.
 */
public class BuildExtractorCliHelper extends UpgraderCliHelper {
  static private final Logger LOG =
          Logger.getLogger(BuildExtractorCliHelper.class.getName());
  /**
   * Creates a set of user data from command line arguments and installation
   * status.
   * @param args String[] of arguments passed in from the command line
   * @return UserData object populated to reflect the input args and status
   * @throws org.opends.quicksetup.UserDataException if something is wrong
   */
  public UpgradeUserData createUserData(String[] args)
    throws UserDataException {
    UpgradeUserData uud = super.createUserData(args);
    // Build extractor is always silent whether user
    // has specified this or not.
    uud.setSilent(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(
                getMsg("upgrade-file-prompt"), null);
        try {
          uud.setInstallPackage(validateInstallPackFile(fileName));
          LOG.log(Level.INFO, "file specified interactively: " +
                  fileName);
          break;
        } catch (UserDataException ude) {
          System.out.println(ude.getMessage());
        }
      }
    } else {
      throw new UserDataException(null,
              getMsg("error-option-required-or-interactive",
                      "-" + FILE_OPTION_SHORT + "/--" + FILE_OPTION_LONG));
    }
    return uud;
  }
  private File validateInstallPackFile(String fileName)
          throws UserDataException
  {
    File f = new File(fileName);
    if (!f.exists()) {
        throw new UserDataException(null,
                getMsg("build-extractor-error-file-no-exist",
                        fileName));
    } else if (f.isDirectory() || !f.getName().toLowerCase().endsWith(".zip")) {
      throw new UserDataException(null,
              getMsg("build-extractor-error-file-not-zip", fileName));
    }
    return f;
  }
}
opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java
@@ -77,7 +77,9 @@
    SUCCESS(getMsg("upgrade-log-status-success")),
    FAILURE(getMsg("upgrade-log-status-failure"));
    FAILURE(getMsg("upgrade-log-status-failure")),
    CANCEL(getMsg("upgrade-log-status-cancel"));
    private String representation;
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
@@ -136,7 +136,12 @@
    }
  }
  private UpgradeLauncher(String[] args) {
  /**
   * Creates an instance.
   *
   * @param args specified on command line
   */
  protected UpgradeLauncher(String[] args) {
    super(args);
  }
opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
@@ -982,25 +982,41 @@
        String formattedDetails =
                Utils.listToString(errors,
                        Constants.LINE_SEPARATOR, /*bullet=*/"\u2022 ", "");
        runWarning = new ApplicationException(
        ApplicationException ae = new ApplicationException(
                ApplicationException.Type.APPLICATION,
                getMsg("error-upgraded-server-starts-with-errors",
                        Constants.LINE_SEPARATOR + formattedDetails), null);
        String cancel = getMsg("upgrade-verification-failure-cancel");
        UserInteraction ui = userInteraction();
        if (ui == null || cancel.equals(ui.confirm(
        if (ui != null) {
          // We are about to present the problems with the upgrade to the
          // user and ask if they would like to continue.  Regardless of
          // whether or not they continue at this point, since they will
          // have seen the errors we consider the errors as warnings.
          runWarning = ae;
          // Ask the user if they would like to continue.
          String cancel = getMsg("upgrade-verification-failure-cancel");
          if (cancel.equals(ui.confirm(
                  getMsg("upgrade-verification-failure-title"),
                  getMsg("upgrade-verification-failure-prompt"),
                  formattedDetails,
                  getMsg("upgrade-verification-failure-title"),
                  UserInteraction.MessageType.ERROR,
                  new String[] { getMsg("continue-button-label"), cancel },
                  new String[]{getMsg("continue-button-label"), cancel},
                  cancel,
                  getMsg("upgrade-verification-failure-view-details")))) {
            // User indicated cancel
            cancel();
            throw new ApplicationException(
              ApplicationException.Type.APPLICATION,
              getMsg("upgrade-canceled"), null);
            checkAbort();
          } else {
            // User wants to continue;  nothing to do
          }
        } else {
          // We can't ask the user if they want to continue so we
          // just bail on the upgrade by throwing an exception which
          // will cause upgrader to exit unsuccessfully
          throw ae;
        }
      } else {
        notifyListeners(formatter.getFormattedDone() +
@@ -1058,7 +1074,13 @@
      }
    } catch (ApplicationException ae) {
      this.runError = ae;
      // We don't consider a  user cancelation exception
      // to be an error.
      if (ae.getType() != ApplicationException.Type.CANCEL) {
        this.runError = ae;
      }
    } catch (Throwable t) {
      this.runError =
              new ApplicationException(ApplicationException.Type.BUG,
@@ -1067,17 +1089,20 @@
      try {
        HistoricalRecord.Status status;
        String note = null;
        if (runError == null) {
        if (runError == null && !abort) {
          status = HistoricalRecord.Status.SUCCESS;
        } else {
          status = HistoricalRecord.Status.FAILURE;
          note = runError.getLocalizedMessage();
          if (abort) {
            status = HistoricalRecord.Status.CANCEL;
          } else {
            status = HistoricalRecord.Status.FAILURE;
            note = runError.getLocalizedMessage();
          }
          // Abort the upgrade and put things back like we found it
          LOG.log(Level.INFO, "canceling upgrade");
          ProgressStep lastProgressStep = getCurrentProgressStep();
          setCurrentProgressStep(UpgradeProgressStep.ABORT);
          LOG.log(Level.INFO, "abort");
          abort(lastProgressStep);
          notifyListeners(formatter.getFormattedDone() +
                  formatter.getLineBreak());
@@ -1178,7 +1203,7 @@
  private void checkAbort() throws ApplicationException {
    if (abort) throw new ApplicationException(
            ApplicationException.Type.APPLICATION,
            ApplicationException.Type.CANCEL,
            getMsg("upgrade-canceled"), null);
  }
@@ -1558,7 +1583,7 @@
   */
  public UserData createUserData(String[] args, CurrentInstallStatus cis)
          throws UserDataException {
    return getCliHelper().createUserData(args, cis);
    return getCliHelper().createUserData(args);
  }
  /**
opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
@@ -29,14 +29,12 @@
import org.opends.quicksetup.CliApplicationHelper;
import org.opends.quicksetup.UserDataException;
import org.opends.quicksetup.CurrentInstallStatus;
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;
import java.io.File;
/**
 * Assists Upgrader utility in CLI drudgery.
@@ -58,35 +56,20 @@
   * Creates a set of user data from command line arguments and installation
   * status.
   * @param args String[] of arguments passed in from the command line
   * @param cis the current installation status
   * @return UserData object populated to reflect the input args and status
   * @throws UserDataException if something is wrong
   */
  public UpgradeUserData createUserData(String[] args, CurrentInstallStatus cis)
  public UpgradeUserData createUserData(String[] args)
    throws UserDataException {
    UpgradeUserData uud = new UpgradeUserData();
    ArgumentParser ap = createArgumentParser();
    try {
      ap.parseArguments(args);
      uud.setSilent(isSilent());
      uud.setNoninteractive(isNoninteractive());
      if (localInstallPackFileNameArg.isPresent()) {
        String localInstallPackFileName =
                localInstallPackFileNameArg.getValue();
        File installPackFile = new File(localInstallPackFileName);
        if (!installPackFile.exists()) {
          throw new UserDataException(null,
                  getMsg("build-extractor-error-file-no-exist",
                          localInstallPackFileName));
        } else {
          uud.setInstallPackage(installPackFile);
        }
      } else {
        // TODO: ask the user for this information if non noninteractive
        throw new UserDataException(null,
                getMsg("error-option-required",
                        "-" + FILE_OPTION_SHORT + "/--" + FILE_OPTION_LONG));
      }
      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, getMsg("error-parsing-options"));