From 54c2799f45256fef4a981fa2a6a7c97a9708ac8b Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Thu, 26 Jul 2007 12:01:44 +0000
Subject: [PATCH] Partial fix for issue 1831 - dsconfig interactive mode.
---
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java | 298 ++++++++++++-----------------------------------------------
1 files changed, 63 insertions(+), 235 deletions(-)
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
index 69ea295..ba3df5d 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
+++ b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -32,16 +32,10 @@
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
-import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
-import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.Reader;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
@@ -62,13 +56,13 @@
import org.opends.server.tools.ClientException;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.InitializationException;
-import org.opends.server.types.NullOutputStream;
-import org.opends.server.util.PasswordReader;
import org.opends.server.util.StaticUtils;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
+import org.opends.server.util.table.TableBuilder;
+import org.opends.server.util.table.TextTablePrinter;
@@ -76,7 +70,7 @@
* This class provides a command-line tool which enables
* administrators to configure the Directory Server.
*/
-public final class DSConfig {
+public final class DSConfig extends ConsoleApplication {
/**
* The tracer object for the debug logger.
@@ -100,35 +94,38 @@
}
}
+
+
/**
* Provides the command-line arguments to the main application for
* processing and returns the exit code as an integer.
*
- * @param args The set of command-line arguments provided to
- * this program.
- * @param initializeServer Indicates whether to perform basic initialization
- * (which should not be done if the tool is running
- * in the same JVM as the server).
- * @param outStream The output stream for standard output.
- * @param errStream The output stream for standard error.
- *
- * @return Zero to indicate that the program completed successfully, or
- * non-zero to indicate that an error occurred.
+ * @param args
+ * The set of command-line arguments provided to this
+ * program.
+ * @param initializeServer
+ * Indicates whether to perform basic initialization (which
+ * should not be done if the tool is running in the same
+ * JVM as the server).
+ * @param outStream
+ * The output stream for standard output.
+ * @param errStream
+ * The output stream for standard error.
+ * @return Zero to indicate that the program completed successfully,
+ * or non-zero to indicate that an error occurred.
*/
public static int main(String[] args, boolean initializeServer,
- OutputStream outStream, OutputStream errStream)
- {
+ OutputStream outStream, OutputStream errStream) {
DSConfig app = new DSConfig(System.in, outStream, errStream,
new LDAPManagementContextFactory());
// Only initialize the client environment when run as a standalone
// application.
- if (initializeServer)
- {
+ if (initializeServer) {
try {
app.initializeClientEnvironment();
} catch (InitializationException e) {
// TODO: is this ok as an error message?
- System.err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ app.printMessage(e.getMessage());
return 1;
}
}
@@ -141,9 +138,6 @@
// already been initialized.
private boolean environmentInitialized = false;
- // The error stream which this application should use.
- private final PrintStream err;
-
// The factory which the application should use to retrieve its
// management context.
private final ManagementContextFactory factory;
@@ -156,16 +150,10 @@
private final Map<SubCommand, SubCommandHandler> handlers =
new HashMap<SubCommand, SubCommandHandler>();
- // The input stream reader which this application should use.
- private final BufferedReader in;
-
// The argument which should be used to request interactive
// behavior.
private BooleanArgument interactiveArgument;
- // The output stream which this application should use.
- private final PrintStream out;
-
// The command-line argument parser.
private final SubCommandArgumentParser parser;
@@ -203,126 +191,17 @@
*/
public DSConfig(InputStream in, OutputStream out, OutputStream err,
ManagementContextFactory factory) {
+ super(in, out, err);
+
this.parser = new SubCommandArgumentParser(this.getClass().getName(),
getMessage(MSGID_CONFIGDS_TOOL_DESCRIPTION), false);
- if (in != null) {
- this.in = new BufferedReader(new InputStreamReader(in));
- } else {
- this.in = new BufferedReader(new Reader() {
-
- @Override
- public void close() throws IOException {
- // Do nothing.
- }
-
-
-
- @Override
- public int read(char[] cbuf, int off, int len) throws IOException {
- return -1;
- }
-
- });
- }
-
- if (out != null) {
- this.out = new PrintStream(out);
- } else {
- this.out = NullOutputStream.printStream();
- }
-
- if (err != null) {
- this.err = new PrintStream(err);
- } else {
- this.err = NullOutputStream.printStream();
- }
-
this.factory = factory;
}
/**
- * Interactively confirms whether a user wishes to perform an
- * action. If the application is non-interactive, then the action is
- * granted by default.
- *
- * @param prompt
- * The prompt describing the action.
- * @return Returns <code>true</code> if the user wishes the action
- * to be performed, or <code>false</code> if they refused,
- * or if an exception occurred.
- */
- public boolean confirmAction(String prompt) {
- if (!isInteractive()) {
- return true;
- }
-
- String yes = Messages.getString("general.yes");
- String no = Messages.getString("general.no");
- String errMsg = Messages.getString("general.confirm.error");
- String error = String.format(errMsg, yes, no);
- prompt = prompt + String.format(" (%s / %s): ", yes, no);
-
- while (true) {
- String response;
- try {
- response = readLineOfInput(prompt);
- } catch (Exception e) {
- return false;
- }
-
- if (response == null) {
- // End of input.
- return false;
- }
-
- response = response.toLowerCase().trim();
- if (response.length() == 0) {
- // Empty input.
- err.println(wrapText(error, MAX_LINE_WIDTH));
- } else if (no.startsWith(response)) {
- return false;
- } else if (yes.startsWith(response)) {
- return true;
- } else {
- // Try again...
- err.println(wrapText(error, MAX_LINE_WIDTH));
- }
- }
- }
-
-
-
- /**
- * Displays a message to the error stream.
- *
- * @param msg
- * The message.
- */
- public void displayMessage(String msg) {
- err.println(wrapText(msg, MAX_LINE_WIDTH));
- }
-
-
-
- /**
- * Displays a message to the error stream if verbose mode is
- * enabled.
- *
- * @param msg
- * The verbose message.
- */
- public void displayVerboseMessage(String msg) {
- if (isVerbose()) {
- err.println(wrapText(msg, MAX_LINE_WIDTH));
- }
- }
-
-
-
- /**
* Initializes core APIs for use when dsconfig will be run as a
* standalone application.
*
@@ -350,11 +229,7 @@
/**
- * Indicates whether or not the user has requested interactive
- * behavior.
- *
- * @return Returns <code>true</code> if the user has requested
- * interactive behavior.
+ * {@inheritDoc}
*/
public boolean isInteractive() {
return interactiveArgument.isPresent();
@@ -363,10 +238,7 @@
/**
- * Indicates whether or not the user has requested quiet output.
- *
- * @return Returns <code>true</code> if the user has requested
- * quiet output.
+ * {@inheritDoc}
*/
public boolean isQuiet() {
return quietArgument.isPresent();
@@ -375,11 +247,7 @@
/**
- * Indicates whether or not the user has requested script-friendly
- * output.
- *
- * @return Returns <code>true</code> if the user has requested
- * script-friendly output.
+ * {@inheritDoc}
*/
public boolean isScriptFriendly() {
return scriptFriendlyArgument.isPresent();
@@ -388,10 +256,7 @@
/**
- * Indicates whether or not the user has requested verbose output.
- *
- * @return Returns <code>true</code> if the user has requested
- * verbose output.
+ * {@inheritDoc}
*/
public boolean isVerbose() {
return verboseArgument.isPresent();
@@ -400,59 +265,24 @@
/**
- * Interactively retrieves a line of input from the console.
- *
- * @param prompt
- * The prompt.
- * @return Returns the line of input, or <code>null</code> if the
- * end of input has been reached.
- * @throws Exception
- * If the line of input could not be retrieved for some
- * reason.
+ * {@inheritDoc}
*/
- public String readLineOfInput(String prompt) throws Exception {
- err.print(wrapText(prompt, MAX_LINE_WIDTH));
- return in.readLine();
- }
-
-
-
- /**
- * Interactively retrieves a password from the console.
- *
- * @param prompt
- * The password prompt.
- * @return Returns the password.
- * @throws Exception
- * If the password could not be retrieved for some reason.
- */
- public String readPassword(String prompt) throws Exception {
- err.print(wrapText(prompt, MAX_LINE_WIDTH));
- char[] pwChars = PasswordReader.readPassword();
- return new String(pwChars);
- }
-
-
-
- /**
- * Gets the management context which sub-commands should use in
- * order to manage the directory server.
- *
- * @return Returns the management context which sub-commands should
- * use in order to manage the directory server.
- * @throws ArgumentException
- * If a management context related argument could not be
- * parsed successfully.
- * @throws ClientException
- * If the management context could not be created.
- */
- ManagementContext getManagementContext() throws ArgumentException,
+ public ManagementContext getManagementContext() throws ArgumentException,
ClientException {
return factory.getManagementContext(this);
}
+ // Displays the provided message followed by a help usage reference.
+ private void displayMessageAndUsageReference(String message) {
+ printMessage(message);
+ printMessage("");
+ printMessage(parser.getHelpUsageReference());
+ }
+
+
+
/**
* Registers the global arguments with the argument parser.
*
@@ -478,7 +308,7 @@
// Register the global arguments.
parser.addGlobalArgument(showUsageArgument);
- parser.setUsageArgument(showUsageArgument, out);
+ parser.setUsageArgument(showUsageArgument, getOutputStream());
parser.addGlobalArgument(verboseArgument);
parser.addGlobalArgument(quietArgument);
parser.addGlobalArgument(scriptFriendlyArgument);
@@ -515,7 +345,8 @@
Map<Tag, SortedSet<SubCommand>> groups =
new TreeMap<Tag, SortedSet<SubCommand>>();
SortedSet<SubCommand> allSubCommands = new TreeSet<SubCommand>(c);
- for (SubCommandHandler handler : builder.getSubCommandHandlers(parser)) {
+ for (SubCommandHandler handler : builder.getSubCommandHandlers(this,
+ parser)) {
SubCommand sc = handler.getSubCommand();
handlers.put(sc, handler);
@@ -578,7 +409,7 @@
} catch (ArgumentException e) {
int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
String message = getMessage(msgID, e.getMessage());
- err.println(wrapText(message, MAX_LINE_WIDTH));
+ printMessage(message);
return 1;
}
@@ -588,9 +419,7 @@
} catch (ArgumentException ae) {
int msgID = MSGID_ERROR_PARSING_ARGS;
String message = getMessage(msgID, ae.getMessage());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -605,9 +434,7 @@
int msgID = MSGID_ERROR_PARSING_ARGS;
String message = getMessage(msgID,
getMessage(MSGID_DSCFG_ERROR_MISSING_SUBCOMMAND));
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -615,9 +442,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, quietArgument.getLongIdentifier(),
verboseArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -625,9 +450,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, quietArgument.getLongIdentifier(),
interactiveArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -635,9 +458,7 @@
int msgID = MSGID_TOOL_CONFLICTING_ARGS;
String message = getMessage(msgID, scriptFriendlyArgument
.getLongIdentifier(), verboseArgument.getLongIdentifier());
- err.println(wrapText(message, MAX_LINE_WIDTH));
- err.println();
- err.println(parser.getHelpUsageReference());
+ displayMessageAndUsageReference(message);
return 1;
}
@@ -645,37 +466,44 @@
try {
factory.validateGlobalArguments();
} catch (ArgumentException e) {
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
return 1;
}
// Retrieve the sub-command implementation and run it.
SubCommandHandler handler = handlers.get(parser.getSubCommand());
try {
- return handler.run(this, out, err);
+ return handler.run();
} catch (ArgumentException e) {
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
return 1;
} catch (ClientException e) {
// If the client exception was caused by a decoding exception
// then we should display the causes.
- err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
+ printMessage(e.getMessage());
Throwable cause = e.getCause();
if (cause instanceof ManagedObjectDecodingException) {
- // FIXME: use a table.
ManagedObjectDecodingException de =
(ManagedObjectDecodingException) cause;
- err.println();
+ printMessage("");
+ TableBuilder builder = new TableBuilder();
for (PropertyException pe : de.getCauses()) {
AbstractManagedObjectDefinition<?, ?> d = de
.getPartialManagedObject().getManagedObjectDefinition();
ArgumentException ae = ArgumentExceptionFactory
.adaptPropertyException(pe, d);
- err.println(wrapText(" * " + ae.getMessage(), MAX_LINE_WIDTH));
+ builder.startRow();
+ builder.appendCell("*");
+ builder.appendCell(ae.getMessage());
}
- err.println();
+
+ TextTablePrinter printer = new TextTablePrinter(getErrorStream());
+ printer.setDisplayHeadings(false);
+ printer.setColumnWidth(1, 0);
+ builder.print(printer);
+ printMessage("");
}
return 1;
@@ -683,7 +511,7 @@
if (debugEnabled()) {
TRACER.debugCaught(DebugLogLevel.ERROR, e);
}
- err.println(wrapText(StaticUtils.stackTraceToString(e), MAX_LINE_WIDTH));
+ printMessage(StaticUtils.stackTraceToString(e));
return 1;
}
}
--
Gitblit v1.10.0