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

matthew_swift
16.40.2007 0a2e22293f5c36807d89441f9bd8c56ae0b59097
Update admin framework and dsconfig to support tagging
of component definitions as advanced and customizable:

* advanced components: these will not be displayed by
default in dsconfig. Examples include the various
system backends

* customizable components: these components are tagged
as intended for customization using the CLI XML
profile. Customizable components are usually the top
level components previously referred to as "generic"
by dsconfig. This term confused users who would, for
example, mistake a "generic" backend for a JE backend.

This change is part of issue 1829.
1 files added
14 files modified
523 ■■■■ changed files
opends/resource/admin/admin-cli.xsd 24 ●●●●● patch | view | raw | blame | history
opends/resource/admin/admin.xsd 35 ●●●●● patch | view | raw | blame | history
opends/resource/admin/cliMOProfile.xsl 12 ●●●●● patch | view | raw | blame | history
opends/resource/admin/metaMO.xsl 81 ●●●● patch | view | raw | blame | history
opends/resource/admin/preprocessor.xsl 4 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/dsconfig.properties 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java 49 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/ManagedObjectOption.java 49 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/RelationOption.java 10 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java 18 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java 103 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java 14 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java 32 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java 41 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java 46 ●●●● patch | view | raw | blame | history
opends/resource/admin/admin-cli.xsd
@@ -14,6 +14,30 @@
      experience.
    </xsd:documentation>
  </xsd:annotation>
  <xsd:element name="managed-object">
    <xsd:annotation>
      <xsd:documentation>
        Defines CLI annotations for use with managed object definitions.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:attribute name="custom" default="false" type="xsd:boolean">
        <xsd:annotation>
          <xsd:documentation>
            Indicates whether the CLI should refer to this managed
            object type as "custom" as opposed to "generic". Custom
            managed object types generally are the top-level type of
            component (e.g. connection-handler but not
            ldap-connection-handler) having a non-advanced java-class
            property. Users create this type of component with a custom
            implementation class. It is better to refer to these as
            "custom" since the term "generic" can mislead users (e.g.
            many users confuse a generic backend as being a JE backend).
          </xsd:documentation>
        </xsd:annotation>
      </xsd:attribute>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="relation">
    <xsd:annotation>
      <xsd:documentation>
opends/resource/admin/admin.xsd
@@ -754,6 +754,16 @@
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name="advanced" type="xsd:boolean" use="optional"
      default="false">
      <xsd:annotation>
        <xsd:documentation>
          Indicates whether or not managed objects referenced by this
          relation should be treated as advanced and be hidden by
          default in client applications.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
    <xsd:attribute name="hidden" type="xsd:boolean" use="optional"
      default="false">
      <xsd:annotation>
@@ -1836,11 +1846,34 @@
              </xsd:documentation>
            </xsd:annotation>
          </xsd:attribute>
          <xsd:attribute name="advanced" type="xsd:boolean"
            use="optional" default="false">
            <xsd:annotation>
              <xsd:documentation>
                Indicates whether or not this managed object should be
                treated as advanced and therefore should be hidden by
                default in client applications. This feature is not
                inherited by child managed objects.
              </xsd:documentation>
            </xsd:annotation>
          </xsd:attribute>
          <xsd:attribute name="hidden" type="xsd:boolean" use="optional"
            default="false">
            <xsd:annotation>
              <xsd:documentation>
                Indicates whether or not this managed object should be
                hidden from client applications. Hidden managed objects
                should rarely be used but are sometimes required in
                order to provide functionality that needs to be exposed
                in management APIs but not in front-ends such as CLIs.
              </xsd:documentation>
            </xsd:annotation>
          </xsd:attribute>
          <xsd:attribute name="extends" type="tns:name-type"
            use="optional">
            <xsd:annotation>
              <xsd:documentation>
                Indicates whether or not this managed object is inherits
                Indicates whether or not this managed object inherits
                from a parent managed object and, if so, the name of the
                parent. If specified, this managed object will inherit
                all of the properties and relations defined in the
opends/resource/admin/cliMOProfile.xsl
@@ -35,6 +35,18 @@
  -->
  <xsl:template match="/">
    <!--
      Determine if the managed object is for customization.
    -->
    <xsl:choose>
      <xsl:when
        test="$this/adm:profile[@name='cli']/cli:managed-object/@custom='true'">
        <xsl:value-of select="'is-for-customization=true&#xa;'" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="'is-for-customization=false&#xa;'" />
      </xsl:otherwise>
    </xsl:choose>
    <!--
      Process each relation definition.
    -->
    <xsl:for-each select="$this-all-relations">
opends/resource/admin/metaMO.xsl
@@ -153,6 +153,26 @@
      <xsl:call-template name="generate-relation-constructor" />
    </xsl:for-each>
    <!--
      Register any optins associated with this managed object definition.
    -->
    <xsl:if test="$this-is-advanced or $this-is-hidden">
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:text>&#xa;</xsl:text>
      <xsl:value-of
        select="'  // Register the options associated with this managed object definition.&#xa;'" />
      <xsl:value-of select="'  static {&#xa;'" />
      <xsl:if test="$this-is-advanced">
        <xsl:value-of
          select="concat('    INSTANCE.registerOption(ManagedObjectOption.ADVANCED);&#xa;')" />
      </xsl:if>
      <xsl:if test="$this-is-hidden">
        <xsl:value-of
          select="concat('    INSTANCE.registerOption(ManagedObjectOption.HIDDEN);&#xa;')" />
      </xsl:if>
      <xsl:value-of select="'  }&#xa;'" />
    </xsl:if>
    <!--
      Register any tags associated with this managed object definition.
    -->
    <xsl:if test="$this/adm:tag">
@@ -923,6 +943,10 @@
                           'CfgDefn.getInstance().get',
                           $java-property-name, 'PropertyDefinition());&#xa;')" />
    </xsl:if>
    <xsl:if test="@advanced='true'">
      <xsl:value-of
        select="'    builder.setOption(RelationOption.ADVANCED);&#xa;'" />
    </xsl:if>
    <xsl:if test="@hidden='true'">
      <xsl:value-of
        select="'    builder.setOption(RelationOption.HIDDEN);&#xa;'" />
@@ -1615,26 +1639,39 @@
        </xsl:message>
      </xsl:if>
      <!--
        Check that all advanced properties are non-mandatory or have a default.
        Check that all advanced properties conform to one of
        the following rules:
        * is mandatory and has a defined default value(s)
        * is mandatory and is part of an advanced managed object
        * is mandatory and is part of an abstract managed object
        * is not mandatory
      -->
      <xsl:if
        test="not($this-is-abstract) and @advanced='true' and @mandatory='true'">
        <xsl:choose>
          <xsl:when test="adm:default-behavior/adm:defined">
            <!--  OK  -->
          </xsl:when>
          <xsl:when test="adm:default-behavior/adm:inherited">
            <!--  OK  -->
          </xsl:when>
          <xsl:otherwise>
            <xsl:message terminate="yes">
              <xsl:value-of
                select="concat('Property &quot;', @name,
                         '&quot; is advanced and mandatory but has no default values.')" />
            </xsl:message>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
      <xsl:choose>
        <xsl:when test="$this-is-advanced">
          <!--  OK  -->
        </xsl:when>
        <xsl:when test="$this-is-abstract">
          <!--  OK  -->
        </xsl:when>
        <xsl:when test="@advanced='true' and @mandatory='true'">
          <xsl:choose>
            <xsl:when test="adm:default-behavior/adm:defined">
              <!--  OK  -->
            </xsl:when>
            <xsl:when test="adm:default-behavior/adm:inherited">
              <!--  OK  -->
            </xsl:when>
            <xsl:otherwise>
              <xsl:message terminate="yes">
                <xsl:value-of
                  select="concat('Advanced property &quot;', @name,
                         '&quot; must have defined or inherited default values.')" />
              </xsl:message>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:when>
      </xsl:choose>
    </xsl:for-each>
    <!-- 
      Now generate the definition.
@@ -1750,9 +1787,13 @@
              select="concat(@managed-object-package, '.server.', $java-class-name, 'Cfg')" />
          </xsl:element>
        </xsl:for-each>
        <xsl:if test="$this-local-relations[@hidden='true']">
        <xsl:if
          test="$this-local-relations[@advanced='true' or @hidden='true']">
          <import>org.opends.server.admin.RelationOption</import>
        </xsl:if>
        <xsl:if test="$this-is-hidden or $this-is-advanced">
          <import>org.opends.server.admin.ManagedObjectOption</import>
        </xsl:if>
        <xsl:if test="$this-all-relations/adm:one-to-many">
          <import>
            org.opends.server.admin.InstantiableRelationDefinition
opends/resource/admin/preprocessor.xsl
@@ -1123,6 +1123,10 @@
    select="$_this_tmp/adm:managed-object | $_this_tmp/adm:root-managed-object" />
  <xsl:variable name="this-is-abstract"
    select="boolean(string($this/@abstract) = 'true')" />
  <xsl:variable name="this-is-advanced"
    select="boolean(string($this/@advanced) = 'true')" />
  <xsl:variable name="this-is-hidden"
    select="boolean(string($this/@hidden) = 'true')" />
  <xsl:variable name="this-is-root"
    select="not(local-name($this) = 'managed-object')" />
  <xsl:variable name="this-package">
opends/src/messages/messages/dsconfig.properties
@@ -442,3 +442,8 @@
INFO_DSCFG_PROMPT_EDIT_TO_ENABLE_146=The referenced %s \
 called "%s" must be enabled so that it can be used with this %s. Do \
 you want to edit its properties in order to enable it?
INFO_DSCFG_CUSTOM_TYPE_OPTION_147=Custom %s
INFO_DSCFG_CUSTOM_TYPE_SYNOPSIS_148=A Custom %s with a user-defined \
 implementation class
INFO_DSCFG_GENERIC_TYPE_SYNOPSIS_149=A Generic %s
INFO_DSCFG_CREATE_TYPE_HELP_HEADING_150=Help: %s
opends/src/server/org/opends/server/admin/AbstractManagedObjectDefinition.java
@@ -32,6 +32,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
@@ -92,6 +93,9 @@
  // The set of tags associated with this managed object.
  private final Set<Tag> allTags;
  // Options applicable to this definition.
  private final Set<ManagedObjectOption> options;
  // The set of managed object definitions which inherit from this definition.
  private final Map<String,
    AbstractManagedObjectDefinition<? extends C, ? extends S>> children;
@@ -120,6 +124,8 @@
    this.allRelationDefinitions =
      new HashMap<String, RelationDefinition<?, ?>>();
    this.allTags = new HashSet<Tag>();
    this.options = EnumSet.noneOf(ManagedObjectOption.class);
    this.children = new HashMap<String,
        AbstractManagedObjectDefinition<? extends C, ? extends S>>();
@@ -592,6 +598,21 @@
  /**
   * Determines whether or not this managed object definition has the
   * specified option.
   *
   * @param option
   *          The option to test.
   * @return Returns <code>true</code> if the option is set, or
   *         <code>false</code> otherwise.
   */
  public final boolean hasOption(ManagedObjectOption option) {
    return options.contains(option);
  }
  /**
   * Determines whether or not this managed object definition has the
   * specified tag.
   *
   * @param t
@@ -749,7 +770,7 @@
  /**
   * Register a constraint with the managed object definition.
   * Register a constraint with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
@@ -763,7 +784,7 @@
  /**
   * Register a property definition with the managed object definition,
   * Register a property definition with this managed object definition,
   * overriding any existing property definition with the same name.
   * <p>
   * This method <b>must not</b> be called by applications.
@@ -781,7 +802,7 @@
  /**
   * Register a relation definition with the managed object definition,
   * Register a relation definition with this managed object definition,
   * overriding any existing relation definition with the same name.
   * <p>
   * This method <b>must not</b> be called by applications.
@@ -799,15 +820,29 @@
  /**
   * Register a tag with the managed object definition.
   * Register an option with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param t
   * @param option
   *          The option to be registered.
   */
  protected final void registerOption(ManagedObjectOption option) {
    options.add(option);
  }
  /**
   * Register a tag with this managed object definition.
   * <p>
   * This method <b>must not</b> be called by applications.
   *
   * @param tag
   *          The tag to be registered.
   */
  protected final void registerTag(Tag t) {
    allTags.add(t);
  protected final void registerTag(Tag tag) {
    allTags.add(tag);
  }
opends/src/server/org/opends/server/admin/ManagedObjectOption.java
New file
@@ -0,0 +1,49 @@
/*
 * 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 2007 Sun Microsystems, Inc.
 */
package org.opends.server.admin;
/**
 * This enumeration contains various options that can be associated
 * with managed object definitions.
 */
public enum ManagedObjectOption {
  /**
   * Use this option to identify managed object types which should be
   * considered as advanced and should not be exposed by default in
   * client applications.
   */
  ADVANCED,
  /**
   * Use this option to identify managed object types which must not
   * be directly exposed in client applications.
   */
  HIDDEN;
}
opends/src/server/org/opends/server/admin/RelationOption.java
@@ -32,12 +32,16 @@
/**
 * This enumeration contains various options that can be associated
 * with relation definitions.
 * <p>
 * Only one option is supported at the moment, but others may be added
 * in future.
 */
public enum RelationOption {
  /**
   * Use this option to identify relations which should be considered
   * as advanced and should not be exposed by default in client
   * applications.
   */
  ADVANCED,
  /**
   * Use this option to identify relations which must not be directly
   * exposed in client applications.
   */
opends/src/server/org/opends/server/tools/dsconfig/CLIProfile.java
@@ -33,6 +33,7 @@
import java.util.LinkedHashSet;
import java.util.Set;
import org.opends.server.admin.AbstractManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectDefinitionResource;
import org.opends.server.admin.RelationDefinition;
@@ -83,4 +84,21 @@
        + r.getName() + ".list-properties");
    return new LinkedHashSet<String>(Arrays.asList(s.split(",")));
  }
  /**
   * Determines if instances of the specified managed object
   * definition are to be used for customization.
   *
   * @param d
   *          The managed object definition.
   * @return Returns <code>true</code> if instances of the specified
   *         managed object definition are to be used for
   *         customization.
   */
  public boolean isForCustomization(AbstractManagedObjectDefinition<?, ?> d) {
    String s = resource.getString(d, "is-for-customization");
    return Boolean.parseBoolean(s);
  }
}
opends/src/server/org/opends/server/tools/dsconfig/CreateSubCommandHandler.java
@@ -55,6 +55,7 @@
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectOption;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
@@ -254,6 +255,20 @@
     * {@inheritDoc}
     */
    public void display(ConsoleApplication app) {
      app.println(INFO_DSCFG_CREATE_TYPE_HELP_HEADING.get(d
          .getUserFriendlyPluralName()));
      app.println();
      app.println(d.getSynopsis());
      if (d.getDescription() != null) {
        app.println();
        app.println(d.getDescription());
      }
      app.println();
      app.println();
      // Create a table containing a description of each component
      // type.
      TableBuilder builder = new TableBuilder();
@@ -266,6 +281,30 @@
      boolean isFirst = true;
      for (ManagedObjectDefinition<?, ?> mod : getSubTypes(d).values()) {
        // Only display advanced types and custom types in advanced mode.
        if (!app.isAdvancedMode()) {
          if (mod.hasOption(ManagedObjectOption.ADVANCED)) {
            continue;
          }
          if (CLIProfile.getInstance().isForCustomization(mod)) {
            continue;
          }
        }
        Message ufn = mod.getUserFriendlyName();
        Message synopsis = mod.getSynopsis();
        Message description = mod.getDescription();
        if (CLIProfile.getInstance().isForCustomization(mod)) {
          ufn = INFO_DSCFG_CUSTOM_TYPE_OPTION.get(ufn);
          synopsis = INFO_DSCFG_CUSTOM_TYPE_SYNOPSIS.get(ufn);
          description = null;
        } else if (mod == d) {
          ufn = INFO_DSCFG_GENERIC_TYPE_OPTION.get(ufn);
          synopsis = INFO_DSCFG_GENERIC_TYPE_SYNOPSIS.get(ufn);
          description = null;
        }
        if (!isFirst) {
          builder.startRow();
          builder.startRow();
@@ -274,13 +313,13 @@
        }
        builder.startRow();
        builder.appendCell(mod.getUserFriendlyName());
        builder.appendCell(mod.getSynopsis());
        if (mod.getDescription() != null) {
        builder.appendCell(ufn);
        builder.appendCell(synopsis);
        if (description != null) {
          builder.startRow();
          builder.startRow();
          builder.appendCell();
          builder.appendCell(mod.getDescription());
          builder.appendCell(description);
        }
      }
@@ -296,12 +335,6 @@
  /**
   * The value for the -t argument which will be used for the most
   * generic managed object when it is instantiable.
   */
  private static final String GENERIC_TYPE = "generic";
  /**
   * The value for the long option set.
   */
  private static final String OPTION_DSCFG_LONG_SET = "set";
@@ -815,17 +848,27 @@
      new TreeMap<String, ManagedObjectDefinition<? extends C, ? extends S>>();
    // If the top-level definition is instantiable, we use the value
    // "generic".
    if (d instanceof ManagedObjectDefinition) {
      ManagedObjectDefinition<? extends C, ? extends S> mod =
        (ManagedObjectDefinition<? extends C, ? extends S>) d;
      map.put(GENERIC_TYPE, mod);
    // "generic" or "custom".
    if (!d.hasOption(ManagedObjectOption.HIDDEN)) {
      if (d instanceof ManagedObjectDefinition) {
        ManagedObjectDefinition<? extends C, ? extends S> mod =
          (ManagedObjectDefinition<? extends C, ? extends S>) d;
        if (CLIProfile.getInstance().isForCustomization(mod)) {
          map.put(DSConfig.CUSTOM_TYPE, mod);
        } else {
          map.put(DSConfig.GENERIC_TYPE, mod);
        }
      }
    }
    // Process its sub-definitions.
    String suffix = "-" + d.getName();
    for (AbstractManagedObjectDefinition<? extends C, ? extends S> c : d
        .getAllChildren()) {
      if (d.hasOption(ManagedObjectOption.HIDDEN)) {
        continue;
      }
      if (c instanceof ManagedObjectDefinition) {
        ManagedObjectDefinition<? extends C, ? extends S> mod =
          (ManagedObjectDefinition<? extends C, ? extends S>) c;
@@ -838,6 +881,12 @@
          name = name.substring(0, name.length() - suffix.length());
        }
        // If this type is intended for customization, prefix it with
        // "custom".
        if (CLIProfile.getInstance().isForCustomization(mod)) {
          name = String.format("%s-%s", DSConfig.CUSTOM_TYPE, name);
        }
        map.put(name, mod);
      }
    }
@@ -869,8 +918,21 @@
      builder.setPrompt(msg);
      for (ManagedObjectDefinition<? extends C, ? extends S> mod : types) {
        // Only display advanced types and custom types in advanced mode.
        if (!app.isAdvancedMode()) {
          if (mod.hasOption(ManagedObjectOption.ADVANCED)) {
            continue;
          }
          if (CLIProfile.getInstance().isForCustomization(mod)) {
            continue;
          }
        }
        Message option = mod.getUserFriendlyName();
        if ((mod == d) && (mod instanceof ManagedObjectDefinition)) {
        if (CLIProfile.getInstance().isForCustomization(mod)) {
          option = INFO_DSCFG_CUSTOM_TYPE_OPTION.get(option);
        } else if (mod == d) {
          option = INFO_DSCFG_GENERIC_TYPE_OPTION.get(option);
        }
        builder.addNumberedOption(option,
@@ -963,7 +1025,7 @@
    }
    this.typeUsage = builder.toString();
    if (!types.containsKey(GENERIC_TYPE)) {
    if (!types.containsKey(DSConfig.GENERIC_TYPE)) {
      // The option is mandatory when non-interactive.
      this.typeArgument = new StringArgument("type", OPTION_DSCFG_SHORT_TYPE,
          OPTION_DSCFG_LONG_TYPE, false, false, true, "{TYPE}", null, null,
@@ -972,9 +1034,10 @@
    } else {
      // The option has a sensible default "generic".
      this.typeArgument = new StringArgument("type", OPTION_DSCFG_SHORT_TYPE,
          OPTION_DSCFG_LONG_TYPE, false, false, true, "{TYPE}", GENERIC_TYPE,
          null, INFO_DSCFG_DESCRIPTION_TYPE_DEFAULT.get(r.getChildDefinition()
              .getUserFriendlyName(), GENERIC_TYPE, typeUsage));
          OPTION_DSCFG_LONG_TYPE, false, false, true, "{TYPE}",
          DSConfig.GENERIC_TYPE, null, INFO_DSCFG_DESCRIPTION_TYPE_DEFAULT.get(
              r.getChildDefinition().getUserFriendlyName(),
              DSConfig.GENERIC_TYPE, typeUsage));
      // Hide the option if it defaults to generic and generic is the
      // only possible value.
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -250,6 +250,20 @@
  }
  /**
   * The type name which will be used for the most generic managed
   * object types when they are instantiable and intended for
   * customization only.
   */
  public static final String CUSTOM_TYPE = "custom";
  /**
   * The type name which will be used for the most generic managed
   * object types when they are instantiable and not intended for
   * customization.
   */
  public static final String GENERIC_TYPE = "generic";
  /**
   * The value for the long option advanced.
   */
  private static final String OPTION_DSCFG_LONG_ADVANCED = "advanced";
opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
@@ -52,6 +52,7 @@
import org.opends.server.admin.DefaultBehaviorProviderVisitor;
import org.opends.server.admin.DefinedDefaultBehaviorProvider;
import org.opends.server.admin.EnumPropertyDefinition;
import org.opends.server.admin.ManagedObjectOption;
import org.opends.server.admin.PropertyDefinition;
import org.opends.server.admin.PropertyDefinitionUsageBuilder;
import org.opends.server.admin.PropertyDefinitionVisitor;
@@ -358,11 +359,6 @@
    }
  }
  /**
   * The type component name to be used for top-level definitions.
   */
  private static final String GENERIC_TYPE = "generic";
  // Strings used in property help.
  private final static String HEADING_SEPARATOR = " : ";
@@ -765,7 +761,7 @@
    String typeName = null;
    if (parent == d) {
      // This was a top-level definition.
      typeName = GENERIC_TYPE;
      typeName = DSConfig.GENERIC_TYPE;
    } else {
      // For the type name we shorten it, if possible, by stripping
      // off the trailing part of the name which matches the
@@ -836,7 +832,7 @@
        }
      } else {
        // Cache the generic definition for improved errors later on.
        tmp = subTypes.get(GENERIC_TYPE);
        tmp = subTypes.get(DSConfig.GENERIC_TYPE);
      }
      if (typeName != null) {
@@ -959,6 +955,17 @@
        // Display help for each property.
        AbstractManagedObjectDefinition<?, ?> mod = subTypes.get(type);
        // Skip hidden types.
        if (mod.hasOption(ManagedObjectOption.HIDDEN)) {
          continue;
        }
        // Skip advanced types if required.
        if (!app.isAdvancedMode()
            && mod.hasOption(ManagedObjectOption.ADVANCED)) {
          continue;
        }
        // Skip if this does not have the required tag.
        if (tag != null && !mod.hasTag(tag)) {
          continue;
@@ -1062,6 +1069,17 @@
        // Display help for each property.
        AbstractManagedObjectDefinition<?, ?> mod = subTypes.get(type);
        // Skip hidden types.
        if (mod.hasOption(ManagedObjectOption.HIDDEN)) {
          continue;
        }
        // Skip advanced types if required.
        if (!app.isAdvancedMode()
            && mod.hasOption(ManagedObjectOption.ADVANCED)) {
          continue;
        }
        // Skip if this does not have the required tag.
        if (tag != null && !mod.hasTag(tag)) {
          continue;
opends/src/server/org/opends/server/tools/dsconfig/ListSubCommandHandler.java
@@ -42,6 +42,7 @@
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectOption;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.OptionalRelationDefinition;
import org.opends.server.admin.PropertyDefinition;
@@ -322,6 +323,20 @@
    if (app.isScriptFriendly()) {
      // Output just the names of the children.
      for (String name : children.keySet()) {
        // Skip advanced and hidden components in non-advanced mode.
        if (!app.isAdvancedMode()) {
          ManagedObject<?> child = children.get(name);
          ManagedObjectDefinition<?, ?> d = child.getManagedObjectDefinition();
          if (d.hasOption(ManagedObjectOption.HIDDEN)) {
            continue;
          }
          if (d.hasOption(ManagedObjectOption.ADVANCED)) {
            continue;
          }
        }
        app.println(Message.raw(name));
      }
    } else {
@@ -341,6 +356,17 @@
        ManagedObject<?> child = children.get(name);
        ManagedObjectDefinition<?, ?> d = child.getManagedObjectDefinition();
        // Skip advanced and hidden components in non-advanced mode.
        if (!app.isAdvancedMode()) {
          if (d.hasOption(ManagedObjectOption.HIDDEN)) {
            continue;
          }
          if (d.hasOption(ManagedObjectOption.ADVANCED)) {
            continue;
          }
        }
        // First output the name.
        builder.startRow();
        builder.appendCell(name);
@@ -348,11 +374,20 @@
        // Output the managed object type in the form used in
        // create-xxx commands.
        String childType = d.getName();
        boolean isCustom = CLIProfile.getInstance().isForCustomization(d);
        if (baseType.equals(childType)) {
          builder.appendCell("generic");
          if (isCustom) {
            builder.appendCell(DSConfig.CUSTOM_TYPE);
          } else {
            builder.appendCell(DSConfig.GENERIC_TYPE);
          }
        } else if (childType.endsWith(typeSuffix)) {
          builder.appendCell(childType.substring(0, childType.length()
              - typeSuffix.length()));
          String ctname = childType.substring(0, childType.length()
              - typeSuffix.length());
          if (isCustom) {
            ctname = String.format("%s-%s", DSConfig.CUSTOM_TYPE, ctname);
          }
          builder.appendCell(ctname);
        } else {
          builder.appendCell(childType);
        }
opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
@@ -40,6 +40,8 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.opends.messages.Message;
import org.opends.server.admin.AbstractManagedObjectDefinition;
@@ -48,7 +50,9 @@
import org.opends.server.admin.DefinitionDecodingException;
import org.opends.server.admin.DurationUnit;
import org.opends.server.admin.InstantiableRelationDefinition;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.ManagedObjectNotFoundException;
import org.opends.server.admin.ManagedObjectOption;
import org.opends.server.admin.ManagedObjectPath;
import org.opends.server.admin.ManagedObjectPathSerializer;
import org.opends.server.admin.OptionalRelationDefinition;
@@ -987,8 +991,41 @@
    app.println();
    app.println();
    String[] children = parent.listChildren(r, d);
    switch (children.length) {
    // Filter out advanced and hidden types if required.
    String[] childNames = parent.listChildren(r, d);
    SortedSet<String> children = new TreeSet<String>(
        String.CASE_INSENSITIVE_ORDER);
    for (String childName : childNames) {
      ManagedObject<?> child;
      try {
        child = parent.getChild(r, childName);
        ManagedObjectDefinition<?, ?> cd = child.getManagedObjectDefinition();
        if (cd.hasOption(ManagedObjectOption.HIDDEN)) {
          continue;
        }
        if (!app.isAdvancedMode()
            && cd.hasOption(ManagedObjectOption.ADVANCED)) {
          continue;
        }
        children.add(childName);
      } catch (DefinitionDecodingException e) {
        // Add it anyway: maybe the user is trying to fix the problem.
        children.add(childName);
      } catch (ManagedObjectDecodingException e) {
        // Add it anyway: maybe the user is trying to fix the problem.
        children.add(childName);
      } catch (ManagedObjectNotFoundException e) {
        // Skip it - the managed object has been concurrently removed.
      }
    }
    switch (children.size()) {
    case 0: {
      // No options available - abort.
      Message msg =
@@ -999,9 +1036,9 @@
      // Only one option available so confirm that the user wishes to
      // access it.
      Message msg = INFO_DSCFG_FINDER_PROMPT_SINGLE.get(
              d.getUserFriendlyName(), children[0]);
              d.getUserFriendlyName(), children.first());
      if (app.confirmAction(msg, true)) {
        return MenuResult.success(children[0]);
        return MenuResult.success(children.first());
      } else {
        return MenuResult.cancel();
      }
@@ -1013,7 +1050,6 @@
      builder.setPrompt(INFO_DSCFG_FINDER_PROMPT_MANY.get(d
          .getUserFriendlyName()));
      Arrays.sort(children, String.CASE_INSENSITIVE_ORDER);
      for (String child : children) {
        Message option = Message.raw("%s", child);
        builder.addNumberedOption(option, MenuResult.success(child));