From 3d8214539ebc6afc6f948f60a8010d3de8c31a0d Mon Sep 17 00:00:00 2001
From: kenneth_suter <kenneth_suter@localhost>
Date: Fri, 08 Jun 2007 19:15:27 +0000
Subject: [PATCH] This commit address several related issues regarding the upgrader CLI:

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java                |   53 +++-
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java                         |   32 +-
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java               |    2 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java             |   66 +++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java                   |    7 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java |  103 ++++++++++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java          |  147 +++++++-------
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java       |   27 --
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java                         |   30 ++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java        |    4 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java         |    7 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java             |    5 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java                    |   31 +-
 opendj-sdk/opends/resource/upgrade                                                           |   13 -
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties        |   17 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java                      |    4 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java                |    2 
 opendj-sdk/opends/resource/upgrade.bat                                                       |   12 
 18 files changed, 381 insertions(+), 181 deletions(-)

diff --git a/opendj-sdk/opends/resource/upgrade b/opendj-sdk/opends/resource/upgrade
index 09a5a4d..b2e2857 100644
--- a/opendj-sdk/opends/resource/upgrade
+++ b/opendj-sdk/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
diff --git a/opendj-sdk/opends/resource/upgrade.bat b/opendj-sdk/opends/resource/upgrade.bat
index 1d1a7a8..7b3591c 100644
--- a/opendj-sdk/opends/resource/upgrade.bat
+++ b/opendj-sdk/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
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
index 4fa82af..9cb4682 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Application.java
+++ b/opendj-sdk/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;
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
index 5ecb378..64f293e 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ApplicationException.java
+++ b/opendj-sdk/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
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
index 50774c1..dfdabd7 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
+++ b/opendj-sdk/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
    */
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
index 0890ab6..e813ecb 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
+++ b/opendj-sdk/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",
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java
index 1d402a1..d0021ba 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CliUserInteraction.java
+++ b/opendj-sdk/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)).
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
index 1ced51f..48dbee8 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Launcher.java
+++ b/opendj-sdk/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()));
+      }
     }
   }
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
index 87c0345..81ed00f 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
+++ b/opendj-sdk/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())
         {
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index cd1833e..0ad6cd5 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opendj-sdk/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;
   }
 
   /**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index 62b7df0..dd50171 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opendj-sdk/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.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
index 440b5be..5112773 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
+++ b/opendj-sdk/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 {
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
index 5a949ae..afcb006 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractor.java
+++ b/opendj-sdk/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
   }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java
new file mode 100644
index 0000000..f967860
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/BuildExtractorCliHelper.java
@@ -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;
+  }
+
+}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java
index 7d974a1..fa1fe2a 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/HistoricalRecord.java
+++ b/opendj-sdk/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;
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
index cacaba6..0eaad6b 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgradeLauncher.java
+++ b/opendj-sdk/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);
   }
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
index 3a3d004..8c29046 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/Upgrader.java
+++ b/opendj-sdk/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);
   }
 
   /**
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
index cef2c78..b62f39d 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/upgrader/UpgraderCliHelper.java
+++ b/opendj-sdk/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"));

--
Gitblit v1.10.0