From e51a74543f9471ab7bdf53d4bb432f2fbafad059 Mon Sep 17 00:00:00 2001
From: lutoff <lutoff@localhost>
Date: Wed, 23 May 2007 08:43:18 +0000
Subject: [PATCH] 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.

---
 opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java             |  140 ++++++++++++
 opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java                |   61 +++++
 opendj-sdk/opends/src/server/org/opends/server/messages/UtilityMessages.java           |   28 ++
 opendj-sdk/opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java |   99 +++++++-
 opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java                       |  323 +++++++++++++++++++++++++++++
 5 files changed, 633 insertions(+), 18 deletions(-)

diff --git a/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java
new file mode 100644
index 0000000..67bb56d
--- /dev/null
+++ b/opendj-sdk/opends/src/ads/org/opends/admin/ads/DsServiceCLI.java
@@ -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;
+  }
+
+}
+
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
index 5ca2233..d02d70f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/AdminMessages.java
+++ b/opendj-sdk/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" );
+
   }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/UtilityMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/UtilityMessages.java
index a87232d..bb6033e 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/UtilityMessages.java
+++ b/opendj-sdk/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:");
   }
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
index 3b2e64a..b42d382 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/opendj-sdk/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";
 }
 
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java b/opendj-sdk/opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java
index 72bcea9..ad45b30 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/args/SubCommandArgumentParser.java
+++ b/opendj-sdk/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);
+        }
+      }
     }
   }
 

--
Gitblit v1.10.0