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

lutoff
23.04.2007 c780f75a684e337357b723443ad2503ddff4af1e
This commit corresponds to the following issues:
https://opends.dev.java.net/issues/show_bug.cgi?id=1340
https://opends.dev.java.net/issues/show_bug.cgi?id=1341

Modifications done in dsframework CLI are:
- add subcommand grouping
- implement subcommand for server registration inside
the admin registry
1 files added
10 files modified
2507 ■■■■ changed files
opends/src/ads/org/opends/admin/ads/ADSContext.java 160 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java 147 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java 107 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java 193 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java 944 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java 742 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java 43 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/AdminMessages.java 95 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ToolMessages.java 41 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ToolConstants.java 33 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java 2 ●●● patch | view | raw | blame | history
opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -61,6 +61,29 @@
{
  private static final Logger LOG =
    Logger.getLogger(ADSContext.class.getName());
  /**
   * Enumeration containing the different server properties syntaxes
   * that could be stored in the ADS.
   */
  public enum ServerPropertySyntax
  {
    /**
     * String syntax.
     */
    STRING,
    /**
     * Integer syntax.
     */
    INTEGER,
    /**
     * Boolean syntax.
     */
    BOOLEAN;
  };
  /**
   * Enumeration containing the different server properties that are stored in
   * the ADS.
@@ -70,80 +93,83 @@
    /**
     * The ID used to identify the server.
     */
    ID("id"),
    ID("id",ServerPropertySyntax.STRING),
    /**
     * The host name of the server.
     */
    HOST_NAME("hostname"),
    HOST_NAME("hostname",ServerPropertySyntax.STRING),
    /**
     * The LDAP port of the server.
     */
    LDAP_PORT("ldapport"),
    LDAP_PORT("ldapport",ServerPropertySyntax.INTEGER),
    /**
     * The JMX port of the server.
     */
    JMX_PORT("jmxport"),
    JMX_PORT("jmxport",ServerPropertySyntax.INTEGER),
    /**
     * The JMX secure port of the server.
     */
    JMXS_PORT("jmxsport"),
    JMXS_PORT("jmxsport",ServerPropertySyntax.INTEGER),
    /**
     * The LDAPS port of the server.
     */
    LDAPS_PORT("ldapsport"),
    LDAPS_PORT("ldapsport",ServerPropertySyntax.INTEGER),
    /**
     * The certificate used by the server.
     */
    CERTIFICATE("certificate"),
    CERTIFICATE("certificate",ServerPropertySyntax.STRING),
    /**
     * The path where the server is installed.
     */
    INSTANCE_PATH("instancepath"),
    INSTANCE_PATH("instancepath",ServerPropertySyntax.STRING),
    /**
     * The description of the server.
     */
    DESCRIPTION("description"),
    DESCRIPTION("description",ServerPropertySyntax.STRING),
    /**
     * The OS of the machine where the server is installed.
     */
    HOST_OS("os"),
    HOST_OS("os",ServerPropertySyntax.STRING),
    /**
     * Whether LDAP is enabled or not.
     */
    LDAP_ENABLED("ldapEnabled"),
    LDAP_ENABLED("ldapEnabled",ServerPropertySyntax.BOOLEAN),
    /**
     * Whether LDAPS is enabled or not.
     */
    LDAPS_ENABLED("ldapsEnabled"),
    LDAPS_ENABLED("ldapsEnabled",ServerPropertySyntax.BOOLEAN),
    /**
     * Whether StartTLS is enabled or not.
     */
    STARTTLS_ENABLED("startTLSEnabled"),
    STARTTLS_ENABLED("startTLSEnabled",ServerPropertySyntax.BOOLEAN),
    /**
     * Whether JMX is enabled or not.
     */
    JMX_ENABLED("jmxEnabled"),
    JMX_ENABLED("jmxEnabled",ServerPropertySyntax.BOOLEAN),
    /**
     * Whether JMX is enabled or not.
     */
    JMXS_ENABLED("jmxsEnabled"),
    JMXS_ENABLED("jmxsEnabled",ServerPropertySyntax.BOOLEAN),
    /**
     * The location of the server.
     */
    LOCATION("location"),
    LOCATION("location",ServerPropertySyntax.STRING),
    /**
     * The groups to which this server belongs.
     */
    GROUPS("memberofgroups");
    GROUPS("memberofgroups",ServerPropertySyntax.STRING);
    private String attrName;
    private ServerPropertySyntax attSyntax;
    /**
     * Private constructor.
     * @param n the name of the attribute.
     */
    private ServerProperty(String n)
    private ServerProperty(String n,ServerPropertySyntax s)
    {
      attrName = n;
      attSyntax = s ;
    }
    /**
@@ -154,8 +180,38 @@
    {
      return attrName;
    }
    /**
     * Returns the attribute syntax.
     * @return the attribute syntax.
     */
    public ServerPropertySyntax getAttributeSyntax()
    {
      return attSyntax;
    }
  };
  private static HashMap<String, ServerProperty> nameToServerProperty = null;
  /**
   * Get a ServerProperty associated to a name.
   * @param name The name of the property to retreive.
   *
   * @return The corresponding ServerProperty or null if name
   * doesn't matech with an existing property.
   */
  public static ServerProperty getPropFromName(String name)
  {
    if (nameToServerProperty == null)
    {
      nameToServerProperty = new HashMap<String, ServerProperty>();
      for (ServerProperty s : ServerProperty.values())
      {
        nameToServerProperty.put(s.getAttributeName(), s);
      }
    }
    return nameToServerProperty.get(name);
  }
  /**
   * The list of server properties that are multivalued.
   */
@@ -294,15 +350,27 @@
  /**
   * Method called to udpate the properties of a server in the ADS.
   * @param serverProperties the new properties of the server.
   * @param newServerId The new server Identifier, or null.
   * @throws ADSContextException if the server could not be registered.
   */
  public void updateServer(Map<ServerProperty, Object> serverProperties)
  throws ADSContextException
  public void updateServer(Map<ServerProperty, Object> serverProperties,
      String newServerId) throws ADSContextException
  {
    LdapName dn = makeDNFromServerProperties(serverProperties);
    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
    try
    {
      if (newServerId != null)
      {
        HashMap<ServerProperty, Object> newServerProps =
          new HashMap<ServerProperty, Object>(serverProperties);
        newServerProps.put(ServerProperty.ID,newServerId);
        LdapName newDn = makeDNFromServerProperties(newServerProps);
        dirContext.rename(dn, newDn);
        dn = newDn ;
        serverProperties.put(ServerProperty.ID,newServerId);
      }
      BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
      dirContext.modifyAttributes(dn, InitialLdapContext.REPLACE_ATTRIBUTE,
          attrs);
    }
@@ -391,7 +459,7 @@
    {
      if (x.getError() == ADSContextException.ErrorType.ALREADY_REGISTERED)
      {
        updateServer(serverProperties);
        updateServer(serverProperties, null);
      }
      else
      {
@@ -950,10 +1018,10 @@
   * port.
   * @throws ADSContextException if something goes wrong.
   */
  private static LdapName makeDNFromHostnamePort(String hostnamePort)
  private static LdapName makeDNFromServerUniqueId(String serverUniqueId)
  throws ADSContextException
  {
    String cnValue = Rdn.escapeValue(hostnamePort);
    String cnValue = Rdn.escapeValue(serverUniqueId);
    return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
  }
@@ -991,6 +1059,12 @@
  private static LdapName makeDNFromServerProperties(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    String serverID ;
    if ( (serverID = getServerID(serverProperties)) != null )
    {
      return makeDNFromServerUniqueId(serverID);
    }
    String hostname = getHostname(serverProperties);
    try
    {
@@ -1000,12 +1074,29 @@
    catch (ADSContextException ace)
    {
      ServerDescriptor s = ServerDescriptor.createStandalone(serverProperties);
      return makeDNFromHostnamePort(s.getHostPort(true));
      return makeDNFromServerUniqueId(s.getHostPort(true));
    }
  }
  /**
   * This method returns the DN of the entry that corresponds to the given
   * server properties.
   * @param serverProperties the server properties.
   * @return the DN of the entry that corresponds to the given server
   * properties.
   * @throws ADSContextException if something goes wrong.
   */
  public static String getServerIdFromServerProperties(
      Map<ServerProperty, Object> serverProperties) throws ADSContextException
  {
    LdapName ldapName = makeDNFromServerProperties(serverProperties);
    String rdn = ldapName.get(ldapName.size() -1);
    int pos = rdn.indexOf("=");
    return rdn.substring(pos+1);
  }
  /**
   * This method returns the DN of the entry that corresponds to the given
   * administrator properties.
   * @param adminProperties the administrator properties.
   * @return the DN of the entry that corresponds to the given administrator
@@ -1422,6 +1513,25 @@
  }
  /**
   * Returns the Server ID for the given properties.
   * @param serverProperties the server properties.
   * @return the server ID for the given properties or null.
   */
  private static String getServerID(
      Map<ServerProperty, Object> serverProperties)
  {
    String result = (String) serverProperties.get(ServerProperty.ID);
    if (result != null)
    {
      if (result.length() == 0)
      {
        result = null;
      }
    }
    return result;
  }
  /**
   * Returns the install path for the given properties.
   * @param serverProperties the server properties.
   * @return the install path for the given properties.
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliAds.java
@@ -31,7 +31,12 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
@@ -41,7 +46,6 @@
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
/**
 * This class is handling server group CLI.
@@ -49,6 +53,11 @@
public class DsFrameworkCliAds implements DsFrameworkCliSubCommandGroup
{
  /**
   * The subcommand Parser.
   */
  DsFrameworkCliParser argParser ;
  /**
   * The enumeration containing the different subCommand names.
   */
  private enum SubCommandNameEnum
@@ -118,16 +127,62 @@
  private StringArgument deleteAdsBackendNameArg;
  /**
   * The subcommand list.
   */
  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
  /**
   * Indicates whether this subCommand should be hidden in the usage
   * information.
   */
  private boolean isHidden;
  /**
   * The subcommand group name.
   */
  private String groupName;
  /**
   * {@inheritDoc}
   */
  public void initializeCliGroup(SubCommandArgumentParser argParser,
  public Set<SubCommand> getSubCommands()
  {
    return subCommands;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isHidden()
  {
    return isHidden ;
  }
  /**
   * {@inheritDoc}
   */
  public String getGroupName()
  {
    return groupName ;
  }
  /**
   * {@inheritDoc}
   */
  public void initializeCliGroup(DsFrameworkCliParser argParser,
      BooleanArgument verboseArg)
      throws ArgumentException
  {
    isHidden = true;
    groupName = "ads";
    this.argParser = argParser;
    // Create-ads subcommand
    createAdsSubCmd = new SubCommand(argParser, SubCommandNameEnum.CREATE_ADS
        .toString(), MSGID_ADMIN_SUBCMD_CREATE_ADS_DESCRIPTION);
    createAdsSubCmd.setHidden(true);
    subCommands.add(createAdsSubCmd);
    createAdsBackendNameArg = new StringArgument("backendName",
        OPTION_SHORT_BACKENDNAME, OPTION_LONG_BACKENDNAME, true, true,
@@ -139,6 +194,7 @@
    deleteAdsSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_ADS
        .toString(), MSGID_ADMIN_SUBCMD_DELETE_ADS_DESCRIPTION);
    deleteAdsSubCmd.setHidden(true);
    subCommands.add(deleteAdsSubCmd);
    deleteAdsBackendNameArg = new StringArgument("backendName",
        OPTION_SHORT_BACKENDNAME, OPTION_LONG_BACKENDNAME, true, true,
@@ -159,29 +215,80 @@
  /**
   * {@inheritDoc}
   */
  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException
  public ReturnCode performSubCommand(SubCommand subCmd, OutputStream outStream,
      OutputStream errStream)
      throws ADSContextException, ArgumentException
  {
    //
    // create-ads subcommand
    if (subCmd.getName().equals(createAdsSubCmd.getName()))
    ADSContext adsCtx = null ;
    InitialLdapContext ctx = null ;
    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
    try
    {
      String backendName = createAdsBackendNameArg.getValue();
      adsContext.createAdminData(backendName);
      return ReturnCode.SUCCESSFUL;
      //
      // create-ads subcommand
      if (subCmd.getName().equals(createAdsSubCmd.getName()))
      {
        String backendName = createAdsBackendNameArg.getValue();
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        adsCtx.createAdminData(backendName);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
      {
        String backendName = deleteAdsBackendNameArg.getValue();
        ADSContextHelper helper = new ADSContextHelper();
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        helper
            .removeAdministrationSuffix(adsCtx.getDirContext(), backendName);
        returnCode =  ReturnCode.SUCCESSFUL;
      }
      else
      {
        // Should never occurs: If we are here, it means that the code to
        // handle to subcommand is not yet written.
        returnCode = ReturnCode.ERROR_UNEXPECTED;
      }
    }
    else if (subCmd.getName().equals(deleteAdsSubCmd.getName()))
    catch (ADSContextException e)
    {
      String backendName = deleteAdsBackendNameArg.getValue();
      ADSContextHelper helper = new ADSContextHelper();
      helper.removeAdministrationSuffix(adsContext.getDirContext(),
          backendName);
      return ReturnCode.SUCCESSFUL;
      if (ctx != null)
      {
        try
        {
          ctx.close();
        }
        catch (NamingException x)
        {
        }
      }
      throw e;
    }
    // Should never occur: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return ReturnCode.ERROR_UNEXPECTED;
    // Close the connection, if needed
    if (ctx != null)
    {
      try
      {
        ctx.close();
      }
      catch (NamingException x)
      {
      }
    }
    // return part
    return returnCode;
  }
}
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliMain.java
@@ -29,12 +29,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.server.admin.ClassLoaderProvider;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.InitializationException;
@@ -208,7 +203,12 @@
    if (argParser.getSubCommand() == null)
    {
      err.println(argParser.getUsage());
      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(argParser.getHelpUsageReference());
      return ReturnCode.ERROR_PARSING_ARGS.getReturnCode();
    }
@@ -219,71 +219,10 @@
      return ret;
    }
    // Check if we need a connection
    // Get connection parameters
    String host = argParser.getHostName() ;
    String port = argParser.getPort() ;
    String dn   = argParser.getBindDN() ;
    String pwd  = argParser.getBindPassword(dn,out,err) ;
    // Try to connect
    InitialLdapContext ctx = null;
    ReturnCode returnCode = ReturnCode.SUCCESSFUL;
    if (argParser.useSSL())
    {
      String ldapsUrl = "ldaps://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createLdapsContext(ldapsUrl,
            dn, pwd, ConnectionUtils.getDefaultLDAPTimeout(), null,
             argParser.getTrustManager(), argParser.getKeyManager());
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
      }
    }
    else
    if (argParser.startTLS())
    {
      String ldapUrl = "ldap://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createStartTLSContext(ldapUrl, dn, pwd,
            ConnectionUtils.getDefaultLDAPTimeout(), null, argParser
                .getTrustManager(), argParser.getKeyManager(), null);
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
      }
    }
    else
    {
      String ldapUrl = "ldap://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
            ConnectionUtils.getDefaultLDAPTimeout(), null);
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
      }
    }
    ADSContext adsContext = new ADSContext(ctx);
    // Should we initialize the server in client mode?
    if (initializeServer)
@@ -298,27 +237,21 @@
      }
      catch (InitializationException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
        err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
        return ReturnCode.ERROR_UNEXPECTED.getReturnCode();
      }
      catch (IllegalStateException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return ReturnCode.CANNOT_CONNECT_TO_ADS.getReturnCode();
        err.println(wrapText(e.getMessage(), MAX_LINE_WIDTH));
        return ReturnCode.ERROR_UNEXPECTED.getReturnCode();
      }
    }
    // perform the subCommand
    ADSContextException adsException = null ;
    ADSContextException adsException = null;
    try
    {
      returnCode = argParser.performSubCommand(adsContext, out, err);
      returnCode = argParser.performSubCommand(out, err);
    }
    catch (ADSContextException e)
    {
@@ -330,15 +263,13 @@
        returnCode = ReturnCode.ERROR_UNEXPECTED;
      }
    }
    catch (ArgumentException ae)
    {
      int msgID = MSGID_CANNOT_INITIALIZE_ARGS;
      String message = getMessage(msgID, ae.getMessage());
    // deconnection
    try
    {
      ctx.close();
    }
    catch (NamingException e)
    {
      // TODO Should we do something ?
      err.println(wrapText(message, MAX_LINE_WIDTH));
      return ReturnCode.CANNOT_INITIALIZE_ARGS.getReturnCode();
    }
    int msgID = returnCode.getMessageId();
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
@@ -27,6 +27,7 @@
package org.opends.server.admin.client.cli;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.messages.AdminMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
@@ -41,16 +42,22 @@
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.net.ssl.KeyManager;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.util.ApplicationKeyManager;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
@@ -71,6 +78,11 @@
public class DsFrameworkCliParser extends SubCommandArgumentParser
{
  /**
   * End Of Line.
   */
  private String EOL = System.getProperty("line.separator");
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
@@ -167,7 +179,7 @@
    Logger.getLogger(DsFrameworkCliParser.class.getName());
  /**
   * The diferent CLI group.
   * The different CLI group.
   */
  public HashSet<DsFrameworkCliSubCommandGroup> cliGroup;
@@ -214,14 +226,48 @@
    // ads  Group cli
    cliGroup.add(new DsFrameworkCliAds());
    // Server Group cli
    // Server-group Group cli
    cliGroup.add(new DsFrameworkCliServerGroup());
    // Server Group cli
    cliGroup.add(new DsFrameworkCliServer());
    // Initialization
    Comparator<SubCommand> c = new Comparator<SubCommand>() {
      public int compare(SubCommand o1, SubCommand o2) {
        return o1.getName().compareTo(o2.getName());
      }
    };
    SortedSet<SubCommand> allSubCommands = new TreeSet<SubCommand>(c);
    for (DsFrameworkCliSubCommandGroup oneCli : cliGroup)
    {
      oneCli.initializeCliGroup(this, verboseArg);
      Set<SubCommand> oneCliSubCmds = oneCli.getSubCommands() ;
      allSubCommands.addAll(oneCliSubCmds);
      // register group help
      String grpName = oneCli.getGroupName();
      String option = OPTION_LONG_HELP + "-" + grpName;
      BooleanArgument arg = new BooleanArgument(option, null, option,
          MSGID_DSCFG_DESCRIPTION_SHOW_GROUP_USAGE, grpName);
      addGlobalArgument(arg);
      arg.setHidden(oneCli.isHidden());
      TreeSet<SubCommand> subCmds = new TreeSet<SubCommand>(c);
      subCmds.addAll(oneCliSubCmds);
      setUsageGroupArgument(arg, subCmds);
    }
    // Register the --help-all argument.
    String option = OPTION_LONG_HELP + "-all";
    BooleanArgument arg = new BooleanArgument(option, null, option,
        MSGID_DSCFG_DESCRIPTION_SHOW_GROUP_USAGE_ALL);
    addGlobalArgument(arg);
    setUsageGroupArgument(arg, allSubCommands);
  }
  /**
@@ -395,7 +441,7 @@
   * @return The password stored into the specified file on by the
   *         command line argument, or prompts it if not specified.
   */
  public String getBindPassword(String dn, PrintStream out, PrintStream err)
  public String getBindPassword(String dn, OutputStream out, OutputStream err)
  {
    if (bindPasswordArg.isPresent())
    {
@@ -405,7 +451,7 @@
        // read the password from the stdin.
        try
        {
          out.print(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn));
          out.write(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn).getBytes());
          char[] pwChars = PasswordReader.readPassword();
          bindPasswordValue = new String(pwChars);
        } catch(Exception ex)
@@ -414,7 +460,14 @@
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, ex);
          }
          err.println(wrapText(ex.getMessage(), MAX_LINE_WIDTH));
          try
          {
            err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes());
            err.write(EOL.getBytes());
          }
          catch (IOException e)
          {
          }
          return null;
        }
      }
@@ -430,7 +483,7 @@
      // read the password from the stdin.
      try
      {
        out.print(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn));
        out.write(getMessage(MSGID_LDAPAUTH_PASSWORD_PROMPT, dn).getBytes());
        char[] pwChars = PasswordReader.readPassword();
        return new String(pwChars);
      }
@@ -440,7 +493,14 @@
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ex);
        }
        err.println(wrapText(ex.getMessage(), MAX_LINE_WIDTH));
        try
        {
          err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes());
          err.write(EOL.getBytes());
        }
        catch (IOException e)
        {
        }
        return null;
      }
    }
@@ -448,22 +508,20 @@
  /**
   * Handle the subcommand.
   *
   * @param adsContext
   *          The context to use to perform ADS operation.
   *
   * @param  outStream         The output stream to use for standard output.
   *
   * @param  errStream         The output stream to use for standard error.
   *
   * @return the return code
   * @throws ADSContextException
   *           If there is a problem with when trying to perform the
   *           operation.
   * @throws ArgumentException
   *           If there is a problem with any of the parameters used
   *           to execute this subcommand.
   */
  public ReturnCode performSubCommand(ADSContext adsContext,
      OutputStream outStream, OutputStream errStream)
    throws ADSContextException
  public ReturnCode performSubCommand(OutputStream outStream,
      OutputStream errStream)
    throws ADSContextException, ArgumentException
  {
    SubCommand subCmd = getSubCommand();
@@ -471,8 +529,7 @@
    {
      if (oneCli.isSubCommand(subCmd))
      {
        return oneCli.performSubCommand(adsContext, subCmd, outStream,
            errStream);
        return oneCli.performSubCommand( subCmd, outStream, errStream);
      }
    }
@@ -767,4 +824,104 @@
    return ReturnCode.SUCCESSFUL_NOP.getReturnCode();
  }
  /**
   * Get the InitialLdapContext that has to be used for the ADS.
   * @param  out         The output stream to use for standard output.
   * @param  err         The output stream to use for standard error.
   *
   * @return The InitialLdapContext that has to be used for the ADS.
   */
  public InitialLdapContext getContext(OutputStream out, OutputStream err)
  {
    // Get connection parameters
    String host = null ;
    String port = null;
    String dn   = null ;
    String pwd  = null;
    InitialLdapContext ctx = null;
    // Get connection parameters
    host = getHostName();
    port = getPort();
    dn   = getBindDN();
    pwd  = getBindPassword(dn, out, err);
    // Try to connect
    if (useSSL())
    {
      String ldapsUrl = "ldaps://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createLdapsContext(ldapsUrl, dn, pwd,
            ConnectionUtils.getDefaultLDAPTimeout(), null,getTrustManager(),
            getKeyManager());
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        try
        {
          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
          err.write(EOL.getBytes());
        }
        catch (IOException e1)
        {
        }
        return null;
      }
    }
    else if (startTLS())
    {
      String ldapUrl = "ldap://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createStartTLSContext(ldapUrl, dn, pwd,
            ConnectionUtils.getDefaultLDAPTimeout(), null, getTrustManager(),
            getKeyManager(), null);
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        try
        {
          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
          err.write(EOL.getBytes());
        }
        catch (IOException e1)
        {
        }
        return null;
      }
    }
    else
    {
      String ldapUrl = "ldap://" + host + ":" + port;
      try
      {
        ctx = ConnectionUtils.createLdapContext(ldapUrl, dn, pwd,
            ConnectionUtils.getDefaultLDAPTimeout(), null);
      }
      catch (NamingException e)
      {
        int msgID = MSGID_ADMIN_CANNOT_CONNECT_TO_ADS;
        String message = getMessage(msgID, host);
        try
        {
          err.write(wrapText(message, MAX_LINE_WIDTH).getBytes());
          err.write(EOL.getBytes());
        }
        catch (IOException e1)
        {
        }
        return null;
      }
    }
    return ctx;
  }
}
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServer.java
New file
@@ -0,0 +1,944 @@
/*
 * 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.server.admin.client.cli;
import static org.opends.server.messages.AdminMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import static org.opends.server.messages.ToolMessages.*;
import static org.opends.server.tools.ToolConstants.*;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.ADSContext.ServerProperty;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
import org.opends.server.tools.dsconfig.ArgumentExceptionFactory;
import org.opends.server.tools.dsconfig.Messages;
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.IntegerArgument;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.table.TableBuilder;
import org.opends.server.util.table.TextTablePrinter;
/**
 * This class is handling server group CLI.
 */
public class DsFrameworkCliServer implements DsFrameworkCliSubCommandGroup
{
  // Strings used in property help.
  private static final String KEY_PREFIX = "help-properties.";
  private final static String DESCRIPTION_OPTIONS_TITLE = Messages
      .getString(KEY_PREFIX + "description.options"); //$NON-NLS-1$
  private final static String DESCRIPTION_OPTIONS_READ = Messages
      .getString(KEY_PREFIX + "description.read"); //$NON-NLS-1$
  private final static String DESCRIPTION_OPTIONS_WRITE = Messages
      .getString(KEY_PREFIX + "description.write"); //$NON-NLS-1$
  private final static String DESCRIPTION_OPTIONS_MANDATORY = Messages
      .getString(KEY_PREFIX + "description.mandatory"); //$NON-NLS-1$
  private final static String DESCRIPTION_OPTIONS_SINGLE = Messages
      .getString(KEY_PREFIX + "description.single-valued"); //$NON-NLS-1$
  /**
   * The subcommand Parser.
   */
  private DsFrameworkCliParser argParser;
  /**
   * The verbose argument.
   */
  private BooleanArgument verboseArg;
  /**
   * The enumeration containing the different subCommand names.
   */
  private enum SubCommandNameEnum
  {
    /**
     * The register-server subcommand.
     */
    REGISTER_SERVER("register-server"),
    /**
     * The unregister-server subcommand.
     */
    UNREGISTER_SERVER("unregister-server"),
    /**
     * The list-servers subcommand.
     */
    LIST_SERVERS("list-servers"),
    /**
     * The get-server-properties subcommand.
     */
    GET_SERVER_PROPERTIES("get-server-properties"),
    /**
     * The set-server-propertiess subcommand.
     */
    SET_SERVER_PROPERTIES("set-server-properties"),
    /**
     * The list-servers subcommand.
     */
    LIST_SERVER_PROPERTIES("list-server-properties");
    // String representation of the value.
    private final String name;
    // Private constructor.
    private SubCommandNameEnum(String name)
    {
      this.name = name;
    }
    /**
     * {@inheritDoc}
     */
    public String toString()
    {
      return name;
    }
    // A lookup table for resolving a unit from its name.
    private static final List<String> nameToSubCmdName;
    static
    {
      nameToSubCmdName = new ArrayList<String>();
      for (SubCommandNameEnum subCmd : SubCommandNameEnum.values())
      {
        nameToSubCmdName.add(subCmd.toString());
      }
    }
    public static boolean isSubCommand(String name)
    {
      return nameToSubCmdName.contains(name);
    }
  }
  /**
   * The 'register-server' subcommand.
   */
  private SubCommand registerServerSubCmd;
  /**
   * The 'serverID' argument of the 'register-server' subcommand.
   */
  private StringArgument registerServerServerIdArg;
  /**
   * The 'serverName' argument of the 'register-server' subcommand.
   */
  private StringArgument registerServerSetArg;
  /**
   * The 'unregister-server' subcommand.
   */
  private SubCommand unregisterServerSubCmd;
  /**
   * The 'serverHost' argument of the 'unregister-server' subcommand.
   */
  private StringArgument unregisterServerServerIDArg;
  /**
   * The 'list-server-properties' subcommand.
   */
  private SubCommand listServerPropertiesSubCmd;
  /**
   * The 'list-servers' subcommand.
   */
  private SubCommand listServersSubCmd;
  /**
   * The 'get-server-properties' subcommand.
   */
  private SubCommand getServerPropertiesSubCmd;
  /**
   * The 'serverID' argument of the 'get-server-properties' subcommand.
   */
  private StringArgument getServerPropertiesServerIdArg;
  /**
   * The 'set-server-properties' subcommand.
   */
  private SubCommand setServerPropertiesSubCmd;
  /**
   * The 'serverID' argument of the 'set-server-properties' subcommand.
   */
  private StringArgument setServerPropertiesServerIdArg;
  /**
   * The 'serverName' argument of the 'set-server-properties' subcommand.
   */
  private StringArgument setServerPropertiesSetArg;
  /**
   * Association between ADSContext enum and properties.
   */
  private HashMap<ServerProperty, Argument> serverProperties;
  /**
   * List of read-only server properties.
   */
  private HashSet<ServerProperty> readonlyServerProperties;
  /**
   * The subcommand list.
   */
  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
  /**
   * Indicates whether this subCommand should be hidden in the usage
   * information.
   */
  private boolean isHidden;
  /**
   * The subcommand group name.
   */
  private String groupName;
  /**
   * {@inheritDoc}
   */
  public Set<SubCommand> getSubCommands()
  {
    return subCommands;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isHidden()
  {
    return isHidden;
  }
  /**
   * {@inheritDoc}
   */
  public String getGroupName()
  {
    return groupName;
  }
  /**
   * {@inheritDoc}
   */
  public void initializeCliGroup(DsFrameworkCliParser argParser,
      BooleanArgument verboseArg) throws ArgumentException
  {
    this.verboseArg = verboseArg;
    isHidden = false;
    groupName = "server";
    this.argParser = argParser;
    // list-server-properties subcommand
    listServerPropertiesSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.LIST_SERVER_PROPERTIES.toString(),
        MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION);
    subCommands.add(listServerPropertiesSubCmd);
    // register-server subcommand
    registerServerSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.REGISTER_SERVER.toString(),
        MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION);
    subCommands.add(registerServerSubCmd);
    registerServerServerIdArg = new StringArgument("serverID", null,
        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
    registerServerSubCmd.addArgument(registerServerServerIdArg);
    registerServerSetArg = new StringArgument(OPTION_LONG_SET,
        OPTION_SHORT_SET, OPTION_LONG_SET, false, true, true,
        OPTION_VALUE_SET, null, null, MSGID_DSCFG_DESCRIPTION_PROP_VAL);
    registerServerSubCmd.addArgument(registerServerSetArg);
    // unregister-server subcommand
    unregisterServerSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.UNREGISTER_SERVER.toString(),
        MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION);
    subCommands.add(unregisterServerSubCmd);
    unregisterServerServerIDArg = new StringArgument("serverID", null,
        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
    unregisterServerSubCmd.addArgument(unregisterServerServerIDArg);
    // list-servers subcommand
    listServersSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.LIST_SERVERS.toString(),
        MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION);
    subCommands.add(listServersSubCmd);
    // get-server-properties subcommand
    getServerPropertiesSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.GET_SERVER_PROPERTIES.toString(),
        MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION);
    subCommands.add(getServerPropertiesSubCmd);
    getServerPropertiesServerIdArg = new StringArgument("serverID", null,
        OPTION_LONG_SERVERID, false, true, OPTION_VALUE_SERVERID,
        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
    getServerPropertiesServerIdArg.setMultiValued(true);
    getServerPropertiesSubCmd.addArgument(getServerPropertiesServerIdArg);
    // set-server-properties subcommand
    setServerPropertiesSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.SET_SERVER_PROPERTIES.toString(),
        MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION);
    subCommands.add(setServerPropertiesSubCmd);
    setServerPropertiesServerIdArg = new StringArgument("serverID", null,
        OPTION_LONG_SERVERID, true, true, OPTION_VALUE_SERVERID,
        MSGID_ADMIN_ARG_SERVERID_DESCRIPTION);
    setServerPropertiesSubCmd.addArgument(setServerPropertiesServerIdArg);
    setServerPropertiesSetArg = new StringArgument(OPTION_LONG_SET,
        OPTION_SHORT_SET, OPTION_LONG_SET, false, true, true,
        OPTION_VALUE_SET, null, null, MSGID_DSCFG_DESCRIPTION_PROP_VAL);
    setServerPropertiesSubCmd.addArgument(setServerPropertiesSetArg);
    // Create association between ADSContext enum and server
    // properties
    // Server properties are mapped to Argument.
    serverProperties = new HashMap<ServerProperty, Argument>();
    readonlyServerProperties = new HashSet<ServerProperty>();
    /**
     * The ID used to identify the server.
     */
    {
      ServerProperty prop = ServerProperty.ID;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(prop.getAttributeName(), null,
          prop.getAttributeName(), false, false, true, "", null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The host name of the server.
     */
    {
      ServerProperty prop = ServerProperty.HOST_NAME;
      String attName = prop.getAttributeName();
      readonlyServerProperties.add(prop);
      StringArgument arg = new StringArgument(attName, null, attName, true,
          false, true, "", "localhost", null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The LDAP port of the server.
     */
    {
      ServerProperty prop = ServerProperty.LDAP_PORT;
      String attName = prop.getAttributeName();
      IntegerArgument arg = new IntegerArgument(attName, null, attName, true,
          true, true, attName, 389, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The JMX port of the server.
     */
    {
      ServerProperty prop = ServerProperty.JMX_PORT;
      String attName = prop.getAttributeName();
      IntegerArgument arg = new IntegerArgument(attName, null, attName,
          false, true, attName, -1);
      arg.setMultiValued(true);
      serverProperties.put(prop, arg);
    }
    /**
     * The JMX secure port of the server.
     */
    {
      ServerProperty prop = ServerProperty.JMXS_PORT;
      String attName = prop.getAttributeName();
      IntegerArgument arg = new IntegerArgument(attName, null, attName,
          false, true, attName, -1);
      arg.setMultiValued(true);
      serverProperties.put(prop, arg);
    }
    /**
     * The LDAPS port of the server.
     */
    {
      ServerProperty prop = ServerProperty.LDAPS_PORT;
      String attName = prop.getAttributeName();
      IntegerArgument arg = new IntegerArgument(attName, null, attName,
          false, true, attName, -1);
      arg.setMultiValued(true);
      serverProperties.put(prop, arg);
    }
    /**
     * The certificate used by the server.
     */
    {
      ServerProperty prop = ServerProperty.CERTIFICATE;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          false, true, attName, null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The path where the server is installed.
     */
    {
      ServerProperty prop = ServerProperty.INSTANCE_PATH;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          false, true, attName, null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The description of the server.
     */
    {
      ServerProperty prop = ServerProperty.DESCRIPTION;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          false, true, attName, null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The OS of the machine where the server is installed.
     */
    {
      ServerProperty prop = ServerProperty.HOST_OS;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          false, true, attName, null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * Whether LDAP is enabled or not.
     */
    {
      ServerProperty prop = ServerProperty.LDAP_ENABLED;
      String attName = prop.getAttributeName();
      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
      arg.setDefaultValue("false");
      serverProperties.put(prop, arg);
    }
    /**
     * Whether LDAPS is enabled or not.
     */
    {
      ServerProperty prop = ServerProperty.LDAPS_ENABLED;
      String attName = prop.getAttributeName();
      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
      arg.setDefaultValue("false");
      serverProperties.put(prop, arg);
    }
    /**
     * Whether StartTLS is enabled or not.
     */
    {
      ServerProperty prop = ServerProperty.STARTTLS_ENABLED;
      String attName = prop.getAttributeName();
      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
      arg.setDefaultValue("false");
      serverProperties.put(prop, arg);
    }
    /**
     * Whether JMX is enabled or not.
     */
    {
      ServerProperty prop = ServerProperty.JMX_ENABLED;
      String attName = prop.getAttributeName();
      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
      arg.setDefaultValue("false");
      serverProperties.put(prop, arg);
    }
    /**
     * Whether JMXS is enabled or not.
     */
    {
      ServerProperty prop = ServerProperty.JMXS_ENABLED;
      String attName = prop.getAttributeName();
      BooleanArgument arg = new BooleanArgument(attName, null, attName, -1);
      arg.setDefaultValue("false");
      serverProperties.put(prop, arg);
    }
    /**
     * The location of the server.
     */
    {
      ServerProperty prop = ServerProperty.LOCATION;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          false, true, attName, null, null, -1);
      serverProperties.put(prop, arg);
    }
    /**
     * The list of groups in which the server is registered.
     */
    {
      ServerProperty prop = ServerProperty.GROUPS;
      String attName = prop.getAttributeName();
      StringArgument arg = new StringArgument(attName, null, attName, false,
          true, true, attName, null, null, -1);
      arg.setHidden(true);
      serverProperties.put(prop, arg);
    }
  }
  /**
   * {@inheritDoc}
   */
  public boolean isSubCommand(SubCommand subCmd)
  {
    return SubCommandNameEnum.isSubCommand(subCmd.getName());
  }
  /**
   * {@inheritDoc}
   */
  public ReturnCode performSubCommand(SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException, ArgumentException
  {
    ADSContext adsCtx = null;
    InitialLdapContext ctx = null;
    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
    try
    {
      // -----------------------
      // register-server subcommand
      // -----------------------
      if (subCmd.getName().equals(registerServerSubCmd.getName()))
      {
        Map<ServerProperty, Object> map =
          mapSetOptionsToMap(registerServerSetArg);
        if (registerServerServerIdArg.isPresent())
        {
          map.put(ServerProperty.ID, registerServerServerIdArg.getValue());
        }
        else
        {
          map.put(ServerProperty.ID, ADSContext
              .getServerIdFromServerProperties(map));
        }
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        adsCtx.registerServer(map);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      // -----------------------
      // unregister-server subcommand
      // -----------------------
      if (subCmd.getName().equals(unregisterServerSubCmd.getName()))
      {
        Map<ServerProperty, Object> map = new HashMap<ServerProperty, Object>();
        if (unregisterServerServerIDArg.isPresent())
        {
          map.put(ServerProperty.ID, unregisterServerServerIDArg.getValue());
        }
        else
        {
          map.put(ServerProperty.ID, ADSContext
              .getServerIdFromServerProperties(map));
        }
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        adsCtx.unregisterServer(map);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      // -----------------------
      // list-servers subcommand
      // -----------------------
      if (subCmd.getName().equals(listServersSubCmd.getName()))
      {
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        Set<Map<ServerProperty, Object>> serverList = adsCtx
            .readServerRegistry();
        PrintStream out = new PrintStream(outStream);
        for (Map<ServerProperty, Object> server : serverList)
        {
          // print out server ID
          out.println(ServerProperty.ID.getAttributeName() + ": "
              + server.get(ServerProperty.ID));
        }
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      // -----------------------
      // get-server-properties subcommand
      // -----------------------
      if (subCmd.getName().equals(getServerPropertiesSubCmd.getName()))
      {
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        Set<Map<ServerProperty, Object>> adsServerList = adsCtx
            .readServerRegistry();
        LinkedList<String> userServerList = getServerPropertiesServerIdArg
            .getValues();
        PrintStream out = new PrintStream(outStream);
        for (Map<ServerProperty, Object> server : adsServerList)
        {
          String serverID = (String) server.get(ServerProperty.ID);
          if (!userServerList.contains(serverID))
          {
            continue;
          }
          // print out server ID
          out.println(ServerProperty.ID.getAttributeName() + ": "
              + server.get(ServerProperty.ID));
          for (ServerProperty sp : server.keySet())
          {
            if (sp.equals(ServerProperty.ID))
            {
              continue;
            }
            out.println(sp.getAttributeName() + ": " + server.get(sp));
          }
          out.println();
        }
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      // -----------------------
      // set-server-properties subcommand
      // -----------------------
      if (subCmd.getName().equals(setServerPropertiesSubCmd.getName()))
      {
        Map<ServerProperty, Object> map =
          mapSetOptionsToMap(setServerPropertiesSetArg);
        // if the ID is specify in the --set list, it may mean that
        // the user wants to rename the serverID
        String newServerId = (String) map.get(ServerProperty.ID) ;
        // replace the serverID in the map
        map.put(ServerProperty.ID, setServerPropertiesServerIdArg.getValue());
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx);
        adsCtx.updateServer(map, newServerId);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      // -----------------------
      // list-server-properties subcommand
      // -----------------------
      if (subCmd.getName().equals(listServerPropertiesSubCmd.getName()))
      {
        PrintStream out = new PrintStream(outStream);
        out.println(DESCRIPTION_OPTIONS_TITLE);
        out.println();
        out.print(" r -- ");
        out.println(DESCRIPTION_OPTIONS_READ);
        out.print(" w -- ");
        out.println(DESCRIPTION_OPTIONS_WRITE);
        out.print(" m -- ");
        out.println(DESCRIPTION_OPTIONS_MANDATORY);
        out.print(" s -- ");
        out.println(DESCRIPTION_OPTIONS_SINGLE);
        out.println();
        TableBuilder table = new TableBuilder();
        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_NAME));
        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_OPTIONS));
        table.appendHeading(getMessage(MSGID_DSCFG_HEADING_PROPERTY_SYNTAX));
        table.appendHeading(getMessage(
            MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE));
        for (ServerProperty serverProp : serverProperties.keySet())
        {
          if (serverProperties.get(serverProp).isHidden())
          {
            continue;
          }
          table.startRow();
          table.appendCell(serverProp.getAttributeName());
          table.appendCell(getPropertyOptionSummary(serverProperties
              .get(serverProp)));
          table.appendCell(serverProp.getAttributeSyntax());
          if (serverProperties.get(serverProp).getDefaultValue() != null)
          {
            table.appendCell(serverProperties.get(serverProp)
                .getDefaultValue());
          }
          else
          {
            table.appendCell("-");
          }
        }
        TextTablePrinter printer = new TextTablePrinter(outStream);
        table.print(printer);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      {
        // Should never occurs: If we are here, it means that the code
        // to
        // handle to subcommand is not yet written.
        returnCode = ReturnCode.ERROR_UNEXPECTED;
      }
    }
    catch (ADSContextException e)
    {
      if (ctx != null)
      {
        try
        {
          ctx.close();
        }
        catch (NamingException x)
        {
        }
      }
      throw e;
    }
    // Close the connection, if needed
    if (ctx != null)
    {
      try
      {
        ctx.close();
      }
      catch (NamingException x)
      {
      }
    }
    // return part
    return returnCode;
  }
  // Compute the options field.
  private String getPropertyOptionSummary(Argument arg)
  {
    StringBuilder b = new StringBuilder();
    if (readonlyServerProperties.contains(
        ADSContext.getPropFromName(arg.getName())))
    {
      b.append("r-"); //$NON-NLS-1$
    }
    else
    {
      b.append("rw"); //$NON-NLS-1$
    }
    if (arg.isRequired())
    {
      b.append('m');
    }
    else
    {
      b.append('-');
    }
    if (arg.isMultiValued())
    {
      b.append('-');
    }
    else
    {
      b.append('s');
    }
    return b.toString();
  }
  /**
   * Translate a Set properties a to a MAP.
   *
   * @param propertySetArgument
   *          The input set argument.
   * @return The created map.
   * @throws ArgumentException
   *           If error error occurs during set parsing.
   */
  private Map<ServerProperty, Object> mapSetOptionsToMap(
      StringArgument propertySetArgument) throws ArgumentException
  {
    HashMap<ServerProperty, Object> map = new HashMap<ServerProperty, Object>();
    for (String m : propertySetArgument.getValues())
    {
      // Parse the property "property:value".
      int sep = m.indexOf(':');
      if (sep < 0)
      {
        throw ArgumentExceptionFactory.missingSeparatorInPropertyArgument(m);
      }
      if (sep == 0)
      {
        throw ArgumentExceptionFactory.missingNameInPropertyArgument(m);
      }
      String propertyName = m.substring(0, sep);
      String value = m.substring(sep + 1, m.length());
      if (value.length() == 0)
      {
        throw ArgumentExceptionFactory.missingValueInPropertyArgument(m);
      }
      // Check that propName is a known prop.
      ServerProperty serverProperty = ADSContext
          .getPropFromName(propertyName);
      if (serverProperty == null)
      {
        int msgID = MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED;
        String message = getMessage(msgID, propertyName);
        throw new ArgumentException(msgID, message);
      }
      // Check that propName is not hidden.
      if (serverProperties.get(serverProperty).isHidden())
      {
        int msgID = MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED;
        String message = getMessage(msgID, propertyName);
        throw new ArgumentException(msgID, message);
      }
      // Check the property Syntax.
      StringBuilder invalidReason = new StringBuilder();
      Argument arg = serverProperties.get(serverProperty) ;
      if ( ! arg.valueIsAcceptable(value, invalidReason))
      {
        int msgID = MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE;
        String message = getMessage(msgID, propertyName, value);
        throw new ArgumentException(msgID, message);
      }
      serverProperties.get(serverProperty).addValue(value);
      // add to the map.
      map.put(serverProperty, value);
    }
    // Check that all mandatory props are set.
    HashSet<PropertyOption> propList;
    for (ServerProperty s : ServerProperty.values())
    {
      Argument arg = serverProperties.get(s);
      if (arg.isHidden())
      {
        continue;
      }
      if (map.containsKey(s))
      {
        continue ;
      }
      if ( ! arg.isRequired())
      {
        continue ;
      }
      // If we are here, it means that the argument is required
      // but not yet is the map. Cjeck if we have a default value.
      if (arg.getDefaultValue() == null)
      {
        int msgID = MSGID_CLI_ERROR_MISSING_PROPERTY;
        String message = getMessage(msgID, s.getAttributeName());
        throw new ArgumentException(msgID, message);
      }
      else
      {
        map.put(s, arg.getDefaultValue());
      }
    }
    return map;
  }
}
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliServerGroup.java
@@ -38,6 +38,8 @@
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.Rdn;
@@ -49,7 +51,6 @@
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.StringArgument;
import org.opends.server.util.args.SubCommand;
import org.opends.server.util.args.SubCommandArgumentParser;
/**
 * This class is handling server group CLI.
@@ -65,7 +66,7 @@
  /**
   * The subcommand Parser.
   */
  SubCommandArgumentParser argParser ;
  DsFrameworkCliParser argParser ;
  /**
   * The verbose argument.
@@ -258,6 +259,22 @@
  private HashMap<ServerGroupProperty, String> attributeDisplayName;
  /**
   * The subcommand list.
   */
  private HashSet<SubCommand> subCommands = new HashSet<SubCommand>();
  /**
   * Indicates whether this subCommand should be hidden in the usage
   * information.
   */
  private boolean isHidden;
  /**
   * The subcommand group name.
   */
  private String groupName;
  /**
   * Get the display attribute name for a given attribute.
   * @param prop The server prperty
   * @return the display attribute name for a given attribute
@@ -266,19 +283,49 @@
  {
    return attributeDisplayName.get(prop);
  }
  /**
   * {@inheritDoc}
   */
  public void initializeCliGroup(SubCommandArgumentParser argParser,
  public Set<SubCommand> getSubCommands()
  {
    return subCommands;
  }
  /**
   * {@inheritDoc}
   */
  public boolean isHidden()
  {
    return isHidden;
  }
  /**
   * {@inheritDoc}
   */
  public String getGroupName()
  {
    return groupName ;
  }
  /**
   * {@inheritDoc}
   */
  public void initializeCliGroup(DsFrameworkCliParser argParser,
      BooleanArgument verboseArg)
      throws ArgumentException
  {
    this.verboseArg = verboseArg ;
    isHidden = false ;
    groupName = "server-group";
    this.argParser = argParser;
    // Create-group subcommand
    createGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.CREATE_GROUP.toString(),
        MSGID_ADMIN_SUBCMD_CREATE_GROUP_DESCRIPTION);
    subCommands.add(createGroupSubCmd);
    createGroupDescriptionArg = new StringArgument("description",
        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
@@ -296,6 +343,7 @@
    modifyGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.MODIFY_GROUP.toString(),
        MSGID_ADMIN_SUBCMD_MODIFY_GROUP_DESCRIPTION);
    subCommands.add(modifyGroupSubCmd);
    modifyGroupDescriptionArg = new StringArgument("new-description",
        OPTION_SHORT_DESCRIPTION, OPTION_LONG_DESCRIPTION, false, false,
@@ -318,6 +366,7 @@
    // delete-group
    deleteGroupSubCmd = new SubCommand(argParser,SubCommandNameEnum.DELETE_GROUP
        .toString(), MSGID_ADMIN_SUBCMD_DELETE_GROUP_DESCRIPTION);
    subCommands.add(deleteGroupSubCmd);
    deleteGroupGroupNameArg = new StringArgument("groupName",
        OPTION_SHORT_GROUPNAME, OPTION_LONG_GROUPNAME, true, true,
@@ -328,11 +377,13 @@
    // list-groups
    listGroupSubCmd = new SubCommand(argParser, "list-groups",
        MSGID_ADMIN_SUBCMD_LIST_GROUPS_DESCRIPTION);
    subCommands.add(listGroupSubCmd);
    // add-to-group
    addToGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.ADD_TO_GROUP.toString(),
        MSGID_ADMIN_SUBCMD_ADD_TO_GROUP_DESCRIPTION);
    subCommands.add(addToGroupSubCmd);
    addToGoupMemberNameArg = new StringArgument("memberName",
        OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -350,6 +401,7 @@
    removeFromGroupSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.REMOVE_FROM_GROUP.toString(),
        MSGID_ADMIN_SUBCMD_REMOVE_FROM_GROUP_DESCRIPTION);
    subCommands.add(removeFromGroupSubCmd);
    removeFromGoupMemberNameArg = new StringArgument("memberName",
        OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -367,6 +419,7 @@
    // list-members
    listMembersSubCmd = new SubCommand(argParser,SubCommandNameEnum.LIST_MEMBERS
        .toString(), MSGID_ADMIN_SUBCMD_LIST_MEMBERS_DESCRIPTION);
    subCommands.add(listMembersSubCmd);
    listMembersGroupNameArg = new StringArgument("groupName",
        OPTION_SHORT_GROUPNAME, OPTION_LONG_GROUPNAME, true, true,
@@ -378,6 +431,7 @@
    listMembershipSubCmd = new SubCommand(argParser,
        SubCommandNameEnum.LIST_MEMBERSHIP.toString(),
        MSGID_ADMIN_SUBCMD_LIST_MEMBERSHIP_DESCRIPTION);
    subCommands.add(listMembershipSubCmd);
    listMembershipMemberNameArg = new StringArgument("memberName",
        OPTION_SHORT_MEMBERNAME, OPTION_LONG_MEMBERNAME, true, true,
@@ -406,362 +460,454 @@
  /**
   * {@inheritDoc}
   */
  public ReturnCode performSubCommand(ADSContext adsContext, SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException
  public ReturnCode performSubCommand(SubCommand subCmd, OutputStream outStream,
      OutputStream errStream)
      throws ADSContextException, ArgumentException
  {
    // -----------------------
    // create-group subcommand
    // -----------------------
    if (subCmd.getName().equals(createGroupSubCmd.getName()))
    ADSContext adsCtx = null ;
    InitialLdapContext ctx = null ;
    ReturnCode returnCode = ReturnCode.ERROR_UNEXPECTED;
    try
    {
      String groupId = createGroupGroupNameArg.getValue();
      HashMap<ServerGroupProperty, Object> serverGroupProperties =
        new HashMap<ServerGroupProperty, Object>();
      // get the GROUP_NAME
      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
      // get the Description
      if (createGroupDescriptionArg.isPresent())
      // -----------------------
      // create-group subcommand
      // -----------------------
      if (subCmd.getName().equals(createGroupSubCmd.getName()))
      {
        serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
            createGroupDescriptionArg.getValue());
      }
        String groupId = createGroupGroupNameArg.getValue();
        HashMap<ServerGroupProperty, Object> serverGroupProperties =
          new HashMap<ServerGroupProperty, Object>();
      // Create the group
      adsContext.createServerGroup(serverGroupProperties);
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // delete-group subcommand
    // -----------------------
    else if (subCmd.getName().equals(deleteGroupSubCmd.getName()))
    {
      String groupId = deleteGroupGroupNameArg.getValue();
      HashMap<ServerGroupProperty, Object> serverGroupProperties =
        new HashMap<ServerGroupProperty, Object>();
        // get the GROUP_NAME
        serverGroupProperties.put(ServerGroupProperty.UID, groupId);
      // get the GROUP_ID
      serverGroupProperties.put(ServerGroupProperty.UID, groupId);
      // Delete the group
      adsContext.deleteServerGroup(serverGroupProperties);
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-groups subcommand
    // -----------------------
    else if (subCmd.getName().equals(listGroupSubCmd.getName()))
    {
      Set<Map<ServerGroupProperty, Object>> result = adsContext
          .readServerGroupRegistry();
      StringBuffer buffer = new StringBuffer();
      // if not verbose mode, print group name (1 per line)
      if (! verboseArg.isPresent())
      {
        for (Map<ServerGroupProperty, Object> groupProps : result)
        // get the Description
        if (createGroupDescriptionArg.isPresent())
        {
          // Get the group name
          buffer.append(groupProps.get(ServerGroupProperty.UID));
          buffer.append(EOL);
          serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
              createGroupDescriptionArg.getValue());
        }
      }
      else
      {
        // Look for the max group identifier length
        int uidLength = 0 ;
        for (ServerGroupProperty sgp : ServerGroupProperty.values())
        // Create the group
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          int cur = attributeDisplayName.get(sgp).toString().length();
          if (cur > uidLength)
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        adsCtx.createServerGroup(serverGroupProperties);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // delete-group subcommand
      // -----------------------
      else if (subCmd.getName().equals(deleteGroupSubCmd.getName()))
      {
        String groupId = deleteGroupGroupNameArg.getValue();
        HashMap<ServerGroupProperty, Object> serverGroupProperties =
          new HashMap<ServerGroupProperty, Object>();
        // get the GROUP_ID
        serverGroupProperties.put(ServerGroupProperty.UID, groupId);
        // Delete the group
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        adsCtx.deleteServerGroup(serverGroupProperties);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // list-groups subcommand
      // -----------------------
      else if (subCmd.getName().equals(listGroupSubCmd.getName()))
      {
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        Set<Map<ServerGroupProperty, Object>> result = adsCtx
            .readServerGroupRegistry();
        StringBuffer buffer = new StringBuffer();
        // if not verbose mode, print group name (1 per line)
        if (! verboseArg.isPresent())
        {
          for (Map<ServerGroupProperty, Object> groupProps : result)
          {
            uidLength = cur;
            // Get the group name
            buffer.append(groupProps.get(ServerGroupProperty.UID));
            buffer.append(EOL);
          }
        }
        uidLength++;
        for (Map<ServerGroupProperty, Object> groupProps : result)
        else
        {
          // Get the group name
          buffer.append(attributeDisplayName.get(ServerGroupProperty.UID));
          // add space
          int curLen = attributeDisplayName.get(ServerGroupProperty.UID)
              .length();
          for (int i = curLen; i < uidLength; i++)
          // Look for the max group identifier length
          int uidLength = 0 ;
          for (ServerGroupProperty sgp : ServerGroupProperty.values())
          {
            buffer.append(" ");
          }
          buffer.append(": ");
          buffer.append(groupProps.get(ServerGroupProperty.UID));
          buffer.append(EOL);
          // Write other props
          for (ServerGroupProperty propName : ServerGroupProperty.values())
          {
            if (propName.compareTo(ServerGroupProperty.UID) == 0)
            int cur = attributeDisplayName.get(sgp).toString().length();
            if (cur > uidLength)
            {
              // We have already displayed the group Id
              continue;
              uidLength = cur;
            }
            buffer.append(attributeDisplayName.get(propName));
          }
          uidLength++;
          for (Map<ServerGroupProperty, Object> groupProps : result)
          {
            // Get the group name
            buffer.append(attributeDisplayName.get(ServerGroupProperty.UID));
            // add space
            curLen = attributeDisplayName.get(propName).length();
            int curLen = attributeDisplayName.get(ServerGroupProperty.UID)
                .length();
            for (int i = curLen; i < uidLength; i++)
            {
              buffer.append(" ");
            }
            buffer.append(": ");
            buffer.append(groupProps.get(ServerGroupProperty.UID));
            buffer.append(EOL);
            if (propName.compareTo(ServerGroupProperty.MEMBERS) == 0)
            // Write other props
            for (ServerGroupProperty propName : ServerGroupProperty.values())
            {
              Set atts = (Set) groupProps.get(propName);
              if (atts != null)
              if (propName.compareTo(ServerGroupProperty.UID) == 0)
              {
                boolean indent = false;
                for (Object att : atts)
                // We have already displayed the group Id
                continue;
              }
              buffer.append(attributeDisplayName.get(propName));
              // add space
              curLen = attributeDisplayName.get(propName).length();
              for (int i = curLen; i < uidLength; i++)
              {
                buffer.append(" ");
              }
              buffer.append(": ");
              if (propName.compareTo(ServerGroupProperty.MEMBERS) == 0)
              {
                Set atts = (Set) groupProps.get(propName);
                if (atts != null)
                {
                  if (indent)
                  boolean indent = false;
                  for (Object att : atts)
                  {
                    buffer.append(EOL);
                    for (int i = 0; i < uidLength + 2; i++)
                    if (indent)
                    {
                      buffer.append(" ");
                      buffer.append(EOL);
                      for (int i = 0; i < uidLength + 2; i++)
                      {
                        buffer.append(" ");
                      }
                    }
                    else
                    {
                      indent = true;
                    }
                    buffer.append(att.toString().substring(3));
                  }
                  else
                  {
                    indent = true;
                  }
                  buffer.append(att.toString().substring(3));
                }
              }
            }
            else
            {
              if (groupProps.get(propName) != null)
              else
              {
                buffer.append(groupProps.get(propName));
                if (groupProps.get(propName) != null)
                {
                  buffer.append(groupProps.get(propName));
                }
              }
              buffer.append(EOL);
            }
            buffer.append(EOL);
          }
          buffer.append(EOL);
        }
      }
      try
      {
        outStream.write(buffer.toString().getBytes());
      }
      catch (IOException e)
      {
      }
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // modify-group subcommand
    // -----------------------
    else if (subCmd.getName().equals(modifyGroupSubCmd.getName()))
    {
      String groupId = modifyGroupGroupNameArg.getValue();
      HashMap<ServerGroupProperty, Object> serverGroupProperties =
        new HashMap<ServerGroupProperty, Object>();
      HashSet<ServerGroupProperty> serverGroupPropertiesToRemove =
        new HashSet<ServerGroupProperty>();
      Boolean updateRequired = false;
      Boolean removeRequired = false;
      // get the GROUP_ID
      if (modifyGroupGroupIdArg.isPresent())
      {
        // rename the entry !
        serverGroupProperties.put(ServerGroupProperty.UID,
            modifyGroupGroupIdArg.getValue());
        updateRequired = true;
      }
      else
      {
        serverGroupProperties.put(ServerGroupProperty.UID, groupId) ;
      }
      // get the Description
      if (modifyGroupDescriptionArg.isPresent())
      {
        String newDesc = modifyGroupDescriptionArg.getValue();
        if (newDesc.length() == 0)
        try
        {
          serverGroupPropertiesToRemove.add(ServerGroupProperty.DESCRIPTION);
          removeRequired = true;
          outStream.write(buffer.toString().getBytes());
        }
        catch (IOException e)
        {
        }
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // modify-group subcommand
      // -----------------------
      else if (subCmd.getName().equals(modifyGroupSubCmd.getName()))
      {
        String groupId = modifyGroupGroupNameArg.getValue();
        HashMap<ServerGroupProperty, Object> serverGroupProperties =
          new HashMap<ServerGroupProperty, Object>();
        HashSet<ServerGroupProperty> serverGroupPropertiesToRemove =
          new HashSet<ServerGroupProperty>();
        Boolean updateRequired = false;
        Boolean removeRequired = false;
        // get the GROUP_ID
        if (modifyGroupGroupIdArg.isPresent())
        {
          // rename the entry !
          serverGroupProperties.put(ServerGroupProperty.UID,
              modifyGroupGroupIdArg.getValue());
          updateRequired = true;
        }
        else
        {
          serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
              modifyGroupDescriptionArg.getValue());
          updateRequired = true;
          serverGroupProperties.put(ServerGroupProperty.UID, groupId) ;
        }
      }
      // Update the server group
      if (updateRequired)
      {
        adsContext.updateServerGroup(groupId, serverGroupProperties);
      }
      if (removeRequired)
      {
        adsContext.removeServerGroupProp(groupId,
            serverGroupPropertiesToRemove);
      }
        // get the Description
        if (modifyGroupDescriptionArg.isPresent())
        {
          String newDesc = modifyGroupDescriptionArg.getValue();
          if (newDesc.length() == 0)
          {
            serverGroupPropertiesToRemove.add(ServerGroupProperty.DESCRIPTION);
            removeRequired = true;
          }
          else
          {
            serverGroupProperties.put(ServerGroupProperty.DESCRIPTION,
                modifyGroupDescriptionArg.getValue());
            updateRequired = true;
          }
        }
      if (updateRequired || removeRequired)
        // Update the server group
        if ( ! (updateRequired || removeRequired ) )
        {
          returnCode = ReturnCode.SUCCESSFUL_NOP;
        }
        // We need to perform an update
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        if (updateRequired)
        {
          adsCtx.updateServerGroup(groupId, serverGroupProperties);
        }
        if (removeRequired)
        {
          adsCtx.removeServerGroupProp(groupId,
              serverGroupPropertiesToRemove);
        }
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // add-to-group subcommand
      // -----------------------
      else if (subCmd.getName().equals(addToGroupSubCmd.getName()))
      {
        String groupId = addToGroupGroupNameArg.getValue();
        HashMap<ServerGroupProperty, Object> serverGroupProperties =
          new HashMap<ServerGroupProperty, Object>();
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        // get the current member list
        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
        if (memberList == null)
        {
          memberList = new HashSet<String>();
        }
        String newMember = "cn="
            + Rdn.escapeValue(addToGoupMemberNameArg.getValue());
        if (memberList.contains(newMember))
        {
          returnCode = ReturnCode.ALREADY_REGISTERED;
        }
        memberList.add(newMember);
        serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
        // Update the server group
        adsCtx.updateServerGroup(groupId, serverGroupProperties);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // remove-from-group subcommand
      // -----------------------
      else if (subCmd.getName().equals(removeFromGroupSubCmd.getName()))
      {
        String groupId = removeFromGroupGroupNameArg.getValue();
        HashMap<ServerGroupProperty, Object> serverGroupProperties =
          new HashMap<ServerGroupProperty, Object>();
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        // get the current member list
        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
        if (memberList == null)
        {
          returnCode = ReturnCode.NOT_YET_REGISTERED;
        }
        String memberToRemove = "cn="
            + Rdn.escapeValue(removeFromGoupMemberNameArg.getValue());
        if (!memberList.contains(memberToRemove))
        {
          returnCode = ReturnCode.NOT_YET_REGISTERED;
        }
        memberList.remove(memberToRemove);
        serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
        // Update the server group
        adsCtx.updateServerGroup(groupId, serverGroupProperties);
        returnCode = ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // list-members subcommand
      // -----------------------
      else if (subCmd.getName().equals(listMembersSubCmd.getName()))
      {
        String groupId = listMembersGroupNameArg.getValue();
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        // get the current member list
        Set<String> memberList = adsCtx.getServerGroupMemberList(groupId);
        if (memberList == null)
        {
          returnCode = ReturnCode.SUCCESSFUL;
        }
        StringBuffer buffer = new StringBuffer();
        for (String member : memberList)
        {
          buffer.append(member.substring(3));
          buffer.append(EOL);
        }
        try
        {
          outStream.write(buffer.toString().getBytes());
        }
        catch (IOException e)
        {
        }
        return ReturnCode.SUCCESSFUL;
      }
      // -----------------------
      // list-membership subcommand
      // -----------------------
      else if (subCmd.getName().equals(listMembershipSubCmd.getName()))
      {
        ctx = argParser.getContext(outStream, errStream);
        if (ctx == null)
        {
          return ReturnCode.CANNOT_CONNECT_TO_ADS;
        }
        adsCtx = new ADSContext(ctx) ;
        Set<Map<ServerGroupProperty, Object>> result = adsCtx
            .readServerGroupRegistry();
        String MemberId = listMembershipMemberNameArg.getValue();
        StringBuffer buffer = new StringBuffer();
        for (Map<ServerGroupProperty, Object> groupProps : result)
        {
          // Get the group name;
          String groupId = groupProps.get(ServerGroupProperty.UID).toString();
          // look for memeber list attribute
          for (ServerGroupProperty propName : groupProps.keySet())
          {
            if (propName.compareTo(ServerGroupProperty.MEMBERS) != 0)
            {
              continue;
            }
            // Check if the member list contains the member-id
            Set atts = (Set) groupProps.get(propName);
            for (Object att : atts)
            {
              if (att.toString().substring(3).toLowerCase().equals(
                  MemberId.toLowerCase()))
              {
                buffer.append(groupId);
                buffer.append(EOL);
                break;
              }
            }
            break;
          }
        }
        try
        {
          outStream.write(buffer.toString().getBytes());
        }
        catch (IOException e)
        {
        }
        returnCode = ReturnCode.SUCCESSFUL;
      }
      else
      {
       return ReturnCode.SUCCESSFUL_NOP;
        // Should never occurs: If we are here, it means that the code to
        // handle to subcommand is not yet written.
        returnCode = ReturnCode.ERROR_UNEXPECTED;
      }
    }
    // -----------------------
    // add-to-group subcommand
    // -----------------------
    else if (subCmd.getName().equals(addToGroupSubCmd.getName()))
    catch (ADSContextException e)
    {
      String groupId = addToGroupGroupNameArg.getValue();
      HashMap<ServerGroupProperty, Object> serverGroupProperties =
        new HashMap<ServerGroupProperty, Object>();
      // get the current member list
      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
      if (memberList == null)
      {
        memberList = new HashSet<String>();
      }
      String newMember = "cn="
          + Rdn.escapeValue(addToGoupMemberNameArg.getValue());
      if (memberList.contains(newMember))
      {
        return ReturnCode.ALREADY_REGISTERED;
      }
      memberList.add(newMember);
      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
      // Update the server group
      adsContext.updateServerGroup(groupId, serverGroupProperties);
      return ReturnCode.SUCCESSFUL;
     if (ctx != null)
     {
       try
       {
         ctx.close();
       }
       catch (NamingException x)
       {
       }
     }
     throw e;
    }
    // -----------------------
    // remove-from-group subcommand
    // -----------------------
    else if (subCmd.getName().equals(removeFromGroupSubCmd.getName()))
    // Close the connection, if needed
    if (ctx != null)
    {
      String groupId = removeFromGroupGroupNameArg.getValue();
      HashMap<ServerGroupProperty, Object> serverGroupProperties =
        new HashMap<ServerGroupProperty, Object>();
      // get the current member list
      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
      if (memberList == null)
      {
        return ReturnCode.NOT_YET_REGISTERED;
      }
      String memberToRemove = "cn="
          + Rdn.escapeValue(removeFromGoupMemberNameArg.getValue());
      if (!memberList.contains(memberToRemove))
      {
        return ReturnCode.NOT_YET_REGISTERED;
      }
      memberList.remove(memberToRemove);
      serverGroupProperties.put(ServerGroupProperty.MEMBERS, memberList);
      // Update the server group
      adsContext.updateServerGroup(groupId, serverGroupProperties);
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-members subcommand
    // -----------------------
    else if (subCmd.getName().equals(listMembersSubCmd.getName()))
    {
      String groupId = listMembersGroupNameArg.getValue();
      // get the current member list
      Set<String> memberList = adsContext.getServerGroupMemberList(groupId);
      if (memberList == null)
      {
        return ReturnCode.SUCCESSFUL;
      }
      StringBuffer buffer = new StringBuffer();
      for (String member : memberList)
      {
        buffer.append(member.substring(3));
        buffer.append(EOL);
      }
      try
      {
        outStream.write(buffer.toString().getBytes());
        ctx.close();
      }
      catch (IOException e)
      catch (NamingException x)
      {
      }
      return ReturnCode.SUCCESSFUL;
    }
    // -----------------------
    // list-membership subcommand
    // -----------------------
    else if (subCmd.getName().equals(listMembershipSubCmd.getName()))
    {
      Set<Map<ServerGroupProperty, Object>> result = adsContext
          .readServerGroupRegistry();
      String MemberId = listMembershipMemberNameArg.getValue();
      StringBuffer buffer = new StringBuffer();
      for (Map<ServerGroupProperty, Object> groupProps : result)
      {
        // Get the group name;
        String groupId = groupProps.get(ServerGroupProperty.UID).toString();
        // look for memeber list attribute
        for (ServerGroupProperty propName : groupProps.keySet())
        {
          if (propName.compareTo(ServerGroupProperty.MEMBERS) != 0)
          {
            continue;
          }
          // Check if the member list contains the member-id
          Set atts = (Set) groupProps.get(propName);
          for (Object att : atts)
          {
            if (att.toString().substring(3).toLowerCase().equals(
                MemberId.toLowerCase()))
            {
              buffer.append(groupId);
              buffer.append(EOL);
              break;
            }
          }
          break;
        }
      }
      try
      {
        outStream.write(buffer.toString().getBytes());
      }
      catch (IOException e)
      {
      }
      return ReturnCode.SUCCESSFUL;
    }
    // Should never occurs: If we are here, it means that the code to
    // handle to subcommand is not yet written.
    return ReturnCode.ERROR_UNEXPECTED;
    // return part
    return returnCode;
  }
}
opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliSubCommandGroup.java
@@ -27,14 +27,13 @@
 package org.opends.server.admin.client.cli;
import java.io.OutputStream;
import java.util.Set;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.ReturnCode;
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;
/**
 * This Interface defines method that a group of subcommand shoud implement.
@@ -53,7 +52,7 @@
   *           If there is a problem with any of the parameters used
   *           to create this argument.
   */
  public void initializeCliGroup(SubCommandArgumentParser argParser,
  public void initializeCliGroup(DsFrameworkCliParser argParser,
      BooleanArgument verboseArg) throws ArgumentException;
  /**
@@ -67,21 +66,43 @@
  /**
   * Handle the subcommand.
   * @param adsContext
   *          The context to use to perform ADS operation.
   * @param subCmd
   *          The actual subcommand with input parameter
   *
   * @param  outStream         The output stream to use for standard output.
   *
   * @param  errStream         The output stream to use for standard error.
   *
   * @return the return code
   * @throws ADSContextException
   *           If there is a problem with when trying to perform the
   *           operation.
   * @throws ArgumentException
   *           If there is a problem with any of the parameters used
   *           to execute this subcommand.
   */
  public ReturnCode performSubCommand(ADSContext adsContext,
      SubCommand subCmd, OutputStream outStream, OutputStream errStream)
      throws ADSContextException;
  public ReturnCode performSubCommand(SubCommand subCmd,
      OutputStream outStream, OutputStream errStream)
      throws ADSContextException, ArgumentException;
  /**
   * Get the subcommands list.
   * @return the subcommand list.
   */
  public Set<SubCommand> getSubCommands();
  /**
   * Indicates whether this subcommand group should be hidden from the usage
   * information.
   *
   * @return <CODE>true</CODE> if this subcommand group should be hidden
   *         from the usage information, or <CODE>false</CODE> if
   *         not.
   */
  public boolean isHidden();
  /**
   * Indicates subcommand group name.
   *
   * @return the subcommand group name
   */
  public String getGroupName();
}
opends/src/server/org/opends/server/messages/AdminMessages.java
@@ -492,6 +492,70 @@
  public static final int MSGID_ADMIN_UNABLE_TO_REGISTER_LISTENER =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_SEVERE_ERROR | 57;
  /**
   * 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_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 58;
  /**
   * 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_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 59;
  /**
   * The message ID for the message that will be used as the
   * description of the "server-name" argument. This does take one
   * argument.
   */
  public static final int MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 60;
  /**
   * The message ID for the message that will be used as the
   * description for the list-server-properties subcommand part of
   * dsservice tool. This does not take any arguments.
   */
  public static final int MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 61;
  /**
   * The message ID for the message that will be used as the
   * description for the list-servers subcommand part of dsservice
   * tool. This does not take any arguments.
   */
  public static final int MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 62;
  /**
   * The message ID for the message that will be used as the
   * description for the get-server-properties subcommand part of
   * dsservice tool. This does not take any arguments.
   */
  public static final int MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 63;
  /**
   * The message ID for the message that will be used as the
   * description for the set-server-properties subcommand part of
   * dsservice tool. This does not take any arguments.
   */
  public static final int MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 64;
  /**
   * The message ID for the message that will be used as the
   * description of the "server-host" argument. This does take one
   * argument.
   */
  public static final int MSGID_ADMIN_ARG_SERVERID_DESCRIPTION =
    CATEGORY_MASK_ADMIN | SEVERITY_MASK_INFORMATIONAL | 65;
  // Prevent instantiation.
  private AdminMessages() {
    // Do nothing.
@@ -665,8 +729,39 @@
    registerMessage(MSGID_ADMIN_ARG_BACKENDNAME_DESCRIPTION,
        "The name of the backend in which the admin data will be stored. " +
        "This is a required argument");
    registerMessage(MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION,
        "Register a server into the administrative domain");
    registerMessage(MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION,
        "Unregister a server from the administrative domain");
    registerMessage(MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION,
        "The server's identifier. This is a required argument");
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION,
        "Describes server properties");
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION,
        "List servers that have been defined");
    registerMessage(MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION,
        "Shows server properties");
    registerMessage(MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION,
        "Modifies server properties");
    registerMessage(MSGID_ADMIN_UNABLE_TO_REGISTER_LISTENER,
        "Unable to register an add/delete listener against the entry \"%s\" " +
        "because it does not exist in the configuration");
    registerMessage(MSGID_ADMIN_SUBCMD_REGISTER_SERVER_DESCRIPTION,
        "Register a server into the administrative domain");
    registerMessage(MSGID_ADMIN_SUBCMD_UNREGISTER_SERVER_DESCRIPTION,
        "Unregister a server from the administrative domain");
    registerMessage(MSGID_ADMIN_ARG_SERVERNAME_DESCRIPTION,
        "The server's identifier. This is a required argument");
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVER_PROPS_DESCRIPTION,
        "Describes server properties");
    registerMessage(MSGID_ADMIN_SUBCMD_LIST_SERVERS_DESCRIPTION,
        "List servers that have been defined");
    registerMessage(MSGID_ADMIN_SUBCMD_GET_SERVER_PROPERTIES_DESCRIPTION,
        "Shows server properties");
    registerMessage(MSGID_ADMIN_SUBCMD_SET_SERVER_PROPERTIES_DESCRIPTION,
        "Modifies server properties");
    registerMessage(MSGID_ADMIN_ARG_SERVERID_DESCRIPTION,
        "The registered server's unique identifier. " +
        "This is a required argument");
  }
}
opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -9150,6 +9150,37 @@
   */
  public static final int MSGID_CONFIGDS_PORT_ALREADY_SPECIFIED  =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1211;
  /**
   * The message ID for the message that will be used if the user
   * attempts to access a property which is not recognized. This takes
   * one argument which is the name of the invalid property.
   */
  public static final int MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED =
      CATEGORY_MASK_TOOLS  | SEVERITY_MASK_SEVERE_ERROR | 1212;
  /**
   * The message ID for the message that will be used if the user
   * doesn't specify a mandatory property. This takes one argument
   * which is the name of the missing property.
   */
  public static final int MSGID_CLI_ERROR_MISSING_PROPERTY =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1213;
  /**
   * The message ID for the message that will be used if the user
   * specify a wrong value of a property. This takes two arguments
   * which is the name of the property and the wrong value.
   */
  public static final int MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 1214;
  /**
   * The message ID for the message that will be used as the
   * heading of the property default value column in tables.
   */
  public static final int MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1215;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -12103,6 +12134,16 @@
                    "Password History");
    registerMessage(MSGID_PWPSTATE_INVALID_RESPONSE_OP_TYPE,
                    "Unrecognized or invalid operation type:  %s");
    registerMessage(MSGID_CLI_ERROR_PROPERTY_UNRECOGNIZED,
                    "The property \"%s\" is not a recognized property");
    registerMessage(MSGID_CLI_ERROR_MISSING_PROPERTY,
                    "The mandatory property \"%s\" is missing");
    registerMessage(MSGID_CLI_ERROR_INVALID_PROPERTY_VALUE,
                    "The value \"%s\" specified fo the property \"%s\" is " +
                    "invalid");
    registerMessage(MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE,
                    "Default value");
  }
}
opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -586,5 +586,38 @@
   * displayed in usage information.
   */
  public static final String OPTION_VALUE_BACKENDNAME = "{backend-name}";
  /**
   * The value for the short option serverID attributes.
   */
  public static final String OPTION_SHORT_SERVERID = null;
  /**
   * The value for the long option serverID
   * attribute.
   */
  public static final String OPTION_LONG_SERVERID= "serverID";
  /**
   * The placeholder value of serverID that will be
   * displayed in usage information.
   */
  public static final String OPTION_VALUE_SERVERID = "{serverID}";
  /**
   * The value for the short option set.
   */
  public static final Character OPTION_SHORT_SET = null;
  /**
  * The value for the long option set.
  */
 public static final String OPTION_LONG_SET = "set";
 /**
  * The placeholder value for the long option set.
  */
 public static final String OPTION_VALUE_SET = "{PROP:VAL}";
}
opends/tests/unit-tests-testng/src/server/org/opends/server/admin/client/cli/CliTest.java
@@ -106,7 +106,7 @@
    
    try
    {
      cli.initializeCliGroup(new SubCommandArgumentParser(null, null, false),
      cli.initializeCliGroup(new DsFrameworkCliParser(null, null, false),
          null);
    }
    catch (ArgumentException e)