()
{
@Override
public Boolean validate(ConsoleApplication app, String input)
{
String ninput = input.toLowerCase().trim();
if (ninput.length() == 0)
{
return defaultValue;
}
else if (no.toString().toLowerCase().startsWith(ninput))
{
return false;
}
else if (yes.toString().toLowerCase().startsWith(ninput))
{
return true;
}
else
{
// Try again...
app.println();
app.println(errMsg);
app.println();
}
return null;
}
};
return readValidatedInput(prompt, validator, CONFIRMATION_MAX_TRIES);
}
/**
* Gets the application error stream.
*
* @return Returns the application error stream.
*/
public final PrintStream getErrorStream()
{
return err;
}
/**
* Gets the application input stream.
*
* @return Returns the application input stream.
*/
public final BufferedReader getInputStream()
{
return in;
}
/**
* Gets the application output stream.
*
* @return Returns the application output stream.
*/
public final PrintStream getOutputStream()
{
return out;
}
/**
* Indicates whether or not the user has requested advanced mode.
*
* @return Returns true
if the user has requested advanced mode.
*/
public abstract boolean isAdvancedMode();
/**
* Indicates whether or not the user has requested interactive behavior.
*
* @return Returns true
if the user has requested interactive
* behavior.
*/
public abstract boolean isInteractive();
/**
* Indicates whether or not this console application is running in its
* menu-driven mode. This can be used to dictate whether output should go to
* the error stream or not. In addition, it may also dictate whether or not
* sub-menus should display a cancel option as well as a quit option.
*
* @return Returns true
if this console application is running in
* its menu-driven mode.
*/
public abstract boolean isMenuDrivenMode();
/**
* Indicates whether or not the user has requested quiet output.
*
* @return Returns true
if the user has requested quiet output.
*/
public abstract boolean isQuiet();
/**
* Indicates whether or not the user has requested script-friendly output.
*
* @return Returns true
if the user has requested script-friendly
* output.
*/
public abstract boolean isScriptFriendly();
/**
* Indicates whether or not the user has requested verbose output.
*
* @return Returns true
if the user has requested verbose output.
*/
public abstract boolean isVerbose();
/**
* Interactively prompts the user to press return to continue. This method
* should be called in situations where a user needs to be given a chance to
* read some documentation before continuing (continuing may cause the
* documentation to be scrolled out of view).
*/
public final void pressReturnToContinue()
{
Message msg = INFO_MENU_PROMPT_RETURN_TO_CONTINUE.get();
try
{
readLineOfInput(msg);
}
catch (CLIException e)
{
// Ignore the exception - applications don't care.
}
}
/**
* Displays a blank line to the error stream.
*/
public final void println()
{
err.println();
}
/**
* Displays a message to the error stream.
*
* @param msg
* The message.
*/
public final void println(Message msg)
{
err.println(wrapText(msg, MAX_LINE_WIDTH));
}
/**
* Displays a message to the error stream.
*
* @param msg
* The message.
*/
public final void print(Message msg)
{
err.print(wrapText(msg, MAX_LINE_WIDTH));
}
/**
* Print a line with EOL in the output stream.
*
* @param msg
* The message to display in normal mode.
* @param indent
* The indentation.
*/
public final void println(final Message msg, final int indent)
{
println(Style.NORMAL, msg, indent);
}
/**
* Print a line with EOL in the output stream.
*
* @param msgStyle
* The type of formatted output desired.
* @param msg
* The message to display in normal mode.
* @param indent
* The indentation.
*/
public final void println(final Style msgStyle, final Message msg,
final int indent)
{
if (!isQuiet())
{
switch (msgStyle)
{
case TITLE:
out.println();
out.println(">>>> " + wrapText(msg, MAX_LINE_WIDTH, indent));
out.println();
break;
case SUBTITLE:
out.println(wrapText(msg, MAX_LINE_WIDTH, indent));
out.println();
break;
case NOTICE:
out.println(wrapText("* " + msg, MAX_LINE_WIDTH, indent));
break;
case ERROR:
out.println();
out.println(wrapText("** " + msg, MAX_LINE_WIDTH, indent));
out.println();
break;
case WARNING:
out.println(wrapText("[!] " + msg, MAX_LINE_WIDTH, indent));
break;
default:
out.println(wrapText(msg, MAX_LINE_WIDTH, indent));
break;
}
}
}
/**
* Displays a blank line to the output stream if we are not in quiet mode.
*/
public final void printlnProgress()
{
if (!isQuiet())
{
out.println();
}
}
/**
* Displays a message to the output stream if we are not in quiet mode.
* Message is wrap to max line width.
*
* @param msg
* The message.
*/
public final void printlnProgress(Message msg)
{
if (!isQuiet())
{
out.println(wrapText(msg, MAX_LINE_WIDTH));
}
}
/**
* Displays a message to the output stream if we are not in quiet mode.
*
* @param msg
* The message.
*/
public final void printProgress(final Message msg)
{
if (!isQuiet())
{
out.print(msg);
}
}
/**
* Prints a progress bar on the same output stream line if not in quiet mode.
*
*
* Like
* msg...... 50%
* if progress is up to 100 :
* msg..................... 100%
* if progress is < 0 :
* msg.... FAIL
* msg..................... FAIL
*
*
* @param linePos
* The progress bar starts at this position on the line.
* @param progress
* The current percentage progress to print.
*/
private final void printProgressBar(final int linePos, final int progress)
{
if (!isQuiet())
{
final int spacesLeft = MAX_LINE_WIDTH - linePos - 10;
StringBuilder bar = new StringBuilder();
if (progress != 0)
{
for (int i = 0; i < PROGRESS_LINE; i++)
{
if (i < (Math.abs(progress) * spacesLeft) / 100
&& bar.length() < spacesLeft)
{
bar.append(".");
}
}
}
bar.append(". ");
if (progress >= 0)
{
bar.append(progress).append("% ");
}
else
{
bar.append("FAIL");
isProgressSuite = false;
}
final int endBuilder = linePos + bar.length();
for (int i = 0; i < endBuilder; i++)
{
bar.append("\b");
}
if (progress >= 100 || progress < 0)
{
bar.append(EOL);
isProgressSuite = false;
}
out.print(bar.toString());
}
}
/**
* Prints a progress bar on the same output stream line if not in quiet mode.
* If the line's length is upper than the limit, the message is wrapped and
* the progress bar is affected to the last one. e.g.
*
*
* Changing matching rule for 'userCertificate' and 'caCertificate' to
* CertificateExactMatch........................................... 100%
*
*
* @param msg
* The message to display before the progress line.
* @param progress
* The current percentage progress to print.
* @param indent
* Indentation of the message.
*/
public final void printProgressBar(String msg, final int progress,
final int indent)
{
if (!isQuiet())
{
String msgToDisplay = wrapText(msg, PROGRESS_LINE, indent);
if (msgToDisplay.length() > PROGRESS_LINE)
{
final String[] msgWrapped = msgToDisplay.split(EOL);
if (!isProgressSuite)
{
for (int pos = 0; pos < msgWrapped.length - 1; pos++)
{
println(Message.raw(msgWrapped[pos]));
}
isProgressSuite = true;
}
msgToDisplay = msgWrapped[msgWrapped.length - 1];
}
print(Message.raw(msgToDisplay));
printProgressBar(msgToDisplay.length(), progress);
}
}
/**
* Display the batch progress string to the error stream, if we are not in
* quiet mode.
*
* @param s
* The string to display
*/
public final void printlnBatchProgress(String s)
{
if (!isQuiet())
{
err.println(s);
}
}
/**
* Displays a message to the error stream indented by the specified number of
* columns.
*
* @param msg
* The message.
* @param indent
* The number of columns to indent.
*/
public final void printErrln(Message msg, int indent)
{
err.println(wrapText(msg, MAX_LINE_WIDTH, indent));
}
/**
* Displays a message to the error stream if verbose mode is enabled.
*
* @param msg
* The verbose message.
*/
public final void printVerboseMessage(Message msg)
{
if (isVerbose() || isInteractive())
{
err.println(wrapText(msg, MAX_LINE_WIDTH));
}
}
/**
* Interactively retrieves a line of input from the console.
*
* @param prompt
* The prompt.
* @return Returns the line of input, or null
if the end of input
* has been reached.
* @throws CLIException
* If the line of input could not be retrieved for some reason.
*/
public final String readLineOfInput(Message prompt) throws CLIException
{
if (prompt != null)
{
err.print(wrapText(prompt, MAX_LINE_WIDTH));
err.print(" ");
}
try
{
String s = in.readLine();
if (s == null)
{
throw CLIException
.adaptInputException(new EOFException("End of input"));
}
else
{
return s;
}
}
catch (IOException e)
{
throw CLIException.adaptInputException(e);
}
}
/**
* Displays a message and read the user's input from output.
*
* @param prompt
* The message to display.
* @param defaultValue
* The default answer by default.
* @param msgStyle
* The formatted style chosen.
* @return The user's input as a string.
* @throws CLIException
* If an Exception occurs during the process.
*/
public final String readInput(final Message prompt,
final String defaultValue, final Style msgStyle)
throws CLIException
{
String answer = null;
final Message messageToDisplay =
INFO_PROMPT_SINGLE_DEFAULT.get(prompt.toString(), defaultValue);
if (msgStyle == Style.TITLE)
{
println();
}
print(messageToDisplay);
out.print(" ");
try
{
// Reads the user input.
answer = in.readLine();
}
catch (IOException e)
{
throw CLIException.adaptInputException(e);
}
if (msgStyle == Style.TITLE
|| msgStyle == Style.SUBTITLE)
{
println();
}
if ("".equals(answer))
{
if (defaultValue == null)
{
println(INFO_ERROR_EMPTY_RESPONSE.get());
}
else
{
return defaultValue;
}
}
return answer;
}
/**
* Commodity method that interactively prompts (on error 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 null
if there should not be a
* default and the user must explicitly provide a value.
* @throws CLIException
* If the line of input could not be retrieved for some reason.
* @return The string value read from the user.
*/
public String readInput(Message prompt, String defaultValue)
throws CLIException
{
while (true)
{
if (defaultValue != null)
{
prompt =
INFO_PROMPT_SINGLE_DEFAULT.get(prompt.toString(), defaultValue);
}
String response = readLineOfInput(prompt);
if ("".equals(response))
{
if (defaultValue == null)
{
println(INFO_ERROR_EMPTY_RESPONSE.get());
}
else
{
return defaultValue;
}
}
else
{
return response;
}
}
}
/**
* Commodity method that interactively prompts (on error 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). If
* an error occurs a message will be logged to the provided logger.
*
* @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 null
if there should not be a
* default and the user must explicitly provide a value.
* @param logger
* the Logger to be used to log the error message.
* @return The string value read from the user.
*/
public String readInput(Message prompt, String defaultValue, Logger logger)
{
String s = defaultValue;
try
{
s = readInput(prompt, defaultValue);
}
catch (CLIException ce)
{
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
}
return s;
}
/**
* Interactively retrieves a password from the console.
*
* @param prompt
* The password prompt.
* @return Returns the password.
* @throws CLIException
* If the password could not be retrieved for some reason.
*/
public final String readPassword(Message prompt) throws CLIException
{
err.print(wrapText(prompt + " ", MAX_LINE_WIDTH));
char[] pwChars;
try
{
pwChars = PasswordReader.readPassword();
}
catch (Exception e)
{
throw CLIException.adaptInputException(e);
}
return new String(pwChars);
}
/**
* Commodity method that interactively retrieves a password from the console.
* If there is an error an error message is logged to the provided Logger and
* null
is returned.
*
* @param prompt
* The password prompt.
* @param logger
* the Logger to be used to log the error message.
* @return Returns the password.
*/
protected final String readPassword(Message prompt, Logger logger)
{
String pwd = null;
try
{
pwd = readPassword(prompt);
}
catch (CLIException ce)
{
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
}
return pwd;
}
/**
* Interactively retrieves a port value from the console.
*
* @param prompt
* The port prompt.
* @param defaultValue
* The port default value.
* @return Returns the port.
* @throws CLIException
* If the port could not be retrieved for some reason.
*/
public final int readPort(Message prompt, final int defaultValue)
throws CLIException
{
ValidationCallback callback = new ValidationCallback()
{
@Override
public Integer validate(ConsoleApplication app, String input)
throws CLIException
{
String ninput = input.trim();
if (ninput.length() == 0)
{
return defaultValue;
}
else
{
try
{
int i = Integer.parseInt(ninput);
if (i < 1 || i > 65535)
{
throw new NumberFormatException();
}
return i;
}
catch (NumberFormatException e)
{
// Try again...
app.println();
app.println(ERR_LDAP_CONN_BAD_PORT_NUMBER.get(ninput));
app.println();
return null;
}
}
}
};
if (defaultValue != -1)
{
prompt =
INFO_PROMPT_SINGLE_DEFAULT.get(prompt.toString(), String
.valueOf(defaultValue));
}
return readValidatedInput(prompt, callback, CONFIRMATION_MAX_TRIES);
}
/**
* Returns a message object for the given NamingException.
*
* @param ne
* the NamingException.
* @param hostPort
* the hostPort representation of the server we were contacting when
* the NamingException occurred.
* @return a message object for the given NamingException.
*/
protected Message getMessageForException(NamingException ne, String hostPort)
{
return Utils.getMessageForException(ne, hostPort);
}
/**
* Commodity method used to repeatidly ask the user to provide a port value.
*
* @param prompt
* the prompt message.
* @param defaultValue
* the default value of the port to be proposed to the user.
* @param logger
* the logger where the errors will be written.
* @return the port value provided by the user.
*/
protected int askPort(Message prompt, int defaultValue, Logger logger)
{
int port = -1;
while (port == -1)
{
try
{
port = readPort(prompt, defaultValue);
}
catch (CLIException ce)
{
port = -1;
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
}
}
return port;
}
/**
* Interactively prompts for user input and continues until valid input is
* provided.
*
* @param
* The type of decoded user input.
* @param prompt
* The interactive prompt which should be displayed on each input
* attempt.
* @param validator
* An input validator responsible for validating and decoding the
* user's response.
* @return Returns the decoded user's response.
* @throws CLIException
* If an unexpected error occurred which prevented validation.
*/
public final T readValidatedInput(Message prompt,
ValidationCallback validator) throws CLIException
{
while (true)
{
String response = readLineOfInput(prompt);
T value = validator.validate(this, response);
if (value != null)
{
return value;
}
}
}
/**
* Interactively prompts for user input and continues until valid input is
* provided.
*
* @param
* The type of decoded user input.
* @param prompt
* The interactive prompt which should be displayed on each input
* attempt.
* @param validator
* An input validator responsible for validating and decoding the
* user's response.
* @param maxTries
* The maximum number of tries that we can make.
* @return Returns the decoded user's response.
* @throws CLIException
* If an unexpected error occurred which prevented validation or if
* the maximum number of tries was reached.
*/
public final T readValidatedInput(Message prompt,
ValidationCallback validator, int maxTries) throws CLIException
{
int nTries = 0;
while (nTries < maxTries)
{
String response = readLineOfInput(prompt);
T value = validator.validate(this, response);
if (value != null)
{
return value;
}
nTries++;
}
throw new CLIException(ERR_TRIES_LIMIT_REACHED.get(maxTries));
}
/**
* Commodity method that interactively confirms whether a user wishes to
* perform an action. If the application is non-interactive, then the provided
* default is returned automatically. If there is an error an error message is
* logged to the provided Logger and the defaul value is returned.
*
* @param prompt
* The prompt describing the action.
* @param defaultValue
* The default value for the confirmation message. This will be
* returned if the application is non-interactive or if the user just
* presses return.
* @param logger
* the Logger to be used to log the error message.
* @return Returns true
if the user wishes the action to be
* performed, or false
if they refused.
* @throws CLIException
* if the user did not provide valid answer after a certain number
* of tries (ConsoleApplication.CONFIRMATION_MAX_TRIES)
*/
protected final boolean askConfirmation(Message prompt, boolean defaultValue,
Logger logger) throws CLIException
{
boolean v = defaultValue;
boolean done = false;
int nTries = 0;
while (!done && (nTries < CONFIRMATION_MAX_TRIES))
{
nTries++;
try
{
v = confirmAction(prompt, defaultValue);
done = true;
}
catch (CLIException ce)
{
if (ce.getMessageObject().getDescriptor().equals(
ERR_CONFIRMATION_TRIES_LIMIT_REACHED)
|| ce.getMessageObject().getDescriptor().equals(
ERR_TRIES_LIMIT_REACHED))
{
throw ce;
}
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
// Try again...
println();
}
}
if (!done)
{
// This means we reached the maximum number of tries
throw new CLIException(ERR_CONFIRMATION_TRIES_LIMIT_REACHED
.get(CONFIRMATION_MAX_TRIES));
}
return v;
}
/**
* Returns an InitialLdapContext using the provided parameters. We try to
* guarantee that the connection is able to read the configuration.
*
* @param host
* the host name.
* @param port
* the port to connect.
* @param useSSL
* whether to use SSL or not.
* @param useStartTLS
* whether to use StartTLS or not.
* @param bindDn
* the bind dn to be used.
* @param pwd
* the password.
* @param connectTimeout
* the timeout in milliseconds to connect to the server.
* @param trustManager
* the trust manager.
* @return an InitialLdapContext connected.
* @throws NamingException
* if there was an error establishing the connection.
*/
protected InitialLdapContext createAdministrativeContext(String host,
int port, boolean useSSL, boolean useStartTLS, String bindDn, String pwd,
int connectTimeout, ApplicationTrustManager trustManager)
throws NamingException
{
InitialLdapContext ctx;
String ldapUrl = ConnectionUtils.getLDAPUrl(host, port, useSSL);
if (useSSL)
{
ctx =
Utils.createLdapsContext(ldapUrl, bindDn, pwd, connectTimeout, null,
trustManager);
}
else if (useStartTLS)
{
ctx =
Utils.createStartTLSContext(ldapUrl, bindDn, pwd, connectTimeout,
null, trustManager, null);
}
else
{
ctx = Utils.createLdapContext(ldapUrl, bindDn, pwd, connectTimeout, null);
}
if (!ConnectionUtils.connectedAsAdministrativeUser(ctx))
{
throw new NoPermissionException(ERR_NOT_ADMINISTRATIVE_USER.get()
.toString());
}
return ctx;
}
/**
* Creates an Initial LDAP Context interacting with the user if the
* application is interactive.
*
* @param ci
* the LDAPConnectionConsoleInteraction object that is assumed to
* have been already run.
* @return the initial LDAP context or null
if the user did not
* accept to trust the certificates.
* @throws ClientException
* if there was an error establishing the connection.
*/
protected InitialLdapContext createInitialLdapContextInteracting(
LDAPConnectionConsoleInteraction ci) throws ClientException
{
return createInitialLdapContextInteracting(ci, isInteractive()
&& ci.isTrustStoreInMemory());
}
/**
* Creates an Initial LDAP Context interacting with the user if the
* application is interactive.
*
* @param ci
* the LDAPConnectionConsoleInteraction object that is assumed to
* have been already run.
* @param promptForCertificate
* whether we should prompt for the certificate or not.
* @return the initial LDAP context or null
if the user did not
* accept to trust the certificates.
* @throws ClientException
* if there was an error establishing the connection.
*/
protected InitialLdapContext createInitialLdapContextInteracting(
LDAPConnectionConsoleInteraction ci, boolean promptForCertificate)
throws ClientException
{
// Interact with the user though the console to get
// LDAP connection information
String hostName = ConnectionUtils.getHostNameForLdapUrl(ci.getHostName());
Integer portNumber = ci.getPortNumber();
String bindDN = ci.getBindDN();
String bindPassword = ci.getBindPassword();
TrustManager trustManager = ci.getTrustManager();
KeyManager keyManager = ci.getKeyManager();
InitialLdapContext ctx;
if (ci.useSSL())
{
String ldapsUrl = "ldaps://" + hostName + ":" + portNumber;
while (true)
{
try
{
ctx =
ConnectionUtils.createLdapsContext(ldapsUrl, bindDN,
bindPassword, ci.getConnectTimeout(), null, trustManager,
keyManager);
ctx.reconnect(null);
break;
}
catch (NamingException e)
{
if (promptForCertificate)
{
OpendsCertificateException oce = getCertificateRootException(e);
if (oce != null)
{
String authType = null;
if (trustManager instanceof ApplicationTrustManager)
{
ApplicationTrustManager appTrustManager =
(ApplicationTrustManager) trustManager;
authType = appTrustManager.getLastRefusedAuthType();
}
if (ci.checkServerCertificate(oce.getChain(), authType, hostName))
{
// If the certificate is trusted, update the trust manager.
trustManager = ci.getTrustManager();
// Try to connect again.
continue;
}
else
{
// Assume user canceled.
return null;
}
}
}
if (e.getCause() != null)
{
if (!isInteractive() && !ci.isTrustAll())
{
if (getCertificateRootException(e) != null
|| (e.getCause() instanceof SSLHandshakeException))
{
Message message =
ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT_NOT_TRUSTED.get(
hostName, String.valueOf(portNumber));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR, message);
}
}
if (e.getCause() instanceof SSLException)
{
Message message =
ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT_WRONG_PORT.get(
hostName, String.valueOf(portNumber));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR, message);
}
}
String hostPort =
ServerDescriptor.getServerRepresentation(hostName, portNumber);
Message message = Utils.getMessageForException(e, hostPort);
throw new ClientException(LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR,
message);
}
}
}
else if (ci.useStartTLS())
{
String ldapUrl = "ldap://" + hostName + ":" + portNumber;
while (true)
{
try
{
ctx =
ConnectionUtils.createStartTLSContext(ldapUrl, bindDN,
bindPassword, ConnectionUtils.getDefaultLDAPTimeout(), null,
trustManager, keyManager, null);
ctx.reconnect(null);
break;
}
catch (NamingException e)
{
if (promptForCertificate)
{
OpendsCertificateException oce = getCertificateRootException(e);
if (oce != null)
{
String authType = null;
if (trustManager instanceof ApplicationTrustManager)
{
ApplicationTrustManager appTrustManager =
(ApplicationTrustManager) trustManager;
authType = appTrustManager.getLastRefusedAuthType();
}
if (ci.checkServerCertificate(oce.getChain(), authType, hostName))
{
// If the certificate is trusted, update the trust manager.
trustManager = ci.getTrustManager();
// Try to connect again.
continue;
}
else
{
// Assume user cancelled.
return null;
}
}
else
{
Message message =
ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT.get(hostName, String
.valueOf(portNumber));
throw new ClientException(
LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR, message);
}
}
Message message =
ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT.get(hostName, String
.valueOf(portNumber));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR,
message);
}
}
}
else
{
String ldapUrl = "ldap://" + hostName + ":" + portNumber;
while (true)
{
try
{
ctx =
ConnectionUtils.createLdapContext(ldapUrl, bindDN, bindPassword,
ConnectionUtils.getDefaultLDAPTimeout(), null);
ctx.reconnect(null);
break;
}
catch (NamingException e)
{
Message message =
ERR_DSCFG_ERROR_LDAP_FAILED_TO_CONNECT.get(hostName, String
.valueOf(portNumber));
throw new ClientException(LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR,
message);
}
}
}
return ctx;
}
/**
* Returns the message to be displayed in the file with the equivalent
* command-line with information about the current time.
*
* @return the message to be displayed in the file with the equivalent
* command-line with information about the current time.
*/
protected String getCurrentOperationDateMessage()
{
String date = formatDateTimeStringForEquivalentCommand(new Date());
return INFO_OPERATION_START_TIME_MESSAGE.get(date).toString();
}
/**
* Formats a Date to String representation in "dd/MMM/yyyy:HH:mm:ss Z".
*
* @param date
* to format; null if date
is null
* @return string representation of the date
*/
protected String formatDateTimeStringForEquivalentCommand(Date date)
{
String timeStr = null;
if (date != null)
{
SimpleDateFormat dateFormat =
new SimpleDateFormat(DATE_FORMAT_LOCAL_TIME);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
timeStr = dateFormat.format(date);
}
return timeStr;
}
/**
* Prompts the user to give the Global Administrator UID.
*
* @param defaultValue
* the default value that will be proposed in the prompt message.
* @param logger
* the Logger to be used to log the error message.
* @return the Global Administrator UID as provided by the user.
*/
protected String askForAdministratorUID(String defaultValue, Logger logger)
{
String s = defaultValue;
try
{
s = readInput(INFO_ADMINISTRATOR_UID_PROMPT.get(), defaultValue);
}
catch (CLIException ce)
{
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
}
return s;
}
/**
* Prompts the user to give the Global Administrator password.
*
* @param logger
* the Logger to be used to log the error message.
* @return the Global Administrator password as provided by the user.
*/
protected String askForAdministratorPwd(Logger logger)
{
String pwd = readPassword(INFO_ADMINISTRATOR_PWD_PROMPT.get(), logger);
return pwd;
}
private OpendsCertificateException getCertificateRootException(Throwable t)
{
OpendsCertificateException oce = null;
while (t != null && oce == null)
{
t = t.getCause();
if (t instanceof OpendsCertificateException)
{
oce = (OpendsCertificateException) t;
}
}
return oce;
}
/**
* Commodity method used to repeatidly ask the user to provide an integer
* value.
*
* @param prompt
* the prompt message.
* @param defaultValue
* the default value to be proposed to the user.
* @param logger
* the logger where the errors will be written.
* @return the value provided by the user.
*/
protected int askInteger(Message prompt, int defaultValue, Logger logger)
{
int newInt = -1;
while (newInt == -1)
{
try
{
newInt = readInteger(prompt, defaultValue);
}
catch (CLIException ce)
{
newInt = -1;
logger.log(Level.WARNING, "Error reading input: " + ce, ce);
}
}
return newInt;
}
/**
* Interactively retrieves an integer value from the console.
*
* @param prompt
* The message prompt.
* @param defaultValue
* The default value.
* @return Returns the value.
* @throws CLIException
* If the value could not be retrieved for some reason.
*/
public final int readInteger(Message prompt, final int defaultValue)
throws CLIException
{
ValidationCallback callback = new ValidationCallback()
{
@Override
public Integer validate(ConsoleApplication app, String input)
throws CLIException
{
String ninput = input.trim();
if (ninput.length() == 0)
{
return defaultValue;
}
else
{
try
{
int i = Integer.parseInt(ninput);
if (i < 1)
{
throw new NumberFormatException();
}
return i;
}
catch (NumberFormatException e)
{
// Try again...
app.println();
app.println(ERR_LDAP_CONN_BAD_INTEGER.get(ninput));
app.println();
return null;
}
}
}
};
if (defaultValue != -1)
{
prompt =
INFO_PROMPT_SINGLE_DEFAULT.get(prompt.toString(), String
.valueOf(defaultValue));
}
return readValidatedInput(prompt, callback, CONFIRMATION_MAX_TRIES);
}
}