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

jvergara
05.40.2007 111c848e2d90d962a7f48d7b4121304247829473
The following changes are targetted to fix a certain number of issues related to the setup command line:

* 1257 setup cli/gui symetry -- allow to start after slient install
* 1264 silent install option is not silent
* 1326 Update setup CLI to integrate common install scenario (partial fix)
* 1404 different CLI/GUI behavior running setup
* 1859 spin off GUI specific CLI commands
* 2184 setup quite/no-prompt
* 2185 setup --cli -Q throws error

The changes basically consist on splitting the current setup command-line into two (the same way we have done for the uninstall). Know we will have one command to launch the setup in CLI mode (setup and setup.bat) and one command to launch the setup in GUI mode (setup-gui and setup-gui.bat).

The behavior of the graphical interface has not changed. However the capabilities of the CLI setup have been extended to allow to match those in the graphical interface (excluding the replication configuration capabilities):

* Configure the LDAPS and StartTLS on the server.
* Start the server.
1 files deleted
4 files added
16 files modified
4665 ■■■■■ changed files
opends/build.xml 9 ●●●●● patch | view | raw | blame | history
opends/resource/setup 2 ●●● patch | view | raw | blame | history
opends/resource/setup-gui 131 ●●●●● patch | view | raw | blame | history
opends/resource/setup-gui.bat 89 ●●●●● patch | view | raw | blame | history
opends/resource/setup.bat 10 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/quicksetup.properties 46 ●●●●● patch | view | raw | blame | history
opends/src/messages/messages/tools.properties 127 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java 36 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/Installation.java 27 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/UserData.java 47 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java 305 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java 235 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java 29 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java 220 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java 24 ●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java 23 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java 13 ●●●●● patch | view | raw | blame | history
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java 3 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/InstallDS.java 2681 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java 604 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java 4 ●●●● patch | view | raw | blame | history
opends/build.xml
@@ -875,12 +875,13 @@
      <fileset file="${resource.dir}/README" />
    </copy>
    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup,uninstall,uninstall-gui,upgrade"
    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup,setup-gui,uninstall,uninstall-gui,upgrade"
         eol="lf" />
    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup.bat,uninstall.bat,uninstall-gui.bat,upgrade.bat"
    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup.bat,setup-gui.bat,uninstall.bat,uninstall-gui.bat,upgrade.bat"
         eol="crlf" />
    <chmod file="${pdir}/setup" perm="755" />
    <chmod file="${pdir}/setup-gui" perm="755" />
    <chmod file="${pdir}/uninstall" perm="755" />
    <chmod file="${pdir}/uninstall-gui" perm="755" />
    <chmod file="${pdir}/upgrade" perm="755" />
@@ -900,7 +901,7 @@
       description="Package the Directory Server for distribution.">
    <zip destfile="${package.dir}/${SHORT_NAME}-${VERSION_NUMBER_STRING}.zip">
      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/**/*"
           excludes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/*,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
           excludes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/*,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
           filemode="644" dirmode="755" />
      <zipfileset dir="${package.dir}"
           includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh"
@@ -910,7 +911,7 @@
           filemode="755" dirmode="755" />
      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/README_WINDOWS.txt"
           filemode="644" dirmode="755" />
      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
           filemode="755" dirmode="755" />
    </zip>
    <property name="package.built" value="true"/>
opends/resource/setup
@@ -118,7 +118,7 @@
# Launch the setup process.
"${JAVA_BIN}" org.opends.quicksetup.installer.InstallLauncher -P setup "${@}"
"${JAVA_BIN}" -Dorg.opends.server.scriptName=setup org.opends.server.tools.InstallDS "${@}"
# return part
RETURN_CODE=$?
opends/resource/setup-gui
New file
@@ -0,0 +1,131 @@
#!/bin/sh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE
# or https://OpenDS.dev.java.net/OpenDS.LICENSE.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at
# trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
# add the following below this CDDL HEADER, with the fields enclosed
# by brackets "[]" replaced with your own identifying information:
#      Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#      Portions Copyright 2006-2007 Sun Microsystems, Inc.
# See if JAVA_HOME is set.  If not, then see if there is a java executable in
# the path and try to figure it out.
if test -z "${JAVA_BIN}"
then
  if test -z "${JAVA_HOME}"
  then
    if test -f "${INSTANCE_ROOT}/lib/set-java-home"
    then
      . "${INSTANCE_ROOT}/bin/set-java-home"
      JAVA_BIN="${JAVA_HOME}/bin/java"
      export JAVA_BIN
    else
      JAVA_BIN=`which java 2> /dev/null`
      if test ${?} -eq 0
      then
        export JAVA_BIN
      else
        echo "Please set JAVA_HOME to the root of a Java 5  (or later) installation."
        exit 1
      fi
    fi
  else
    JAVA_BIN="${JAVA_HOME}/bin/java"
    export JAVA_BIN
  fi
fi
# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
# system environment variables for security and compatibility reasons.
PATH=/bin:/usr/bin
LD_LIBRARY_PATH=
LD_LIBRARY_PATH_32=
LD_LIBRARY_PATH_64=
LD_PRELOAD=
LD_PRELOAD_32=
LD_PRELOAD_64=
export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
# Capture the current working directory so that we can change to it later.
# Then capture the location of this script and the Directory Server instance
# root so that we can use them to create appropriate paths.
WORKING_DIR=`pwd`
cd `dirname "${0}"`
SCRIPT_DIR=`pwd`
INSTANCE_ROOT=${SCRIPT_DIR}
export INSTANCE_ROOT
cd "${WORKING_DIR}"
# Configure the appropriate CLASSPATH.
CLASSPATH=${INSTANCE_ROOT}/classes
for JAR in ${INSTANCE_ROOT}/lib/*.jar
do
  CLASSPATH=${CLASSPATH}:${JAR}
done
export CLASSPATH
# Determine whether the detected Java environment is acceptable for use.
if test -z "${JAVA_ARGS}"
then
  "${JAVA_BIN}" -client org.opends.server.tools.InstallDS -t 2> /dev/null
  if test ${?} -eq 0
  then
    JAVA_ARGS="-client"
  else
    "${JAVA_BIN}" org.opends.server.tools.InstallDS -t 2> /dev/null
    if test ${?} -ne 0
    then
      echo "ERROR:  The detected Java version could not be used.  Please set "
      echo "        JAVA_HOME to the root of a Java 5 (or later) installation."
      exit 1
    fi
  fi
else
  "${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.InstallDS -t 2> /dev/null
  if test ${?} -ne 0
  then
    echo "ERROR:  The detected Java version could not be used.  Please set "
    echo "        JAVA_HOME to the root of a Java 5 (or later) installation."
    exit 1
  fi
fi
# Launch the setup process.
"${JAVA_BIN}" org.opends.quicksetup.installer.SetupGuiLauncher "${@}"
# return part
RETURN_CODE=$?
if test ${RETURN_CODE} -eq 50
then
  # Version info was on requested
  exit 0
else
  exit ${RETURN_CODE}
fi
opends/resource/setup-gui.bat
New file
@@ -0,0 +1,89 @@
@echo off
rem CDDL HEADER START
rem
rem The contents of this file are subject to the terms of the
rem Common Development and Distribution License, Version 1.0 only
rem (the "License").  You may not use this file except in compliance
rem with the License.
rem
rem You can obtain a copy of the license at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE
rem or https://OpenDS.dev.java.net/OpenDS.LICENSE.
rem See the License for the specific language governing permissions
rem and limitations under the License.
rem
rem When distributing Covered Code, include this CDDL HEADER in each
rem file and include the License file at
rem trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
rem add the following below this CDDL HEADER, with the fields enclosed
rem by brackets "[]" replaced with your own identifying information:
rem      Portions Copyright [yyyy] [name of copyright owner]
rem
rem CDDL HEADER END
rem
rem
rem      Portions Copyright 2007 Sun Microsystems, Inc.
setlocal
for %%i in (%~sf0) do set DIR_HOME=%%~dPsi.
set INSTANCE_ROOT=%DIR_HOME%
:checkJavaBin
if "%JAVA_BIN%" == "" goto noJavaBin
goto setClassPath
:noJavaBin
if "%JAVA_HOME%" == "" goto noJavaHome
if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noJavaHome
if not exist "%DIR_HOME%\lib\set-java-home.bat" goto noSetJavaHome
call "%DIR_HOME%\lib\set-java-home.bat"
set JAVA_BIN=%JAVA_HOME%\bin\java.exe
goto setClassPath
:noSetJavaHome
echo Error: JAVA_HOME environment variable is not set.
echo        Please set it to a valid Java 5 (or later) installation.
pause
goto end
:noValidJavaHome
echo ERROR:  The detected Java version could not be used.  Please set
echo         JAVA_HOME to to a valid Java 5 (or later) installation.
pause
goto end
:setClassPath
FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
set CLASSPATH=%DIR_HOME%\classes;%CLASSPATH%
set PATH=%SystemRoot%
rem Test that the provided JDK is 1.5 compatible.
"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
if not %errorlevel% == 0 goto noValidJavaHome
if "%~1" == "" goto callLaunch
goto callJava
:callLaunch
"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.SetupGuiLauncher
goto end
:callJava
"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.SetupGuiLauncher %*
rem return part
if %errorlevel% == 50 goto version
goto end
:version
rem version information was requested. Return code should be 0.
exit /B 0
:end
opends/resource/setup.bat
@@ -84,15 +84,7 @@
"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
if not %errorlevel% == 0 goto noValidJavaHome
if "%~1" == "" goto callLaunch
goto callJava
:callLaunch
"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat
goto end
:callJava
"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat %*
"%JAVA_BIN%" %JAVA_ARGS% -Dorg.opends.server.scriptName=setup.bat org.opends.server.tools.InstallDS %*
rem return part
if %errorlevel% == 50 goto version
opends/src/messages/messages/quicksetup.properties
@@ -219,7 +219,7 @@
INFO_DETAILS_LABEL=Details:
INFO_DIRECTORY_DATA_LABEL=Directory Data:
INFO_DIRECTORY_EXISTS_NOT_EMPTY=The directory %s is not empty.
INFO_DIRECTORY_MANAGER_DN_IS_CONFIG_DN=The provided Administrative User DN is \
INFO_DIRECTORY_MANAGER_DN_IS_CONFIG_DN=The provided Root User DN is \
 used for the configuration of the Directory Server.
INFO_DIRECTORY_NOT_WRITABLE=You do not have write access on the directory %s. \
 You must have file right access on the Installation directory.
@@ -237,9 +237,9 @@
INFO_EMPTY_ADMINISTRATOR_UID=You must provide a Global Administrative User \
 ID.
INFO_EMPTY_BASE_DN=You must provide a Directory Base DN.
INFO_EMPTY_DIRECTORY_MANAGER_DN=You must provide an Administrative User DN.
INFO_EMPTY_DIRECTORY_MANAGER_DN=You must provide an Root User DN.
INFO_EMPTY_HOST_NAME=You must provide the name of the host.
INFO_EMPTY_PWD=You must provide the password of the Administrative User.
INFO_EMPTY_PWD=You must provide the password of the Root User.
INFO_EMPTY_REMOTE_DN=You must provide a value for the Administrative User.
INFO_EMPTY_REMOTE_HOST=You must provide the fully qualified name of the host.
INFO_EMPTY_REMOTE_PWD=You must provide an Admin User password.
@@ -259,12 +259,12 @@
 communication.
INFO_ERROR_ACCESSING_JKS_KEYSTORE=Could not access the JKS key store.  Check \
 that the contents of the file correspond to a valid JKS key store, that you \
 have access rights to it and that the provided password is valid.
 have access rights to it and that the provided PIN is valid.
INFO_ERROR_ACCESSING_PKCS11_KEYSTORE=Could not access the PKCS#11 key store. \
 Check that is installed and that the provided password is valid.
 Check that is installed and that the provided PIN is valid.
INFO_ERROR_ACCESSING_PKCS12_KEYSTORE=Could not access the PKCS#12 key store. \
 Check that the contents of the file correspond to a valid PKCS#12 key store, \
 that you have access rights to it and that the provided password is valid.
 that you have access rights to it and that the provided PIN is valid.
INFO_ERROR_APPLY_LDIF_ADD=Error processing add operation of %s: %s
INFO_ERROR_APPLY_LDIF_DELETE=Error processing delete operation of %s: %s
INFO_ERROR_APPLY_LDIF_MODIFY=Error processing modification operation of %s: \
@@ -483,7 +483,7 @@
INFO_HOST_NAME_TOOLTIP=Enter the name of the host.
INFO_HTML_SEPARATOR_COLOR=666666
INFO_IMPORT_AUTOMATICALLY_GENERATED_LABEL=Import Automatically-Generated \
 Example Data
 Sample Data
INFO_IMPORT_AUTOMATICALLY_GENERATED_TOOLTIP=Populate the base DN with \
 automatically-generated LDAP data
INFO_IMPORT_DATA_FROM_LDIF_LABEL=Import Data from LDIF File
@@ -520,6 +520,9 @@
INFO_INSTALLANDUPGRADER_RBUPGRADE_LABEL=Upgrade Existing Server Instance
INFO_INSTALLANDUPGRADER_RBUPGRADE_TOOLTIP=Select to upgrade an existing \
 server instance.
INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG_CLI=The Directory Server \
 contains some database files.%nThe setup will delete the contents of these \
 database files.
INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG=The Directory Server \
 contains some database files.<br>If you continue with the setup the contents \
 of these database files will be deleted.
@@ -528,6 +531,9 @@
INFO_INSTALLSTATUS_INSTALLED=OpenDS Server Already Configured<br> QuickSetup \
 can only be used with OpenDS Servers that have not yet been configured.  The \
 current server:%s
INFO_INSTALLSTATUS_INSTALLED_CLI=OpenDS Server Already Configured%n %s \
 command-line can only be used with OpenDS Servers that have not yet been \
 configured.  The current server:%s
INFO_INSTALLSTATUS_NOT_INSTALLED=The Directory Server is not installed.
INFO_INSTALLSTATUS_SERVERRUNNING=Is currently running on port %s
INFO_INSTRUCTIONS_COLOR=000,000,000
@@ -555,9 +561,9 @@
INFO_KEYSTORE_PATH_NOT_A_FILE=The provided key store path is not a file.
INFO_KEYSTORE_PATH_NOT_PROVIDED=You must provide the path of the key store.
INFO_KEYSTORE_PATH_TOOLTIP=Absolute path to the keystore.
INFO_KEYSTORE_PWD_EMPTY=You must provide the password of the key store.
INFO_KEYSTORE_PWD_LABEL=Key Store Password:
INFO_KEYSTORE_PWD_TOOLTIP=Provide the password required to access the \
INFO_KEYSTORE_PWD_EMPTY=You must provide the PIN of the key store.
INFO_KEYSTORE_PWD_LABEL=Key Store PIN:
INFO_KEYSTORE_PWD_TOOLTIP=Provide the PIN (password) required to access the \
 existing key store.
INFO_KEYSTORE_TYPE_LABEL=Key Store Type:
INFO_LDIF_FILE_DOES_NOT_EXIST=The provided LDIF file does not exist.
@@ -580,10 +586,10 @@
INFO_NO_SUFFIXES_CHOSEN_TO_REPLICATE=You must select at least one base DN to \
 replicate contents with.
INFO_NOT_A_BASE_DN=The provided Directory Base DN is not a valid DN.
INFO_NOT_A_DIRECTORY_MANAGER_DN=The provided Administrative User DN is not a \
INFO_NOT_A_DIRECTORY_MANAGER_DN=The provided Root User DN is not a \
 valid DN.
INFO_NOT_A_DIRECTORY_MANAGER_IN_CONFIG=The provided DN is not one of the \
 Administrative User DN.
 Root User DN.
INFO_NOT_AVAILABLE_LABEL=<not available>
INFO_NOT_ENOUGH_DISK_SPACE=There is not enough free disk space under %s.%nAt \
 least %s megabytes of free disk space are required to install OpenDS.
@@ -638,7 +644,7 @@
INFO_PKCS12_CERTIFICATE_TOOLTIP=Select this option if you have a PKCS#12 \
 certificate.
INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST=No certificates for the PCKS#12 key store \
 could be found.  Check that the provided path and password are valid and that \
 could be found.  Check that the provided path and PIN are valid and that \
 the key store contains certificates.
INFO_PREVIOUS_BUTTON_LABEL=< Previous
INFO_PREVIOUS_BUTTON_TOOLTIP=Go to Previous Step
@@ -653,6 +659,7 @@
INFO_PROGRESS_CREATING_ADS_ON_REMOTE=Creating Registration Configuration on \
 %s
INFO_PROGRESS_CREATING_BASE_ENTRY=Creating Base Entry %s
INFO_PROGRESS_CREATING_BASE_ENTRIES=Creating Base Entry for the base DNs
INFO_PROGRESS_DELETING_DIRECTORY=Deleting directory %s
INFO_PROGRESS_DELETING_EXTERNAL_DB_FILES=Deleting Database Files outside the \
 Installation Path:
@@ -674,6 +681,7 @@
INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED=Importing \
 Automatically-Generated Data (%s Entries):
INFO_PROGRESS_IMPORTING_LDIF=Importing LDIF file %s:
INFO_PROGRESS_IMPORTING_LDIFS=Importing LDIF files %s:
INFO_PROGRESS_INITIALIZING_ADS=Initializing Registration information
INFO_PROGRESS_INITIALIZING_SUFFIX=Initializing base DN %s with the contents \
 from %s:
@@ -693,7 +701,7 @@
INFO_PROGRESS_UPDATING_CERTIFICATES=Configuring Certificates
INFO_PROGRESSBAR_INITIAL_LABEL=Starting...
INFO_PROGRESSBAR_TOOLTIP=Progress Bar
INFO_PWD_TOO_SHORT=The minimum length required for the Administrative User \
INFO_PWD_TOO_SHORT=The minimum length required for the Root User \
 password is %s characters.
INFO_QUIT_BUTTON_INSTALL_TOOLTIP=Quit Setup
INFO_QUIT_BUTTON_LABEL=Quit
@@ -795,15 +803,15 @@
 alias.
INFO_SELECT_ALIAS_TITLE=OpenDS QuickSetup
INFO_SELF_SIGNED_CERTIFICATE=Create a new Self-Signed Certificate
INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL=Administrative User DN:
INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL=Root User DN:
INFO_SERVER_DIRECTORY_MANAGER_DN_TOOLTIP=Enter the distinguished name (DN) of \
 the Administrative User account that will used for managing OpenDS
 the inital Root User account that will used for managing OpenDS
INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_LABEL=Password (confirm):
INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_TOOLTIP=Re-enter the password for \
 the OpenDS Administrative User account
 the OpenDS inital Root User account
INFO_SERVER_DIRECTORY_MANAGER_PWD_LABEL=Password:
INFO_SERVER_DIRECTORY_MANAGER_PWD_TOOLTIP=Enter a password for the OpenDS \
 Administrative User account
 inital Root User account
INFO_SERVER_ERROR=Error on %s:
INFO_SERVER_LOCATION_LABEL=Installation Path:
INFO_SERVER_LOCATION_PARENT_TOOLTIP=Enter the full path to the parent \
@@ -823,7 +831,7 @@
INFO_SERVER_SECURITY_TOOLTIP=The LDAP Secure Access Configuration for the new \
 OpenDS server.
INFO_SERVER_SETTINGS_PANEL_INSTRUCTIONS=Enter a port to listen for LDAP \
 requests and enter a password for the OpenDS administrative user.
 requests and enter a password for the OpenDS initial Root user.
INFO_SERVER_SETTINGS_PANEL_INSTRUCTIONS_WEBSTART=Choose a location for the \
 server files and enter a password for the OpenDS administrative user.
INFO_SERVER_SETTINGS_PANEL_TITLE=Server Settings
opends/src/messages/messages/tools.properties
@@ -216,9 +216,9 @@
INFO_DESCRIPTION_ENCODING_115=Use the specified character set for \
 command-line input
INFO_DESCRIPTION_VERBOSE_116=Use verbose mode
INFO_DESCRIPTION_KEYSTOREPATH_117=Certificate keystore path
INFO_DESCRIPTION_KEYSTOREPATH_117=Certificate key store path
INFO_DESCRIPTION_TRUSTSTOREPATH_118=Certificate trust store path
INFO_DESCRIPTION_KEYSTOREPASSWORD_119=Certificate keystore PIN
INFO_DESCRIPTION_KEYSTOREPASSWORD_119=Certificate key store PIN
INFO_DESCRIPTION_HOST_120=Directory server hostname or IP address
INFO_DESCRIPTION_PORT_121=Directory server port number
INFO_DESCRIPTION_SHOWUSAGE_122=Display this usage information
@@ -669,9 +669,9 @@
INFO_STOPDS_DESCRIPTION_STOP_TIME_384=Time to begin the shutdown in \
 YYYYMMDDhhmmss format (local time)
INFO_STOPDS_DESCRIPTION_TRUST_ALL_385=Trust all server SSL certificates
INFO_STOPDS_DESCRIPTION_KSFILE_386=Certificate keystore path
INFO_STOPDS_DESCRIPTION_KSPW_387=Certificate keystore PIN
INFO_STOPDS_DESCRIPTION_KSPWFILE_388=Certificate keystore PIN file
INFO_STOPDS_DESCRIPTION_KSFILE_386=Certificate key store path
INFO_STOPDS_DESCRIPTION_KSPW_387=Certificate key store PIN
INFO_STOPDS_DESCRIPTION_KSPWFILE_388=Certificate key store PIN file
INFO_STOPDS_DESCRIPTION_TSFILE_389=Certificate trust store path
INFO_STOPDS_DESCRIPTION_TSPW_390=Certificate trust store PIN
INFO_STOPDS_DESCRIPTION_TSPWFILE_391=Certificate trust store PIN file
@@ -861,7 +861,7 @@
INFO_INSTALLDS_DESCRIPTION_LDAPPORT_493=Specifies the port on which the \
 Directory Server should listen for LDAP communication
INFO_INSTALLDS_DESCRIPTION_SKIPPORT_494=Skip the check to determine whether \
 the specified LDAP port is usable
 the specified ports are usable
INFO_INSTALLDS_DESCRIPTION_ROOTDN_495=Specifies the DN for the initial root \
 user for the Directory Server
INFO_INSTALLDS_DESCRIPTION_ROOTPW_496=Specifies the password for the initial \
@@ -886,7 +886,7 @@
INFO_INSTALLDS_PROMPT_IMPORT_505=Do you wish to populate the directory \
 database with information from an existing LDIF file?
INFO_INSTALLDS_PROMPT_IMPORT_FILE_506=Please specify the path to the LDIF \
 file containing the data to import
 file containing the data to import:
SEVERE_ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS_507=ERROR:  You may not \
 provide both the %s and the %s arguments at the same time
INFO_INSTALLDS_PROMPT_ADDBASE_508=Would you like to have the base %s entry \
@@ -906,9 +906,9 @@
 for the initial root user.  When performing a quiet installation, this must \
 be provided using either the %s or the %s argument
INFO_INSTALLDS_PROMPT_ROOT_PASSWORD_514=Please provide the password to use \
 for the initial root user
 for the initial root user:
INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD_515=Please re-enter the password \
 for confirmation
 for confirmation:
INFO_INSTALLDS_STATUS_CONFIGURING_DS_516=Applying the requested configuration \
 to the Directory Server...
INFO_INSTALLDS_STATUS_CREATING_BASE_LDIF_517=Creating a temporary LDIF file \
@@ -1186,10 +1186,10 @@
 communication with the Directory Server
INFO_LDAPPWMOD_DESCRIPTION_BLIND_TRUST_648=Blindly trust any SSL certificate \
 presented by the server
INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_649=The path to the keystore to use when \
INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_649=The path to the key store to use when \
 establishing SSL/TLS communication with the server
INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PINFILE_650=The path to a file containing \
 the PIN needed to access the contents of the keystore
 the PIN needed to access the contents of the key store
INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_651=The path to the trust store to use \
 when establishing SSL/TLS communication with the server
INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PINFILE_652=The path to a file \
@@ -1252,8 +1252,8 @@
 from a Directory Server backend in LDIF form
INFO_LDIFIMPORT_TOOL_DESCRIPTION_687=This utility may be used to import LDIF \
 data into a Directory Server backend
INFO_INSTALLDS_TOOL_DESCRIPTION_688=This utility may be used to define a base \
 configuration for the Directory Server
INFO_INSTALLDS_TOOL_DESCRIPTION_688=This utility may be used to setup the \
 Directory Server
INFO_LDAPCOMPARE_TOOL_DESCRIPTION_689=This utility may be used to perform \
 LDAP compare operations in the Directory Server
INFO_LDAPDELETE_TOOL_DESCRIPTION_690=This utility may be used to perform LDAP \
@@ -1292,7 +1292,7 @@
SEVERE_ERR_TOOL_SASLEXTERNAL_NEEDS_SSL_OR_TLS_706=SASL EXTERNAL \
 authentication may only be requested if SSL or StartTLS is used
SEVERE_ERR_TOOL_SASLEXTERNAL_NEEDS_KEYSTORE_707=SASL EXTERNAL authentication \
 may only be used if a client certificate keystore is specified
 may only be used if a client certificate key store is specified
INFO_LDAPSEARCH_PSEARCH_CHANGE_TYPE_708=# Persistent search change type:  %s
INFO_LDAPSEARCH_PSEARCH_PREVIOUS_DN_709=# Persistent search previous entry \
 DN:  %s
@@ -1310,7 +1310,7 @@
INFO_LDAPSEARCH_ACCTUSABLE_LOCKED_718=#   The account is locked
INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK_719=#   Time until the account \
 is unlocked:  %s
INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE_720=Certificate keystore PIN file
INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE_720=Certificate key store PIN file
INFO_DESCRIPTION_TRUSTSTOREPASSWORD_721=Certificate trust store PIN
INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE_722=Certificate trust store PIN file
INFO_LISTBACKENDS_TOOL_DESCRIPTION_723=This utility may be used to list the \
@@ -1353,10 +1353,10 @@
INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA_753=Specifies that the database should \
 be populated with the specified number of sample entries
INFO_INSTALLDS_HEADER_POPULATE_TYPE_754=Options for populating the database:
INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY_755=Only create the base entry
INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY_756=Leave the database empty
INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF_757=Import data from an LDIF file
INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE_758=Load \
INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY_755=1.  Only create the base entry
INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY_756=2.  Leave the database empty
INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF_757=3.  Import data from an LDIF file
INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE_758=4.  Load \
 automatically-generated sample data
INFO_INSTALLDS_PROMPT_POPULATE_CHOICE_759=Database population selection:
SEVERE_ERR_INSTALLDS_NO_SUCH_LDIF_FILE_780=ERROR:  The specified LDIF file %s \
@@ -1366,7 +1366,7 @@
SEVERE_ERR_INSTALLDS_CANNOT_CREATE_TEMPLATE_FILE_782=ERROR:  Cannot create \
 the template file for generating sample data:  %s
INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PIN_783=The PIN needed to access the \
 contents of the keystore
 contents of the key store
INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PIN_784=The PIN needed to access the \
 contents of the trust store
INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_OPERATIONAL_785=Exclude operational \
@@ -1548,7 +1548,7 @@
 occurred while attempting to update the trust manager provider DN used for \
 LDAPS communication: %s
INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH_870=Specifies the path of the \
 keystore to be used by the key manager provider
 key store to be used by the key manager provider
INFO_CONFIGDS_DESCRIPTION_CERTNICKNAME_871=Specifies the nickname of the \
 certificate that the connection handler should use when accepting SSL-based \
 connections or performing StartTLS negotiation
@@ -1622,9 +1622,9 @@
 get and set password policy state information
INFO_PWPSTATE_DESCRIPTION_SASLOPTIONS_1103=SASL bind options
INFO_PWPSTATE_DESCRIPTION_TRUST_ALL_1104=Trust all server SSL certificates
INFO_PWPSTATE_DESCRIPTION_KSFILE_1105=Certificate keystore path
INFO_PWPSTATE_DESCRIPTION_KSPW_1106=Certificate keystore PIN
INFO_PWPSTATE_DESCRIPTION_KSPWFILE_1107=Certificate keystore PIN file
INFO_PWPSTATE_DESCRIPTION_KSFILE_1105=Certificate key store path
INFO_PWPSTATE_DESCRIPTION_KSPW_1106=Certificate key store PIN
INFO_PWPSTATE_DESCRIPTION_KSPWFILE_1107=Certificate key store PIN file
INFO_PWPSTATE_DESCRIPTION_TSFILE_1108=Certificate trust store path
INFO_PWPSTATE_DESCRIPTION_TSPW_1109=Certificate trust store PIN
INFO_PWPSTATE_DESCRIPTION_TSPWFILE_1110=Certificate trust store PIN file
@@ -1885,9 +1885,9 @@
INFO_LDAP_CONN_DESCRIPTION_BINDPWFILE_1306=Bind password file
INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS_1307=SASL bind options
INFO_LDAP_CONN_DESCRIPTION_TRUST_ALL_1308=Trust all server SSL certificates
INFO_LDAP_CONN_DESCRIPTION_KSFILE_1309=Certificate keystore path
INFO_LDAP_CONN_DESCRIPTION_KSPW_1310=Certificate keystore PIN
INFO_LDAP_CONN_DESCRIPTION_KSPWFILE_1311=Certificate keystore PIN file
INFO_LDAP_CONN_DESCRIPTION_KSFILE_1309=Certificate key store path
INFO_LDAP_CONN_DESCRIPTION_KSPW_1310=Certificate key store PIN
INFO_LDAP_CONN_DESCRIPTION_KSPWFILE_1311=Certificate key store PIN file
INFO_LDAP_CONN_DESCRIPTION_TSFILE_1312=Certificate trust store path
INFO_LDAP_CONN_DESCRIPTION_TSPW_1313=Certificate trust store PIN
INFO_LDAP_CONN_DESCRIPTION_TSPWFILE_1314=Certificate trust store PIN file
@@ -2007,6 +2007,77 @@
 passed to the JVM when running the server
SEVERE_ERR_CREATERC_JAVA_HOME_DOESNT_EXIST_1378=The directory %s specified \
 as the JAVA_HOME path does not exist or is not a directory
SEVERE_ERR_UPGRADE_INCOMPATIBLE_ARGS_1379=The argument '%s' is incompatible \
INFO_INSTALLDS_STATUS_COMMAND_LINE_1379=To see basic server configuration \
status and configuration you can launch %s
INFO_INSTALLDS_PROMPT_ENABLE_SSL_1380=Do you want to enable SSL?
INFO_INSTALLDS_PROMPT_LDAPSPORT_1381=On which port would you like the \
 Directory Server to accept connections from LDAPS clients?
INFO_INSTALLDS_ENABLE_STARTTLS_1382=Do you want to enable Start TLS?
INFO_INSTALLDS_PROMPT_JKS_PATH_1383=Java Key Store (JKS) path:
INFO_INSTALLDS_PROMPT_PKCS12_PATH_1384=PKCS#12 key Store path:
INFO_INSTALLDS_PROMPT_KEYSTORE_PASSWORD_1385=Key store PIN:
INFO_INSTALLDS_PROMPT_CERTNICKNAME_1386=Use nickname %s?
INFO_INSTALLDS_HEADER_CERT_TYPE_1387=Certificate server options:
INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED_1388=1.  Generate self-signed \
 certificate (recommended for testing purposes only)
INFO_INSTALLDS_CERT_OPTION_JKS_1389=2.  Use an existing certificate located on \
 a Java Key Store (JKS)
INFO_INSTALLDS_CERT_OPTION_PKCS12_1390=3.  Use an existing certificate located \
 on a PKCS#12 key store
INFO_INSTALLDS_CERT_OPTION_PKCS11_1391=4.  Use an existing certificate on a \
 PKCS#11 token
INFO_INSTALLDS_PROMPT_CERT_TYPE_CHOICE_1392=Certificate type selection:
INFO_INSTALLDS_PROMPT_START_SERVER_1393=Do you want to start the server when \
 the configuration is completed?
SEVERE_ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND_1394=The provided certificate \
 nickname could not be found.  The key store contains the following \
 certificate nicknames: %s
SEVERE_ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME_1395=The key store contains the \
 following certificate nicknames: %s.%nYou have to provide the nickname of the \
 certificate you want to use
INFO_INSTALLDS_DESCRIPTION_DO_NOT_START_1396=Do not start the server when the \
 configuration is completed
INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS_1397=Enable StartTLS to allow \
 secure communication with the server using the LDAP port
INFO_INSTALLDS_DESCRIPTION_LDAPSPORT_1398=Specifies the port on which the \
 Directory Server should listen for LDAPS communication.  The LDAPS port will \
 be configured and SSL will be enabled only if this argument is explicitly \
 specified
INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED_1399=Specifies to generate a \
 self-signed certificate that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
INFO_INSTALLDS_DESCRIPTION_USE_PKCS11_1400=Specifies to use a certificate in a \
 PKCS#11 token that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE_1401=Specifies the path of a Java \
 Key Store (JKS) containing a certificate to be used as the server certificate
INFO_INSTALLDS_DESCRIPTION_USE_PKCS12_1402=Specifies the path of a PKCS#12 key \
 store containing the certificate that the server should use when accepting \
 SSL-based connections or performing StartTLS negotiation
INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_1403=Certificate key store PIN.  \
 A PIN is required when you specify to use an existing certificate (JKS, \
 PKCS#12 or PKCS#11) as server certificate
INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE_1404=Certificate key store \
 PIN file.  A PIN is required when you specify to use an existing certificate \
 (JKS, PKCS#12 or PKCS#11) as server certificate
INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME_1405=Specifies the nickname of the \
 certificate that the server should use when accepting SSL-based \
 connections or performing StartTLS negotiation
SEVERE_ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED_1406=You have \
 specified several certificate types to be used.  Only one certificate type \
 (self-signed, JKS, PKCS#12 or PCKS#11) is allowed
SEVERE_ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS_1407=You have \
 chosen to enable SSL or StartTLS.  You must specify which type of certificate \
 you want the server to use
SEVERE_ERR_INSTALLDS_NO_KEYSTORE_PASSWORD_1408=You must provide the PIN of the \
 keystore to retrieve the certificate to be used by the server.  You can use \
 {%s} or {%s}
INFO_INSTALLDS_DESCRIPTION_NO_PROMPT_1409=Perform an installation in \
 non-interactive mode.  If some data in the command is missing the user will \
 not be prompted and the tool will fail
SEVERE_ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED_1410=You have specified to use a \
 certificate as server certificate.  You must enable SSL (using option {%s}) \
 or Start TLS (using option %s)
SEVERE_ERR_UPGRADE_INCOMPATIBLE_ARGS_1411=The argument '%s' is incompatible \
 with '%s'
opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
@@ -95,21 +95,39 @@
      isInstalled = msgs.size() > 0;
      if (canOverwriteCurrentInstall)
      {
        installationMsg =
          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG.get();
        installationMsg = !Utils.isCli()?
          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG.get() :
          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG_CLI.get();
      }
      else if (isInstalled)
      {
        MessageBuilder buf = new MessageBuilder();
        buf.append("<ul>");
        for (Message msg : msgs)
        if (Utils.isCli())
        {
          buf.append("\n<li>");
          buf.append(msg);
          buf.append("</li>");
          buf = new MessageBuilder();
          for (Message msg : msgs)
          {
            buf.append(Constants.LINE_SEPARATOR);
            buf.append("- "+msg);
          }
          String cmd = Utils.isWindows() ?
              Installation.WINDOWS_SETUP_FILE_NAME :
                Installation.UNIX_SETUP_FILE_NAME;
          installationMsg =
            INFO_INSTALLSTATUS_INSTALLED_CLI.get(cmd, buf.toString());
        }
        buf.append("</ul>");
        installationMsg = INFO_INSTALLSTATUS_INSTALLED.get( buf.toString() );
        else
        {
          buf.append("<ul>");
          for (Message msg : msgs)
          {
            buf.append("\n<li>");
            buf.append(msg);
            buf.append("</li>");
          }
          buf.append("</ul>");
          installationMsg = INFO_INSTALLSTATUS_INSTALLED.get( buf.toString() );
        }
      }
    }
    if (!isInstalled)
opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -139,6 +139,16 @@
  public static final String WINDOWS_SETUP_FILE_NAME = "setup.bat";
  /**
   * The UNIX GUI setup script file name.
   */
  public static final String UNIX_SETUP_GUI_FILE_NAME = "setup-gui";
  /**
   * The Windows GUI setup batch file name.
   */
  public static final String WINDOWS_SETUP_GUI_FILE_NAME = "setup-gui.bat";
  /**
   * The UNIX uninstall script file name.
   */
  public static final String UNIX_UNINSTALL_FILE_NAME = "uninstall";
@@ -744,6 +754,23 @@
  }
  /**
   * Gets the status command file appropriate for the current operating
   * system.
   * @return File object representing the status command
   */
  public File getStatusCommandFile() {
    File statusPanelCommandFile;
    if (Utils.isWindows()) {
      statusPanelCommandFile = new File(getBinariesDirectory(),
              WINDOWS_STATUSCLI_FILE_NAME);
    } else {
      statusPanelCommandFile = new File(getBinariesDirectory(),
              UNIX_STATUSCLI_FILE_NAME);
    }
    return statusPanelCommandFile;
  }
  /**
   * Gets information about the build that was used to produce the bits
   * for this installation.
   * @return BuildInformation object describing this installation
opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import org.opends.admin.ads.ServerDescriptor;
@@ -63,7 +64,7 @@
  private String globalAdministratorPassword;
  private SecurityOptions securityOptions;
  private int serverJMXPort;
  private int serverJMXPort = -1;
  private boolean startServer;
@@ -87,6 +88,10 @@
  private boolean forceOnError;
  private String configurationFile;
  private String configurationClass;
  /**
   * Creates a user data object with default values.
   */
@@ -96,8 +101,10 @@
    enableWindowsService = false;
    forceOnError = true;
    LinkedList<String> baseDn = new LinkedList<String>();
    baseDn.add("dc=example,dc=com");
    NewSuffixOptions defaultNewSuffixOptions = new NewSuffixOptions(
        NewSuffixOptions.Type.CREATE_BASE_ENTRY, "dc=example,dc=com");
        NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDn);
    setNewSuffixOptions(defaultNewSuffixOptions);
    // See what we can propose as port
@@ -655,4 +662,40 @@
    this.remoteWithNoReplicationPort.clear();
    this.remoteWithNoReplicationPort.putAll(remoteWithNoReplicationPort);
  }
  /**
   * Returns the configuration file to be used.
   * @return the configuration file to be used.
   */
  public String getConfigurationFile()
  {
    return configurationFile;
  }
  /**
   * Sets the configuration file to be used.
   * @param configurationFile the configuration file to be used.
   */
  public void setConfigurationFile(String configurationFile)
  {
    this.configurationFile = configurationFile;
  }
  /**
   * Returns the configuration class to be used.
   * @return the configuration class to be used.
   */
  public String getConfigurationClassName()
  {
    return configurationClass;
  }
  /**
   * Sets the configuration class to be used.
   * @param configurationClass the configuration class to be used.
   */
  public void setConfigurationClassName(String configurationClass)
  {
    this.configurationClass = configurationClass;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
File was deleted
opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -156,7 +156,7 @@
  /**
   * An static String that contains the class name of ConfigFileHandler.
   */
  protected static final String CONFIG_CLASS_NAME =
  protected static final String DEFAULT_CONFIG_CLASS_NAME =
      "org.opends.server.extensions.ConfigFileHandler";
  /** Alias of a self-signed certificate. */
@@ -180,8 +180,8 @@
      if (!QuickSetupLog.isInitialized())
        QuickSetupLog.initLogFileHandler(
                File.createTempFile(
                        InstallLauncher.LOG_FILE_PREFIX,
                        InstallLauncher.LOG_FILE_SUFFIX));
                    SetupGuiLauncher.LOG_FILE_PREFIX,
                    SetupGuiLauncher.LOG_FILE_SUFFIX));
    } catch (IOException e) {
      System.err.println("Failed to initialize log");
    }
@@ -708,29 +708,34 @@
  }
  /**
   * Creates a template file based in the contents of the UserData object.
   * This template file is used to generate automatically data.  To generate
   * Creates the template files based in the contents of the UserData object.
   * These templates files are used to generate automatically data.  To generate
   * the template file the code will basically take into account the value of
   * the base dn and the number of entries to be generated.
   *
   * @return the file object pointing to the create template file.
   * @return a list of file objects pointing to the create template files.
   * @throws ApplicationException if an error occurs.
   */
  protected File createTemplateFile() throws ApplicationException {
  private LinkedList<File> createTemplateFiles() throws ApplicationException {
    LinkedList<File> files = new LinkedList<File>();
    try
    {
      return SetupUtils.createTemplateFile(
                  getUserData().getNewSuffixOptions().getBaseDn(),
                  getUserData().getNewSuffixOptions().getNumberEntries());
      int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
      for (String baseDn : getUserData().getNewSuffixOptions().getBaseDns())
      {
        files.add(SetupUtils.createTemplateFile(baseDn, nEntries));
      }
    }
    catch (IOException ioe)
    {
      Message failedMsg = getThrowableMsg(
              INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
          INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
      throw new ApplicationException(
          ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
          failedMsg, ioe);
    }
    return files;
  }
  /**
@@ -743,10 +748,10 @@
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(CONFIG_CLASS_NAME);
    argList.add(getConfigurationClassName());
    argList.add("-c");
    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
    argList.add(getConfigurationFile());
    argList.add("-p");
    argList.add(String.valueOf(getUserData().getServerPort()));
@@ -811,10 +816,12 @@
    }
    // For the moment do not enable JMX
    /*
    argList.add("-x");
    argList.add(String.valueOf(getUserData().getServerJMXPort()));
     */
    if (getUserData().getServerJMXPort() > 0)
    {
      argList.add("-x");
      argList.add(String.valueOf(getUserData().getServerJMXPort()));
    }
    argList.add("-D");
    argList.add(getUserData().getDirectoryManagerDn());
@@ -823,8 +830,13 @@
    if (createNotReplicatedSuffix())
    {
      argList.add("-b");
      argList.add(getUserData().getNewSuffixOptions().getBaseDn());
      LinkedList<String> baseDns =
        getUserData().getNewSuffixOptions().getBaseDns();
      for (String baseDn : baseDns)
      {
        argList.add("-b");
        argList.add(baseDn);
      }
    }
    else
    {
@@ -976,26 +988,44 @@
   * @throws ApplicationException if something goes wrong.
   */
  private void createBaseEntry() throws ApplicationException {
    notifyListeners(getFormattedWithPoints(
        INFO_PROGRESS_CREATING_BASE_ENTRY.get(
                getUserData().getNewSuffixOptions().getBaseDn())));
    LinkedList<String> baseDns =
      getUserData().getNewSuffixOptions().getBaseDns();
    if (baseDns.size() == 1)
    {
      notifyListeners(getFormattedWithPoints(
        INFO_PROGRESS_CREATING_BASE_ENTRY.get(baseDns.getFirst())));
    }
    else
    {
      notifyListeners(getFormattedWithPoints(
          INFO_PROGRESS_CREATING_BASE_ENTRIES.get()));
    }
    InstallerHelper helper = new InstallerHelper();
    String baseDn = getUserData().getNewSuffixOptions().getBaseDn();
    File tempFile = helper.createBaseEntryTempFile(baseDn);
    LinkedList<File> ldifFiles = new LinkedList<File>();
    for (String baseDn : baseDns)
    {
      ldifFiles.add(helper.createBaseEntryTempFile(baseDn));
    }
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(CONFIG_CLASS_NAME);
    argList.add(getConfigurationClassName());
    argList.add("-f");
    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
    argList.add(getConfigurationFile());
    argList.add("-n");
    argList.add(getBackendName());
    argList.add("-l");
    argList.add(tempFile.getAbsolutePath());
    for (File f : ldifFiles)
    {
      argList.add("-l");
      argList.add(f.getAbsolutePath());
    }
    argList.add("-F");
    argList.add("-q");
@@ -1034,23 +1064,36 @@
   * @throws ApplicationException if something goes wrong.
   */
  private void importLDIF() throws ApplicationException {
    LinkedList<String> ldifPaths =
      getUserData().getNewSuffixOptions().getLDIFPaths();
    MessageBuilder mb = new MessageBuilder();
    mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIF.get(
            getUserData().getNewSuffixOptions().getLDIFPath())));
    if (ldifPaths.size() > 1)
    {
      mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIFS.get(
            getStringFromCollection(ldifPaths, ", "))));
    }
    else
    {
      mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIF.get(
          ldifPaths.getFirst())));
    }
    mb.append(getLineBreak());
    notifyListeners(mb.toMessage());
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(CONFIG_CLASS_NAME);
    argList.add(getConfigurationClassName());
    argList.add("-f");
    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
    argList.add(getConfigurationFile());
    argList.add("-n");
    argList.add(getBackendName());
    argList.add("-l");
    argList.add(getUserData().getNewSuffixOptions().getLDIFPath());
    for (String ldifPath : ldifPaths)
    {
      argList.add("-l");
      argList.add(ldifPath);
    }
    argList.add("-F");
    String[] args = new String[argList.size()];
    argList.toArray(args);
@@ -1079,7 +1122,7 @@
   * @throws ApplicationException if something goes wrong.
   */
  private void importAutomaticallyGenerated() throws ApplicationException {
    File templatePath = createTemplateFile();
    LinkedList<File> templatePaths = createTemplateFiles();
    int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
    MessageBuilder mb = new MessageBuilder();
    mb.append(getFormattedProgress(
@@ -1088,40 +1131,46 @@
    mb.append(getLineBreak());
    notifyListeners(mb.toMessage());
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(CONFIG_CLASS_NAME);
    argList.add("-f");
    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
    argList.add("-n");
    argList.add(getBackendName());
    argList.add("-t");
    argList.add(templatePath.getAbsolutePath());
    argList.add("-s"); // seed
    argList.add("0");
    String[] args = new String[argList.size()];
    argList.toArray(args);
    try
    for (File templatePath : templatePaths)
    {
      InstallerHelper helper = new InstallerHelper();
      int result = helper.invokeImportLDIF(args);
      ArrayList<String> argList = new ArrayList<String>();
      argList.add("-C");
      argList.add(getConfigurationClassName());
      if (result != 0)
      argList.add("-f");
      argList.add(getConfigurationFile());
      argList.add("-n");
      argList.add(getBackendName());
      argList.add("-t");
      argList.add(templatePath.getAbsolutePath());
      argList.add("-s"); // seed
      argList.add("0");
      // append: each file contains data for each base DN.
      argList.add("-a");
      String[] args = new String[argList.size()];
      argList.toArray(args);
      try
      {
        InstallerHelper helper = new InstallerHelper();
        int result = helper.invokeImportLDIF(args);
        if (result != 0)
        {
          throw new ApplicationException(
              ReturnCode.CONFIGURATION_ERROR,
              INFO_ERROR_IMPORT_LDIF_TOOL_RETURN_CODE.get(
                  Integer.toString(result)), null);
        }
      } catch (Throwable t)
      {
        throw new ApplicationException(
            ReturnCode.CONFIGURATION_ERROR,
            INFO_ERROR_IMPORT_LDIF_TOOL_RETURN_CODE.get(
                    Integer.toString(result)), null);
            getThrowableMsg(INFO_ERROR_IMPORT_AUTOMATICALLY_GENERATED.get(
                listToString(argList, " "), t.getLocalizedMessage()), t), t);
      }
    } catch (Throwable t)
    {
      throw new ApplicationException(
          ReturnCode.CONFIGURATION_ERROR,
          getThrowableMsg(INFO_ERROR_IMPORT_AUTOMATICALLY_GENERATED.get(
                  listToString(argList, " "), t.getLocalizedMessage()), t), t);
    }
  }
@@ -1313,12 +1362,16 @@
    if (getUserData().getReplicationOptions().getType()
            == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY)
    {
      String dn = getUserData().getNewSuffixOptions().getBaseDn();
      dns.add(dn);
      LinkedList<String> baseDns =
        getUserData().getNewSuffixOptions().getBaseDns();
      dns.addAll(baseDns);
      HashSet<String> h = new HashSet<String>();
      h.add(getLocalReplicationServer());
      adsServers.add(getLocalReplicationServer());
      replicationServers.put(dn, h);
      for (String dn : baseDns)
      {
        replicationServers.put(dn, h);
      }
    }
    else
    {
@@ -3235,7 +3288,12 @@
        qs.displayFieldInvalid(FieldName.LDIF_PATH, true);
      } else if (validBaseDn)
      {
        dataOptions = new NewSuffixOptions(type, baseDn, ldifPath);
        LinkedList<String> baseDns = new LinkedList<String>();
        baseDns.add(baseDn);
        LinkedList<String> ldifPaths = new LinkedList<String>();
        ldifPaths.add(ldifPath);
        dataOptions = new NewSuffixOptions(type, baseDns, ldifPaths);
        qs.displayFieldInvalid(FieldName.LDIF_PATH, false);
      }
      break;
@@ -3277,7 +3335,10 @@
      if (startErrors == errorMsgs.size() && validBaseDn)
      {
        // No validation errors
        dataOptions = new NewSuffixOptions(type, baseDn, new Integer(nEntries));
        LinkedList<String> baseDns = new LinkedList<String>();
        baseDns.add(baseDn);
        dataOptions = new NewSuffixOptions(type, baseDns,
            new Integer(nEntries));
      }
      break;
@@ -3286,7 +3347,9 @@
      qs.displayFieldInvalid(FieldName.NUMBER_ENTRIES, false);
      if (validBaseDn)
      {
        dataOptions = new NewSuffixOptions(type, baseDn);
        LinkedList<String> baseDns = new LinkedList<String>();
        baseDns.add(baseDn);
        dataOptions = new NewSuffixOptions(type, baseDns);
      }
    }
@@ -3901,6 +3964,38 @@
    }
  }
  /**
   * Returns the configuration file path to be used when invoking the
   * command-lines.
   * @return the configuration file path to be used when invoking the
   * command-lines.
   */
  private String getConfigurationFile()
  {
    String file = getUserData().getConfigurationFile();
    if (file == null)
    {
      file = getPath(getInstallation().getCurrentConfigurationFile());
    }
    return file;
  }
  /**
   * Returns the configuration class name to be used when invoking the
   * command-lines.
   * @return the configuration class name to be used when invoking the
   * command-lines.
   */
  private String getConfigurationClassName()
  {
    String className = getUserData().getConfigurationClassName();
    if (className == null)
    {
      className = DEFAULT_CONFIG_CLASS_NAME;
    }
    return className;
  }
  private String getLocalReplicationServer()
  {
    return getUserData().getHostName()+":"+
opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
@@ -28,6 +28,8 @@
package org.opends.quicksetup.installer;
import java.util.LinkedList;
/**
 * This class is used to provide a data model for the Data Options panel of the
@@ -67,9 +69,9 @@
  private Type type = Type.NOTHING;
  private String baseDn;
  private LinkedList<String> baseDns = new LinkedList<String>();
  private String ldifPath;
  private LinkedList<String> ldifPaths = new LinkedList<String>();
  private int numberEntries = 2000;
@@ -91,12 +93,19 @@
  public NewSuffixOptions(Type type, Object... args)
  {
    this.type = type;
    baseDn = (String) args[0];
    LinkedList<?> v = (LinkedList<?>)args[0];
    for (Object o : v)
    {
      baseDns.add((String)o);
    }
    switch (type)
    {
    case IMPORT_FROM_LDIF_FILE:
      ldifPath = (String) args[1];
      v = (LinkedList<?>)args[1];
      for (Object o : v)
      {
        ldifPaths.add((String)o);
      }
      break;
    case IMPORT_AUTOMATICALLY_GENERATED_DATA:
@@ -120,9 +129,10 @@
   * Returns the path of the LDIF file used to import data.
   * @return the path of the LDIF file used to import data.
   */
  public String getLDIFPath()
  public LinkedList<String> getLDIFPaths()
  {
    return ldifPath;
    LinkedList<String> copy = new LinkedList<String>(ldifPaths);
    return copy;
  }
  /**
@@ -140,8 +150,9 @@
   *
   * @return the base DN of the suffix that will be created in the server.
   */
  public String getBaseDn()
  public LinkedList<String> getBaseDns()
  {
    return baseDn;
    LinkedList<String> copy = new LinkedList<String>(baseDns);
    return copy;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java
New file
@@ -0,0 +1,220 @@
/*
 * 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.installer;
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.messages.ToolMessages.INFO_DESCRIPTION_SHOWUSAGE;
import static org.opends.server.tools.ToolConstants.OPTION_LONG_HELP;
import static org.opends.server.tools.ToolConstants.OPTION_SHORT_HELP;
import java.io.File;
import java.util.logging.Logger;
import org.opends.quicksetup.ReturnCode;
import org.opends.quicksetup.CliApplication;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.Launcher;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.installer.offline.OfflineInstaller;
import org.opends.quicksetup.util.Utils;
import org.opends.messages.Message;
import org.opends.messages.ToolMessages;
import org.opends.server.util.ServerConstants;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
/**
 * This class is called by the setup GUI command line to launch the setup
 * of 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 SetupGuiLauncher extends Launcher {
  /** Prefix for log files. */
  static public final String LOG_FILE_PREFIX = "opends-setup-gui-";
  /** Suffix for log files. */
  static public final String LOG_FILE_SUFFIX = ".log";
  static private final Logger LOG =
          Logger.getLogger(SetupGuiLauncher.class.getName());
  /**
   * The main method which is called by the setup GUI 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) {
    try {
      QuickSetupLog.initLogFileHandler(
              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX),
              "org.opends.quicksetup.installer");
    } catch (Throwable t) {
      System.err.println("Unable to initialize log");
      t.printStackTrace();
    }
    new SetupGuiLauncher(args).launch();
  }
  private ArgumentParser argParser;
  /**
   * Creates a launcher.
   *
   * @param args the arguments passed by the command lines.
   */
  public SetupGuiLauncher(String[] args) {
    super(args);
    String scriptName;
    if (Utils.isWindows()) {
      scriptName = Installation.WINDOWS_SETUP_GUI_FILE_NAME;
    } else {
      scriptName = Installation.UNIX_SETUP_GUI_FILE_NAME;
    }
    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
    initializeParser();
  }
  /**
   * Initialize the contents of the argument parser.
   */
  protected void initializeParser()
  {
    argParser = new ArgumentParser(getClass().getName(),
        INFO_SETUP_LAUNCHER_USAGE_DESCRIPTION.get(),
        false);
    try
    {
      BooleanArgument showUsageArg = new BooleanArgument("showUsage",
          OPTION_SHORT_HELP,
          OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get());
      argParser.addArgument(showUsageArg);
      argParser.setUsageArgument(showUsageArg);
      argParser.parseArguments(args);
    }
    catch (ArgumentException ae)
    {
      System.err.println(org.opends.server.util.StaticUtils.wrapText(
          ToolMessages.ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()),
          Utils.getCommandLineMaxLineWidth()));
    }
  }
  /**
   * {@inheritDoc}
   */
  public void launch() {
    if (shouldPrintVersion())
    {
      if (!argParser.usageOrVersionDisplayed())
      {
        printVersion();
      }
      System.exit(ReturnCode.PRINT_VERSION.getReturnCode());
    }
    else if (shouldPrintUsage()) {
      if (!argParser.usageOrVersionDisplayed())
      {
        printUsage(false);
      }
      System.exit(ReturnCode.SUCCESSFUL.getReturnCode());
    } else {
      willLaunchGui();
      int exitCode = launchGui(args);
      if (exitCode != 0) {
        File logFile = QuickSetupLog.getLogFile();
        if (logFile != null)
        {
          guiLaunchFailed(logFile.toString());
        }
        else
        {
          guiLaunchFailed(null);
        }
        System.exit(exitCode);
      }
    }
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isCli() {
    return false;
  }
  /**
   * {@inheritDoc}
   */
  public ArgumentParser getArgumentParser() {
    return this.argParser;
  }
  /**
   * {@inheritDoc}
   */
  protected void guiLaunchFailed(String logFileName) {
    if (logFileName != null)
    {
      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED_DETAILS.get(
              logFileName));
    }
    else
    {
      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED.get());
    }
  }
  /**
   * {@inheritDoc}
   */
  protected void willLaunchGui() {
    System.out.println(INFO_SETUP_LAUNCHER_LAUNCHING_GUI.get());
    System.setProperty("org.opends.quicksetup.Application.class",
            OfflineInstaller.class.getName());
  }
  /**
   * {@inheritDoc}
   */
  protected Message getFrameTitle() {
    return INFO_FRAME_INSTALL_TITLE.get();
  }
  /**
   * {@inheritDoc}
   */
  protected CliApplication createCliApplication() {
    return null;
  }
}
opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -74,6 +74,8 @@
  private HashMap<InstallProgressStep, Message> hmSummary =
      new HashMap<InstallProgressStep, Message>();
  private ApplicationException runError;
  private static final Logger LOG =
    Logger.getLogger(OfflineInstaller.class.getName());
  /**
@@ -82,12 +84,13 @@
   */
  public void run()
  {
    initMaps();
    runError = null;
    PrintStream origErr = System.err;
    PrintStream origOut = System.out;
    try
    {
      initMaps();
      System.setErr(getApplicationErrorStream());
      System.setOut(getApplicationOutputStream());
@@ -181,6 +184,7 @@
        notifyListeners(html);
        LOG.log(Level.SEVERE, "Error installing.", ex);
      }
      runError = ex;
    }
    catch (Throwable t)
    {
@@ -203,9 +207,13 @@
      Message msg = getFormattedError(ex, true);
      notifyListeners(msg);
      LOG.log(Level.SEVERE, "Error installing.", t);
      runError = ex;
    }
    System.setErr(origErr);
    System.setOut(origOut);
    finally
    {
      System.setErr(origErr);
      System.setOut(origOut);
    }
  }
  /**
@@ -225,6 +233,14 @@
  }
  /**
   * {@inheritDoc}
   */
  public ApplicationException getRunError()
  {
    return runError;
  }
  /**
   * Called when the user elects to cancel this operation.
   */
  protected void uninstall() {
opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
@@ -38,6 +38,7 @@
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.HashMap;
import java.util.LinkedList;
import javax.swing.Box;
import javax.swing.ButtonGroup;
@@ -348,7 +349,16 @@
    switch (fieldName)
    {
    case DIRECTORY_BASE_DN:
      value = defaultUserData.getNewSuffixOptions().getBaseDn();
      LinkedList<String> defaults =
        defaultUserData.getNewSuffixOptions().getBaseDns();
      if ((defaults != null) && !defaults.isEmpty())
      {
        value = defaults.getFirst();
      }
      else
      {
        value = null;
      }
      break;
    case DATA_OPTIONS:
@@ -356,7 +366,16 @@
      break;
    case LDIF_PATH:
      value = defaultUserData.getNewSuffixOptions().getLDIFPath();
      defaults =
        defaultUserData.getNewSuffixOptions().getLDIFPaths();
      if ((defaults != null) && !defaults.isEmpty())
      {
        value = defaults.getFirst();
      }
      else
      {
        value = null;
      }
      break;
    case NUMBER_ENTRIES:
opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -294,10 +294,12 @@
      Message arg2;
      NewSuffixOptions options = userInstallData.getNewSuffixOptions();
      switch (options.getType())
      {
      case CREATE_BASE_ENTRY:
        arg2 = INFO_REVIEW_CREATE_BASE_ENTRY_LABEL.get(options.getBaseDn());
        arg2 = INFO_REVIEW_CREATE_BASE_ENTRY_LABEL.get(
            options.getBaseDns().getFirst());
        break;
@@ -306,7 +308,7 @@
        break;
      case IMPORT_FROM_LDIF_FILE:
        arg2 = INFO_REVIEW_IMPORT_LDIF.get(options.getLDIFPath());
        arg2 = INFO_REVIEW_IMPORT_LDIF.get(options.getLDIFPaths().getFirst());
        break;
      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
@@ -315,10 +317,11 @@
        break;
      default:
        throw new IllegalArgumentException("Unknow type: " + options.getType());
        throw new IllegalArgumentException("Unknown type: "+options.getType());
      }
      msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDn(), arg2);
      msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDns().getFirst(),
          arg2);
    }
    else
    {
@@ -334,9 +337,9 @@
      }
      msg = INFO_REVIEW_REPLICATE_SUFFIX.get(buf.toString());
    }
    return msg.toString();
  }
   /**
    * Returns the String representing the replication port configuration.
    * @param userInstallData the DataOptions of the user.
opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -1209,7 +1209,8 @@
    else if (name.endsWith(".sh"))
    {
      perm = "755";
    } else if (name.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
    } else if (name.endsWith(Installation.UNIX_SETUP_GUI_FILE_NAME) ||
            name.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
            name.endsWith(Installation.UNIX_UNINSTALL_GUI_FILE_NAME) ||
            name.endsWith(Installation.UNIX_UNINSTALL_FILE_NAME) ||
            name.endsWith(Installation.UNIX_UPGRADE_FILE_NAME))
opends/src/server/org/opends/server/tools/InstallDS.java
@@ -24,1153 +24,1627 @@
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.server.tools;
import org.opends.messages.Message;
import static org.opends.messages.AdminToolMessages.*;
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.messages.ToolMessages.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.security.KeyStoreException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;
import java.util.logging.Logger;
import org.opends.messages.Message;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.CliApplicationHelper;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.CurrentInstallStatus;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.QuickSetupLog;
import org.opends.quicksetup.SecurityOptions;
import org.opends.quicksetup.UserData;
import org.opends.quicksetup.UserDataException;
import org.opends.quicksetup.event.ProgressUpdateEvent;
import org.opends.quicksetup.event.ProgressUpdateListener;
import org.opends.quicksetup.installer.NewSuffixOptions;
import org.opends.quicksetup.installer.offline.OfflineInstaller;
import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
import org.opends.quicksetup.util.Utils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.extensions.ConfigFileHandler;
import org.opends.server.types.DN;
import org.opends.server.types.ExistingFileBehavior;
import org.opends.server.types.LDIFExportConfig;
import org.opends.server.types.InitializationException;
import org.opends.server.types.NullOutputStream;
import org.opends.server.util.CertificateManager;
import org.opends.server.util.SetupUtils;
import org.opends.server.util.LDIFWriter;
import org.opends.server.util.PasswordReader;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.args.IntegerArgument;
import org.opends.server.util.args.StringArgument;
import static org.opends.messages.ToolMessages.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.tools.ToolConstants.*;
/**
 * This class provides a very simple mechanism for installing the OpenDS
 * Directory Service.  It performs the following tasks:
 * <UL>
 *   <LI>Checks if the server is already installed and running</LI>
 *   <LI>Ask the user what base DN should be used for the data</LI>
 *   <LI>Ask the user whether to create the base entry, or to import LDIF</LI>
 *   <LI>Ask the user for the LDAP port and make sure it's available</LI>
 *   <LI>Ask the user for the default root DN and password</LI>
 *   <LI>Ask the user to enable SSL or not and for the type of certificate that
 *   the server must use</LI>
 *   <LI>Ask the user if they want to start the server when done installing</LI>
 * </UL>
 */
public class InstallDS
public class InstallDS  extends CliApplicationHelper
{
  /**
   * The fully-qualified name of this class.
   */
  private static final String CLASS_NAME = "org.opends.server.tools.InstallDS";
  private PlainTextProgressMessageFormatter formatter =
    new PlainTextProgressMessageFormatter();
  /** Prefix for log files. */
  static public final String LOG_FILE_PREFIX = "opends-setup-";
  /** Suffix for log files. */
  static public final String LOG_FILE_SUFFIX = ".log";
  /**
   * Indicates whether we think we're running on a Windows system.
   */
  private static final boolean isWindows = SetupUtils.isWindows();
  /**
   * The version string for the server.
   */
  private static String versionString;
  /**
   * The name of the program used to launch this installation process.
   */
  private static String programName;
  /**
   * The value that indicates that only the base entry should be created.
   */
  private static final int POPULATE_TYPE_BASE_ONLY = 1;
  /**
   * The value that indicates that the database should be left empty.
   */
  private static final int POPULATE_TYPE_LEAVE_EMPTY = 2;
  /**
   * The value that indicates that data should be imported from an LDIF file.
   */
  private static final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
  /**
   * The value that indicates that the database should be populated with sample
   * data.
   */
  private static final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
  /**
   * Invokes the <CODE>installMain</CODE> method with the provided arguments.
   * The enumeration containing the different return codes that the command-line
   * can have.
   *
   * @param  args  The command-line arguments to use for this program.
   */
  public static void main(String[] args)
  enum ErrorReturnCode
  {
    int exitCode = installMain(args);
    if (exitCode != 0)
    /**
     * Successful setup.
     */
    SUCCESSFUL(0),
    /**
     * We did no have an error but the setup was not executed (displayed
     * version or usage).
     */
    SUCCESSFUL_NOP(0),
    /**
     * Unexpected error (potential bug).
     */
    ERROR_UNEXPECTED(1),
    /**
     * Cannot parse arguments or data provided by user is not valid.
     */
    ERROR_USER_DATA(2),
    /**
     * Error server already installed.
     */
    ERROR_SERVER_ALREADY_INSTALLED(3),
    /**
     * Error initializing server.
     */
    ERROR_INITIALIZING_SERVER(4);
    private int returnCode;
    private ErrorReturnCode(int returnCode)
    {
      System.exit(filterExitCode(exitCode));
      this.returnCode = returnCode;
    }
    /**
     * Get the corresponding return code value.
     *
     * @return The corresponding return code value.
     */
    public int getReturnCode()
    {
      return returnCode;
    }
  };
  /**
   * The Logger.
   */
  static private final Logger LOG = Logger.getLogger(InstallDS.class.getName());
  // The argument parser
  private InstallDSArgumentParser argParser;
  /**
   * Constructor for the SetupCli object.
   *
   * @param out the print stream to use for standard output.
   * @param err the print stream to use for standard error.
   * @param in the input stream to use for standard input.
   */
  public InstallDS(PrintStream out, PrintStream err, InputStream in)
  {
    super(out, err, in);
  }
  /**
   * The main method for the setup CLI tool.
   *
   * @param args the command-line arguments provided to this program.
   */
  public static void main(String[] args)
  {
    int retCode = mainCLI(args, true, System.out, System.err, System.in);
    System.exit(retCode);
  }
  /**
   * Prompts the user for the necessary information, installs the OpenDS
   * software in the appropriate location, and gives it the desired
   * configuration.
   * Parses the provided command-line arguments and uses that information to
   * run the setup tool.
   *
   * @param  args  The command-line arguments to use for this program.
   * @param args the command-line arguments provided to this program.
   *
   * @return  A value of zero if the installation process was successful, or a
   *          nonzero value if a problem occurred.
   * @return The error code.
   */
  public static int installMain(String[] args)
  {
    // Construct the product version string and the setup filename.
    versionString = DirectoryServer.getVersionString();
    if (isWindows)
  public static int mainCLI(String[] args)
  {
    return mainCLI(args, true, System.out, System.err, System.in);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the setup tool.
   *
   * @param  args              The command-line arguments provided to this
   *                           program.
   * @param initializeServer   Indicates whether to initialize the server.
   * @param  outStream         The output stream to use for standard output, or
   *                           <CODE>null</CODE> if standard output is not
   *                           needed.
   * @param  errStream         The output stream to use for standard error, or
   *                           <CODE>null</CODE> if standard error is not
   *                           needed.
   * @param  inStream          The input stream to use for standard input.
   * @return The error code.
   */
  public static int mainCLI(String[] args, boolean initializeServer,
      OutputStream outStream, OutputStream errStream, InputStream inStream)
  {
    PrintStream out;
    if (outStream == null)
    {
      programName = "setup.bat";
      out = NullOutputStream.printStream();
    }
    else
    {
      programName = "setup";
      out = new PrintStream(outStream);
    }
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
    // Create and initialize the argument parser for this program.
    Message toolDescription = INFO_INSTALLDS_TOOL_DESCRIPTION.get();
    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
                                                  false);
    BooleanArgument   addBaseEntry;
    BooleanArgument   cliMode;
    BooleanArgument   testOnly;
    BooleanArgument   showUsage;
    BooleanArgument   quietInstall;
    BooleanArgument   skipPortCheck;
    BooleanArgument   enableWindowsService;
    FileBasedArgument rootPWFile;
    IntegerArgument   ldapPort;
    IntegerArgument   jmxPort;
    IntegerArgument   sampleData;
    StringArgument    baseDN;
    StringArgument    configClass;
    StringArgument    configFile;
    StringArgument    importLDIF;
    StringArgument    progName;
    StringArgument    rootDN;
    StringArgument    rootPWString;
    PrintStream err;
    if (errStream == null)
    {
      err = NullOutputStream.printStream();
    }
    else
    {
      err = new PrintStream(errStream);
    }
    try {
      QuickSetupLog.initLogFileHandler(
              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX),
              "org.opends.server.tools");
      QuickSetupLog.disableConsoleLogging();
    } catch (Throwable t) {
      System.err.println("Unable to initialize log");
      t.printStackTrace();
    }
    InstallDS install = new InstallDS(out, err, inStream);
    return install.execute(args, initializeServer);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the setup CLI.
   *
   * @param args the command-line arguments provided to this program.
   * @param  initializeServer  Indicates whether to initialize the server.
   *
   * @return the return code (SUCCESSFUL, USER_DATA_ERROR or BUG.
   */
  public int execute(String[] args, boolean initializeServer)
  {
    argParser = new InstallDSArgumentParser(InstallDS.class.getName());
    try
    {
      testOnly = new BooleanArgument(
              "test", 't', "testOnly",
              INFO_INSTALLDS_DESCRIPTION_TESTONLY.get());
      testOnly.setHidden(true);
      argParser.addArgument(testOnly);
      progName = new StringArgument(
              "progname", 'P', "programName", false,
              false, true, "{programName}", programName,
              null, INFO_INSTALLDS_DESCRIPTION_PROGNAME.get());
      progName.setHidden(true);
      argParser.addArgument(progName);
      configFile = new StringArgument(
              "configfile", 'c', "configFile", false,
              false, true, "{configFile}", null, null,
              INFO_DESCRIPTION_CONFIG_FILE.get());
      configFile.setHidden(true);
      argParser.addArgument(configFile);
      configClass = new StringArgument(
              "configclass", OPTION_SHORT_CONFIG_CLASS,
              OPTION_LONG_CONFIG_CLASS, false,
              false, true, OPTION_VALUE_CONFIG_CLASS,
              ConfigFileHandler.class.getName(), null,
              INFO_DESCRIPTION_CONFIG_CLASS.get());
      configClass.setHidden(true);
      argParser.addArgument(configClass);
      // NOTE:  This argument isn't actually used for anything, but it provides
      // consistency with the setup script, which does take a --cli option.
      cliMode = new BooleanArgument(
              "cli", null, OPTION_LONG_CLI,
              INFO_INSTALLDS_DESCRIPTION_CLI.get());
      argParser.addArgument(cliMode);
      quietInstall = new BooleanArgument(
              "quiet", OPTION_SHORT_QUIET,
              OPTION_LONG_QUIET,
              INFO_INSTALLDS_DESCRIPTION_SILENT.get());
      argParser.addArgument(quietInstall);
      baseDN = new StringArgument(
              "basedn", OPTION_SHORT_BASEDN,
              OPTION_LONG_BASEDN, false, true, true,
              OPTION_VALUE_BASEDN,
              "dc=example,dc=com", null,
              INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
      argParser.addArgument(baseDN);
      addBaseEntry = new BooleanArgument(
              "addbase", 'a', "addBaseEntry",
              INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
      argParser.addArgument(addBaseEntry);
      importLDIF = new StringArgument(
              "importldif", OPTION_SHORT_LDIF_FILE,
              OPTION_LONG_LDIF_FILE, false,
              true, true, OPTION_VALUE_LDIF_FILE,
              null, null,
              INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
      argParser.addArgument(importLDIF);
      sampleData = new IntegerArgument(
              "sampledata", 'd', "sampleData", false,
              false, true, "{numEntries}", 0, null,
              true, 0, false, 0,
              INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
      argParser.addArgument(sampleData);
      ldapPort = new IntegerArgument(
              "ldapport", OPTION_SHORT_PORT,
              "ldapPort", false, false,
              true, OPTION_VALUE_PORT, 389,
              null, true, 1, true, 65535,
              INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
      argParser.addArgument(ldapPort);
      jmxPort = new IntegerArgument(
              "jmxport", 'x', "jmxPort", false, false,
              true, "{jmxPort}",
              SetupUtils.getDefaultJMXPort(), null, true,
              1, true, 65535,
              INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
      argParser.addArgument(jmxPort);
      skipPortCheck = new BooleanArgument(
              "skipportcheck", 'S', "skipPortCheck",
              INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
      argParser.addArgument(skipPortCheck);
      rootDN = new StringArgument(
              "rootdn",OPTION_SHORT_ROOT_USER_DN,
              OPTION_LONG_ROOT_USER_DN, false, true,
              true, OPTION_VALUE_ROOT_USER_DN,
              "cn=Directory Manager",
              null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
      argParser.addArgument(rootDN);
      rootPWString = new StringArgument(
              "rootpwstring", OPTION_SHORT_BINDPWD,
              "rootUserPassword",
              false, false, true,
              "{password}", null,
              null,
              INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
      argParser.addArgument(rootPWString);
      rootPWFile = new FileBasedArgument(
              "rootpwfile",
              OPTION_SHORT_BINDPWD_FILE,
              "rootUserPasswordFile", false, false,
              OPTION_VALUE_BINDPWD_FILE,
              null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
      argParser.addArgument(rootPWFile);
      enableWindowsService = new BooleanArgument(
              "enablewindowsservice", 'e',
              "enableWindowsService",
              INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
      if (SetupUtils.isWindows())
      {
        argParser.addArgument(enableWindowsService);
      }
      showUsage = new BooleanArgument("help", OPTION_SHORT_HELP,
                                      OPTION_LONG_HELP,
                                      INFO_INSTALLDS_DESCRIPTION_HELP.get());
      argParser.addArgument(showUsage);
      argParser.setUsageArgument(showUsage);
      argParser.initializeArguments();
    }
    catch (ArgumentException ae)
    {
      System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
      System.err.println(argParser.getUsage());
      return 1;
      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      printErrorMessage(message);
      return ErrorReturnCode.ERROR_UNEXPECTED.getReturnCode();
    }
    // Parse all of the configuration arguments.
    // Validate user provided data
    try
    {
      argParser.parseArguments(args);
    }
    catch (ArgumentException ae)
    {
      System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
      System.err.println(argParser.getUsage());
      return 1;
      Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
      printErrorMessage(message);
      printLineBreak();
      printErrorMessage(argParser.getUsage());
      return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
    }
    // If either the showUsage or testOnly or version arguments were provided,
    //  If either the showUsage or testOnly or version arguments were provided,
    // then we're done.
    if (argParser.usageOrVersionDisplayed() || testOnly.isPresent())
    if (argParser.usageOrVersionDisplayed() ||
        argParser.testOnlyArg.isPresent())
    {
      return 0;
      return ErrorReturnCode.SUCCESSFUL_NOP.getReturnCode();
    }
    try
    {
      Set<Integer> ports = new HashSet<Integer>();
      if (ldapPort.isPresent())
      {
        ports.add(ldapPort.getIntValue());
      }
      if (jmxPort.isPresent())
      {
        if (ports.contains(jmxPort.getIntValue()))
        {
          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
                  String.valueOf(jmxPort.getIntValue()));
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          System.err.println(argParser.getUsage());
          return 1;
        }
        else
        {
          ports.add(jmxPort.getIntValue());
        }
      }
      checkInstallStatus();
    }
    catch (ArgumentException ae)
    catch (InitializationException ie)
    {
      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
      printErrorMessage(ie.getMessageObject());
      return ErrorReturnCode.ERROR_SERVER_ALREADY_INSTALLED.getReturnCode();
    }
    // Make sure that the user didn't provide conflicting arguments.
    if (addBaseEntry.isPresent())
    if (initializeServer)
    {
      if (importLDIF.isPresent())
      try
      {
        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
                addBaseEntry.getLongIdentifier(),
                importLDIF.getLongIdentifier());
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
        initializeDirectoryServer(argParser.configFileArg.getValue(),
            argParser.configClassArg.getValue());
      }
      else if (sampleData.isPresent())
      catch (InitializationException ie)
      {
        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
                addBaseEntry.getLongIdentifier(),
                sampleData.getLongIdentifier());
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
        printErrorMessage(ie.getMessageObject());
        return ErrorReturnCode.ERROR_INITIALIZING_SERVER.getReturnCode();
      }
    }
    else if (importLDIF.isPresent() && sampleData.isPresent())
    {
      Message message = ERR_TOOL_CONFLICTING_ARGS.get(
              importLDIF.getLongIdentifier(),
              sampleData.getLongIdentifier());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }
    UserData uData = new UserData();
    // Make sure the path to the configuration file was given.
    String configFileName;
    if (configFile.isPresent())
    if (isInteractive())
    {
      configFileName = configFile.getValue();
      promptIfRequired(uData);
    }
    else
    {
      Message message = ERR_INSTALLDS_NO_CONFIG_FILE.get(
              configFile.getLongIdentifier());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
      try
      {
        initializeUserDataWithParser(uData);
      }
      catch (UserDataException ude)
      {
        printErrorMessage(ude.getMessageObject());
        return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
      }
    }
    OfflineInstaller installer = new OfflineInstaller();
    installer.setUserData(uData);
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
    installer.setProgressMessageFormatter(formatter);
    installer.addProgressUpdateListener(
        new ProgressUpdateListener() {
          public void progressUpdate(ProgressUpdateEvent ev) {
            if (ev.getNewLogs() != null)
            {
              printProgressMessage(ev.getNewLogs());
            }
          }
        });
    printProgressLineBreak();
    // Get the configuration handler class name.
    String configClassName = configClass.getValue();
    installer.run();
    ApplicationException ue = installer.getRunError();
    // If this isn't a quiet install, then print the version string.
    if (! quietInstall.isPresent())
    String cmd;
    // Use this instead a call to Installation to avoid to launch a new JVM
    // just to retrieve a path.
    String root = Utils.getInstallPathFromClasspath();
    if (SetupUtils.isWindows())
    {
      System.out.println(versionString);
      System.out.println();
      Message message = INFO_INSTALLDS_INITIALIZING.get();
      System.out.println(wrapText(message, MAX_LINE_WIDTH));
      String binDir = Utils.getPath(root,
          Installation.WINDOWS_BINARIES_PATH_RELATIVE);
      cmd = Utils.getPath(binDir, Installation.WINDOWS_STATUSCLI_FILE_NAME);
    }
    else
    {
      String binDir = Utils.getPath(root,
          Installation.UNIX_BINARIES_PATH_RELATIVE);
      cmd = Utils.getPath(binDir, Installation.UNIX_STATUSCLI_FILE_NAME);
    }
    printProgressLineBreak();
    printProgressLineBreak();
    printProgressMessage(INFO_INSTALLDS_STATUS_COMMAND_LINE.get(cmd));
    printProgressLineBreak();
    if (ue != null)
    {
      return ue.getType().getReturnCode();
    }
    else
    {
      return ErrorReturnCode.SUCCESSFUL.getReturnCode();
    }
  }
  /**
   * Checks if the server is installed or not.
   * @throws InitializationException if the server is already installed and
   * configured or if the user did not accept to overwrite the existing
   * databases.
   */
  private void checkInstallStatus() throws InitializationException
  {
    CurrentInstallStatus installStatus = new CurrentInstallStatus();
    if (installStatus.canOverwriteCurrentInstall())
    {
      if (isInteractive())
      {
        printLine(installStatus.getInstallationMsg(), true);
        if (!confirm(INFO_CLI_DO_YOU_WANT_TO_CONTINUE.get()))
        {
          throw new InitializationException(Message.EMPTY, null);
        }
      }
      else
      {
        printWarningMessage(installStatus.getInstallationMsg());
      }
    }
    else if (installStatus.isInstalled())
    {
      throw new InitializationException(installStatus.getInstallationMsg(),
          null);
    }
  }
  /**
   * Initialize the directory server to be able to perform the operations
   * required during the installation.
   * @param configFile the configuration file to be used to initialize the
   * server.
   * @param configClass the configuration class to be used to initialize the
   * server.
   * @throws InitializationException if there was an error during
   * initialization.
   */
  private void initializeDirectoryServer(String configFile, String configClass)
  throws InitializationException
  {
    printProgressLineBreak();
    printProgressMessage(DirectoryServer.getVersionString());
    printProgressLineBreak();
    printProgressMessage(INFO_INSTALLDS_INITIALIZING.get());
    printProgressLineBreak();
    // Perform a base-level initialization that will be required to get
    // minimal functionality like DN parsing to work.
    DirectoryServer directoryServer = DirectoryServer.getInstance();
    directoryServer.bootstrapClient();
    DirectoryServer.bootstrapClient();
    try
    {
      directoryServer.initializeJMX();
      DirectoryServer.initializeJMX();
    }
    catch (Exception e)
    catch (Throwable t)
    {
      Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_JMX.get(
              String.valueOf(configFile.getValue()),
              e.getMessage());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
              String.valueOf(configFile), t.getMessage());
      throw new InitializationException(message, t);
    }
    try
    {
      directoryServer.initializeConfiguration(configClass.getValue(),
                                              configFile.getValue());
      directoryServer.initializeConfiguration(configClass, configFile);
    }
    catch (Exception e)
    catch (Throwable t)
    {
      Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_CONFIG.get(
              String.valueOf(configFile.getValue()),
                                  e.getMessage());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
              configFile, t.getMessage());
      throw new InitializationException(message, t);
    }
    try
    {
      directoryServer.initializeSchema();
    }
    catch (Exception e)
    catch (Throwable t)
    {
      Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_SCHEMA.get(
              String.valueOf(configFile.getValue()),
                                  e.getMessage());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
              configFile, t.getMessage());
      throw new InitializationException(message, t);
    }
  }
  /**
   * {@inheritDoc}
   */
  protected boolean isQuiet()
  {
    return argParser.quietArg.isPresent();
  }
    // Determine the LDAP port number.
    int ldapPortNumber;
    if (quietInstall.isPresent() || ldapPort.isPresent())
  /**
   * {@inheritDoc}
   */
  protected boolean isInteractive()
  {
    return !argParser.noPromptArg.isPresent();
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line.  It assumes that it is being called in no
   * prompt mode.
   * @param uData the UserData object.
   * @throws UserDataException if something went wrong checking the data.
   */
  private void initializeUserDataWithParser(UserData uData)
  throws UserDataException
  {
    LinkedList<Message> errorMessages = new LinkedList<Message>();
    uData.setConfigurationClassName(argParser.configClassArg.getValue());
    uData.setConfigurationFile(argParser.configFileArg.getValue());
    uData.setQuiet(isQuiet());
    //  Check the validity of the directory manager DNs
    String dmDN = argParser.directoryManagerDNArg.getValue();
    try
    {
      DN.decode(dmDN);
    }
    catch (Exception e)
    {
      Message message =
        ERR_INSTALLDS_CANNOT_PARSE_DN.get(dmDN, e.getMessage());
      errorMessages.add(message);
    }
    uData.setDirectoryManagerDn(dmDN);
    uData.setDirectoryManagerPwd(argParser.getDirectoryManagerPassword());
    // Check the validity of the base DNs
    LinkedList<String> baseDNs = argParser.baseDNArg.getValues();
    if (baseDNs.isEmpty())
    {
      baseDNs.add(argParser.baseDNArg.getDefaultValue());
    }
    for (String baseDN : baseDNs)
    {
      try
      {
        ldapPortNumber = ldapPort.getIntValue();
        if (! skipPortCheck.isPresent())
        {
          // Check if the port can be used.
          if (!SetupUtils.canUseAsPort(ldapPortNumber))
          {
            Message message;
            if (SetupUtils.isPriviledgedPort(ldapPortNumber))
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                      ldapPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            else
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            return 1;
          }
        }
      }
      catch (ArgumentException ae)
      {
        System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
        return 1;
      }
    }
    else
    {
      while (true)
      {
        Message message = INFO_INSTALLDS_PROMPT_LDAPPORT.get();
        ldapPortNumber = promptForInteger(message, 389, 1, 65535);
        if (skipPortCheck.isPresent())
        {
            break;
        }
        else
        {
          // Check if the port can be used.
          if (SetupUtils.canUseAsPort(ldapPortNumber))
          {
              break;
          }
          else
          {
            if (SetupUtils.isPriviledgedPort(ldapPortNumber))
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                      ldapPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            else
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
          }
        }
      }
    }
//  Determine the JMX port number.
    int jmxPortNumber;
    if (quietInstall.isPresent() || jmxPort.isPresent())
    {
      try
      {
        jmxPortNumber = jmxPort.getIntValue();
        if (! skipPortCheck.isPresent())
        {
          // Check if the port can be used.
          if (!SetupUtils.canUseAsPort(jmxPortNumber))
          {
            Message message;
            if (SetupUtils.isPriviledgedPort(jmxPortNumber))
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                      jmxPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            else
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            return 1;
          }
        }
      }
      catch (ArgumentException ae)
      {
        System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
        return 1;
      }
    }
    else
    {
      /* Do not ask for the JMX port if the user did not provide it.*/
      jmxPortNumber = -1;
      /*
      while (true)
      {
        Message message = INFO_INSTALLDS_PROMPT_JMXPORT.get();
        jmxPortNumber = promptForInteger(message,
            SetupUtils.getDefaultJMXPort(), 1, 65535);
        if (skipPortCheck.isPresent())
        {
            break;
        }
        else
        {
          // Check if the port can be used.
          if (SetupUtils.canUseAsPort(jmxPortNumber))
          {
              break;
          }
          else
          {
            if (SetupUtils.isPriviledgedPort(jmxPortNumber))
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                        jmxPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
            else
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
              System.err.println(wrapText(message, MAX_LINE_WIDTH));
            }
          }
        }
      }
      */
    }
    // Determine the initial root user DN.
    LinkedList<DN> rootDNs;
    if (rootDN.isPresent())
    {
      rootDNs = new LinkedList<DN>();
      for (String s : rootDN.getValues())
      {
        try
        {
          rootDNs.add(DN.decode(s));
        }
        catch (Exception e)
        {
          Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
                  s, e.getMessage());
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
    }
    else if (quietInstall.isPresent())
    {
      rootDNs = new LinkedList<DN>();
      try
      {
        rootDNs.add(DN.decode(rootDN.getDefaultValue()));
      }
      catch (Exception e)
      {
        Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
                rootDN.getDefaultValue(),
                                    e.getMessage());
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }
    }
    else
    {
      Message message = INFO_INSTALLDS_PROMPT_ROOT_DN.get();
      rootDNs = new LinkedList<DN>();
      rootDNs.add(promptForDN(message, rootDN.getDefaultValue()));
    }
    // Determine the initial root user password.
    String rootPassword;
    if (rootPWString.isPresent())
    {
      rootPassword = rootPWString.getValue();
      if (rootPWFile.isPresent())
      {
        Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
                rootPWString.getLongIdentifier(),
                rootPWFile.getLongIdentifier());
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }
    }
    else if (rootPWFile.isPresent())
    {
      rootPassword = rootPWFile.getValue();
    }
    else if (quietInstall.isPresent())
    {
      Message message = ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
              rootPWString.getLongIdentifier(),
              rootPWFile.getLongIdentifier());
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }
    else
    {
      Message initialPrompt = INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get();
      Message confirmPrompt = INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get();
      rootPassword =
           new String(promptForPassword(initialPrompt, confirmPrompt));
    }
    // Determine the directory base DN.
    LinkedList<DN> baseDNs;
    if (baseDN.isPresent())
    {
      baseDNs = new LinkedList<DN>();
      for (String s : baseDN.getValues())
      {
        try
        {
          baseDNs.add(DN.decode(s));
        }
        catch (Exception e)
        {
          Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
                  s, e.getMessage());
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          return 1;
        }
      }
    }
    else if (quietInstall.isPresent())
    {
      try
      {
        baseDNs = new LinkedList<DN>();
        baseDNs.add(DN.decode(baseDN.getDefaultValue()));
        DN.decode(baseDN);
      }
      catch (Exception e)
      {
        Message message =
                ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN.getDefaultValue(),
                                    e.getMessage());
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
          ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN, e.getMessage());
        errorMessages.add(message);
      }
    }
    else
    {
      Message message = INFO_INSTALLDS_PROMPT_BASEDN.get();
      baseDNs = new LinkedList<DN>();
      baseDNs.add(promptForDN(message, baseDN.getDefaultValue()));
    }
    // Determine how to populate the database.
    int                populateType = POPULATE_TYPE_LEAVE_EMPTY;
    int                numUsers     = -1;
    LinkedList<String> ldifFiles    = null;
    if (addBaseEntry.isPresent())
    try
    {
      populateType = POPULATE_TYPE_BASE_ONLY;
    }
    else if (importLDIF.isPresent())
    {
      ldifFiles    = importLDIF.getValues();
      populateType = POPULATE_TYPE_IMPORT_FROM_LDIF;
    }
    else if (sampleData.isPresent())
    {
      try
      int ldapPort = argParser.ldapPortArg.getIntValue();
      uData.setServerPort(ldapPort);
      if (!argParser.skipPortCheckArg.isPresent())
      {
        numUsers     = sampleData.getIntValue();
        populateType = POPULATE_TYPE_GENERATE_SAMPLE_DATA;
      }
      catch (Exception e)
      {
        // This should never happen.
        e.printStackTrace();
        return 1;
      }
    }
    else if (quietInstall.isPresent())
    {
      populateType = POPULATE_TYPE_LEAVE_EMPTY;
    }
    else
    {
      System.out.println(wrapText(
              INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(),
              MAX_LINE_WIDTH));
      System.out.println(wrapText("1.  " +
              INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(),
              MAX_LINE_WIDTH));
      System.out.println(wrapText("2.  " +
              INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(),
              MAX_LINE_WIDTH));
      System.out.println(wrapText("3.  " +
              INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(),
              MAX_LINE_WIDTH));
      System.out.println(wrapText("4.  " +
              INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(),
              MAX_LINE_WIDTH));
      populateType = promptForInteger(
              INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(), 1, 1, 4);
      System.out.println();
      if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
      {
        ldifFiles = new LinkedList<String>();
        while (true)
        // Check if the port can be used.
        if (!SetupUtils.canUseAsPort(ldapPort))
        {
          Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
          String path    = promptForString(message, "");
          if (new File(path).exists())
          Message message;
          if (SetupUtils.isPriviledgedPort(ldapPort))
          {
            ldifFiles.add(path);
            System.out.println();
            break;
            message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                ldapPort);
          }
          else
          {
            message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            System.err.println();
            message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPort);
          }
          errorMessages.add(message);
        }
      }
      if (argParser.jmxPortArg.isPresent())
      {
        int jmxPort = argParser.jmxPortArg.getIntValue();
        uData.setServerPort(jmxPort);
        //   Check if the port can be used.
        if (!argParser.skipPortCheckArg.isPresent())
        {
          if (!SetupUtils.canUseAsPort(jmxPort))
          {
            Message message;
            if (SetupUtils.isPriviledgedPort(jmxPort))
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                  jmxPort);
            }
            else
            {
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPort);
            }
            errorMessages.add(message);
          }
        }
      }
    }
    catch (ArgumentException ae)
    {
      errorMessages.add(ae.getMessageObject());
    }
    NewSuffixOptions dataOptions;
    if (argParser.importLDIFArg.isPresent())
    {
      // Check that the files exist
      LinkedList<String> nonExistingFiles = new LinkedList<String>();
      for (String file : argParser.importLDIFArg.getValues())
      {
        if (!Utils.fileExists(file))
        {
          nonExistingFiles.add(file);
        }
      }
      if (nonExistingFiles.size() > 0)
      {
        errorMessages.add(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
            Utils.getStringFromCollection(nonExistingFiles, ", ")));
      }
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE, baseDNs,
          argParser.importLDIFArg.getValues());
    }
    else if (argParser.addBaseEntryArg.isPresent())
    {
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
    }
    else if (argParser.sampleDataArg.isPresent())
    {
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, baseDNs,
          new Integer(argParser.sampleDataArg.getValue()));
    }
    else
    {
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
    }
    uData.setNewSuffixOptions(dataOptions);
    // Check that the security data provided is valid.
    String certNickname = argParser.certNicknameArg.getValue();
    String pwd = argParser.getKeyStorePassword();
    boolean enableSSL = argParser.ldapsPortArg.isPresent();
    boolean enableStartTLS = argParser.enableStartTLSArg.isPresent();
    int ldapsPort = -1;
    try
    {
      ldapsPort = enableSSL ? argParser.ldapsPortArg.getIntValue() : -1;
    }
    catch (ArgumentException ae)
    {
      errorMessages.add(ae.getMessageObject());
    }
    if (enableSSL)
    {
      if (!argParser.skipPortCheckArg.isPresent())
      {
        if (!SetupUtils.canUseAsPort(ldapsPort))
        {
          if (SetupUtils.isPriviledgedPort(ldapsPort))
          {
            errorMessages.add(
                ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(ldapsPort));
          }
          else
          {
            errorMessages.add(ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapsPort));
          }
        }
      }
    }
    SecurityOptions securityOptions;
    LinkedList<String> keystoreAliases = new LinkedList<String>();
    if (argParser.generateSelfSignedCertificateArg.isPresent())
    {
      securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
          enableSSL, enableStartTLS, ldapsPort);
    }
    else if (argParser.useJavaKeyStoreArg.isPresent())
    {
      String path = argParser.useJavaKeyStoreArg.getValue();
      checkCertificateInKeystore(SecurityOptions.CertificateType.JKS, path, pwd,
          certNickname, errorMessages, keystoreAliases);
      securityOptions = SecurityOptions.createJKSCertificateOptions(
          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
    }
    else if (argParser.usePkcs12Arg.isPresent())
    {
      String path = argParser.usePkcs12Arg.getValue();
      checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS12, path,
          pwd, certNickname, errorMessages, keystoreAliases);
      securityOptions = SecurityOptions.createPKCS12CertificateOptions(
          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
    }
    else if (argParser.usePkcs11Arg.isPresent())
    {
      checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS11, null,
          pwd, certNickname, errorMessages, keystoreAliases);
      securityOptions = SecurityOptions.createPKCS11CertificateOptions(
          pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
    }
    else
    {
      securityOptions = SecurityOptions.createNoCertificateOptions();
    }
    uData.setSecurityOptions(securityOptions);
    uData.setEnableWindowsService(
        argParser.enableWindowsServiceArg.isPresent());
    uData.setStartServer(!argParser.doNotStartArg.isPresent());
    if (errorMessages.size() > 0)
    {
      throw new UserDataException(null,
          Utils.getMessageFromCollection(errorMessages,
              formatter.getLineBreak().toString()));
    }
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line. If the user did not provide explicitly some
   * data or if the provided data is not valid, it prompts the user to provide
   * it.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequired(UserData uData)
  {
    uData.setConfigurationClassName(argParser.configClassArg.getValue());
    uData.setConfigurationFile(argParser.configFileArg.getValue());
    uData.setQuiet(isQuiet());
    promptIfRequiredForDirectoryManager(uData);
    promptIfRequiredForPortData(uData);
    promptIfRequiredForImportData(uData);
    promptIfRequiredForSecurityData(uData);
    promptIfRequiredForWindowsService(uData);
    promptIfRequiredForStartServer(uData);
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the Directory Manager parameters.
   * If the user did not provide explicitly some data or if the provided data is
   * not valid, it prompts the user to provide it.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequiredForDirectoryManager(UserData uData)
  {
    LinkedList<String> dns = promptIfRequiredForDNs(
        argParser.directoryManagerDNArg, INFO_INSTALLDS_PROMPT_ROOT_DN.get(),
        true);
    uData.setDirectoryManagerDn(dns.getFirst());
    String pwd = argParser.getDirectoryManagerPassword();
    while (pwd == null)
    {
      printLineBreak();
      String pwd1 = null;
      // Prompt for password and confirm.
      while (pwd1 == null)
      {
        pwd1 = promptForPassword(INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get());
        if ("".equals(pwd1))
        {
          pwd1 = null;
          printLineBreak();
          printErrorMessage(INFO_EMPTY_PWD.get());
        }
      }
      String pwd2 =
        promptForPassword(INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get());
      if (pwd1.equals(pwd2))
      {
        pwd = pwd1;
      }
      else
      {
        printLineBreak();
        printErrorMessage(ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get());
      }
    }
    uData.setDirectoryManagerPwd(pwd);
  }
  /**
   * This method returns a list of DNs.  It checks that the provided list of
   * actually contain some values.  If no valid values are found it prompts
   * the user to provide a valid DN.
   * @param arg the Argument that the user provided to specify the DNs.
   * @param promptMsg the prompt message to be displayed.
   * @param includeLineBreak whether to include a line break before the first
   * prompt or not.
   * @return a list of valid DNs.
   */
  private LinkedList<String> promptIfRequiredForDNs(StringArgument arg,
      Message promptMsg, boolean includeLineBreak)
  {
    LinkedList<String> dns = new LinkedList<String>();
    boolean usedProvided = false;
    boolean firstPrompt = true;
    while (dns.isEmpty())
    {
      boolean prompted = false;
      if (usedProvided || !arg.isPresent())
      {
        if (firstPrompt && includeLineBreak)
        {
          printLineBreak();
        }
        String dn = promptForString(promptMsg, arg.getDefaultValue());
        firstPrompt = false;
        dns.add(dn);
        prompted = true;
      }
      else
      {
        dns.addAll(arg.getValues());
      }
      LinkedList<String> toRemove = new LinkedList<String>();
      for (String dn : dns)
      {
        try
        {
          DN.decode(dn);
        }
        catch (Exception e)
        {
          toRemove.add(dn);
          Message message = prompted ? ERR_INSTALLDS_INVALID_DN_RESPONSE.get() :
            ERR_INSTALLDS_CANNOT_PARSE_DN.get(dn, e.getMessage());
          printErrorMessage(message);
        }
      }
      if (toRemove.size() > 0)
      {
        printLineBreak();
      }
      dns.removeAll(toRemove);
    }
    return dns;
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the LDAP and JMX port parameters.
   * If the user did not provide explicitly some data or if the provided data is
   * not valid, it prompts the user to provide it.
   * Note: this method does not update nor check the LDAPS port.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequiredForPortData(UserData uData)
  {
    LinkedList<Integer> usedPorts = new LinkedList<Integer>();
    //  Determine the LDAP port number.
    int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
        INFO_INSTALLDS_PROMPT_LDAPPORT.get(), usedPorts, true);
    uData.setServerPort(ldapPort);
    usedPorts.add(ldapPort);
    if (argParser.jmxPortArg.isPresent())
    {
      int jmxPort = promptIfRequiredForPortData(argParser.jmxPortArg,
          INFO_INSTALLDS_PROMPT_JMXPORT.get(), usedPorts, true);
      uData.setServerJMXPort(jmxPort);
    }
    else
    {
      uData.setServerJMXPort(-1);
    }
  }
  /**
   * This method returns a valid port value.  It checks that the provided
   * argument contains a valid port. If a valid port is not found it prompts
   * the user to provide a valid port.
   * @param arg the Argument that the user provided to specify the port.
   * @param promptMsg the prompt message to be displayed.
   * @param usedPorts the list of ports the user provided before for other
   * connection handlers.
   * @param includeLineBreak whether to include a line break before the first
   * prompt or not.
   * @return a valid port number.
   */
  private int promptIfRequiredForPortData(IntegerArgument portArg,
      Message promptMsg, Collection<Integer> usedPorts,
      boolean includeLineBreak)
  {
    int portNumber = -1;
    boolean usedProvided = false;
    boolean firstPrompt = true;
    while (portNumber == -1)
    {
      try
      {
        boolean prompted = false;
        if (usedProvided || !portArg.isPresent())
        {
          int defaultValue = -1;
          if (portArg.getDefaultValue() != null)
          {
            defaultValue = Integer.parseInt(portArg.getDefaultValue());
          }
          if (firstPrompt && includeLineBreak)
          {
            printLineBreak();
          }
          portNumber = promptForPort(promptMsg, defaultValue);
          prompted = true;
          firstPrompt = false;
        }
        else
        {
          portNumber = portArg.getIntValue();
          usedProvided = true;
        }
        if (!argParser.skipPortCheckArg.isPresent())
        {
          // Check if the port can be used.
          if (!SetupUtils.canUseAsPort(portNumber))
          {
            Message message;
            if (SetupUtils.isPriviledgedPort(portNumber))
            {
              if (prompted || includeLineBreak)
              {
                printLineBreak();
              }
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
                  portNumber);
              printErrorMessage(message);
              portNumber = -1;
            }
            else
            {
              if (prompted || includeLineBreak)
              {
                printLineBreak();
              }
              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(portNumber);
              printErrorMessage(message);
              printLineBreak();
              portNumber = -1;
            }
          }
        }
        if (portNumber != -1)
        {
          if (usedPorts.contains(portNumber))
          {
            Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
                String.valueOf(portNumber));
            printErrorMessage(message);
            printLineBreak();
            portNumber = -1;
          }
        }
      }
      catch (ArgumentException ae)
      {
        printErrorMessage(ae.getMessage());
      }
    }
    return portNumber;
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the base DN and data import parameters.
   * If the user did not provide explicitly some data or if the provided data is
   * not valid, it prompts the user to provide it.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequiredForImportData(UserData uData)
  {
    // Check the validity of the base DNs
    LinkedList<String> baseDNs = promptIfRequiredForDNs(
        argParser.baseDNArg, INFO_INSTALLDS_PROMPT_BASEDN.get(), true);
    NewSuffixOptions dataOptions;
    if (argParser.importLDIFArg.isPresent())
    {
      // Check that the files exist
      LinkedList<String> nonExistingFiles = new LinkedList<String>();
      LinkedList<String> importLDIFFiles = new LinkedList<String>();
      for (String file : argParser.importLDIFArg.getValues())
      {
        if (!Utils.fileExists(file))
        {
          nonExistingFiles.add(file);
        }
        else
        {
          importLDIFFiles.add(file);
        }
      }
      if (nonExistingFiles.size() > 0)
      {
        printLineBreak();
        printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
            Utils.getStringFromCollection(nonExistingFiles, ", ")));
      }
      while (importLDIFFiles.isEmpty())
      {
        printLineBreak();
        String path = promptForString(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
            null);
        if (!Utils.fileExists(path))
        {
          printLineBreak();
          printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path));
        }
        else
        {
          importLDIFFiles.add(path);
        }
      }
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
          baseDNs, importLDIFFiles);
    }
    else if (argParser.addBaseEntryArg.isPresent())
    {
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.CREATE_BASE_ENTRY,
          baseDNs);
    }
    else if (argParser.sampleDataArg.isPresent())
    {
      int numUsers;
      try
      {
        numUsers = argParser.sampleDataArg.getIntValue();
      }
      catch (ArgumentException ae)
      {
        printLineBreak();
        printErrorMessage(ae.getMessageObject());
        Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
      }
      dataOptions = new NewSuffixOptions(
          NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
          baseDNs, numUsers);
    }
    else
    {
      final int POPULATE_TYPE_BASE_ONLY = 1;
      final int POPULATE_TYPE_LEAVE_EMPTY = 2;
      final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
      final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
      Message[] options = new Message[] {
          Message.raw(String.valueOf(POPULATE_TYPE_BASE_ONLY)),
          Message.raw(String.valueOf(POPULATE_TYPE_LEAVE_EMPTY)),
          Message.raw(String.valueOf(POPULATE_TYPE_IMPORT_FROM_LDIF)),
          Message.raw(String.valueOf(POPULATE_TYPE_GENERATE_SAMPLE_DATA))
        };
      printLineBreak();
      printLine(INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(), true);
      printLine(INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(), true);
      printLine(INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(), true);
      printLine(INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(), true);
      printLine(INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(), true);
      Message answer = promptConfirm(
          INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(),
            options[0], options);
      int populateType = new Integer(answer.toString());
      if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
      {
        LinkedList<String> importLDIFFiles = new LinkedList<String>();
        while (importLDIFFiles.isEmpty())
        {
          Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
          printLineBreak();
          String path = promptForString(message, null);
          if (Utils.fileExists(path))
          {
            importLDIFFiles.add(path);
          }
          else
          {
            message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
            printLineBreak();
            printErrorMessage(message);
          }
        }
        dataOptions = new NewSuffixOptions(
            NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
            baseDNs, importLDIFFiles);
      }
      else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
      {
        Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
        System.out.println();
        int numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
        dataOptions = new NewSuffixOptions(
            NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
            baseDNs, numUsers);
      }
      else if (populateType == POPULATE_TYPE_LEAVE_EMPTY)
      {
        dataOptions = new NewSuffixOptions(
            NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
      }
      else if (populateType == POPULATE_TYPE_BASE_ONLY)
      {
        dataOptions = new NewSuffixOptions(
            NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
      }
      else
      {
        throw new IllegalStateException("Unexpected populateType: "+
            populateType);
      }
    }
    uData.setNewSuffixOptions(dataOptions);
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the security parameters.
   * If the user did not provide explicitly some data or if the provided data is
   * not valid, it prompts the user to provide it.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequiredForSecurityData(UserData uData)
  {
    // Check that the security data provided is valid.
    boolean enableSSL = false;
    boolean enableStartTLS = false;
    int ldapsPort = -1;
    LinkedList<Integer> usedPorts = new LinkedList<Integer>();
    usedPorts.add(uData.getServerPort());
    if (uData.getServerJMXPort() != -1)
    {
      usedPorts.add(uData.getServerJMXPort());
    }
    // Ask to enable SSL
    ldapsPort = -1;
    if (!argParser.ldapsPortArg.isPresent())
    {
      printLineBreak();
      enableSSL = confirm(INFO_INSTALLDS_PROMPT_ENABLE_SSL.get(), false);
      if (enableSSL)
      {
        ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
            INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, false);
      }
    }
    else
    {
      ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
          INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, true);
      enableSSL = true;
    }
    // Ask to enable Start TLS
    if (!argParser.enableStartTLSArg.isPresent())
    {
      printLineBreak();
      enableStartTLS = confirm(INFO_INSTALLDS_ENABLE_STARTTLS.get(),
          argParser.enableStartTLSArg.isPresent());
    }
    else
    {
      enableStartTLS = true;
    }
    SecurityOptions securityOptions;
    if (argParser.generateSelfSignedCertificateArg.isPresent())
    {
      securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
          enableSSL, enableStartTLS, ldapsPort);
    }
    else if (argParser.useJavaKeyStoreArg.isPresent())
    {
      securityOptions =
        createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
            enableSSL, enableStartTLS, ldapsPort);
    }
    else if (argParser.usePkcs12Arg.isPresent())
    {
      securityOptions =
        createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS12,
            enableSSL, enableStartTLS, ldapsPort);
    }
    else if (argParser.usePkcs11Arg.isPresent())
    {
      securityOptions =
        createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS11,
            enableSSL, enableStartTLS, ldapsPort);
    }
    else
    {
      if (!enableSSL && !enableStartTLS)
      {
        // If the user did not want to enable SSL or start TLS do not ask
        // to create a certificate.
        securityOptions = SecurityOptions.createNoCertificateOptions();
      }
      else
      {
        final int SELF_SIGNED = 1;
        final int JKS = 2;
        final int PKCS12 = 3;
        final int PKCS11 = 4;
        Message[] options = new Message[] {
            Message.raw(String.valueOf(SELF_SIGNED)),
            Message.raw(String.valueOf(JKS)),
            Message.raw(String.valueOf(PKCS12)),
            Message.raw(String.valueOf(PKCS11))
          };
        printLineBreak();
        printLine(INFO_INSTALLDS_HEADER_CERT_TYPE.get(), true);
        printLine(INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED.get(), true);
        printLine(INFO_INSTALLDS_CERT_OPTION_JKS.get(), true);
        printLine(INFO_INSTALLDS_CERT_OPTION_PKCS12.get(), true);
        printLine(INFO_INSTALLDS_CERT_OPTION_PKCS11.get(), true);
        Message answer = promptConfirm(
            INFO_INSTALLDS_PROMPT_CERT_TYPE_CHOICE.get(),
              options[0], options);
        int certType = new Integer(answer.toString());
        if (certType == SELF_SIGNED)
        {
          securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
                enableSSL, enableStartTLS, ldapsPort);
        }
        else if (certType == JKS)
        {
          securityOptions =
            createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
                enableSSL, enableStartTLS, ldapsPort);
        }
        else if (certType == PKCS12)
        {
          securityOptions =
            createSecurityOptionsPrompting(
                SecurityOptions.CertificateType.PKCS12, enableSSL,
                enableStartTLS, ldapsPort);
        }
        else if (certType == PKCS11)
        {
          securityOptions =
            createSecurityOptionsPrompting(
                SecurityOptions.CertificateType.PKCS11, enableSSL,
                enableStartTLS, ldapsPort);
        }
        else
        {
          throw new IllegalStateException("Unexpected cert type: "+ certType);
        }
      }
    }
    uData.setSecurityOptions(securityOptions);
  }
  /**
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the Windows Service parameters.
   * If the user did not provide explicitly the data, it prompts the user to
   * provide it.
   * @param uData the UserData object to be updated.
   */
  private void promptIfRequiredForWindowsService(UserData uData)
  {
    boolean enableService = false;
    // If we are in Windows ask if the server must run as a windows service.
    if (SetupUtils.isWindows())
    {
      if (quietInstall.isPresent())
      {
        enableService = enableWindowsService.isPresent();
      }
      else if (enableWindowsService.isPresent())
      if (argParser.enableWindowsServiceArg.isPresent())
      {
        enableService = true;
      }
      else
      {
        printLineBreak();
        Message message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
        enableService = promptForBoolean(message, Boolean.TRUE);
        enableService = confirm(message, false);
      }
    }
    // At this point, we should be able to invoke the ConfigureDS utility to
    // apply the requested configuration.
    ArrayList<String> argList = new ArrayList<String>();
    argList.add("-C");
    argList.add(configClassName);
    argList.add("-c");
    argList.add(configFileName);
    argList.add("-p");
    argList.add(String.valueOf(ldapPortNumber));
    if (jmxPortNumber != -1)
    {
      argList.add("-x");
      argList.add(String.valueOf(jmxPortNumber));
    }
    for (DN dn : baseDNs)
    {
      argList.add("-b");
      argList.add(dn.toString());
    }
    for (DN dn : rootDNs)
    {
      argList.add("-D");
      argList.add(dn.toString());
    }
    argList.add("-w");
    argList.add(rootPassword);
    String[] configureDSArguments = new String[argList.size()];
    argList.toArray(configureDSArguments);
    if (! quietInstall.isPresent())
    {
      System.out.println();
      Message message = INFO_INSTALLDS_STATUS_CONFIGURING_DS.get();
      System.out.println(wrapText(message, MAX_LINE_WIDTH));
    }
    int returnValue = ConfigureDS.configMain(configureDSArguments);
    if (returnValue != 0)
    {
      return returnValue;
    }
    // If we need to create a base LDIF file or a template file, then do so now.
    if (populateType == POPULATE_TYPE_BASE_ONLY)
    {
      // Create a temporary LDIF file that will hold the entry to add.
      if (! quietInstall.isPresent())
      {
        Message message = INFO_INSTALLDS_STATUS_CREATING_BASE_LDIF.get();
        System.out.println(wrapText(message, MAX_LINE_WIDTH));
      }
      try
      {
        File   ldifFile     = File.createTempFile("opends-base-entry", ".ldif");
        String ldifFilePath = ldifFile.getAbsolutePath();
        ldifFile.deleteOnExit();
        LDIFExportConfig exportConfig =
             new LDIFExportConfig(ldifFilePath, ExistingFileBehavior.OVERWRITE);
        LDIFWriter writer = new LDIFWriter(exportConfig);
        for (DN dn : baseDNs)
        {
          writer.writeEntry(createEntry(dn));
        }
        writer.close();
        if (ldifFiles == null)
        {
          ldifFiles = new LinkedList<String>();
        }
        ldifFiles.add(ldifFilePath);
      }
      catch (Exception e)
      {
        Message message = ERR_INSTALLDS_CANNOT_CREATE_BASE_ENTRY_LDIF.get(
                String.valueOf(e));
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }
    }
    else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
    {
      try
      {
        File templateFile = SetupUtils.createTemplateFile(
                                 baseDNs.getFirst().toString(), numUsers);
        if (ldifFiles == null)
        {
          ldifFiles = new LinkedList<String>();
        }
        ldifFiles.add(templateFile.getAbsolutePath());
      }
      catch (Exception e)
      {
        Message message = ERR_INSTALLDS_CANNOT_CREATE_TEMPLATE_FILE.get(
                String.valueOf(e));
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
        return 1;
      }
    }
    if ((ldifFiles != null) && (! ldifFiles.isEmpty()))
    {
      if (! quietInstall.isPresent())
      {
        Message message = INFO_INSTALLDS_STATUS_IMPORTING_LDIF.get();
        System.out.println(wrapText(message, MAX_LINE_WIDTH));
      }
      // Use the ImportLDIF tool to perform the import.
      argList = new ArrayList<String>();
      argList.add("-C");
      argList.add(configClassName);
      argList.add("-f");
      argList.add(configFileName);
      argList.add("-n");
      argList.add("userRoot");
      for (String s : ldifFiles)
      {
        if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
        {
          argList.add("-t");
        }
        else
        {
          argList.add("-l");
        }
        argList.add(s);
      }
      if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
      {
        argList.add("-s");
        argList.add("0");
      }
      if (populateType == POPULATE_TYPE_BASE_ONLY)
      {
        argList.add("-q");
      }
      String[] importLDIFArguments = new String[argList.size()];
      argList.toArray(importLDIFArguments);
      returnValue = ImportLDIF.mainImportLDIF(importLDIFArguments);
      if (returnValue != 0)
      {
        Message message = ERR_INSTALLDS_IMPORT_UNSUCCESSFUL.get();
        System.out.println(wrapText(message, MAX_LINE_WIDTH));
        return returnValue;
      }
      else
      {
        Message message = INFO_INSTALLDS_IMPORT_SUCCESSFUL.get();
        System.out.println(wrapText(message, MAX_LINE_WIDTH));
      }
    }
    // Try to write a file that can be used to set the JAVA_HOME environment
    // variable for the administrative scripts and client tools provided with
    // the server.  If this fails, then it's not a big deal.
    try
    {
      String serverRoot = System.getenv("INSTANCE_ROOT");
      if ((serverRoot == null) || (serverRoot.length() == 0))
      {
        File f = new File(configFileName);
        serverRoot = f.getParentFile().getParentFile().getAbsolutePath();
      }
      // This isn't likely to happen, and it's not a serious problem even if it
      // does.
      SetupUtils.writeSetJavaHome(serverRoot);
    } catch (Exception e) {}
    if (enableService)
    {
      Message message = INFO_INSTALLDS_ENABLING_WINDOWS_SERVICE.get();
      System.out.println(wrapText(message, MAX_LINE_WIDTH));
      int code = ConfigureWindowsService.enableService(System.out,
          System.err);
      switch (code)
      {
      case ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
        break;
      case ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
        break;
      default:
        // It did not work.
        return code;
      }
    }
    // If we've gotten here, then everything seems to have gone smoothly.
    if (! quietInstall.isPresent())
    {
      Message message = INFO_INSTALLDS_STATUS_SUCCESS.get();
      System.out.println(wrapText(message, MAX_LINE_WIDTH));
    }
    return 0;
    uData.setEnableWindowsService(enableService);
  }
  /**
   * Interactively prompts (on standard output) the user to provide a Boolean
   * value.  The answer provided must be one of "true", "t", "yes", "y",
   * "false", "f", "no", or "n", ignoring capitalization.  It will keep
   * prompting until an acceptable value is given.
   *
   * @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 <CODE>boolean</CODE> value read from the user input.
   * This method updates the contents of a UserData object with what the user
   * specified in the command-line for the Directory Manager parameters.
   * If the user did not provide explicitly the data, it prompts the user to
   * provide it.
   * @param uData the UserData object to be updated.
   */
  private static boolean promptForBoolean(Message prompt, Boolean defaultValue)
  private void promptIfRequiredForStartServer(UserData uData)
  {
    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
    while (true)
    boolean startServer = false;
    if (!argParser.doNotStartArg.isPresent())
    {
      System.out.println();
      System.out.println(wrappedPrompt);
      printLineBreak();
      Message message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
      startServer = confirm(message);
    }
    uData.setStartServer(startServer);
  }
      if (defaultValue == null)
  /**
   * Checks that the provided parameters are valid to access an existing
   * keystore.  This method adds the encountered errors to the provided
   * list of Message.  It also adds the alias (nicknames) found to the provided
   * list of String.
   * @param type the type of keystore.
   * @param path the path of the keystore.
   * @param pwd the password (PIN) to access the keystore.
   * @param certNickname the certificate nickname that we are looking for (or
   * null if we just one to get the one that is in the keystore).
   * @param errorMessages the list that will be updated with the errors
   * encountered.
   * @param nicknameList the list that will be updated with the nicknames found
   * in the keystore.
   */
  private void checkCertificateInKeystore(SecurityOptions.CertificateType type,
      String path, String pwd, String certNickname,
      LinkedList<Message> errorMessages, LinkedList<String> nicknameList)
  {
    boolean errorWithPath = false;
    if (type != SecurityOptions.CertificateType.PKCS11)
    {
      File f = new File(path);
      if (!f.exists())
      {
        System.out.print(": ");
        errorMessages.add(INFO_KEYSTORE_PATH_DOES_NOT_EXIST.get());
        errorWithPath = true;
      }
      else
      else if (!f.isFile())
      {
        System.out.print("[");
        if (defaultValue)
        errorMessages.add(INFO_KEYSTORE_PATH_NOT_A_FILE.get());
        errorWithPath = true;
      }
    }
    if (!errorWithPath)
    {
      try
      {
        CertificateManager certManager;
        switch (type)
        {
          System.out.print(INFO_INSTALLDS_PROMPT_VALUE_YES.get());
          case JKS:
          certManager = new CertificateManager(
              path,
              CertificateManager.KEY_STORE_TYPE_JKS,
              pwd);
          break;
          case PKCS12:
          certManager = new CertificateManager(
              path,
              CertificateManager.KEY_STORE_TYPE_PKCS12,
              pwd);
          break;
          case PKCS11:
          certManager = new CertificateManager(
              CertificateManager.KEY_STORE_PATH_PKCS11,
              CertificateManager.KEY_STORE_TYPE_PKCS11,
              pwd);
          break;
          default:
            throw new IllegalArgumentException("Invalid type: "+type);
        }
        String[] aliases = certManager.getCertificateAliases();
        if ((aliases == null) || (aliases.length == 0))
        {
          // Could not retrieve any certificate
          switch (type)
          {
          case JKS:
            errorMessages.add(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST.get());
            break;
          case PKCS12:
            errorMessages.add(INFO_JKS_KEYSTORE_DOES_NOT_EXIST.get());
            break;
          case PKCS11:
            errorMessages.add(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST.get());
            break;
          default:
            throw new IllegalArgumentException("Invalid type: "+type);
          }
        }
        else
        {
          System.out.print(INFO_INSTALLDS_PROMPT_VALUE_NO.get());
          for (int i=0; i<aliases.length; i++)
          {
            nicknameList.add(aliases[i]);
          }
          String aliasString = Utils.getStringFromCollection(nicknameList,
              ", ");
          if (certNickname != null)
          {
            // Check if the cert alias is in the list.
            boolean found = false;
            for (int i=0; i<aliases.length && !found; i++)
            {
              found = aliases[i].equalsIgnoreCase(certNickname);
            }
            if (!found)
            {
              errorMessages.add(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND.get(
                  aliasString));
            }
          }
          else if (aliases.length > 1)
          {
            errorMessages.add(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME.get(
                aliasString));
          }
        }
        System.out.print("]: ");
      }
      System.out.flush();
      String response = toLowerCase(readLine());
      if (response.equals("true") || response.equals("yes") ||
          response.equals("t") || response.equals("y"))
      catch (KeyStoreException ke)
      {
        return true;
      }
      else if (response.equals("false") || response.equals("no") ||
               response.equals("f") || response.equals("n"))
      {
        return false;
      }
      else if (response.equals(""))
      {
        if (defaultValue == null)
        // Could not access to the keystore: because the password is no good,
        // because the provided file is not a valid keystore, etc.
        switch (type)
        {
          Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
        case JKS:
          errorMessages.add(INFO_ERROR_ACCESSING_JKS_KEYSTORE.get());
          break;
        case PKCS12:
          errorMessages.add(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE.get());
          break;
        case PKCS11:
          errorMessages.add(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE.get());
          break;
        default:
          throw new IllegalArgumentException("Invalid type: "+type);
        }
        else
        {
          return defaultValue;
        }
      }
      else
      {
        Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
      }
    }
  }
  /**
   * Creates a SecurityOptions object that corresponds to the provided
   * parameters.  If the parameters are not valid, it prompts the user to
   * provide them.
   * @param type the keystore type.
   * @param enableSSL whether to enable SSL or not.
   * @param enableStartTLS whether to enable StartTLS or not.
   * @param ldapsPort the LDAPS port to use.
   * @return a SecurityOptions object that corresponds to the provided
   * parameters (or to what the user provided after being prompted).
   */
  private SecurityOptions createSecurityOptionsPrompting(
      SecurityOptions.CertificateType type, boolean enableSSL,
      boolean enableStartTLS, int ldapsPort)
  {
    SecurityOptions securityOptions;
    String path;
    String certNickname = argParser.certNicknameArg.getValue();
    String pwd = argParser.getKeyStorePassword();
    Message pathPrompt;
    String defaultPathValue;
    switch (type)
    {
    case JKS:
      path = argParser.useJavaKeyStoreArg.getValue();
      pathPrompt = INFO_INSTALLDS_PROMPT_JKS_PATH.get();
      defaultPathValue = argParser.useJavaKeyStoreArg.getValue();
      break;
    case PKCS11:
      path = null;
      defaultPathValue = null;
      pathPrompt = null;
      break;
    case PKCS12:
      path = argParser.usePkcs12Arg.getValue();
      defaultPathValue = argParser.usePkcs12Arg.getValue();
      pathPrompt = INFO_INSTALLDS_PROMPT_PKCS12_PATH.get();
      break;
    default:
      throw new IllegalStateException(
          "Called promptIfRequiredCertificate with invalid type: "+type);
    }
    LinkedList<Message> errorMessages = new LinkedList<Message>();
    LinkedList<String> keystoreAliases = new LinkedList<String>();
    boolean firstTry = true;
    while ((errorMessages.size() > 0) || firstTry)
    {
      boolean prompted = false;
      if (errorMessages.size() > 0)
      {
        printLineBreak();
        printErrorMessage(Utils.getMessageFromCollection(errorMessages,
            formatter.getLineBreak().toString()));
      }
      if (type != SecurityOptions.CertificateType.PKCS11)
      {
        if (containsKeyStorePathErrorMessage(errorMessages) || (path == null))
        {
          printLineBreak();
          path = promptForString(pathPrompt, defaultPathValue);
          prompted = true;
          if (pwd != null)
          {
            errorMessages.clear();
            keystoreAliases.clear();
            checkCertificateInKeystore(type, path, pwd, certNickname,
                errorMessages, keystoreAliases);
            if (!errorMessages.isEmpty())
            {
              // Reset password: this might be a new keystore
              pwd = null;
            }
          }
        }
      }
      if (containsKeyStorePasswordErrorMessage(errorMessages) ||
          (pwd == null))
      {
        if (!prompted)
        {
          printLineBreak();
        }
        pwd = promptForPassword(
            INFO_INSTALLDS_PROMPT_KEYSTORE_PASSWORD.get());
      }
      if (containsCertNicknameErrorMessage(errorMessages))
      {
        if (!prompted)
        {
          printLineBreak();
        }
        certNickname = promptForCertificateNickname(keystoreAliases);
      }
      errorMessages.clear();
      keystoreAliases.clear();
      checkCertificateInKeystore(type, path, pwd, certNickname, errorMessages,
          keystoreAliases);
      firstTry = false;
    }
    if (certNickname == null)
    {
      certNickname = keystoreAliases.getFirst();
    }
    switch (type)
    {
      case JKS:
        securityOptions = SecurityOptions.createJKSCertificateOptions(
        path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
        break;
      case PKCS12:
        securityOptions = SecurityOptions.createPKCS12CertificateOptions(
            path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
        break;
      case PKCS11:
        securityOptions = SecurityOptions.createPKCS11CertificateOptions(
            pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
        break;
      default:
        throw new IllegalStateException(
            "Called createSecurityOptionsPrompting with invalid type: "+type);
    }
    return securityOptions;
  }
  /**
   * Tells if any of the error messages provided corresponds to a problem
   * with the key store path.
   * @param msgs the messages to analyze.
   * @return <CODE>true</CODE> if any of the error messages provided corresponds
   * to a problem with the key store path and <CODE>false</CODE> otherwise.
   */
  private boolean containsKeyStorePathErrorMessage(Collection<Message> msgs)
  {
    boolean found = false;
    for (Message msg : msgs)
    {
      if (msg.getDescriptor().equals(INFO_KEYSTORE_PATH_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_KEYSTORE_PATH_NOT_A_FILE) ||
          msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
      {
        found = true;
        break;
      }
    }
    return found;
  }
  /**
   * Tells if any of the error messages provided corresponds to a problem
   * with the key store password.
   * @param msgs the messages to analyze.
   * @return <CODE>true</CODE> if any of the error messages provided corresponds
   * to a problem with the key store password and <CODE>false</CODE> otherwise.
   */
  private boolean containsKeyStorePasswordErrorMessage(Collection<Message> msgs)
  {
    boolean found = false;
    for (Message msg : msgs)
    {
      if (msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
      {
        found = true;
        break;
      }
    }
    return found;
  }
  /**
   * Tells if any of the error messages provided corresponds to a problem
   * with the certificate nickname.
   * @param msgs the messages to analyze.
   * @return <CODE>true</CODE> if any of the error messages provided corresponds
   * to a problem with the certificate nickname and <CODE>false</CODE>
   * otherwise.
   */
  private boolean containsCertNicknameErrorMessage(Collection<Message> msgs)
  {
    boolean found = false;
    for (Message msg : msgs)
    {
      if (msg.getDescriptor().equals(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND) ||
          msg.getDescriptor().equals(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME))
      {
        found = true;
        break;
      }
    }
    return found;
  }
  /**
   * Interactively prompts (on standard output) the user to provide an integer
@@ -1190,308 +1664,81 @@
   *
   * @return  The <CODE>int</CODE> value read from the user input.
   */
  private static int promptForInteger(Message prompt, Integer defaultValue,
  private int promptForInteger(Message prompt, Integer defaultValue,
                                      Integer lowerBound, Integer upperBound)
  {
    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
    while (true)
    int returnValue = -1;
    while (returnValue == -1)
    {
      System.out.println();
      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(""))
      String s = promptForString(prompt, String.valueOf(defaultValue));
      if (s.equals(""))
      {
        if (defaultValue == null)
        {
          Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          printErrorMessage(message);
          printLineBreak();
        }
        else
        {
          return defaultValue;
          returnValue = defaultValue;
        }
      }
      else
      {
        try
        {
          int intValue = Integer.parseInt(response);
          int intValue = Integer.parseInt(s);
          if ((lowerBound != null) && (intValue < lowerBound))
          {
            Message message =
                ERR_INSTALLDS_INTEGER_BELOW_LOWER_BOUND.get(lowerBound);
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            printErrorMessage(message);
            printLineBreak();
          }
          else if ((upperBound != null) && (intValue > upperBound))
          {
            Message message =
                ERR_INSTALLDS_INTEGER_ABOVE_UPPER_BOUND.get(upperBound);
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
            printErrorMessage(message);
            printLineBreak();
          }
          else
          {
            return intValue;
            returnValue = intValue;
          }
        }
        catch (NumberFormatException nfe)
        {
          Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
          printErrorMessage(message);
          printLineBreak();
        }
      }
    }
    return returnValue;
  }
  /**
   * Interactively prompts (on standard output) the user to provide a DN value.
   * Any non-empty string will be allowed if it can be parsed as a valid DN (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 DN value read from the user.
   * Prompts the user to accept on the certificates that appears on the list
   * and returns the chosen certificate nickname.
   * @param nicknames the list of certificates the user must choose from.
   * @return the chosen certificate nickname.
   */
  private static DN promptForDN(Message prompt, String defaultValue)
  private String promptForCertificateNickname(LinkedList<String> nicknames)
  {
    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
    while (true)
    String nickname = null;
    while (nickname == null)
    {
      System.out.println();
      System.out.println(wrappedPrompt);
      if (defaultValue == null)
      for (String n : nicknames)
      {
        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)
        if (confirm(INFO_INSTALLDS_PROMPT_CERTNICKNAME.get(n)))
        {
          Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
        }
        else
        {
          try
          {
            return DN.decode(defaultValue);
          }
          catch (Exception e)
          {
            Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
            System.err.println(wrapText(message, MAX_LINE_WIDTH));
          }
        }
      }
      else
      {
        try
        {
          return DN.decode(response);
        }
        catch (Exception e)
        {
          Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
        }
      }
    }
  }
  /**
   * 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.
   */
  private static String promptForString(Message prompt, String defaultValue)
  {
      System.out.println();
    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
    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)
        {
          Message message = ERR_INSTALLDS_INVALID_STRING_RESPONSE.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
        }
        else
        {
          return defaultValue;
        }
      }
      else
      {
        return response;
      }
    }
  }
  /**
   * Interactively prompts (on standard output) the user to provide a string
   * value.  The response that the user provides will not be echoed, and it must
   * be entered twice for confirmation.  No default value will be allowed, and
   * the string entered must contain at least one character.
   *
   * @param  initialPrompt  The initial prompt to present to the user.
   * @param  reEntryPrompt  The prompt to present to the user when requesting
   *                        that the value be re-entered for confirmation.
   *
   * @return  The string value read from the user.
   */
  private static char[] promptForPassword(Message initialPrompt,
                                          Message reEntryPrompt)
  {
    String wrappedInitialPrompt = wrapText(initialPrompt, MAX_LINE_WIDTH);
    String wrappedReEntryPrompt = wrapText(reEntryPrompt, MAX_LINE_WIDTH);
    while (true)
    {
      System.out.println();
      System.out.print(wrappedInitialPrompt);
      System.out.print(": ");
      System.out.flush();
      char[] password = PasswordReader.readPassword();
      if ((password == null) || (password.length == 0))
      {
        Message message = ERR_INSTALLDS_INVALID_PASSWORD_RESPONSE.get();
        System.err.println(wrapText(message, MAX_LINE_WIDTH));
      }
      else
      {
        System.out.print(wrappedReEntryPrompt);
        System.out.print(": ");
        System.out.flush();
        char[] confirmedPassword = PasswordReader.readPassword();
        if ((confirmedPassword == null) ||
            (! Arrays.equals(password, confirmedPassword)))
        {
          Message message = ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get();
          System.err.println(wrapText(message, MAX_LINE_WIDTH));
        }
        else
        {
          return password;
        }
      }
    }
  }
  /**
   * 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 static String readLine()
  {
    try
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      while (true)
      {
        int b = System.in.read();
        if ((b < 0) || (b == '\n'))
        {
          nickname = 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)
    {
      Message message =
          ERR_INSTALLDS_ERROR_READING_FROM_STDIN.get(String.valueOf(e));
      System.err.println(wrapText(message, MAX_LINE_WIDTH));
      return null;
    }
    return nickname;
  }
}
opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
New file
@@ -0,0 +1,604 @@
/*
 * 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.server.tools;
import static org.opends.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.opends.messages.Message;
import org.opends.quicksetup.Constants;
import org.opends.quicksetup.Installation;
import org.opends.quicksetup.util.Utils;
import org.opends.server.extensions.ConfigFileHandler;
import org.opends.server.util.SetupUtils;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentParser;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.args.IntegerArgument;
import org.opends.server.util.args.StringArgument;
/**
 * Class used to parse the arguments of the setup command-line and to check
 * that there are not conflicting arguments (nor missing arguments in no prompt
 * mode).
 * Note that this class does not perform checks involving network (like if
 * a given port is free) nor the validity of the certificate information
 * provided.
 */
class InstallDSArgumentParser extends ArgumentParser
{
  BooleanArgument   testOnlyArg;
  BooleanArgument   addBaseEntryArg;
  BooleanArgument   showUsageArg;
  BooleanArgument   quietArg;
  BooleanArgument   noPromptArg;
  BooleanArgument   skipPortCheckArg;
  BooleanArgument   enableWindowsServiceArg;
  BooleanArgument   doNotStartArg;
  BooleanArgument   enableStartTLSArg;
  BooleanArgument   generateSelfSignedCertificateArg;
  BooleanArgument   usePkcs11Arg;
  FileBasedArgument directoryManagerPwdFileArg;
  FileBasedArgument keyStorePasswordFileArg;
  IntegerArgument   ldapPortArg;
  IntegerArgument   ldapsPortArg;
  IntegerArgument   jmxPortArg;
  IntegerArgument   sampleDataArg;
  StringArgument    baseDNArg;
  StringArgument    configClassArg;
  StringArgument    configFileArg;
  StringArgument    importLDIFArg;
  StringArgument    directoryManagerDNArg;
  StringArgument    directoryManagerPwdStringArg;
  StringArgument    useJavaKeyStoreArg;
  StringArgument    usePkcs12Arg;
  StringArgument    keyStorePasswordArg;
  StringArgument    certNicknameArg;
  StringArgument    progNameArg;
  private static final Logger LOG = Logger.getLogger(
      InstallDSArgumentParser.class.getName());
  /**
   * The default constructor for this class.
   * @param mainClassName the class name of the main class for the command-line
   * that is being used.
   */
  public InstallDSArgumentParser(String mainClassName)
  {
    super(mainClassName, INFO_INSTALLDS_TOOL_DESCRIPTION.get(), false);
  }
  /**
   * Initializes the arguments without parsing them.
   * @throws ArgumentException if there was an error creating or adding the
   * arguments.  If this occurs is likely to be a bug.
   */
  public void initializeArguments() throws ArgumentException
  {
    testOnlyArg = new BooleanArgument(
        "test", 't', "testOnly",
        INFO_INSTALLDS_DESCRIPTION_TESTONLY.get());
    testOnlyArg.setHidden(true);
    addArgument(testOnlyArg);
    configFileArg = new StringArgument(
        "configfile", 'c', "configFile", false,
        false, true, "{configFile}", getDefaultConfigFile(), null,
        INFO_DESCRIPTION_CONFIG_FILE.get());
    configFileArg.setHidden(true);
    addArgument(configFileArg);
    configClassArg = new StringArgument(
        "configclass", OPTION_SHORT_CONFIG_CLASS,
        OPTION_LONG_CONFIG_CLASS, false,
        false, true, OPTION_VALUE_CONFIG_CLASS,
        ConfigFileHandler.class.getName(), null,
        INFO_DESCRIPTION_CONFIG_CLASS.get());
    configClassArg.setHidden(true);
    addArgument(configClassArg);
    String defaultProgName;
    if (SetupUtils.isWindows())
    {
      defaultProgName = Installation.WINDOWS_SETUP_FILE_NAME;
    }
    else
    {
      defaultProgName = Installation.UNIX_SETUP_FILE_NAME;
    }
    progNameArg = new StringArgument(
        "progname", 'P', "programName", false,
        false, true, "{programName}", defaultProgName,
        null, INFO_INSTALLDS_DESCRIPTION_PROGNAME.get());
    progNameArg.setHidden(true);
    addArgument(progNameArg);
    quietArg = new BooleanArgument(
        "quiet", OPTION_SHORT_QUIET,
        OPTION_LONG_QUIET,
        INFO_INSTALLDS_DESCRIPTION_SILENT.get());
    addArgument(quietArg);
    noPromptArg = new BooleanArgument(
        OPTION_LONG_NO_PROMPT,
        OPTION_SHORT_NO_PROMPT,
        OPTION_LONG_NO_PROMPT,
        INFO_INSTALLDS_DESCRIPTION_NO_PROMPT.get());
    addArgument(noPromptArg);
    baseDNArg = new StringArgument(
        "basedn", OPTION_SHORT_BASEDN,
        OPTION_LONG_BASEDN, false, true, true,
        OPTION_VALUE_BASEDN,
        "dc=example,dc=com", null,
        INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
    addArgument(baseDNArg);
    addBaseEntryArg = new BooleanArgument(
        "addbase", 'a', "addBaseEntry",
        INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
    addArgument(addBaseEntryArg);
    importLDIFArg = new StringArgument(
        "importldif", OPTION_SHORT_LDIF_FILE,
        OPTION_LONG_LDIF_FILE, false,
        true, true, OPTION_VALUE_LDIF_FILE,
        null, null,
        INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
    addArgument(importLDIFArg);
    sampleDataArg = new IntegerArgument(
        "sampledata", 'd', "sampleData", false,
        false, true, "{numEntries}", 0, null,
        true, 0, false, 0,
        INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
    addArgument(sampleDataArg);
    ldapPortArg = new IntegerArgument(
        "ldapport", OPTION_SHORT_PORT,
        "ldapPort", false, false,
        true, OPTION_VALUE_PORT, 389,
        null, true, 1, true, 65535,
        INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
    addArgument(ldapPortArg);
    jmxPortArg = new IntegerArgument(
        "jmxport", 'x', "jmxPort", false, false,
        true, "{jmxPort}",
        SetupUtils.getDefaultJMXPort(), null, true,
        1, true, 65535,
        INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
    addArgument(jmxPortArg);
    skipPortCheckArg = new BooleanArgument(
        "skipportcheck", 'S', "skipPortCheck",
        INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
    addArgument(skipPortCheckArg);
    directoryManagerDNArg = new StringArgument(
        "rootdn",OPTION_SHORT_ROOT_USER_DN,
        OPTION_LONG_ROOT_USER_DN, false, false,
        true, OPTION_VALUE_ROOT_USER_DN,
        "cn=Directory Manager",
        null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
    addArgument(directoryManagerDNArg);
    directoryManagerPwdStringArg = new StringArgument(
        "rootpwstring", OPTION_SHORT_BINDPWD,
        "rootUserPassword",
        false, false, true,
        "{password}", null,
        null,
        INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
    addArgument(directoryManagerPwdStringArg);
    directoryManagerPwdFileArg = new FileBasedArgument(
        "rootpwfile",
        OPTION_SHORT_BINDPWD_FILE,
        "rootUserPasswordFile", false, false,
        OPTION_VALUE_BINDPWD_FILE,
        null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
    addArgument(directoryManagerPwdFileArg);
    enableWindowsServiceArg = new BooleanArgument(
        "enablewindowsservice", 'e',
        "enableWindowsService",
        INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
    if (SetupUtils.isWindows())
    {
      addArgument(enableWindowsServiceArg);
    }
    doNotStartArg = new BooleanArgument(
        "donotstart", 'O', "donotstart",
        INFO_INSTALLDS_DESCRIPTION_DO_NOT_START.get());
    addArgument(doNotStartArg);
    enableStartTLSArg = new BooleanArgument(
        "enableStartTLS", OPTION_SHORT_START_TLS, "enableStartTLS",
        INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS.get());
    addArgument(enableStartTLSArg);
    ldapsPortArg = new IntegerArgument(
        "ldapsport", OPTION_SHORT_USE_SSL,
        "ldapsPort", false, false,
        true, OPTION_VALUE_PORT, 636,
        null, true, 1, true, 65535,
        INFO_INSTALLDS_DESCRIPTION_LDAPSPORT.get());
    addArgument(ldapsPortArg);
    generateSelfSignedCertificateArg = new BooleanArgument(
        "generateSelfSignedCertificate",
        null, "generateSelfSignedCertificate",
        INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED.get());
    addArgument(generateSelfSignedCertificateArg);
    usePkcs11Arg = new BooleanArgument("usePkcs11Keystore",
        null, "usePkcs11Keystore",
        INFO_INSTALLDS_DESCRIPTION_USE_PKCS11.get());
    addArgument(usePkcs11Arg);
    useJavaKeyStoreArg = new StringArgument("useJavaKeystore",
        null, "useJavaKeystore", false, false,
        true, OPTION_VALUE_KEYSTOREPATH, null, null,
        INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE.get());
    addArgument(useJavaKeyStoreArg);
    usePkcs12Arg = new StringArgument("usePkcs12keyStore",
        null, "usePkcs12keyStore", false, false,
        true, OPTION_VALUE_KEYSTOREPATH, null, null,
        INFO_INSTALLDS_DESCRIPTION_USE_PKCS12.get());
    addArgument(usePkcs12Arg);
    keyStorePasswordArg = new StringArgument("keystorePassword",
        OPTION_SHORT_KEYSTORE_PWD,
        OPTION_LONG_KEYSTORE_PWD, false, false, true,
        OPTION_VALUE_KEYSTORE_PWD, null, null,
        INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD.get());
    addArgument(keyStorePasswordArg);
    keyStorePasswordFileArg = new FileBasedArgument("keystorePasswordFile",
        OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false,
        false, OPTION_VALUE_KEYSTORE_PWD_FILE, null, null,
        INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE.get());
    addArgument(keyStorePasswordFileArg);
    certNicknameArg = new StringArgument("certnickname",
        OPTION_SHORT_CERT_NICKNAME, OPTION_LONG_CERT_NICKNAME,
        false, false, true, OPTION_VALUE_CERT_NICKNAME, null, null,
        INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME.get());
    addArgument(certNicknameArg);
    showUsageArg = new BooleanArgument("help", OPTION_SHORT_HELP,
        OPTION_LONG_HELP,
        INFO_INSTALLDS_DESCRIPTION_HELP.get());
    addArgument(showUsageArg);
    setUsageArgument(showUsageArg);
  }
  /**
   * {@inheritDoc}
   */
  @Override()
  public void parseArguments(String[] args) throws ArgumentException
  {
    LinkedHashSet<Message> errorMessages = new LinkedHashSet<Message>();
    try
    {
      super.parseArguments(args);
    }
    catch (ArgumentException ae)
    {
      LOG.log(Level.SEVERE, "Error parsing arguments: "+ae, ae);
      errorMessages.add(ae.getMessageObject());
    }
    checkConfigFileArg(errorMessages);
    checkServerPassword(errorMessages);
    checkProvidedPorts(errorMessages);
    checkImportDataArguments(errorMessages);
    checkSecurityArguments(errorMessages);
    if (errorMessages.size() > 0)
    {
      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(
          Utils.getMessageFromCollection(errorMessages,
              Constants.LINE_SEPARATOR));
      throw new ArgumentException(message);
    }
  }
  /**
   * Returns the directory manager password provided by the user.  This method
   * should be called after a call to parseArguments.
   * @return the directory manager password provided by the user.
   */
  public String getDirectoryManagerPassword()
  {
    String pwd = null;
    if (directoryManagerPwdStringArg.isPresent())
    {
      pwd = directoryManagerPwdStringArg.getValue();
    }
    else if (directoryManagerPwdFileArg.isPresent())
    {
      pwd = directoryManagerPwdFileArg.getValue();
    }
    return pwd;
  }
  /**
   * Returns the key store password provided by the user.  This method should be
   * called after a call to parseArguments.
   * @return the key store password provided by the user.
   */
  public String getKeyStorePassword()
  {
    String pwd = null;
    if (keyStorePasswordArg.isPresent())
    {
      pwd = keyStorePasswordArg.getValue();
    }
    else if (keyStorePasswordArg.isPresent())
    {
      pwd = keyStorePasswordFileArg.getValue();
    }
    return pwd;
  }
  /**
   * Checks that we have a config file value (at least the default value).
   * @param errorMessages the list of messages to which we add the error
   * messages describing the problems encountered during the execution of the
   * checking.
   */
  private void checkConfigFileArg(Collection<Message> errorMessages)
  {
    //  Make sure the path to the configuration file was given.
    if (configFileArg.getValue() == null)
    {
      Message message = ERR_INSTALLDS_NO_CONFIG_FILE.get(
              configFileArg.getLongIdentifier());
      errorMessages.add(message);
    }
  }
  /**
   * Checks that there are no conflicts with the directory manager passwords.
   * If we are in no prompt mode, check that the password was provided.
   * @param errorMessages the list of messages to which we add the error
   * messages describing the problems encountered during the execution of the
   * checking.
   */
  private void checkServerPassword(Collection<Message> errorMessages)
  {
    if (directoryManagerPwdStringArg.isPresent() &&
        directoryManagerPwdFileArg.isPresent())
    {
      Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
          directoryManagerPwdStringArg.getLongIdentifier(),
          directoryManagerPwdFileArg.getLongIdentifier());
      errorMessages.add(message);
    }
    if (noPromptArg.isPresent() && !directoryManagerPwdStringArg.isPresent() &&
        !directoryManagerPwdFileArg.isPresent())
    {
      Message message = ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
          directoryManagerPwdStringArg.getLongIdentifier(),
          directoryManagerPwdFileArg.getLongIdentifier());
      errorMessages.add(message);
    }
  }
  /**
   * Checks that there are no conflicts with the provided ports (like if the
   * user provided the same port for different protocols).
   * @param errorMessages the list of messages to which we add the error
   * messages describing the problems encountered during the execution of the
   * checking.
   */
  private void checkProvidedPorts(Collection<Message> errorMessages)
  {
    /**
     * Check that the provided ports do not match.
     */
    try
    {
      Set<Integer> ports = new HashSet<Integer>();
      ports.add(ldapPortArg.getIntValue());
      if (jmxPortArg.isPresent())
      {
        if (ports.contains(jmxPortArg.getIntValue()))
        {
          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
                  String.valueOf(jmxPortArg.getIntValue()));
          errorMessages.add(message);
        }
        else
        {
          ports.add(jmxPortArg.getIntValue());
        }
      }
      if (ldapsPortArg.isPresent())
      {
        if (ports.contains(ldapsPortArg.getIntValue()))
        {
          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
                  String.valueOf(ldapsPortArg.getIntValue()));
          errorMessages.add(message);
        }
        else
        {
          ports.add(ldapsPortArg.getIntValue());
        }
      }
    }
    catch (ArgumentException ae)
    {
      LOG.log(Level.SEVERE, "Unexpected error.  "+
          "Assuming that it is caused by a previous parsing issue: "+ae, ae);
    }
  }
  /**
   * Checks that there are no conflicts with the import data arguments.
   * @param errorMessages the list of messages to which we add the error
   * messages describing the problems encountered during the execution of the
   * checking.
   */
  private void checkImportDataArguments(Collection<Message> errorMessages)
  {
    //  Make sure that the user didn't provide conflicting arguments.
    if (addBaseEntryArg.isPresent())
    {
      if (importLDIFArg.isPresent())
      {
        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
                addBaseEntryArg.getLongIdentifier(),
                importLDIFArg.getLongIdentifier());
        errorMessages.add(message);
      }
      else if (sampleDataArg.isPresent())
      {
        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
                addBaseEntryArg.getLongIdentifier(),
                sampleDataArg.getLongIdentifier());
        errorMessages.add(message);
      }
    }
    else if (importLDIFArg.isPresent() && sampleDataArg.isPresent())
    {
      Message message = ERR_TOOL_CONFLICTING_ARGS.get(
              importLDIFArg.getLongIdentifier(),
              sampleDataArg.getLongIdentifier());
      errorMessages.add(message);
    }
  }
  /**
   * Checks that there are no conflicts with the security arguments.
   * If we are in no prompt mode, check that all the information required has
   * been provided (but not if this information is valid: we do not try to
   * open the keystores or to check that the LDAPS port is in use).
   * @param errorMessages the list of messages to which we add the error
   * messages describing the problems encountered during the execution of the
   * checking.
   */
  private void checkSecurityArguments(Collection<Message> errorMessages)
  {
    boolean certificateRequired = ldapsPortArg.isPresent() ||
    enableStartTLSArg.isPresent();
    int certificateType = 0;
    if (generateSelfSignedCertificateArg.isPresent())
    {
      certificateType++;
    }
    if (useJavaKeyStoreArg.isPresent())
    {
      certificateType++;
    }
    if (usePkcs11Arg.isPresent())
    {
      certificateType++;
    }
    if (usePkcs12Arg.isPresent())
    {
      certificateType++;
    }
    if (certificateType > 1)
    {
      errorMessages.add(ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED.get());
    }
    if (certificateRequired && noPromptArg.isPresent() &&
        (certificateType == 0))
    {
      errorMessages.add(
          ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS.get());
    }
    if (certificateType == 1)
    {
      if (!generateSelfSignedCertificateArg.isPresent())
      {
        // Check that we have only a password.
        if (keyStorePasswordArg.isPresent() &&
            keyStorePasswordFileArg.isPresent())
        {
          Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
              keyStorePasswordArg.getLongIdentifier(),
              keyStorePasswordFileArg.getLongIdentifier());
          errorMessages.add(message);
        }
        // Check that we have one password in no prompt mode.
        if (noPromptArg.isPresent() && !keyStorePasswordArg.isPresent() &&
            !keyStorePasswordFileArg.isPresent())
        {
          Message message = ERR_INSTALLDS_NO_KEYSTORE_PASSWORD.get(
              keyStorePasswordArg.getLongIdentifier(),
              keyStorePasswordFileArg.getLongIdentifier());
          errorMessages.add(message);
        }
      }
      if (noPromptArg.isPresent() && !ldapsPortArg.isPresent() &&
          !enableStartTLSArg.isPresent())
      {
        Message message = ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED.get(
            ldapsPortArg.getLongIdentifier(),
            enableStartTLSArg.getLongIdentifier());
        errorMessages.add(message);
      }
    }
  }
  /**
   * Returns the default config file retrieved by inspecting the class loader.
   * @return the default config file retrieved by inspecting the class loader.
   */
  private String getDefaultConfigFile()
  {
    // Use this instead of Installation.getLocal() because making that call
    // starts a new JVM and the command-line becomes less responsive.
    String root = Utils.getInstallPathFromClasspath();
    String configDir = Utils.getPath(root, Installation.CONFIG_PATH_RELATIVE);
    return Utils.getPath(configDir, Installation.CURRENT_CONFIG_FILE_NAME);
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java
@@ -95,14 +95,14 @@
    } else {
      args.add(new File(root, "setup.bat").getPath());
    }
    args.add("--cli");
    args.add("-Q");
    args.add("-n");
    args.add("-p");
    args.add(Integer.toString(ldapPort));
    args.add("-x");
    args.add(Integer.toString(jmxPort));
    args.add("-w");
    args.add(DIRECTORY_MANAGER_PASSWORD);
    args.add("-O");
    ProcessBuilder pb = new ProcessBuilder(args);
    Process p = pb.start();