From 1c8d96d71d1bae9188f2aa3d1237082afd47c649 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 06 Feb 2015 09:13:16 +0000
Subject: [PATCH] OPENDJ-1242 (CR-5982) Enable dsconfig to generate doc for properties changed through subcommand options
---
opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java | 24 +++-
opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java | 201 ++++++++++++++++++++++++--------
opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java | 79 +++++++++----
3 files changed, 220 insertions(+), 84 deletions(-)
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java
index e06bd63..5734756 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java
@@ -1170,41 +1170,70 @@
+ PROPERTY_SCRIPT_NAME + "'.");
}
- sb.append("<refsect2 xml:id=\"").append(scriptName).append("-").append(sc.getName()).append("\">").append(EOL);
- sb.append(" <title>dsconfig ").append(sc.getName()).append("</title>").append(EOL);
+ final String idRef = scriptName + "-" + sc.getName();
+ final String nameRef = scriptName + " " + sc.getName();
+ sb.append("<refsect2 xml:id=\"").append(idRef).append("\">").append(EOL);
+ sb.append(" <title>").append(nameRef).append("</title>").append(EOL);
sb.append(" <para>").append(sc.getDescription()).append("</para>").append(EOL);
if (!sc.getArguments().isEmpty()) {
- sb.append(" <variablelist>").append(EOL);
+ sb.append(" <refsect3 xml:id=\"").append(idRef).append("-options\">").append(EOL);
+ sb.append(" <title>Options</title>").append(EOL);
+ sb.append(" <variablelist>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ sb.append(" The <command>").append(nameRef)
+ .append("</command> command supports the following options.").append(EOL);
+ sb.append(" </para>").append(EOL);
+ String nameOption = null;
for (Argument a : sc.getArguments()) {
- sb.append(" <varlistentry>").append(EOL);
- sb.append(" <term><option>");
- Character shortID = a.getShortIdentifier();
- if (shortID != null) {
- sb.append("-").append(shortID.charValue());
+ sb.append(" <varlistentry>").append(EOL);
+ sb.append(" <term>");
+ final String option = getOption(a);
+ sb.append(option);
+ sb.append("</term>").append(EOL);
+ sb.append(" <listitem>").append(EOL);
+ sb.append(" <para>").append(a.getDescription()).append("</para>").append(EOL);
+ final String longID = a.getLongIdentifier();
+ if (!"set".equals(longID)
+ && !"reset".equals(longID)
+ && !"add".equals(longID)
+ && !"remove".equals(longID)) {
+ nameOption = option;
}
- String longID = a.getLongIdentifier();
- if (shortID != null && longID != null) {
- sb.append(" | ");
- }
- if (longID != null) {
- sb.append("--").append(longID);
- }
- if (a.needsValue()) {
- sb.append(" ").append(a.getValuePlaceholder());
- }
- sb.append("</option></term>").append(EOL);
- sb.append(" <listitem>").append(EOL);
- sb.append(" <para>").append(a.getDescription()).append("</para>").append(EOL);
if (subCommandUsageHandler != null) {
- subCommandUsageHandler.appendUsage(sb, sc, longID);
+ subCommandUsageHandler.appendArgumentAdditionalInfo(sb, sc, a, nameOption);
}
- sb.append(" </listitem>").append(EOL);
- sb.append(" </varlistentry>").append(EOL);
+ sb.append(" </listitem>").append(EOL);
+ sb.append(" </varlistentry>").append(EOL);
}
- sb.append(" </variablelist>").append(EOL);
+ sb.append(" </variablelist>").append(EOL);
+ sb.append(" </refsect3>").append(EOL);
+ }
+ if (subCommandUsageHandler != null) {
+ subCommandUsageHandler.appendProperties(sb, sc);
}
sb.append("</refsect2>").append(EOL);
}
+
+ private String getOption(Argument a) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("<option>");
+ final Character shortID = a.getShortIdentifier();
+ if (shortID != null) {
+ sb.append("-").append(shortID.charValue());
+ }
+ final String longID = a.getLongIdentifier();
+ if (shortID != null && longID != null) {
+ sb.append(" | ");
+ }
+ if (longID != null) {
+ sb.append("--").append(longID);
+ }
+ if (a.needsValue()) {
+ sb.append(" ").append(a.getValuePlaceholder());
+ }
+ sb.append("</option>");
+ return sb.toString();
+ }
}
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java
index 3d4e30f..4884b73 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java
@@ -32,15 +32,27 @@
public interface SubCommandUsageHandler {
/**
- * Invoked when the sub-command usage information should be printed.
+ * Appends properties information for the sub-command.
*
* @param builder
- * the string builder
- * @param sc
+ * the string builder where to append
+ * @param subCommand
* the sub command for which to print usage information
- * @param argLongID
- * the argument long identifier
*/
- void appendUsage(StringBuilder builder, SubCommand sc, String argLongID);
+ void appendProperties(StringBuilder builder, SubCommand subCommand);
+
+ /**
+ * Appends additional information for the provided sub-command argument.
+ *
+ * @param builder
+ * the string builder where to append
+ * @param subCommand
+ * the sub command for which to print usage information
+ * @param arg
+ * the argument for which to append additional information
+ * @param nameOption
+ * the string representing the name option
+ */
+ void appendArgumentAdditionalInfo(StringBuilder builder, SubCommand subCommand, Argument arg, String nameOption);
}
diff --git a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java
index 4d04547..b9594ed 100644
--- a/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java
+++ b/opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java
@@ -47,6 +47,7 @@
import java.io.PrintStream;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -126,51 +127,158 @@
*/
public final class DSConfig extends ConsoleApplication {
+ private static final String ALLOW_UNLIMITED = "A value of \"-1\" or \"unlimited\" for no limit.";
+ private static final String ACI_SYNTAX_REL_URL =
+ "<link" + EOL
+ + " xlink:show=\"new\"" + EOL
+ + " xlink:href=\"admin-guide#about-acis\"" + EOL
+ + " xlink:role=\"http://docbook.org/xlink/role/olink\">" + EOL
+ + "<citetitle>About Access Control Instructions</citetitle></link>" + EOL;
+ private static final String DURATION_SYNTAX_REL_URL =
+ " <itemizedlist>" + EOL
+ + " <para>Some property values take a time duration. Durations are expressed" + EOL
+ + " as numbers followed by units. For example <literal>1 s</literal> means" + EOL
+ + " one second, and <literal>2 w</literal> means two weeks. Some durations" + EOL
+ + " have minimum granularity or maximum units, so you cannot necessary specify" + EOL
+ + " every duration in milliseconds or weeks for example. Some durations allow" + EOL
+ + " you to use a special value to mean unlimited. Units are specified as" + EOL
+ + " follows.</para>" + EOL
+ + " <listitem><para><literal>ms</literal>: milliseconds</para></listitem>" + EOL
+ + " <listitem><para><literal>s</literal>: seconds</para></listitem>" + EOL
+ + " <listitem><para><literal>m</literal>: minutes</para></listitem>" + EOL
+ + " <listitem><para><literal>h</literal>: hours</para></listitem>" + EOL
+ + " <listitem><para><literal>d</literal>: days</para></listitem>" + EOL
+ + " <listitem><para><literal>w</literal>: weeks</para></listitem>" + EOL
+ + " </itemizedlist>" + EOL;
+
// FIXME: I18n support. Today all the strings are hardcoded in this file
private final class DSConfigSubCommandUsageHandler implements SubCommandUsageHandler {
- private static final String ALLOW_UNLIMITED = "A value of \"-1\" or \"unlimited\" for no limit.";
- private static final String ACI_SYNTAX_REL_URL =
- "<link"
- + " xlink:show=\"new\""
- + " xlink:href=\"admin-guide#about-acis\""
- + " xlink:role=\"http://docbook.org/xlink/role/olink\">"
- + "<citetitle>About Access Control Instructions</citetitle></link>";
- private static final String DURATION_SYNTAX_REL_URL =
- " <itemizedlist>"
- + " <para>Some property values take a time duration. Durations are expressed"
- + " as numbers followed by units. For example <literal>1 s</literal> means"
- + " one second, and <literal>2 w</literal> means two weeks. Some durations"
- + " have minimum granularity or maximum units, so you cannot necessary specify"
- + " every duration in milliseconds or weeks for example. Some durations allow"
- + " you to use a special value to mean unlimited. Units are specified as"
- + " follows.</para>"
- + " <listitem><para><literal>ms</literal>: milliseconds</para></listitem>"
- + " <listitem><para><literal>s</literal>: seconds</para></listitem>"
- + " <listitem><para><literal>m</literal>: minutes</para></listitem>"
- + " <listitem><para><literal>h</literal>: hours</para></listitem>"
- + " <listitem><para><literal>d</literal>: days</para></listitem>"
- + " <listitem><para><literal>w</literal>: weeks</para></listitem>"
- + " </itemizedlist>";
+ /** {@inheritDoc} */
+ @Override
+ public void appendArgumentAdditionalInfo(StringBuilder sb, SubCommand sc, Argument a, String nameOption) {
+ final AbstractManagedObjectDefinition<?, ?> defn = getManagedObjectDefinition(sc);
+ if (defn == null) {
+ return;
+ }
+ final String longID = a.getLongIdentifier();
+ if ("set".equals(longID)
+ || "reset".equals(longID)
+ || "add".equals(longID)
+ || "remove".equals(longID)) {
+ sb.append(" <para>").append(EOL);
+ final LocalizableMessage name = defn.getUserFriendlyName();
+ sb.append(" ").append(name).append(" properties depend on the ").append(name)
+ .append(" type, which depends on the ").append(nameOption).append(" option.").append(EOL);
+ sb.append(" </para>").append(EOL);
+ } else {
+ listSubtypes(sb, a.getValuePlaceholder(), defn);
+ }
+ return;
+ }
+
+ private void listSubtypes(StringBuilder sb, LocalizableMessage placeholder,
+ AbstractManagedObjectDefinition<?, ?> defn) {
+ sb.append(" <variablelist>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ final LocalizableMessage name = defn.getUserFriendlyName();
+ sb.append(" ").append(name).append(" properties depend on the ").append(name)
+ .append(" type, which depends on the ").append(placeholder).append(" you provide.").append(EOL);
+ sb.append(" </para>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ sb.append(" By default, OpenDJ directory server supports the following ")
+ .append(defn.getUserFriendlyName()).append(" types:").append(EOL);
+ sb.append(" </para>").append(EOL);
+
+ for (AbstractManagedObjectDefinition<?, ?> childDefn : getLeafChildren(defn)) {
+ sb.append(" <varlistentry>").append(EOL);
+ sb.append(" <term>").append(childDefn.getName()).append("</term>").append(EOL);
+ sb.append(" <listitem>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ sb.append(" Default ").append(placeholder).append(": ")
+ .append(childDefn.getUserFriendlyName()).append(EOL);
+ sb.append(" </para>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ final boolean isEnabled = propertyExists(childDefn, "enabled");
+ sb.append(" Enabled by default: ").append(isEnabled).append(EOL);
+ sb.append(" </para>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ final String string = "dsconfig-set-log-publisher-prop-file-based-access";
+ sb.append(" See <xref linkend=\"").append(string)
+ .append("\" /> for the properties of this ").append(defn.getUserFriendlyName())
+ .append(" type.").append(EOL);
+ sb.append(" </para>").append(EOL);
+ sb.append(" </listitem>").append(EOL);
+ sb.append(" </varlistentry>").append(EOL);
+ }
+ sb.append(" </variablelist>").append(EOL);
+ }
+
+ private boolean propertyExists(AbstractManagedObjectDefinition<?, ?> defn, String name) {
+ try {
+ return defn.getPropertyDefinition(name) != null;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
/** {@inheritDoc} */
@Override
- public void appendUsage(StringBuilder sb, SubCommand sc, String argLongID) {
- final SubCommandHandler sch = handlers.get(sc);
- if (sch instanceof HelpSubCommandHandler) {
+ public void appendProperties(StringBuilder sb, SubCommand sc) {
+ final AbstractManagedObjectDefinition<?, ?> defn = getManagedObjectDefinition(sc);
+ if (defn == null) {
return;
}
- final RelationDefinition<?, ?> rd = getRelationDefinition(sch);
- final AbstractManagedObjectDefinition<?, ?> defn = rd.getChildDefinition();
- final List<PropertyDefinition<?>> props =
- new ArrayList<PropertyDefinition<?>>(defn.getAllPropertyDefinitions());
- Collections.sort(props);
- final String propPrefix = getScriptName() + "-" + sc.getName() + "-" + argLongID + "-";
- sb.append(EOL);
- toSimpleList(props, propPrefix, sb);
- sb.append(EOL);
- toVariableList(props, defn, propPrefix, sb);
+ for (AbstractManagedObjectDefinition<?, ?> childDefn : getLeafChildren(defn)) {
+ final List<PropertyDefinition<?>> props =
+ new ArrayList<PropertyDefinition<?>>(childDefn.getAllPropertyDefinitions());
+ Collections.sort(props);
+
+ final String propPrefix = getScriptName() + "-" + sc.getName() + "-" + childDefn.getName();
+ sb.append(" <refsect3 xml:id=\"").append(propPrefix).append("\">").append(EOL);
+ sb.append(" <title>").append(childDefn.getUserFriendlyName()).append("</title>").append(EOL);
+ sb.append(" <para>").append(EOL);
+ sb.append(" ").append(defn.getUserFriendlyPluralName()).append(" of type ")
+ .append(childDefn.getName()).append(" have the following properties:").append(EOL);
+ sb.append(" </para>").append(EOL);
+ toVariableList(props, defn, propPrefix, sb);
+ sb.append(" </refsect3>").append(EOL);
+ }
+ }
+
+ private AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition(SubCommand sc) {
+ final SubCommandHandler sch = handlers.get(sc);
+ if (sch instanceof HelpSubCommandHandler) {
+ return null;
+ }
+ final RelationDefinition<?, ?> rd = getRelationDefinition(sch);
+ return rd.getChildDefinition();
+ }
+
+ private List<AbstractManagedObjectDefinition<?, ?>> getLeafChildren(
+ AbstractManagedObjectDefinition<?, ?> defn) {
+ final ArrayList<AbstractManagedObjectDefinition<?, ?>> results =
+ new ArrayList<AbstractManagedObjectDefinition<?, ?>>();
+ addLeafChildren(results, defn);
+ Collections.sort(results, new Comparator<AbstractManagedObjectDefinition<?, ?>>() {
+ @Override
+ public int compare(AbstractManagedObjectDefinition<?, ?> o1, AbstractManagedObjectDefinition<?, ?> o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ return results;
+ }
+
+ private void addLeafChildren(final Collection<AbstractManagedObjectDefinition<?, ?>> results,
+ final AbstractManagedObjectDefinition<?, ?> defn) {
+ for (AbstractManagedObjectDefinition<?, ?> child : defn.getChildren()) {
+ if (child.getChildren().isEmpty()) {
+ results.add(child);
+ } else {
+ addLeafChildren(results, child);
+ }
+ }
}
private RelationDefinition<?, ?> getRelationDefinition(final SubCommandHandler sch) {
@@ -188,22 +296,13 @@
return null;
}
- private void toSimpleList(List<PropertyDefinition<?>> props, String propPrefix, StringBuilder b) {
- b.append(" <simplelist>").append(EOL);
- for (PropertyDefinition<?> prop : props) {
- b.append(" <member><xref linkend=\"")
- .append(propPrefix).append(prop.getName()).append("\" /></member>").append(EOL);
- }
- b.append(" </simplelist>").append(EOL);
- }
-
private void toVariableList(List<PropertyDefinition<?>> props, AbstractManagedObjectDefinition<?, ?> defn,
String propPrefix, StringBuilder b) {
final String indent = " ";
b.append(" <variablelist>").append(EOL);
for (PropertyDefinition<?> prop : props) {
b.append(" <varlistentry xml:id=\"")
- .append(propPrefix).append(prop.getName()).append("\">").append(EOL);
+ .append(propPrefix).append("-").append(prop.getName()).append("\">").append(EOL);
b.append(" <term>").append(prop.getName()).append("</term>").append(EOL);
b.append(" <listitem>").append(EOL);
b.append(" <variablelist>").append(EOL);
@@ -235,24 +334,20 @@
private void appendAllowedValues(StringBuilder b, PropertyDefinition<?> prop, String indent) {
b.append(indent).append("<varlistentry>").append(EOL);
b.append(indent).append(" <term>").append("Allowed Values").append("</term>").append(EOL);
+ b.append(indent).append(" <listitem>").append(EOL);
if (prop instanceof EnumPropertyDefinition) {
- b.append(indent).append(" <listitem>").append(EOL);
b.append(indent).append(" <variablelist>").append(EOL);
appendSyntax(b, prop, indent + " ");
b.append(indent).append(" </variablelist>").append(EOL);
- b.append(indent).append(" </listitem>").append(EOL);
} else if (prop instanceof BooleanPropertyDefinition) {
- b.append(indent).append(" <listitem>").append(EOL);
b.append(indent).append(" <para>true</para>").append(EOL);
b.append(indent).append(" <para>false</para>").append(EOL);
- b.append(indent).append(" </listitem>").append(EOL);
} else {
- b.append(indent).append(" <listitem>").append(EOL);
b.append(indent).append(" <para>");
appendSyntax(b, prop, indent);
b.append("</para>").append(EOL);
- b.append(indent).append(" </listitem>").append(EOL);
}
+ b.append(indent).append(" </listitem>").append(EOL);
b.append(indent).append("</varlistentry>").append(EOL);
}
@@ -303,7 +398,7 @@
final StringBuilder res = new StringBuilder();
for (Iterator<String> it = behavior.getDefaultValues().iterator(); it.hasNext();) {
String str = it.next();
- res.append(str).append(it.hasNext() ? "\n" : "");
+ res.append(str).append(it.hasNext() ? "\n" : ""); // TODO JNR refactor
}
return res.toString();
} else if (defaultBehavior instanceof AliasDefaultBehaviorProvider) {
--
Gitblit v1.10.0