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

lutoff
23.43.2007 37de7a1e53f4b3a69030828068557fcd9a4b0722
This is the first commit related to issue https://opends.dev.java.net/issues/show_bug.cgi?id=1334
This commit defines the CLI usage, with no underlying action.
1 files added
4 files modified
651 ■■■■■ changed files
opends/src/ads/org/opends/admin/ads/DsServiceCLI.java 323 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/AdminMessages.java 140 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/UtilityMessages.java 28 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ToolConstants.java 61 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java 99 ●●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/DsServiceCLI.java
New file
@@ -0,0 +1,323 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 */
package org.opends.admin.ads;
import java.io.OutputStream;
import java.io.PrintStream;
import org.opends.server.types.NullOutputStream;
import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
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 org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.messages.AdminMessages.*;
import static org.opends.server.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 tool that can be used to Directory Server services.
 */
public class DsServiceCLI
{
  /**
   * The fully-qualified name of this class.
   */
  private static final String CLASS_NAME =
      "org.opends.admin.ads.DsServiceCLI";
  // The print stream to use for standard error.
  private PrintStream err;
  // The print stream to use for standard output.
  private PrintStream out;
  /**
   * Constructor for the DsServiceCLI object.
   *
   * @param  out            The print stream to use for standard output.
   * @param  err            The print stream to use for standard error.
   */
  public DsServiceCLI(PrintStream out, PrintStream err)
  {
    this.out           = out;
    this.err           = err;
  }
  /**
   * The main method for dsservice tool.
   *
   * @param  args  The command-line arguments provided to this program.
   */
  public static void main(String[] args)
  {
    int retCode = mainCLI(args, System.out, System.err);
    if(retCode != 0)
    {
      System.exit(retCode);
    }
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the dsservice tool.
   *
   * @param  args  The command-line arguments provided to this program.
   *
   * @return The error code.
   */
  public static int mainCLI(String[] args)
  {
    return mainCLI(args, System.out, System.err);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the dsservice tool.
   *
   * @param  args              The command-line arguments provided to this
   *                           program.
   * @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.
   *
   * @return The error code.
   */
  public static int mainCLI(String[] args, OutputStream outStream,
      OutputStream errStream)
  {
    PrintStream out;
    if (outStream == null)
    {
      out = NullOutputStream.printStream();
    }
    else
    {
      out = new PrintStream(outStream);
    }
    PrintStream err;
    if (errStream == null)
    {
      err = NullOutputStream.printStream();
    }
    else
    {
      err = new PrintStream(errStream);
    }
    // Create the command-line argument parser for use with this program.
    String toolDescription = getMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION);
    SubCommandArgumentParser argParser = new SubCommandArgumentParser(
        CLASS_NAME, toolDescription, false);
    // GLOBAL OPTION
    try
    {
      BooleanArgument showUsage = null;
      BooleanArgument useSSL = null;
      StringArgument hostName = null;
      IntegerArgument port = null;
      StringArgument bindDN = null;
      FileBasedArgument bindPasswordFile = null;
      BooleanArgument verbose = null;
      showUsage = new BooleanArgument("showUsage", OPTION_SHORT_HELP,
          OPTION_LONG_HELP, MSGID_DESCRIPTION_SHOWUSAGE);
      argParser.addGlobalArgument(showUsage);
      argParser.setUsageArgument(showUsage, out);
      useSSL = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL,
          OPTION_LONG_USE_SSL, MSGID_DESCRIPTION_USE_SSL);
      argParser.addGlobalArgument(useSSL);
      hostName = new StringArgument("host", OPTION_SHORT_HOST,
          OPTION_LONG_HOST, false, false, true, OPTION_VALUE_HOST, "localhost",
          null, MSGID_DESCRIPTION_HOST);
      argParser.addGlobalArgument(hostName);
      port = new IntegerArgument("port", OPTION_SHORT_PORT, OPTION_LONG_PORT,
          false, false, true, OPTION_VALUE_PORT, 389, null,
          MSGID_DESCRIPTION_PORT);
      argParser.addGlobalArgument(port);
      bindDN = new StringArgument("bindDN", OPTION_SHORT_BINDDN,
          OPTION_LONG_BINDDN, false, false, true, OPTION_VALUE_BINDDN,
          "cn=Directory Manager", null, MSGID_DESCRIPTION_BINDDN);
      argParser.addGlobalArgument(bindDN);
      bindPasswordFile = new FileBasedArgument("bindPasswordFile",
          OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_BINDPWD_FILE, false, false,
          OPTION_VALUE_BINDPWD_FILE, null, null,
          MSGID_DESCRIPTION_BINDPASSWORDFILE);
      argParser.addGlobalArgument(bindPasswordFile);
      verbose = new BooleanArgument("verbose", 'v', "verbose",
          MSGID_DESCRIPTION_VERBOSE);
      argParser.addGlobalArgument(verbose);
    }
    catch (ArgumentException ae)
    {
      int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
      String message = getMessage(msgID, ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }
    // SERVER GROUP MANAGEMENT
    try
    {
      SubCommand subCmd ;
      Argument argument;
      // Create-group subcommand
      subCmd = new SubCommand(argParser,"create-group",true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION);
      argument = new StringArgument("description", OPTION_SHORT_DESCRIPTION,
          OPTION_LONG_DESCRIPTION, false, false, true,
          OPTION_VALUE_DESCRIPTION, "", null,
          MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION);
      subCmd.addArgument(argument);
      // modify-group
      subCmd = new SubCommand(argParser,"modify-group",true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION);
      argument = new StringArgument("new-description",
          OPTION_SHORT_DESCRIPTION,
          OPTION_LONG_DESCRIPTION, false, false, true,
          OPTION_VALUE_DESCRIPTION, "", null,
          MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION);
      subCmd.addArgument(argument);
      argument = new StringArgument("new-groupID",
          OPTION_SHORT_GROUPID,
          OPTION_LONG_GROUPID, false, false, true,
          OPTION_VALUE_GROUPID, "", null,
          MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION);
      subCmd.addArgument(argument);
      // delete-group
      subCmd = new SubCommand(argParser,"delete-group",true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION);
      // list-groups
      subCmd = new SubCommand(argParser,"list-groups",
          MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION);
      // add-to-group
      subCmd = new SubCommand(argParser,"add-to-group",
          true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
      argument = new StringArgument("memberID",
          OPTION_SHORT_MEMBERID,
          OPTION_LONG_MEMBERID, false, false, true,
          OPTION_VALUE_MEMBERID, "", null,
          MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION);
      subCmd.addArgument(argument);
      // remove-from-group
      subCmd = new SubCommand(argParser,"remove-from-group",
          true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
      argument = new StringArgument("memberID",
          OPTION_SHORT_MEMBERID,
          OPTION_LONG_MEMBERID, false, false, true,
          OPTION_VALUE_MEMBERID, "", null,
          MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION);
      subCmd.addArgument(argument);
      // list-members
      subCmd = new SubCommand(argParser,"list-members",
          true,1,1,
          OPERAND_GROUPID,
          MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION);
      // list-membership
      subCmd = new SubCommand(argParser,"list-membership",
          true,1,1,
          OPERAND_MEMBERID,
          MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
    } catch (ArgumentException ae)
    {
      int    msgID   = MSGID_CANNOT_INITIALIZE_ARGS;
      String message = getMessage(msgID, ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return 1;
    }
    // Parse the command-line arguments provided to this program.
    try
    {
      argParser.parseArguments(args);
    }
    catch (ArgumentException ae)
    {
      int    msgID   = MSGID_ERROR_PARSING_ARGS;
      String message = getMessage(msgID, ae.getMessage());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      err.println(argParser.getUsage());
      return 1;
    }
    // If we should just display usage information, then print it and exit.
    if (argParser.usageDisplayed())
    {
      return 0;
    }
    return 0;
  }
}
opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -198,6 +198,114 @@
  public static final int MSGID_ADMIN_CANNOT_READ_EXTENSION_MANIFEST =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_SEVERE_ERROR | 17;
  /**
   * The message ID for the message that will be used as the description for the
   * dsservice tool.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_TOOL_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 18;
  /**
   * The message ID for the message that will be used as the description for the
   * create-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 19;
  /**
   * The message ID for the message that will be used as the description of the
   * "description" argument.  This does take one argument.
   */
  public static final int MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 20;
  /**
   * The message ID for the message that will be used as the description for the
   * modify-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 21;
  /**
   * The message ID for the message that will be used as the description of the
   * new "description" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 22;
  /**
   * The message ID for the message that will be used as the description of the
   * new "groupid" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 23;
  /**
   * The message ID for the message that will be used as the description for the
   * delete-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 24;
  /**
   * The message ID for the message that will be used as the description for the
   * list-groups subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 25;
  /**
   * The message ID for the message that will be used as the description for the
   * add-to-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 26;
  /**
   * The message ID for the message that will be used as the description of the
   * added "member-id" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 27;
  /**
   * The message ID for the message that will be used as the description for the
   * remove-from-group subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 28;
  /**
   * The message ID for the message that will be used as the description of the
   * removed "member-id" argument.  This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 29;
  /**
   * The message ID for the message that will be used as the description for the
   * list-members subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 30;
  /**
   * The message ID for the message that will be used as the description for the
   * list-members subcommand part of dsservice tool.
   * This does not take any arguments.
   */
  public static final int MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 31;
  // Prevent instantiation.
  private AdminMessages() {
    // Do nothing.
@@ -288,5 +396,37 @@
        "The administration manifest file %s associated with the " +
        "extension %s cannot be loaded because an unexpected error " +
        "occurred while trying to read it:  %s");
    registerMessage(MSGID_DSSERVICE_TOOL_DESCRIPTION,
        "This utility may be used to perform " +
        "operations in the Directory Server administration framework");
    registerMessage(MSGID_DSSERVICE_SUBCMD_CREATE_GROUP_DESCRIPTION,
        "Create a new group of servers");
    registerMessage(MSGID_DSSERVICE_ARG_DESCRIPTION_DESCRIPTION,
        "The group description. If not specified, " +
        "the description will be empty");
    registerMessage(MSGID_DSSERVICE_SUBCMD_MODIFY_GROUP_DESCRIPTION,
        "Modify a group's properties");
    registerMessage(MSGID_DSSERVICE_ARG_NEW_DESCRIPTION_DESCRIPTION,
        "If specified, the new description");
    registerMessage(MSGID_DSSERVICE_ARG_NEW_GROUPID_DESCRIPTION,
        "If specified, the new group's identifier");
    registerMessage(MSGID_DSSERVICE_SUBCMD_DELETE_GROUP_DESCRIPTION,
        "Delete an existing group of servers" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_GROUPS_DESCRIPTION,
        "List groups that have been defined" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_ADD_TO_GROUP_DESCRIPTION,
        "Add a member to a group" );
    registerMessage(MSGID_DSSERVICE_ARG_ADD_MEMBERID_DESCRIPTION,
        "The member to add" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION,
        "Remove a member from a group" );
    registerMessage(MSGID_DSSERVICE_ARG_REMOVE_MEMBERID_DESCRIPTION,
        "The member to remove" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_MEMBERS_DESCRIPTION,
        "List members of the specified group" );
    registerMessage(MSGID_DSSERVICE_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION,
        "List groups in which the specified server is a member" );
  }
}
opends/src/server/org/opends/server/messages/UtilityMessages.java
@@ -1591,6 +1591,27 @@
  public static final int MSGID_VALIDATOR_PRECONDITION_NOT_MET =
       CATEGORY_MASK_UTIL | SEVERITY_MASK_SEVERE_ERROR | 148;
  /**
   * The message ID for the message that will be used as the description of the
   * Global option.  This does not take any arguments.
   */
  public static final int MSGID_GLOBAL_OPTIONS =
    CATEGORY_MASK_UTIL | SEVERITY_MASK_INFORMATIONAL | 149;
  /**
   * The message ID for the message that will be used as the description of the
   * Global option reference.  This does take one argument.
   */
  public static final int MSGID_GLOBAL_OPTIONS_REFERENCE =
    CATEGORY_MASK_UTIL | SEVERITY_MASK_INFORMATIONAL | 150;
  /**
   * The message ID for the message that will be used as the description of the
   * Global option reference.  This does take 2 arguments.
   */
  public static final int MSGID_SUBCMD_OPTIONS =
    CATEGORY_MASK_UTIL | SEVERITY_MASK_INFORMATIONAL | 151;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -2121,6 +2142,13 @@
                    "A precondition of the invoked method was not met.  This " +
                    "This usually means there is a defect somewhere in the " +
                    "call stack.  Details: %s");
    registerMessage(MSGID_GLOBAL_OPTIONS,
                    "Global Options:");
    registerMessage(MSGID_GLOBAL_OPTIONS_REFERENCE,
                    "See \"%s --help\"");
    registerMessage(MSGID_SUBCMD_OPTIONS,
                    "SubCommand Options:");
  }
}
opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -509,5 +509,66 @@
     */
     public static final String OPTION_LONG_PRODUCT_VERSION  = "version";
  /**
   * The value for the short option description attributes.
   */
  public static final char OPTION_SHORT_DESCRIPTION = 'd';
  /**
   * The value for the long option description attribute.
   */
  public static final String OPTION_LONG_DESCRIPTION = "description";
  /**
   * The placeholder value of description that will be
   * displayed in usage information.
   */
  public static final String OPTION_VALUE_DESCRIPTION = "{description}";
  /**
   * The value for the short option groupid attributes.
   */
  public static final char OPTION_SHORT_GROUPID = 'g';
  /**
   * The value for the long option groupid
   * attribute.
   */
  public static final String OPTION_LONG_GROUPID= "groupId";
  /**
   * The placeholder value of groupid that will be
   * displayed in usage information.
   */
  public static final String OPTION_VALUE_GROUPID = "{group-id}";
  /**
   * The value for the short option member-id attributes.
   */
  public static final char OPTION_SHORT_MEMBERID = 'm';
  /**
   * The value for the long member-id version
   * attribute.
   */
  public static final String OPTION_LONG_MEMBERID= "memberId";
  /**
   * The placeholder value of member-id that will be
   * displayed in usage information.
   */
  public static final String OPTION_VALUE_MEMBERID = "{member-id}";
  /**
   * The placeholder value of group_id that will be
   * displayed in usage information.
   */
  public static final String OPERAND_GROUPID = "GROUP_ID";
  /**
   * The placeholder value of member_id that will be
   * displayed in usage information.
   */
  public static final String OPERAND_MEMBERID = "MEMBER_ID";
}
opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java
@@ -1303,26 +1303,34 @@
      }
      Character shortIDChar = a.getShortIdentifier();
      boolean isHelpArg = usageArgument.getName().equals(a.getName());
      if (shortIDChar != null)
      {
        buffer.append("    -");
        if (isHelpArg)
        {
          buffer.append("-?, ");
        }
        buffer.append("-");
        buffer.append(shortIDChar);
        buffer.append(value);
        String longIDString = a.getLongIdentifier();
        if (longIDString != null)
        {
          buffer.append(", --");
          buffer.append(longIDString);
          buffer.append(value);
        }
        buffer.append(value);
      }
      else
      {
        String longIDString = a.getLongIdentifier();
        if (longIDString != null)
        {
          buffer.append("    --");
          if (isHelpArg)
          {
            buffer.append("-?, ");
          }
          buffer.append("--");
          buffer.append(longIDString);
          buffer.append(value);
        }
@@ -1380,16 +1388,17 @@
    if ( ! globalArgumentList.isEmpty())
    {
      buffer.append(EOL);
      buffer.append("Global Options:");
      buffer.append(getMessage(MSGID_GLOBAL_OPTIONS));
      buffer.append(EOL);
      buffer.append("    See \"" + printName + " --help\".");
      buffer.append("    ");
      buffer.append(getMessage(MSGID_GLOBAL_OPTIONS_REFERENCE, printName));
      buffer.append(EOL);
    }
    if ( ! subCommand.getArguments().isEmpty() )
    {
      buffer.append(EOL);
      buffer.append("SubCommand Options:");
      buffer.append(getMessage(MSGID_SUBCMD_OPTIONS));
      buffer.append(EOL);
    }
    for (Argument a : subCommand.getArguments())
@@ -1404,20 +1413,25 @@
      // Write a line with the short and/or long identifiers that may be used
      // for the argument.
      Character shortID = a.getShortIdentifier();
      String longID = a.getLongIdentifier();
      if (shortID != null)
      {
        int currentLength = buffer.length();
        buffer.append("   -");
        if (usageArgument.getName().equals(a.getName()))
        {
          buffer.append("-?, ");
        }
        buffer.append("-");
        buffer.append(shortID.charValue());
        if (a.needsValue())
        if (a.needsValue() && longID == null)
        {
          buffer.append(" ");
          buffer.append(a.getValuePlaceholder());
        }
        String longID = a.getLongIdentifier();
        if (longID != null)
        {
          StringBuilder newBuffer = new StringBuilder();
@@ -1430,7 +1444,7 @@
            newBuffer.append(a.getValuePlaceholder());
          }
          int lineLength = (buffer.length() - currentLength) + 2 +
          int lineLength = (buffer.length() - currentLength) +
                           newBuffer.length();
          if (lineLength > 80)
          {
@@ -1439,7 +1453,6 @@
          }
          else
          {
            buffer.append("  ");
            buffer.append(newBuffer.toString());
          }
        }
@@ -1448,10 +1461,13 @@
      }
      else
      {
        String longID = a.getLongIdentifier();
        if (longID != null)
        {
          buffer.append("   --");
          if (usageArgument.getName().equals(a.getName()))
          {
            buffer.append("-?, ");
          }
          buffer.append("--");
          buffer.append(longID);
          if (a.needsValue())
@@ -1463,14 +1479,61 @@
          buffer.append(EOL);
        }
      }
      indentAndWrap("   ", a.getDescription(), buffer);
      if (a.isRequired())
      // Write one or more lines with the description of the argument.  We will
      // indent the description five characters and try our best to wrap at or
      // before column 79 so it will be friendly to 80-column displays.
      String description = a.getDescription();
      if (description.length() <= 75)
      {
        buffer.append("   This argument is mandatory.");
        buffer.append("    ");
        buffer.append(description);
        buffer.append(EOL);
      }
      buffer.append(EOL);
      else
      {
        String s = description;
        while (s.length() > 75)
        {
          int spacePos = s.lastIndexOf(' ', 75);
          if (spacePos > 0)
          {
            buffer.append("    ");
            buffer.append(s.substring(0, spacePos).trim());
            s = s.substring(spacePos+1).trim();
            buffer.append(EOL);
          }
          else
          {
            // There are no spaces in the first 74 columns.  See if there is one
            // after that point.  If so, then break there.  If not, then don't
            // break at all.
            spacePos = s.indexOf(' ');
            if (spacePos > 0)
            {
              buffer.append("    ");
              buffer.append(s.substring(0, spacePos).trim());
              s = s.substring(spacePos+1).trim();
              buffer.append(EOL);
            }
            else
            {
              buffer.append("    ");
              buffer.append(s);
              s = "";
              buffer.append(EOL);
            }
          }
        }
        if (s.length() > 0)
        {
          buffer.append("    ");
          buffer.append(s);
          buffer.append(EOL);
        }
      }
    }
  }