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

kenneth_suter
29.37.2007 f738665ce7ea61f640e4219c8bfd590efea22650
- Created CliApplication interface which defines a common inteface between CliApplications and controlling logic.

- Created QuickSetupCli which is a controller for running CliApplications

- Created CliApplicationHelper (and UninstallCliHelper) having methods for reading input, prompting the user etc. Applications can delegate to the helper classes for these methods if necessary.

- Create a common Launcher class from which InstallLauncher and UninstallLauncher extend. It has common ways of invoking the applications. Setup overrides this behavior since it just ends up calling InstallDS.
1 files deleted
5 files added
5 files modified
2449 ■■■■■ changed files
opends/src/quicksetup/org/opends/quicksetup/Application.java 4 ●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java 75 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java 226 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Launcher.java 281 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java 11 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java 209 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java 251 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCli.java 719 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCliHelper.java 408 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java 252 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java 13 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Application.java
@@ -60,13 +60,11 @@
   * Creates an application by instantiating the Application class
   * denoted by the System property
   * <code>org.opends.quicksetup.Application.class</code>.
   * @param formatter ProgressMessageFormatter that will be passed to the
   *                  constructor of Application
   * @return Application object that was newly instantiated
   * @throws ApplicationException if there was a problem creating
   *         the new Application object
   */
  static public Application create(ProgressMessageFormatter formatter)
  static public Application create()
          throws ApplicationException {
    Application app;
    String appClassName =
opends/src/quicksetup/org/opends/quicksetup/CliApplication.java
New file
@@ -0,0 +1,75 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
import org.opends.quicksetup.event.ProgressNotifier;
import org.opends.quicksetup.util.ProgressMessageFormatter;
/**
 * Represents a quick setup CLI application.
 */
public interface CliApplication extends ProgressNotifier, Runnable {
  /**
   * Creates a set of user data from command line arguments and installation
   * status.
   * @param args String[] of arguments passed in from the command line
   * @param status the current installation status
   * @return UserData object populated to reflect the input args and status
   * @throws UserDataException if something is wrong
   */
  UserData createUserData(String[] args, CurrentInstallStatus status)
          throws UserDataException;
  /**
   * Sets the user data this application will use when running.
   * @param userData UserData to use when running
   */
  void setUserData(UserData userData);
  /**
   * Sets the formatter that will be used to format messages.
   * @param formatter ProgressMessageFormatter used to format messages
   */
  void setProgressMessageFormatter(ProgressMessageFormatter formatter);
  /**
   * Indicates whether or not this applicat is finished running.
   * @return boolean where true indicates we are not running
   */
  boolean isFinished();
  /**
   * Gets any exception that happened while this application was running.
   * A null value returned from this method indicates that the execution
   * of the CLI program is not complete or was successful.
   * @return an exception that happened while the CLI was running
   */
  ApplicationException getException();
}
opends/src/quicksetup/org/opends/quicksetup/CliApplicationHelper.java
New file
@@ -0,0 +1,226 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.io.ByteArrayOutputStream;
import java.util.Set;
import java.util.ArrayList;
import java.util.logging.Logger;
/**
 * Helper class containing useful methods for processing input and output
 * for a CliApplication.
 */
public class CliApplicationHelper {
  static private final Logger LOG =
          Logger.getLogger(CliApplication.class.getName());
  /**
   * 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).  The method will display the
   * message until the user provides one of the values in the validValues
   * parameter.
   *
   * @param  formatKey     Key for access the prompts format string from the
   *                       bundle
   * @param  prompt        The prompt to present to the user.
   * @param  defaultValue  The default value returned if the user clicks enter.
   * @param  validValues   The valid values that can be accepted as user input.
   *
   * @return The string value read from the user.
   */
  protected String promptConfirm(String formatKey, String prompt,
                                 String defaultValue,
                                 String[] validValues) {
    System.out.println();
    boolean isValid = false;
    String response = null;
    while (!isValid)
    {
      String msg = getMsg(formatKey,
          new String[] {prompt, defaultValue});
      System.out.print(msg);
      System.out.flush();
      response = readLine();
      if (response.equals(""))
      {
        response = defaultValue;
      }
      for (int i=0; i<validValues.length && !isValid; i++)
      {
        isValid = validValues[i].equalsIgnoreCase(response);
      }
    }
    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
   *          attempting to read the response.
   */
  private String readLine()
  {
    try
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      while (true)
      {
        int b = System.in.read();
        if ((b < 0) || (b == '\n'))
        {
          break;
        }
        else if (b == '\r')
        {
          int b2 = System.in.read();
          if (b2 == '\n')
          {
            break;
          }
          else
          {
            baos.write(b);
            baos.write(b2);
          }
        }
        else
        {
          baos.write(b);
        }
      }
      return new String(baos.toByteArray(), "UTF-8");
    }
    catch (Exception e)
    {
      System.err.println(getMsg("cli-uninstall-error-reading-stdin"));
      return null;
    }
  }
  /**
   * Returns <CODE>true</CODE> if this is a silent uninstall and
   * <CODE>false</CODE> otherwise.
   * @param args the arguments passed in the command line.
   * @return <CODE>true</CODE> if this is a silent uninstall and
   * <CODE>false</CODE> otherwise.
   */
  protected boolean isSilent(String[] args)
  {
    boolean isSilent = false;
    for (int i=0; i<args.length && !isSilent; i++)
    {
      if (args[i].equalsIgnoreCase("--silentUninstall") ||
          args[i].equalsIgnoreCase("-s"))
      {
        isSilent = true;
      }
    }
    return isSilent;
  }
  /**
   * Commodity method used to validate the arguments provided by the user in
   * the command line and updating the UserData object accordingly.
   * @param userData the UserData object to be updated.
   * @param args the arguments passed in the command line.
   * @param validArgs arguments that are acceptable by this application.
   * @throws org.opends.quicksetup.UserDataException if there is an error with
   * the data provided by the user.
   */
  protected void validateArguments(UserData userData,
                                 String[] args,
                                 Set<String> validArgs) throws UserDataException
  {
    ArrayList<String> errors = new ArrayList<String>();
    for (String arg1 : args) {
      if (validArgs.contains(arg1)) {
        // Ignore
      } else {
        String[] arg = {arg1};
        errors.add(getMsg("cli-uninstall-unknown-argument", arg));
      }
    }
    if (errors.size() > 0)
    {
      String msg = Utils.getStringFromCollection(errors,
          QuickSetupCli.LINE_SEPARATOR+QuickSetupCli.LINE_SEPARATOR);
      throw new UserDataException(null, msg);
    }
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   * @param key String key
   * @return String message
   */
  protected static String getMsg(String key)
  {
    return org.opends.server.util.StaticUtils.wrapText(getI18n().getMsg(key),
        Utils.getCommandLineMaxLineWidth());
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   * @param key String key
   * @param args String[] args
   * @return String message
   */
  protected static String getMsg(String key, String[] args)
  {
    return org.opends.server.util.StaticUtils.wrapText(
        getI18n().getMsg(key, args), Utils.getCommandLineMaxLineWidth());
  }
  /**
   * Gets the resource provider instance.
   * @return ResourceProvider instance
   */
  protected static ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
}
opends/src/quicksetup/org/opends/quicksetup/Launcher.java
New file
@@ -0,0 +1,281 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.i18n.ResourceProvider;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
/**
 * Responsible for providing initial evaluation of command line arguments
 * and determining whether to launch a CLI, GUI, or print a usage statement.
 */
public abstract class Launcher {
  /** Arguments with which this launcher was invoked. */
  protected String[] args;
  /**
   * Creates a Launcher.
   * @param args String[] of argument passes from the command line
   */
  public Launcher(String[] args) {
    if (args == null) {
      throw new IllegalArgumentException("args cannot be null");
    }
    this.args = args;
  }
  /**
   * 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 shouldPrintUsage() {
    boolean printUsage = false;
    if (!isCli() && args.length > 0) {
      printUsage = true;
    } else {
      if ((args != null) && (args.length > 0)) {
        for (String arg : args) {
          if (arg.equalsIgnoreCase("-H") ||
                  arg.equalsIgnoreCase("--help")) {
            printUsage = true;
          }
        }
      }
    }
    return printUsage;
  }
  /**
   * Indicates whether the launcher will launch a command line versus
   * a graphical application based on the contents of the arguments
   * passed into the constructor.
   * @return boolean where true indicates that a CLI application should
   * be launched
   */
  protected boolean isCli() {
    boolean isCli = false;
    for (String arg : args) {
      if (arg.equalsIgnoreCase("--cli")) {
        isCli = true;
        break;
      }
    }
    return isCli;
  }
  /**
   * Creates an internationaized message based on the input key and
   * properly formatted for the terminal.
   * @param key for the message in the bundle
   * @return String message properly formatted for the terminal
   */
  protected String getMsg(String key)
  {
    return org.opends.server.util.StaticUtils.wrapText(getI18n().getMsg(key),
        Utils.getCommandLineMaxLineWidth());
  }
  /**
   * Prints a usage message to the terminal and exits
   * with exit code QuickSetupCli.USER_DATA_ERROR.
   * @param i18nMsg localized user message that will
   * be printed to std error
   */
  protected void printUsage(String i18nMsg) {
    System.err.println(i18nMsg);
    System.exit(QuickSetupCli.USER_DATA_ERROR);
  }
  /**
   * Launches the graphical uninstall. The graphical uninstall is launched in a
   * different thread that the main thread because if we have a problem with the
   * graphical system (for instance the DISPLAY environment variable is not
   * correctly set) the native libraries will call exit. However if we launch
   * this from another thread, the thread will just be killed.
   *
   * This code also assumes that if the call to SplashWindow.main worked (and
   * the splash screen was displayed) we will never get out of it (we will call
   * a System.exit() when we close the graphical uninstall dialog).
   *
   * @param args String[] the arguments used to call the SplashWindow main
   *         method
   * @return 0 if everything worked fine, or 1 if we could not display properly
   *         the SplashWindow.
   */
  protected int launchGui(final String[] args)
  {
    final int[] returnValue =
      { -1 };
    Thread t = new Thread(new Runnable()
    {
      public void run()
      {
        // Setup MacOSX native menu bar before AWT is loaded.
        Utils.setMacOSXMenuBar(getFrameTitle());
        SplashScreen.main(args);
        returnValue[0] = 0;
      }
    });
    /*
     * This is done to avoid displaying the stack that might occur if there are
     * problems with the display environment.
     */
    PrintStream printStream = System.err;
    System.setErr(new EmptyPrintStream());
    t.start();
    try
    {
      t.join();
    }
    catch (InterruptedException ie)
    {
      /* An error occurred, so the return value will be -1.  We got nothing to
      do with this exception. */
    }
    System.setErr(printStream);
    return returnValue[0];
  }
  /**
   * Gets the frame title of the GUI application that will be used
   * in some operating systems.
   * @return internationalized String representing the frame title
   */
  abstract protected String getFrameTitle();
  /**
   * Launches the command line based uninstall.
   *
   * @param args the arguments passed
   * @param cliApp the CLI application to launch
   * @return 0 if everything worked fine, and an error code if something wrong
   *         occurred.
   */
  protected int launchCli(String[] args, CliApplication cliApp) {
    System.out.println(getMsg("uninstall-launcher-launching-cli"));
    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;
  }
  /**
   * Prints a usage statement to terminal and exits
   * with an error code.
   */
  protected abstract void printUsage();
  /**
   * Creates a CLI application that will be run if the
   * launcher needs to launch a CLI application.
   * @return CliApplication that will be run
   */
  protected abstract CliApplication createCliApplication();
  /**
   * Called before the launcher launches the GUI.  Here
   * subclasses can do any application specific things
   * like set system properties of print status messages
   * that need to be done before the GUI launches.
   */
  protected abstract void willLaunchGui();
  /**
   * Called if launching of the GUI failed.  Here
   * subclasses can so application specific things
   * like print a message.
   */
  protected abstract void guiLaunchFailed();
  /**
   * The main method which is called by the uninstall command lines.
   */
  public void launch() {
    if (shouldPrintUsage()) {
      printUsage();
    } else if (isCli()) {
      int exitCode = launchCli(args, createCliApplication());
      if (exitCode != 0) {
        System.exit(exitCode);
      }
    } else {
      willLaunchGui();
      int exitCode = launchGui(args);
      if (exitCode != 0) {
        guiLaunchFailed();
        exitCode = launchCli(args, createCliApplication());
        if (exitCode != 0) {
          System.exit(exitCode);
        }
      }
    }
  }
  /**
   * This class is used to avoid displaying the error message related to display
   * problems that we might have when trying to display the SplashWindow.
   *
   */
  private class EmptyPrintStream extends PrintStream {
    /**
     * Default constructor.
     *
     */
    public EmptyPrintStream()
    {
      super(new ByteArrayOutputStream(), true);
    }
    /**
     * {@inheritDoc}
     */
    public void println(String msg)
    {
    }
  }
  private ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
}
opends/src/quicksetup/org/opends/quicksetup/QuickSetup.java
@@ -117,7 +117,7 @@
  {
    ProgressMessageFormatter formatter = new HtmlProgressMessageFormatter();
    try {
      application = Application.create(formatter);
      application = Application.create();
      application.setProgressMessageFormatter(formatter);
    } catch (ApplicationException e) {
      LOG.log(Level.INFO, "error", e);
@@ -135,15 +135,6 @@
    }
  }
  private Application createApplication(ProgressMessageFormatter formatter) {
    try {
      application = Application.create(formatter);
    } catch (ApplicationException e) {
      LOG.log(Level.INFO, "error", e);
    }
    return application;
  }
  /**
   * Gets the current installation status of the filesystem
   * bits this quick setup is managing.
opends/src/quicksetup/org/opends/quicksetup/QuickSetupCli.java
New file
@@ -0,0 +1,209 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup;
import org.opends.quicksetup.util.ProgressMessageFormatter;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.i18n.ResourceProvider;
/**
 * Controller for managing the execution of a CliApplication.
 */
public class QuickSetupCli {
  /**
   * Return code: Uninstall successful.
   */
  static public int SUCCESSFUL = 0;
  /**
   * Return code: User Cancelled uninstall.
   */
  static public int CANCELLED = 1;
  /**
   * Return code: User provided invalid data.
   */
  static public int USER_DATA_ERROR = 2;
  /**
   * Return code: Error accessing file system (reading/writing).
   */
  static public int ERROR_ACCESSING_FILE_SYSTEM = 3;
  /**
   * Return code: Error stopping server.
   */
  static public int ERROR_STOPPING_SERVER = 4;
  /**
   * Return code: Bug.
   */
  static public int BUG = 5;
  /** Platform dependent filesystem separator. */
  public static String LINE_SEPARATOR = System.getProperty("line.separator");
  /** Arguments passed in the command line. */
  protected String[] args;
  private CliApplication cliApp;
  /**
   * Creates a QuickSetupCli instance.
   * @param cliApp the application to be run
   * @param args arguments passed in from the command line
   */
  public QuickSetupCli(CliApplication cliApp, String[] args) {
    this.cliApp = cliApp;
    this.args = args;
  }
  /**
   * Parses the user data and prompts the user for data if required.  If the
   * user provides all the required data it launches the Uninstaller.
   *
   * @return the return code (SUCCESSFUL, CANCELLED, USER_DATA_ERROR,
   * ERROR_ACCESSING_FILE_SYSTEM, ERROR_STOPPING_SERVER or BUG.
   */
  public int run()
  {
    int returnValue;
    // Parse the arguments
    try
    {
      CurrentInstallStatus installStatus = new CurrentInstallStatus();
      UserData userData = cliApp.createUserData(args, installStatus);
      if (userData != null)
      {
        ProgressMessageFormatter formatter =
                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)
              {
                System.out.print(
                    org.opends.server.util.StaticUtils.wrapText(ev.getNewLogs(),
                        Utils.getCommandLineMaxLineWidth()));
              }
            });
        new Thread(cliApp).start();
        while (!cliApp.isFinished())
        {
          try
          {
            Thread.sleep(100);
          }
          catch (Exception ex)
          {
          }
        }
        ApplicationException ue = cliApp.getException();
        if (ue != null)
        {
          switch (ue.getType())
          {
          case FILE_SYSTEM_ERROR:
            returnValue = ERROR_ACCESSING_FILE_SYSTEM;
            break;
          case STOP_ERROR:
            returnValue = ERROR_STOPPING_SERVER;
            break;
          case BUG:
            returnValue = BUG;
            break;
            default:
              throw new IllegalStateException(
                  "Unknown ApplicationException type: "+ue.getType());
          }
        }
        else
        {
          returnValue = SUCCESSFUL;
        }
      }
      else
      {
        // User cancelled installation.
        returnValue = CANCELLED;
      }
    }
    catch (UserDataException uude)
    {
      System.err.println(LINE_SEPARATOR+uude.getLocalizedMessage()+
          LINE_SEPARATOR);
      returnValue = USER_DATA_ERROR;
    }
    return returnValue;
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   * @param key String key
   * @return String message
   */
  protected static String getMsg(String key)
  {
    return org.opends.server.util.StaticUtils.wrapText(getI18n().getMsg(key),
        Utils.getCommandLineMaxLineWidth());
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   * @param key String key
   * @param args String[] args
   * @return String message
   */
  protected static String getMsg(String key, String[] args)
  {
    return org.opends.server.util.StaticUtils.wrapText(
        getI18n().getMsg(key, args), Utils.getCommandLineMaxLineWidth());
  }
  private static ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
@@ -26,12 +26,10 @@
 */
package org.opends.quicksetup.installer;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import org.opends.quicksetup.SplashScreen;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.util.Utils;
/**
@@ -39,59 +37,85 @@
 * the Directory Server. It just checks the command line arguments and the
 * environment and determines whether the graphical or the command line
 * based setup much be launched.
 *
 */
public class InstallLauncher
{
public class InstallLauncher extends Launcher {
  /**
   * The main method which is called by the setup command lines.
   *
   * @param args the arguments passed by the command lines.  In the case
   * we want to launch the cli setup they are basically the arguments that we
   * will pass to the org.opends.server.tools.InstallDS class.
   */
  public static void main(String[] args)
  {
    boolean displayUsage = false;
    boolean useCli = false;
    if ((args != null) && (args.length > 0))
    {
      for (int i = 0; i < args.length; i++)
      {
        if (args[i].equals("--cli"))
        {
          useCli = true;
        }
  public static void main(String[] args) {
    new InstallLauncher(args).launch();
      }
      if (!useCli)
      {
        if (args.length > 0)
        {
          if (args.length == 2)
          {
  /**
   * Creates a launcher.
   *
   * @param args the arguments passed by the command lines.
   */
  public InstallLauncher(String[] args) {
    super(args);
  }
  /**
   * {@inheritDoc}
   */
  protected boolean shouldPrintUsage() {
    boolean displayUsage = false;
    if ((args != null) && (args.length > 0)) {
      if (!isCli()) {
        if (args.length > 0) {
          if (args.length == 2) {
            /*
             * Just ignore the -P argument that is passed by the setup command
             * line.
             */
            if (!args[0].equals("-P"))
            {
            if (!args[0].equals("-P")) {
              displayUsage = true;
            }
          } else
          {
          } else {
            displayUsage = true;
          }
        }
      }
    }
    if (displayUsage)
    {
    return displayUsage;
  }
  /**
   * {@inheritDoc}
   */
  protected void guiLaunchFailed() {
    System.err.println(getMsg("setup-launcher-gui-launched-failed"));
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(getMsg("setup-launcher-launching-gui"));
    System.setProperty("org.opends.quicksetup.Application.class",
            "org.opends.quicksetup.installer.offline.OfflineInstaller");
  }
  /**
   * {@inheritDoc}
   */
  protected String getFrameTitle() {
    return getMsg("frame-install-title");
  }
  /**
   * {@inheritDoc}
   */
  public void printUsage() {
      String arg;
      if (Utils.isWindows())
      {
    if (Utils.isWindows()) {
        arg = Utils.getWindowsSetupFileName();
      } else
      {
    } else {
        arg = Utils.getUnixSetupFileName();
      }
      /*
@@ -100,68 +124,45 @@
       */
      String msg;
      if (Utils.isWindows())
      {
    if (Utils.isWindows()) {
        msg= getMsg("setup-launcher-usage-windows");
      }
      else
      {
    } else {
        msg= getMsg("setup-launcher-usage-unix");
      }
      msg = msg.replace("{0}", arg);
      System.err.println(msg);
      System.exit(1);
    } else if (useCli)
    {
      int exitCode = launchCliSetup(args);
      if (exitCode != 0)
      {
        System.exit(exitCode);
      }
    } else
    {
      System.setProperty("org.opends.quicksetup.Application.class",
              "org.opends.quicksetup.installer.offline.OfflineInstaller");
      int exitCode = launchGuiSetup(args);
      if (exitCode != 0)
      {
        System.err.println(getMsg("setup-launcher-gui-launched-failed"));
        exitCode = launchCliSetup(args);
        if (exitCode != 0)
        {
          System.exit(exitCode);
        }
      }
    }
    printUsage(msg);
  }
  /**
   * Launches the command line based setup.
   * @param args the arguments passed
   * @return 0 if everything worked fine, and an error code if something wrong
   * occurred (as specified in org.opends.server.tools.InstallDS).
   * @see org.opends.server.tools.InstallDS
   * {@inheritDoc}
   */
  private static int launchCliSetup(String[] args)
  {
  protected CliApplication createCliApplication() {
    // Setup currently has no implemented CliApplication
    // but rather relies on InstallDS from the server
    // package.  Note that launchCli is overloaded
    // to run this application instead of the default
    // behavior in Launcher
    return null;
  }
  /**
   * {@inheritDoc}
   */
  @Override
  protected int launchCli(String[] args, CliApplication cliApp) {
    System.setProperty("org.opends.quicksetup.cli", "true");
    if (Utils.isWindows())
    {
    if (Utils.isWindows()) {
      System.setProperty("org.opends.server.scriptName",
          Utils.getWindowsSetupFileName());
    } else
    {
    } else {
      System.setProperty("org.opends.server.scriptName",
          Utils.getUnixSetupFileName());
    }
    ArrayList<String> newArgList = new ArrayList<String>();
    if (args != null)
    {
      for (int i = 0; i < args.length; i++)
      {
        if (!args[i].equalsIgnoreCase("--cli"))
        {
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        if (!args[i].equalsIgnoreCase("--cli")) {
          newArgList.add(args[i]);
        }
      }
@@ -177,92 +178,4 @@
    return org.opends.server.tools.InstallDS.installMain(newArgs);
  }
  /**
   * Launches the graphical setup. The graphical setup is launched in a
   * different thread that the main thread because if we have a problem with the
   * graphical system (for instance the DISPLAY environment variable is not
   * correctly set) the native libraries will call exit. However if we launch
   * this from another thread, the thread will just be killed.
   *
   * This code also assumes that if the call to SplashWindow.main worked (and
   * the splash screen was displayed) we will never get out of it (we will call
   * a System.exit() when we close the graphical setup dialog).
   *
   * @params String[] args the arguments used to call the SplashWindow main
   *         method
   * @return 0 if everything worked fine, or 1 if we could not display properly
   *         the SplashWindow.
   */
  private static int launchGuiSetup(final String[] args)
  {
    System.out.println(getMsg("setup-launcher-launching-gui"));
    final int[] returnValue =
      { -1 };
    Thread t = new Thread(new Runnable()
    {
      public void run()
      {
        // Setup MacOSX native menu bar before AWT is loaded.
        Utils.setMacOSXMenuBar(getMsg("frame-install-title"));
        SplashScreen.main(args);
        returnValue[0] = 0;
      }
    });
    /*
     * This is done to avoid displaying the stack that might occur if there are
     * problems with the display environment.
     */
    PrintStream printStream = System.err;
    System.setErr(new EmptyPrintStream());
    t.start();
    try
    {
      t.join();
    }
    catch (InterruptedException ie)
    {
      /* An error occurred, so the return value will be -1.  We got nothing to
      do with this exception. */
    }
    System.setErr(printStream);
    return returnValue[0];
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   */
  private static String getMsg(String key)
  {
    return getI18n().getMsg(key);
  }
  private static ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
  /**
   * This class is used to avoid displaying the error message related to display
   * problems that we might have when trying to display the SplashWindow.
   *
   */
  static class EmptyPrintStream extends PrintStream
  {
    /**
     * Default constructor.
     *
     */
    public EmptyPrintStream()
    {
      super(new ByteArrayOutputStream(), true);
    }
    /**
     * {@inheritDoc}
     */
    public void println(String msg)
    {
    }
  }
}
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCli.java
File was deleted
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallCliHelper.java
New file
@@ -0,0 +1,408 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.quicksetup.uninstaller;
import org.opends.quicksetup.*;
import org.opends.quicksetup.util.Utils;
import java.util.HashSet;
import java.util.Set;
/**
 * The class used to provide some CLI interface in the uninstall.
 *
 * This class basically is in charge of parsing the data provided by the user
 * in the command line and displaying messages asking the user for information.
 *
 * Once the user has provided all the required information it calls Uninstaller
 * and launches it.
 *
 */
class UninstallCliHelper extends CliApplicationHelper {
  static private String FORMAT_KEY = "cli-uninstall-confirm-prompt";
  /**
   * Creates a UserData based in the arguments provided.  It asks
   * user for additional information if what is provided in the arguments is not
   * enough.
   * @param args the arguments provided in the command line.
   * @param installStatus the current install status.
   * @return the UserData object with what the user wants to uninstall
   * and null if the user cancels the uninstallation.
   * @throws UserDataException if there is an error parsing the data
   * in the arguments.
   */
  public UninstallUserData createUserData(String[] args,
      CurrentInstallStatus installStatus) throws UserDataException
  {
    UninstallUserData userData = new UninstallUserData();
    boolean silentUninstall;
    boolean isCancelled = false;
    /* Step 1: validate the arguments
     */
    Set<String> validArgs = new HashSet<String>();
    validArgs.add("--cli");
    validArgs.add("-H");
    validArgs.add("--help");
    validArgs.add("--silentUninstall");
    validArgs.add("-s");
    validateArguments(userData, args, validArgs);
    silentUninstall = isSilent(args);
    /* Step 2: If this is not a silent install ask for confirmation to delete
     * the different parts of the installation
     */
    Set<String> outsideDbs = getOutsideDbs(installStatus);
    Set<String> outsideLogs = getOutsideLogs(installStatus);
    if (silentUninstall)
    {
      userData.setRemoveBackups(true);
      userData.setRemoveConfigurationAndSchema(true);
      userData.setRemoveDatabases(true);
      userData.setRemoveLDIFs(true);
      userData.setRemoveLibrariesAndTools(true);
      userData.setRemoveLogs(true);
      userData.setExternalDbsToRemove(outsideDbs);
      userData.setExternalLogsToRemove(outsideLogs);
    }
    else
    {
      isCancelled = askWhatToDelete(userData, outsideDbs, outsideLogs);
    }
    /*
     * Step 3: check if server is running.  Depending if it is running and the
     * OS we are running, ask for authentication information.
     */
    if (!isCancelled)
    {
      isCancelled = askConfirmationToStop(userData, silentUninstall);
    }
    if (isCancelled)
    {
      userData = null;
    }
    return userData;
  }
  /**
   * Returns a Set of relative paths containing the db paths outside the
   * installation.
   * @param installStatus the Current Install Status object.
   * @return a Set of relative paths containing the db paths outside the
   * installation.
   */
  private Set<String> getOutsideDbs(CurrentInstallStatus installStatus)
  {
    return Utils.getOutsideDbs(installStatus);
  }
  /**
   * Returns a Set of relative paths containing the log paths outside the
   * installation.
   * @param installStatus the Current Install Status object.
   * @return a Set of relative paths containing the log paths outside the
   * installation.
   */
  private Set<String> getOutsideLogs(CurrentInstallStatus installStatus)
  {
    return Utils.getOutsideLogs(installStatus);
  }
  /**
   * Commodity method used to ask the user to confirm the deletion of certain
   * parts of the server.  It updates the provided UserData object
   * accordingly.  Returns <CODE>true</CODE> if the user cancels and <CODE>
   * false</CODE> otherwise.
   * @param userData the UserData object to be updated.
   * @param outsideDbs the set of relative paths of databases located outside
   * the installation path of the server.
   * @param outsideLogs the set of relative paths of log files located outside
   * the installation path of the server.
   * @return <CODE>true</CODE> if the user cancels and <CODE>false</CODE>
   * otherwise.
   */
  private boolean askWhatToDelete(UninstallUserData userData,
      Set<String> outsideDbs, Set<String> outsideLogs)
  {
    boolean cancelled = false;
    String answer = promptConfirm(FORMAT_KEY,
            getMsg("cli-uninstall-what-to-delete"),
        "1", new String[] {"1", "2", "3"});
    if ("3".equals(answer))
    {
      cancelled = true;
    }
    else if ("1".equals(answer))
    {
      userData.setRemoveBackups(true);
      userData.setRemoveConfigurationAndSchema(true);
      userData.setRemoveDatabases(true);
      userData.setRemoveLDIFs(true);
      userData.setRemoveLibrariesAndTools(true);
      userData.setRemoveLogs(true);
      userData.setExternalDbsToRemove(outsideDbs);
      userData.setExternalLogsToRemove(outsideLogs);
    }
    else
    {
      boolean somethingSelected = false;
      while (!somethingSelected)
      {
//      Ask for confirmation for the different items
        String[] keys = {
            "cli-uninstall-confirm-libraries-binaries",
            "cli-uninstall-confirm-databases",
            "cli-uninstall-confirm-logs",
            "cli-uninstall-confirm-configuration-schema",
            "cli-uninstall-confirm-backups",
            "cli-uninstall-confirm-ldifs",
            "cli-uninstall-confirm-outsidedbs",
            "cli-uninstall-confirm-outsidelogs"
        };
        String[] validValues = {
            getMsg("cli-uninstall-yes-long"), getMsg("cli-uninstall-no-long"),
            getMsg("cli-uninstall-yes-short"), getMsg("cli-uninstall-no-short")
        };
        boolean[] answers = new boolean[keys.length];
        for (int i=0; i<keys.length; i++)
        {
          boolean ignore = ((i == 6) && (outsideDbs.size() == 0)) ||
          ((i == 7) && (outsideLogs.size() == 0));
          if (!ignore)
          {
            String msg;
            if (i == 6)
            {
              String[] arg = {Utils.getStringFromCollection(outsideDbs,
                  QuickSetupCli.LINE_SEPARATOR)};
              msg = getMsg(keys[i], arg);
            }
            else if (i == 7)
            {
              String[] arg = {Utils.getStringFromCollection(outsideLogs,
                  QuickSetupCli.LINE_SEPARATOR)};
              msg = getMsg(keys[i], arg);
            }
            else
            {
              msg = getMsg(keys[i]);
            }
            answer = promptConfirm(FORMAT_KEY,
                msg, getMsg("cli-uninstall-yes-long"),
                validValues);
            answers[i] =
                    getMsg("cli-uninstall-yes-long").equalsIgnoreCase(answer) ||
                    getMsg("cli-uninstall-yes-short").equalsIgnoreCase(answer);
          }
          else
          {
            answers[i] = false;
          }
        }
        for (int i=0; i<answers.length; i++)
        {
          switch (i)
          {
          case 0:
            userData.setRemoveLibrariesAndTools(answers[i]);
            break;
          case 1:
            userData.setRemoveDatabases(answers[i]);
            break;
          case 2:
            userData.setRemoveLogs(answers[i]);
            break;
          case 3:
            userData.setRemoveConfigurationAndSchema(answers[i]);
            break;
          case 4:
            userData.setRemoveBackups(answers[i]);
            break;
          case 5:
            userData.setRemoveLDIFs(answers[i]);
            break;
          case 6:
            if (answers[i])
            {
              userData.setExternalDbsToRemove(outsideDbs);
            }
            break;
          case 7:
            if (answers[i])
            {
              userData.setExternalLogsToRemove(outsideLogs);
            }
            break;
          }
        }
        if ((userData.getExternalDbsToRemove().size() == 0) &&
            (userData.getExternalLogsToRemove().size() == 0) &&
            !userData.getRemoveLibrariesAndTools() &&
            !userData.getRemoveDatabases() &&
            !userData.getRemoveConfigurationAndSchema() &&
            !userData.getRemoveBackups() &&
            !userData.getRemoveLDIFs() &&
            !userData.getRemoveLogs())
        {
          somethingSelected = false;
          System.out.println(QuickSetupCli.LINE_SEPARATOR+
              getMsg("cli-uninstall-nothing-to-be-uninstalled"));
        }
        else
        {
          somethingSelected = true;
        }
      }
    }
    return cancelled;
  }
  /**
   * Commodity method used to ask the user (when necessary) if the server must
   * be stopped or not.  If required it also asks the user authentication to
   * be able to shut down the server in Windows.
   * @param userData the UserData object to be updated with the
   * authentication of the user.
   * @param silentUninstall boolean telling whether this is a silent uninstall
   * or not.
   * @return <CODE>true</CODE> if the user wants to continue with uninstall and
   * <CODE>false</CODE> otherwise.
   * @throws UserDataException if there is a problem with the data
   * provided by the user (in the particular case where we are on silent
   * uninstall and some data is missing or not valid).
   */
  private boolean askConfirmationToStop(UserData userData,
                                        boolean silentUninstall)
  throws UserDataException
  {
    boolean cancelled = false;
    if (CurrentInstallStatus.isServerRunning())
    {
        if (!silentUninstall)
        {
            /* Ask for confirmation to stop server */
            cancelled = !confirmToStopServer();
        }
        if (!cancelled)
        {
            /* During all the confirmations, the server might be stopped. */
            userData.setStopServer(CurrentInstallStatus.isServerRunning());
        }
    }
    else
    {
      userData.setStopServer(false);
      if (!silentUninstall)
      {
        /* Ask for confirmation to delete files */
        cancelled = !confirmDeleteFiles();
      }
    }
    return cancelled;
  }
  /**
   *  Ask for confirmation to stop server.
   *  @return <CODE>true</CODE> if the user wants to continue and stop the
   *  server.  <CODE>false</CODE> otherwise.
   */
  private boolean confirmToStopServer()
  {
    boolean confirm = true;
    String[] validValues = {
        getMsg("cli-uninstall-yes-short"),
        getMsg("cli-uninstall-no-short"),
        getMsg("cli-uninstall-yes-long"),
        getMsg("cli-uninstall-no-long")
    };
    String answer = promptConfirm(FORMAT_KEY,
        getMsg("cli-uninstall-confirm-stop"),
        getMsg("cli-uninstall-yes-long"), validValues);
    if (getMsg("cli-uninstall-no-short").equalsIgnoreCase(answer) ||
        getMsg("cli-uninstall-no-long").equalsIgnoreCase(answer))
    {
      confirm = false;
    }
    return confirm;
  }
  /**
   *  Ask for confirmation to delete files.
   *  @return <CODE>true</CODE> if the user wants to continue and delete the
   *  files.  <CODE>false</CODE> otherwise.
   */
  private boolean confirmDeleteFiles()
  {
    boolean confirm = true;
    String[] validValues = {
        getMsg("cli-uninstall-yes-short"),
        getMsg("cli-uninstall-no-short"),
        getMsg("cli-uninstall-yes-long"),
        getMsg("cli-uninstall-no-long")
    };
    String answer = promptConfirm(FORMAT_KEY,
        getMsg("cli-uninstall-confirm-delete-files"),
        getMsg("cli-uninstall-yes-long"), validValues);
    if (getMsg("cli-uninstall-no-short").equalsIgnoreCase(answer) ||
        getMsg("cli-uninstall-no-long").equalsIgnoreCase(answer))
    {
      confirm = false;
    }
    return confirm;
  }
}
opends/src/quicksetup/org/opends/quicksetup/uninstaller/UninstallLauncher.java
@@ -27,11 +27,8 @@
package org.opends.quicksetup.uninstaller;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.opends.quicksetup.SplashScreen;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.util.Utils;
/**
@@ -39,198 +36,77 @@
 * of the Directory Server. It just checks the command line arguments and the
 * environment and determines whether the graphical or the command line
 * based uninstall much be launched.
 *
 */
public class UninstallLauncher
{
public class UninstallLauncher extends Launcher {
  /**
   * The main method which is called by the uninstall command lines.
   * The main method which is called by the setup command lines.
   *
   * @param args the arguments passed by the command lines.  In the case
   * we want to launch the cli setup they are basically the arguments that we
   * will pass to the org.opends.server.tools.InstallDS class.
   */
  public static void main(String[] args) {
    new UninstallLauncher(args).launch();
  }
  /**
   * Creates a launcher.
   *
   * @param args the arguments passed by the command lines.
   */
  public static void main(String[] args)
  {
    boolean printUsage = false;
    boolean useCli = false;
    if ((args != null) && (args.length > 0))
    {
      for (int i = 0; i < args.length; i++)
      {
        if (args[i].equalsIgnoreCase("--cli"))
        {
          useCli = true;
        }
        else if (args[i].equalsIgnoreCase("-H") ||
            args[i].equalsIgnoreCase("--help"))
        {
          printUsage = true;
        }
      }
      if (!useCli)
      {
        if (args.length > 0)
        {
          printUsage = true;
        }
      }
    }
    if (printUsage)
    {
      printUsage();
      System.exit(1);
    } else if (useCli)
    {
      int exitCode = launchCliUninstall(args);
      if (exitCode != 0)
      {
        System.exit(exitCode);
      }
    } else
    {
      System.setProperty("org.opends.quicksetup.uninstall", "true");
      System.setProperty("org.opends.quicksetup.Application.class",
              "org.opends.quicksetup.uninstaller.Uninstaller");
      int exitCode = launchGuiUninstall(args);
      if (exitCode != 0)
      {
        System.err.println(getMsg("uninstall-launcher-gui-launched-failed"));
        exitCode = launchCliUninstall(args);
        if (exitCode != 0)
        {
          System.exit(exitCode);
        }
      }
    }
  }
  /**
   * Launches the command line based uninstall.
   * @param args the arguments passed
   * @return 0 if everything worked fine, and an error code if something wrong
   * occurred.
   */
  private static int launchCliUninstall(String[] args)
  {
    System.setProperty("org.opends.quicksetup.cli", "true");
    UninstallCli cli = new UninstallCli(args);
    int returnValue = cli.run();
    if (returnValue == UninstallCli.USER_DATA_ERROR)
    {
      printUsage();
    }
//    Add an extra space systematically
    System.out.println();
    return returnValue;
  }
  /**
   * Launches the graphical uninstall. The graphical uninstall is launched in a
   * different thread that the main thread because if we have a problem with the
   * graphical system (for instance the DISPLAY environment variable is not
   * correctly set) the native libraries will call exit. However if we launch
   * this from another thread, the thread will just be killed.
   *
   * This code also assumes that if the call to SplashWindow.main worked (and
   * the splash screen was displayed) we will never get out of it (we will call
   * a System.exit() when we close the graphical uninstall dialog).
   *
   * @params String[] args the arguments used to call the SplashWindow main
   *         method
   * @return 0 if everything worked fine, or 1 if we could not display properly
   *         the SplashWindow.
   */
  private static int launchGuiUninstall(final String[] args)
  {
    System.out.println(getMsg("uninstall-launcher-launching-gui"));
    final int[] returnValue =
      { -1 };
    Thread t = new Thread(new Runnable()
    {
      public void run()
      {
        // Setup MacOSX native menu bar before AWT is loaded.
        Utils.setMacOSXMenuBar(getMsg("frame-uninstall-title"));
        SplashScreen.main(args);
        returnValue[0] = 0;
      }
    });
    /*
     * This is done to avoid displaying the stack that might occur if there are
     * problems with the display environment.
     */
    PrintStream printStream = System.err;
    System.setErr(new EmptyPrintStream());
    t.start();
    try
    {
      t.join();
    }
    catch (InterruptedException ie)
    {
      /* An error occurred, so the return value will be -1.  We got nothing to
      do with this exception. */
    }
    System.setErr(printStream);
    return returnValue[0];
  }
  private static void printUsage()
  {
    String arg;
    if (Utils.isWindows())
    {
      arg = Utils.getWindowsUninstallFileName();
    } else
    {
      arg = Utils.getUnixUninstallFileName();
    }
    /*
     * This is required because the usage message contains '{' characters that
     * mess up the MessageFormat.format method.
     */
    String msg = getMsg("uninstall-launcher-usage");
    msg = msg.replace("{0}", arg);
    System.err.println(msg);
  }
  /**
   * The following three methods are just commodity methods to get localized
   * messages.
   */
  private static String getMsg(String key)
  {
    return org.opends.server.util.StaticUtils.wrapText(getI18n().getMsg(key),
        Utils.getCommandLineMaxLineWidth());
  }
  private static ResourceProvider getI18n()
  {
    return ResourceProvider.getInstance();
  }
  /**
   * This class is used to avoid displaying the error message related to display
   * problems that we might have when trying to display the SplashWindow.
   *
   */
  static class EmptyPrintStream extends PrintStream
  {
    /**
     * Default constructor.
     *
     */
    public EmptyPrintStream()
    {
      super(new ByteArrayOutputStream(), true);
  public UninstallLauncher(String[] args) {
    super(args);
    }
    /**
     * {@inheritDoc}
     */
    public void println(String msg)
    {
  protected void guiLaunchFailed() {
    System.err.println(getMsg("uninstall-launcher-gui-launched-failed"));
    }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(getMsg("uninstall-launcher-launching-gui"));
    System.setProperty("org.opends.quicksetup.uninstall", "true");
    System.setProperty("org.opends.quicksetup.Application.class",
            "org.opends.quicksetup.uninstaller.Uninstaller");
  }
  /**
   * {@inheritDoc}
   */
  protected CliApplication createCliApplication() {
    return new Uninstaller();
  }
  /**
   * {@inheritDoc}
   */
  protected String getFrameTitle() {
    return getMsg("frame-uninstall-title");
  }
  /**
   * {@inheritDoc}
   */
  protected void printUsage() {
    String arg;
    if (Utils.isWindows()) {
      arg = Utils.getWindowsUninstallFileName();
    } else {
      arg = Utils.getUnixUninstallFileName();
    }
    String msg = getMsg("uninstall-launcher-usage");
    /*
     * This is required because the usage message contains '{' characters that
     * mess up the MessageFormat.format method.
     */
    msg = msg.replace("{0}", arg);
    printUsage(msg);
  }
}
opends/src/quicksetup/org/opends/quicksetup/uninstaller/Uninstaller.java
@@ -37,7 +37,7 @@
/**
 * This class is in charge of performing the uninstallation of Open DS.
 */
public class Uninstaller extends Application {
public class Uninstaller extends Application implements CliApplication {
  private ProgressStep status = UninstallProgressStep.NOT_STARTED;
@@ -51,6 +51,8 @@
  private Boolean isWindowsServiceEnabled;
  private UninstallCliHelper cliHelper = new UninstallCliHelper();
  /**
   * {@inheritDoc}
   */
@@ -61,6 +63,15 @@
  /**
   * {@inheritDoc}
   */
  public UserData createUserData(String[] args, CurrentInstallStatus status)
    throws UserDataException
  {
    return cliHelper.createUserData(args, status);
  }
  /**
   * {@inheritDoc}
   */
  protected String getInstallationPath() {
    return null;
  }