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

matthew_swift
23.55.2007 0a513d14b86d6192e71d1cfeb1b7719fcddd4f74
Fix issue 1819: add support for tagging properties as advanced.

It is now possible to tag a property as advanced. This is achieved by adding the "advanced" attribute to XML property definitions. For example:

<adm:property name="java-implementation-class" mandatory="true" advanced="true">
...
</adm:property>

Advanced properties must be either option or, if they are mandatory, have default values (defined or inherited). This constraint is enforced except for abstract property definitions where sub-definitions can override the property and give it a default (this is the case for java implementation class properties).

Dsconfig has been modified so that get-xxx-prop and list-properties sub-commands only display advanced properties if the user provides the "--advanced" command line option. There will be similar support for set-xxx-prop and create-xxx sub-commands once they have a fully functional interactive mode (issue 1831).

This change just adds support for advanced properties. A subsequent change (for issue 1829) will designate which properties are advanced.
10 files modified
200 ■■■■■ changed files
opendj-sdk/opends/resource/admin/admin.xsd 13 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/metaMO.xsl 55 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyOption.java 7 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/admin/client/PropertySet.java 5 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java 37 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java 6 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java 22 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java 52 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/messages.properties 1 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/resource/admin/admin.xsd
@@ -393,6 +393,19 @@
        </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 property should be treated as an
          advanced property and hidden by default in client
          applications. Advanced properties should either be optional
          (i.e. not mandatory) or be mandatory with default values. This
          constraint is required so that users do not have to specify
          values for advanced properties.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:attribute>
  </xsd:complexType>
  <xsd:complexType name="property-reference-type">
    <xsd:annotation>
opendj-sdk/opends/resource/admin/metaMO.xsl
@@ -622,6 +622,10 @@
      <xsl:value-of
        select="'      builder.setOption(PropertyOption.HIDDEN);&#xa;'" />
    </xsl:if>
    <xsl:if test="@advanced='true'">
      <xsl:value-of
        select="'      builder.setOption(PropertyOption.ADVANCED);&#xa;'" />
    </xsl:if>
    <xsl:variable name="action-type">
      <xsl:choose>
        <xsl:when test="adm:requires-admin-action">
@@ -637,14 +641,6 @@
    </xsl:variable>
    <xsl:value-of
      select="concat('      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.', $action-type, ', INSTANCE, &quot;', @name, '&quot;));&#xa;')" />
    <xsl:if
      test="not(@mandatory='true') and not(adm:default-behavior)">
      <xsl:message terminate="yes">
        <xsl:value-of
          select="concat('No default behavior defined for non-mandatory property &quot;', @name,
                         '&quot;.')" />
      </xsl:message>
    </xsl:if>
    <xsl:choose>
      <xsl:when
        test="not(adm:default-behavior) or adm:default-behavior/adm:undefined">
@@ -1640,6 +1636,45 @@
    Main document parsing template.
  -->
  <xsl:template match="/">
    <!--  Perform some initial validation.
    -->
    <xsl:for-each select="$this-all-properties">
      <!--
        Check that all non-mandatory properties have a default behavior.
      -->
      <xsl:if
        test="not(@mandatory='true') and not(adm:default-behavior)">
        <xsl:message terminate="yes">
          <xsl:value-of
            select="concat('No default behavior defined for non-mandatory property &quot;', @name,
                         '&quot;.')" />
        </xsl:message>
      </xsl:if>
      <!--
        Check that all advanced properties are non-mandatory or have a default.
      -->
      <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:for-each>
    <!--
      Now generate the definition.
    -->
    <xsl:call-template name="copyright-notice" />
    <xsl:value-of
      select="concat('package ', $this-package, '.meta;&#xa;')" />
@@ -1653,6 +1688,7 @@
                                       @read-only='true' or
                                       @monitoring='true' or
                                       @hidden='true' or
                                       @advanced='true' or
                                       @mandatory='true']">
          <import>org.opends.server.admin.PropertyOption</import>
        </xsl:if>
@@ -1742,8 +1778,7 @@
              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[@hidden='true']">
          <import>org.opends.server.admin.RelationOption</import>
        </xsl:if>
        <xsl:if test="$this-all-relations/adm:one-to-many">
opendj-sdk/opends/src/admin/defn/org/opends/server/admin/std/ConnectionHandlerConfiguration.xml
@@ -61,7 +61,7 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="java-implementation-class" mandatory="true">
  <adm:property name="java-implementation-class" mandatory="true" advanced="true">
    <adm:synopsis>
      The fully-qualified name of the Java class that provides the
      <adm:user-friendly-name />
opendj-sdk/opends/src/server/org/opends/server/admin/PropertyOption.java
@@ -35,6 +35,13 @@
 */
public enum PropertyOption {
  /**
   * Use this option to identify properties which should be considered
   * as advanced and should not be exposed by default in client
   * applications.
   */
  ADVANCED,
  /**
   * Use this option to identify properties which must not be directly
   * exposed in client applications.
   */
opendj-sdk/opends/src/server/org/opends/server/admin/client/PropertySet.java
@@ -417,7 +417,10 @@
    }
    if (values.isEmpty() && d.hasOption(PropertyOption.MANDATORY)) {
      throw new PropertyIsMandatoryException(d);
      // But only if there are no default values.
      if (property.getDefaultValues().isEmpty()) {
        throw new PropertyIsMandatoryException(d);
      }
    }
    // Validate each value.
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -9181,6 +9181,31 @@
  public static final int MSGID_CLI_HEADING_PROPERTY_DEFAULT_VALUE =
    CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1215;
  /**
   * The message ID for the message that will be used as the
   * description of the advanced mode argument in get-xxx-prop
   * sub-commands. This takes a single argument which is the user
   * friendly name of the component.
   */
  public static final int MSGID_DSCFG_DESCRIPTION_ADVANCED_GET =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1216;
  /**
   * The message ID for the message that will be used as the
   * description of the advanced mode argument in create-xxx and
   * set-xxx-prop sub-commands. This takes no arguments.
   */
  public static final int MSGID_DSCFG_DESCRIPTION_ADVANCED_SET =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1217;
  /**
   * The message ID for the message that will be used as the
   * description of the advanced mode argument in the list-properties
   * sub-command. This takes no arguments.
   */
  public static final int MSGID_DSCFG_DESCRIPTION_ADVANCED_HELP =
       CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 1218;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -11543,6 +11568,18 @@
                    "Modifies the display output to show one property " +
                    "value per line");
    registerMessage(MSGID_DSCFG_DESCRIPTION_ADVANCED_GET,
                    "Modifies the display output to show the advanced " +
                    "properties of the %s");
    registerMessage(MSGID_DSCFG_DESCRIPTION_ADVANCED_SET,
                    "Allows the configuration of advanced properties " +
                    "during interactive mode");
    registerMessage(MSGID_DSCFG_DESCRIPTION_ADVANCED_HELP,
                    "Modifies the display output to show the advanced " +
                    "properties of components");
    registerMessage(MSGID_DSCFG_DESCRIPTION_FORCE, "Ignore non-existent %s");
    registerMessage(MSGID_DSCFG_DESCRIPTION_UNIT_TIME,
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/GetPropSubCommandHandler.java
@@ -166,6 +166,8 @@
    // Register common arguments.
    registerPropertyNameArgument(this.subCommand);
    registerAdvancedModeArgument(this.subCommand,
        MSGID_DSCFG_DESCRIPTION_ADVANCED_GET, r.getUserFriendlyName());
    registerRecordModeArgument(this.subCommand);
    registerUnitSizeArgument(this.subCommand);
    registerUnitTimeArgument(this.subCommand);
@@ -266,6 +268,10 @@
        continue;
      }
      if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
        continue;
      }
      if (propertyNames.isEmpty() || propertyNames.contains(pd.getName())) {
        displayProperty(app, builder, child, pd, valuePrinter);
      }
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/HelpSubCommandHandler.java
@@ -387,6 +387,9 @@
  private static final String FIELD_YES =
    Messages.getString("general.yes"); //$NON-NLS-1$
  private final static String HEADING_ADVANCED = Messages
      .getString(KEY_PREFIX + "heading.advanced"); //$NON-NLS-1$
  private final static String HEADING_DEFAULT = Messages.getString(KEY_PREFIX
      + "heading.default"); //$NON-NLS-1$
@@ -493,6 +496,8 @@
    this.subCommand.addArgument(this.typeArgument);
    // Register common arguments.
    registerAdvancedModeArgument(this.subCommand,
        MSGID_DSCFG_DESCRIPTION_ADVANCED_HELP);
    registerPropertyNameArgument(this.subCommand);
    this.types = new TreeMap<String, AbstractManagedObjectDefinition<?, ?>>();
@@ -545,6 +550,15 @@
    // Display options.
    builder.startRow();
    builder.appendCell(HEADING_ADVANCED);
    builder.appendCell(HEADING_SEPARATOR);
    if (pd.hasOption(PropertyOption.ADVANCED)) {
      builder.appendCell(FIELD_YES);
    } else {
      builder.appendCell(FIELD_NO);
    }
    builder.startRow();
    builder.appendCell(HEADING_MULTI_VALUED);
    builder.appendCell(HEADING_SEPARATOR);
    if (pd.hasOption(PropertyOption.MULTI_VALUED)) {
@@ -725,6 +739,10 @@
          continue;
        }
        if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
          continue;
        }
        if (!propertyNames.isEmpty() && !propertyNames.contains(pd.getName())) {
          continue;
        }
@@ -781,6 +799,10 @@
          continue;
        }
        if (!isAdvancedMode() && pd.hasOption(PropertyOption.ADVANCED)) {
          continue;
        }
        if (!propertyNames.isEmpty() && !propertyNames.contains(pd.getName())) {
          continue;
        }
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/SubCommandHandler.java
@@ -482,6 +482,11 @@
  }
  /**
   * The value for the long option advanced.
   */
  private static final String OPTION_DSCFG_LONG_ADVANCED = "advanced";
  /**
   * The value for the long option property.
   */
  private static final String OPTION_DSCFG_LONG_PROPERTY = "property";
@@ -502,6 +507,11 @@
  private static final String OPTION_DSCFG_LONG_UNIT_TIME = "unit-time";
  /**
   * The value for the short option advanced.
   */
  private static final Character OPTION_DSCFG_SHORT_ADVANCED = null;
  /**
   * The value for the short option property.
   */
  private static final Character OPTION_DSCFG_SHORT_PROPERTY = null;
@@ -521,6 +531,9 @@
   */
  private static final char OPTION_DSCFG_SHORT_UNIT_TIME = 'M';
  // The argument which should be used to request advanced mode.
  private BooleanArgument advancedModeArgument;
  // The argument which should be used to specify zero or more
  // property names.
  private StringArgument propertyArgument;
@@ -809,6 +822,22 @@
  /**
   * Determines whether the user requested advanced mode.
   *
   * @return Returns <code>true</code> if the user requested
   *         advanced mode.
   */
  protected final boolean isAdvancedMode() {
    if (advancedModeArgument != null) {
      return advancedModeArgument.isPresent();
    } else {
      return false;
    }
  }
  /**
   * Determines whether the user requested record-mode.
   *
   * @return Returns <code>true</code> if the user requested
@@ -825,6 +854,29 @@
  /**
   * Registers the advanced mode argument with the sub-command.
   *
   * @param subCommand
   *          The sub-command.
   * @param descriptionID
   *          The usage description message ID to be used for the
   *          argument.
   * @param args
   *          The arguments for the usage description.
   * @throws ArgumentException
   *           If the advanced mode argument could not be registered.
   */
  protected final void registerAdvancedModeArgument(SubCommand subCommand,
      int descriptionID, String... args) throws ArgumentException {
    this.advancedModeArgument = new BooleanArgument(OPTION_DSCFG_LONG_ADVANCED,
        OPTION_DSCFG_SHORT_ADVANCED, OPTION_DSCFG_LONG_ADVANCED, descriptionID,
        (Object[]) args);
    subCommand.addArgument(advancedModeArgument);
  }
  /**
   * Registers the property name argument with the sub-command.
   *
   * @param subCommand
opendj-sdk/opends/src/server/org/opends/server/tools/dsconfig/messages.properties
@@ -14,6 +14,7 @@
help-properties.heading.managed-object=Managed Object: %s
help-properties.heading.default=Default behavior
help-properties.heading.mandatory=Mandatory
help-properties.heading.advanced=Advanced
help-properties.heading.multi-valued=Multi-valued
help-properties.heading.read-only=Read-only
help-properties.heading.syntax=Syntax