From 314e6e2709c4b0ebfe509e262ca366874f9069da Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Wed, 11 Mar 2015 11:59:20 +0000
Subject: [PATCH] CR-6316 OPENDJ-1786 Automate integration of generated content
---
opendj-cli/src/main/resources/templates/refEntry.ftl | 51 -
opendj-cli/src/main/resources/templates/refSect1.ftl | 41 ++
opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java | 4
opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java | 50 ++
opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java | 22
opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java | 23 +
opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java | 162 ++++++++
opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java | 19
opendj-cli/src/main/resources/templates/optionsRefSect1.ftl | 62 +++
opendj-cli/src/main/resources/templates/refSect2.ftl | 42 +-
opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java | 116 ++++-
opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties | 240 ++++++++++++
opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java | 311 +++++++++++----
13 files changed, 929 insertions(+), 214 deletions(-)
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java
index 0b11e7b..3c57458 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/Argument.java
@@ -40,7 +40,7 @@
* for an application. This is an abstract class that must be subclassed in
* order to provide specific functionality.
*/
-public abstract class Argument {
+public abstract class Argument implements DocDescriptionSupplement {
/**
* Indicates whether this argument should be hidden in the usage
* information.
@@ -239,30 +239,16 @@
}
/**
- * A supplement to the description for this argument
- * intended for use in generated reference documentation.
+ * A supplement to the description intended for use in generated reference documentation.
*/
private LocalizableMessage docDescriptionSupplement;
- /**
- * Retrieves a supplement to the description for this argument
- * intended for use in generated reference documentation.
- *
- * @return The supplement to the description for this argument
- * for use in generated reference documentation,
- * or LocalizableMessage.EMPTY if there is no supplement.
- */
+ /** {@inheritDoc} */
public LocalizableMessage getDocDescriptionSupplement() {
return docDescriptionSupplement != null ? docDescriptionSupplement : LocalizableMessage.EMPTY;
}
- /**
- * Sets a supplement to the description for this argument
- * intended for use in generated reference documentation.
- *
- * @param docDescriptionSupplement The supplement to the description for this argument
- * for use in generated reference documentation.
- */
+ /** {@inheritDoc} */
public void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
this.docDescriptionSupplement = docDescriptionSupplement;
}
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java
index a55aa2e..2dee2ad 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java
@@ -65,7 +65,7 @@
* file to obtain default values for arguments there if they are not specified
* on the command-line.
*/
-public class ArgumentParser {
+public class ArgumentParser implements ToolRefDocContainer {
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
/**
@@ -617,23 +617,14 @@
*/
private LocalizableMessage shortToolDescription;
- /**
- * Gets a short description for this tool, suitable in a man page summary line.
- *
- * @return A short description for this tool,
- * suitable in a man page summary line,
- * or LocalizableMessage.EMPTY if there is no short description.
- */
- LocalizableMessage getShortToolDescription() {
+ /** {@inheritDoc} */
+ @Override
+ public LocalizableMessage getShortToolDescription() {
return shortToolDescription != null ? shortToolDescription : LocalizableMessage.EMPTY;
}
- /**
- * Sets a short description for this tool, suitable in a man page summary line.
- *
- * @param shortDescription The short description for this tool,
- * suitable in a man page summary line.
- */
+ /** {@inheritDoc} */
+ @Override
public void setShortToolDescription(final LocalizableMessage shortDescription) {
this.shortToolDescription = shortDescription;
}
@@ -642,29 +633,86 @@
* A supplement to the description for this tool
* intended for use in generated reference documentation.
*/
- private LocalizableMessage docToolDescriptionSupplement;
+ private DocDescriptionSupplement docToolDescriptionSupplement;
- /**
- * Retrieves a supplement to the description for this tool,
- * intended for use in generated reference documentation.
- *
- * @return A supplement to the description for this tool
- * intended for use in generated reference documentation,
- * or LocalizableMessage.EMPTY if there is no supplement.
- */
- LocalizableMessage getDocToolDescriptionSupplement() {
- return docToolDescriptionSupplement != null ? docToolDescriptionSupplement : LocalizableMessage.EMPTY;
+ /** {@inheritDoc} */
+ @Override
+ public LocalizableMessage getDocToolDescriptionSupplement() {
+ this.docToolDescriptionSupplement =
+ constructIfNull(this.docToolDescriptionSupplement);
+ return this.docToolDescriptionSupplement.getDocDescriptionSupplement();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setDocToolDescriptionSupplement(final LocalizableMessage supplement) {
+ this.docToolDescriptionSupplement =
+ constructIfNull(this.docToolDescriptionSupplement);
+ this.docToolDescriptionSupplement.setDocDescriptionSupplement(supplement);
}
/**
- * Sets a supplement to the description for this tool,
+ * A supplement to the description for all subcommands of this tool,
* intended for use in generated reference documentation.
- *
- * @param docToolDescriptionSupplement The supplement to the description for this tool
- * intended for use in generated reference documentation.
*/
- public void setDocToolDescriptionSupplement(final LocalizableMessage docToolDescriptionSupplement) {
- this.docToolDescriptionSupplement = docToolDescriptionSupplement;
+ private class DocSubcommandsDescriptionSupplement implements DocDescriptionSupplement {
+ /**
+ * A supplement to the description intended for use in generated reference documentation.
+ */
+ private LocalizableMessage docDescriptionSupplement;
+
+ /** {@inheritDoc} */
+ public LocalizableMessage getDocDescriptionSupplement() {
+ return docDescriptionSupplement != null ? docDescriptionSupplement : LocalizableMessage.EMPTY;
+ }
+
+ /** {@inheritDoc} */
+ public void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
+ this.docDescriptionSupplement = docDescriptionSupplement;
+ }
+ }
+
+ private DocDescriptionSupplement docSubcommandsDescriptionSupplement;
+
+ /** {@inheritDoc} */
+ @Override
+ public LocalizableMessage getDocSubcommandsDescriptionSupplement() {
+ this.docSubcommandsDescriptionSupplement =
+ constructIfNull(this.docSubcommandsDescriptionSupplement);
+ return this.docSubcommandsDescriptionSupplement.getDocDescriptionSupplement();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setDocSubcommandsDescriptionSupplement(final LocalizableMessage supplement) {
+ this.docSubcommandsDescriptionSupplement =
+ constructIfNull(this.docSubcommandsDescriptionSupplement);
+ this.docSubcommandsDescriptionSupplement.setDocDescriptionSupplement(supplement);
+ }
+
+ private DocDescriptionSupplement constructIfNull(DocDescriptionSupplement supplement) {
+ if (supplement != null) {
+ return supplement;
+ }
+ return new DocSubcommandsDescriptionSupplement();
+ }
+
+ /**
+ * Additional paths to DocBook XML {@code RefSect1} documents
+ * to be appended after generated content in reference documentation.
+ */
+ private String[] pathsToTrailingRefSect1s;
+
+ /** {@inheritDoc} */
+ @Override
+ public String[] getPathsToTrailingRefSect1s() {
+ return pathsToTrailingRefSect1s != null ? pathsToTrailingRefSect1s : new String[0];
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void setPathsToTrailingRefSect1s(final String... paths) {
+ this.pathsToTrailingRefSect1s = paths;
}
/**
@@ -689,7 +737,7 @@
final StringBuilder buffer = new StringBuilder();
usageOrVersionDisplayed = true;
if (System.getProperty("org.forgerock.opendj.gendoc") != null) {
- toRefEntry(buffer);
+ toRefEntry(buffer, getSynopsisArgs(), argumentList);
} else {
getUsage(buffer);
}
@@ -697,56 +745,128 @@
}
/**
+ * Return the list of arguments for the generated reference documentation.
+ *
+ * @return The list of arguments for the generated reference documentation.
+ */
+ String getSynopsisArgs() {
+ if (allowsTrailingArguments()) {
+ if (trailingArgsDisplayName != null) {
+ return trailingArgsDisplayName;
+ } else {
+ return INFO_ARGPARSER_USAGE_TRAILINGARGS.get().toString();
+ }
+ }
+ return null;
+ }
+
+ /**
* Appends a generated DocBook XML RefEntry (man page) to the StringBuilder.
*
- * @param sb Append the RefEntry element to this.
+ * @param builder Append the RefEntry element to this.
+ * @param synopsisArgs List of arguments for the command synopsis.
+ * @param argList List of (global) arguments for this tool.
*/
- private void toRefEntry(StringBuilder sb) {
+ void toRefEntry(StringBuilder builder, String synopsisArgs, List<Argument> argList) {
final String scriptName = getScriptName();
if (scriptName == null) {
throw new RuntimeException("The script name should have been set via the environment property '"
+ PROPERTY_SCRIPT_NAME + "'.");
}
- // Model for a FreeMarker template.
Map<String, Object> map = new HashMap<String, Object>();
map.put("locale", Locale.getDefault().getLanguage());
map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
map.put("name", scriptName);
map.put("shortDesc", getShortToolDescription());
map.put("descTitle", REF_TITLE_DESCRIPTION.get());
- map.put("optsTitle", REF_TITLE_OPTIONS.get());
- map.put("optsIntro", REF_INTRO_OPTIONS.get(scriptName));
- String args = null;
- if (allowsTrailingArguments) {
- if (trailingArgsDisplayName != null) {
- args = trailingArgsDisplayName;
- } else {
- args = INFO_ARGPARSER_USAGE_TRAILINGARGS.get().toString();
- }
- }
- map.put("args", args);
+ map.put("args", synopsisArgs);
map.put("description", getToolDescription());
-
- // If there is a supplement to the description for this utility,
- // then it is already DocBook XML, so use it as is.
map.put("info", getDocToolDescriptionSupplement());
- if (!argumentList.isEmpty()) {
- List<Map<String, Object>> options = new LinkedList<Map<String, Object>>();
- for (Argument a : argumentList) {
- Map<String, Object> option = new HashMap<String, Object>();
- option.put("synopsis", getOptionSynopsis(a));
- option.put("description", a.getDescription());
- option.put("default", REF_DEFAULT.get(a.getDefaultValue()));
-
- // If there is a supplement to the description for this argument,
- // then it is already DocBook XML, so use it as is.
- option.put("info", a.getDocDescriptionSupplement());
- options.add(option);
- }
- map.put("options", options);
+ if (!argList.isEmpty()) {
+ map.put("optionSection", getOptionsRefSect1(scriptName));
}
- applyTemplate(sb, "refEntry.ftl", map);
+ map.put("subcommands", null);
+ map.put("trailingSections", pathsToXIncludes(getPathsToTrailingRefSect1s()));
+ applyTemplate(builder, "refEntry.ftl", map);
+ }
+
+
+ /**
+ * Returns a generated DocBook XML RefSect1 element for all command options.
+ * @param scriptName The name of this script.
+ * @return The RefSect1 element as a String.
+ */
+ protected String getOptionsRefSect1(String scriptName) {
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("name", scriptName);
+ map.put("title", REF_TITLE_OPTIONS.get());
+ map.put("intro", REF_INTRO_OPTIONS.get(scriptName));
+
+ Argument helpArgument = null;
+ final boolean printHeaders = printUsageGroupHeaders();
+ List<Map<String, Object>> groups = new LinkedList<Map<String, Object>>();
+ for (final ArgumentGroup argGroup : argumentGroups) {
+ Map<String, Object> group = new HashMap<String, Object>();
+
+ // Add the group's description if any
+ if (argGroup.containsArguments() && printHeaders) {
+ LocalizableMessage description = argGroup.getDescription();
+ if (description != LocalizableMessage.EMPTY) {
+ group.put("description", argGroup.getDescription());
+ } else {
+ group.put("description", INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get());
+ }
+ }
+
+ List<Map<String, Object>> options = new LinkedList<Map<String, Object>>();
+ final SortedSet<Argument> args = sortArguments(argGroup.getArguments());
+ for (final Argument a : args) {
+ if (a.isHidden()) {
+ continue;
+ }
+
+ // The help argument should be added at the end.
+ if (isUsageArgument(a)) {
+ helpArgument = a;
+ continue;
+ }
+
+ options.add(getArgumentMap(a));
+ }
+ group.put("options", options);
+ if (!options.isEmpty()) {
+ groups.add(group);
+ }
+ }
+ if (helpArgument != null) {
+ Map<String, Object> helpGroup = new HashMap<String, Object>();
+ helpGroup.put("description", null);
+ List<Map<String, Object>> options = new LinkedList<Map<String, Object>>();
+ options.add(getArgumentMap(helpArgument));
+ helpGroup.put("options", options);
+ groups.add(helpGroup);
+ }
+ map.put("groups", groups);
+
+ StringBuilder sb = new StringBuilder();
+ applyTemplate(sb, "optionsRefSect1.ftl", map);
+ return sb.toString();
+ }
+
+ /**
+ * Returns a map containing information about an argument option.
+ * @param a The argument
+ * @return A map containing information about an argument option
+ */
+ private Map<String, Object> getArgumentMap(final Argument a) {
+ Map<String, Object> option = new HashMap<String, Object>();
+ option.put("synopsis", getOptionSynopsis(a));
+ option.put("description", a.getDescription());
+ String dv = a.getDefaultValue();
+ option.put("default", dv != null ? REF_DEFAULT.get(dv) : null);
+ option.put("info", a.getDocDescriptionSupplement());
+ return option;
}
/**
@@ -805,33 +925,8 @@
}
}
- final SortedSet<Argument> args = new TreeSet<Argument>(new Comparator<Argument>() {
-
- /** {@inheritDoc} */
- @Override
- public int compare(final Argument o1, final Argument o2) {
- final String s1 = getIdentifier(o1);
- final String s2 = getIdentifier(o2);
- final int res = s1.compareToIgnoreCase(s2);
- if (res != 0) {
- return res;
- }
- // Lowercase options first then uppercase.
- return -s1.compareTo(s2);
- }
-
- private String getIdentifier(final Argument o1) {
- if (o1.getShortIdentifier() != null) {
- return o1.getShortIdentifier().toString();
- }
- return o1.getLongIdentifier();
- }
-
- });
- args.addAll(argGroup.getArguments());
-
+ final SortedSet<Argument> args = sortArguments(argGroup.getArguments());
for (final Argument a : args) {
- // If this argument is hidden, then skip it.
if (a.isHidden()) {
continue;
}
@@ -854,6 +949,40 @@
}
/**
+ * Sorts arguments by identifier, lowercase options first then uppercase.
+ *
+ * @param arguments The arguments to sort.
+ * @return The set of arguments in sorted order.
+ */
+ SortedSet<Argument> sortArguments(final List<Argument> arguments) {
+ final SortedSet<Argument> result = new TreeSet<Argument>(new Comparator<Argument>() {
+
+ /** {@inheritDoc} */
+ @Override
+ public int compare(final Argument o1, final Argument o2) {
+ final String s1 = getIdentifier(o1);
+ final String s2 = getIdentifier(o2);
+ final int res = s1.compareToIgnoreCase(s2);
+ if (res != 0) {
+ return res;
+ }
+ // Lowercase options first then uppercase.
+ return -s1.compareTo(s2);
+ }
+
+ private String getIdentifier(final Argument o1) {
+ if (o1.getShortIdentifier() != null) {
+ return o1.getShortIdentifier().toString();
+ }
+ return o1.getLongIdentifier();
+ }
+
+ });
+ result.addAll(arguments);
+ return result;
+ }
+
+ /**
* Returns the script name or a Java equivalent command-line string.
*
* @return the script name or a Java equivalent command-line string
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java
new file mode 100644
index 0000000..09562e6
--- /dev/null
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocDescriptionSupplement.java
@@ -0,0 +1,50 @@
+/*
+ * 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 legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 legal-notices/CDDLv1_0.txt.
+ * 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
+ *
+ *
+ * Copyright 2015 ForgeRock AS.
+ */
+package com.forgerock.opendj.cli;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+/**
+ * Documentation that supplements generated descriptions.
+ */
+public interface DocDescriptionSupplement {
+
+ /**
+ * Retrieves a supplement to the description intended for use in generated reference documentation.
+ *
+ * @return The supplement to the description for use in generated reference documentation,
+ * or LocalizableMessage.EMPTY if there is no supplement.
+ */
+ public LocalizableMessage getDocDescriptionSupplement();
+
+ /**
+ * Sets a supplement to the description intended for use in generated reference documentation.
+ *
+ * @param docDescriptionSupplement The supplement to the description
+ * for use in generated reference documentation.
+ */
+ public void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement);
+}
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java
index a60d99a..828029f 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java
@@ -32,6 +32,8 @@
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
/**
@@ -134,4 +136,25 @@
final String id = argument.getLongIdentifier();
return ("add".equals(id) || "remove".equals(id) || "reset".equals(id) || "set".equals(id));
}
+
+ /**
+ * Translate paths to XML files to XInclude elements.
+ *
+ * @return XInclude elements corresponding to the paths.
+ */
+ static List<String> pathsToXIncludes(final String[] paths) {
+ if (paths == null) {
+ return new LinkedList<String>();
+ }
+
+ // Assume xmlns:xinclude="http://www.w3.org/2001/XInclude",
+ // as in the declaration of resources/templates/refEntry.ftl.
+ final String nameSpace = "xinclude";
+ List<String> xIncludes = new LinkedList<String>();
+ for (int i = 0; i < paths.length; ++i) {
+ xIncludes.add("<" + nameSpace + ":include href=\"" + paths[i] + "\" />");
+ }
+
+ return xIncludes;
+ }
}
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java
index 9fec2a5..42f4580 100644
--- a/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommand.java
@@ -39,7 +39,7 @@
* This class defines a data structure for holding information about a subcommand that may be used with the subcommand
* argument parser. The subcommand has a name, a description, and a set of arguments.
*/
-public class SubCommand {
+public class SubCommand implements DocDescriptionSupplement {
/** Indicates whether this subCommand should be hidden in the usage information. */
private boolean isHidden;
@@ -169,25 +169,12 @@
*/
private LocalizableMessage docDescriptionSupplement;
- /**
- * Retrieves a supplement to the description for this subcommand
- * intended for use in generated reference documentation.
- *
- * @return The supplement to the description for this subcommand
- * for use in generated reference documentation,
- * or LocalizableMessage.EMPTY if there is no supplement.
- */
+ /** {@inheritDoc} */
public LocalizableMessage getDocDescriptionSupplement() {
return docDescriptionSupplement != null ? docDescriptionSupplement : LocalizableMessage.EMPTY;
}
- /**
- * Sets a supplement to the description for this subcommand
- * intended for use in generated reference documentation.
- *
- * @param docDescriptionSupplement The supplement to the description for this subcommand
- * for use in generated reference documentation.
- */
+ /** {@inheritDoc} */
public void setDocDescriptionSupplement(final LocalizableMessage docDescriptionSupplement) {
this.docDescriptionSupplement = docDescriptionSupplement;
}
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 6777007..262c3b0 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
@@ -33,12 +33,15 @@
import static com.forgerock.opendj.util.StaticUtils.*;
import java.io.OutputStream;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.SortedMap;
@@ -1104,31 +1107,32 @@
}
/**
- * Appends a list generated DocBook XML RefSect2 elements to the StringBuilder, one per subcommand.
+ * Appends a generated DocBook XML RefEntry element for this command to the StringBuilder.
*
- * <br>
- *
- * Note: The result is not a complete XML document.
- * Instead you must wrap the resulting list of RefSect2 elements in a RefSect1.
- *
- * @param builder Append the list of RefSect2 elements to this.
- * @param values The SubCommands containing the reference information.
+ * @param builder Append the RefEntry element to this.
+ * @param subCommands SubCommands containing reference information.
*/
- private void generateReferenceDoc(final StringBuilder builder, Collection<SubCommand> values) {
- for (SubCommand s : values) {
- toRefSect2(s, builder);
+ private void generateReferenceDoc(final StringBuilder builder, Collection<SubCommand> subCommands) {
+ toRefEntry(builder, subCommands);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ String getSynopsisArgs() {
+ if (subCommands.isEmpty()) {
+ return INFO_SUBCMDPARSER_OPTIONS.get().toString();
+ } else {
+ return INFO_SUBCMDPARSER_SUBCMD_AND_OPTIONS.get().toString();
}
}
/**
- * Appends a generated DocBook XML RefSect2 element for a single subcommand to the StringBuilder.
+ * Appends a generated DocBook XML RefEntry (man page) to the StringBuilder.
*
- * @param sc
- * The SubCommand containing reference information.
- * @param sb
- * Append the RefSect2 element to this.
+ * @param builder Append the RefEntry element to this.
+ * @param subCommands Collection of subcommands for this tool.
*/
- private void toRefSect2(SubCommand sc, StringBuilder sb) {
+ void toRefEntry(StringBuilder builder, Collection<SubCommand> subCommands) {
final String scriptName = getScriptName();
if (scriptName == null) {
throw new RuntimeException("The script name should have been set via the environment property '"
@@ -1137,20 +1141,72 @@
// Model for a FreeMarker template.
Map<String, Object> map = new HashMap<String, Object>();
- map.put("id", scriptName + "-" + sc.getName());
- final String name = scriptName + " " + sc.getName();
+ map.put("locale", Locale.getDefault().getLanguage());
+ map.put("year", new SimpleDateFormat("yyyy").format(new Date()));
+ map.put("name", scriptName);
+ map.put("shortDesc", getShortToolDescription());
+ map.put("descTitle", REF_TITLE_DESCRIPTION.get());
+ map.put("args", getSynopsisArgs());
+ map.put("description", getToolDescription());
+ map.put("info", getDocToolDescriptionSupplement());
+ if (!globalArgumentList.isEmpty()) {
+ map.put("optionSection", getOptionsRefSect1(scriptName));
+ }
+ map.put("subcommands", toRefSect1(scriptName, subCommands));
+ map.put("trailingSections", pathsToXIncludes(getPathsToTrailingRefSect1s()));
+ applyTemplate(builder, "refEntry.ftl", map);
+ }
+
+ /**
+ * Returns a generated DocBook XML RefSect1 element for all subcommands.
+ * @param scriptName The name of this script.
+ * @param subCommands The SubCommands containing the reference information.
+ * @return The RefSect1 element as a String.
+ */
+ private String toRefSect1(String scriptName, Collection<SubCommand> subCommands) {
+ if (subCommands.isEmpty()) {
+ return "";
+ }
+
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("name", scriptName);
+ map.put("info", getDocSubcommandsDescriptionSupplement());
+
+ List<String> scUsageList = new ArrayList<String>();
+ for (SubCommand subCommand : subCommands) {
+ scUsageList.add(toRefSect2(scriptName, subCommand));
+ }
+ map.put("subcommands", scUsageList);
+
+ StringBuilder sb = new StringBuilder();
+ applyTemplate(sb, "refSect1.ftl", map);
+ return sb.toString();
+ }
+
+ /**
+ * Returns a generated DocBook XML RefSect2 element for a single subcommand to the StringBuilder.
+ *
+ * @param scriptName The name of this script.
+ * @param subCommand The SubCommand containing reference information.
+ * @return The RefSect2 element as a String.
+ */
+ private String toRefSect2(String scriptName, SubCommand subCommand) {
+ // Model for a FreeMarker template.
+ Map<String, Object> map = new HashMap<String, Object>();
+ map.put("id", scriptName + "-" + subCommand.getName());
+ final String name = scriptName + " " + subCommand.getName();
map.put("name", name);
- map.put("description", sc.getDescription());
- map.put("optsTitle", REF_TITLE_OPTIONS.get());
- map.put("optsIntro", REF_INTRO_OPTIONS.get(name));
+ map.put("description", subCommand.getDescription());
+ map.put("optionsTitle", REF_TITLE_OPTIONS.get());
+ map.put("optionsIntro", REF_INTRO_OPTIONS.get(name));
// If there is a supplement to the description for this subcommand,
// then it is already DocBook XML, so use it as is.
- map.put("info", sc.getDocDescriptionSupplement());
- if (!sc.getArguments().isEmpty()) {
+ map.put("info", subCommand.getDocDescriptionSupplement());
+ if (!subCommand.getArguments().isEmpty()) {
List<Map<String, Object>> options = new LinkedList<Map<String, Object>>();
String nameOption = null;
- for (Argument a : sc.getArguments()) {
+ for (Argument a : subCommand.getArguments()) {
Map<String, Object> option = new HashMap<String, Object>();
String optionSynopsis = getOptionSynopsis(a);
option.put("synopsis", optionSynopsis);
@@ -1162,9 +1218,10 @@
}
// Let this build its own arbitrarily formatted additional info.
- info.put("usage", subCommandUsageHandler.getArgumentAdditionalInfo(sc, a, nameOption));
+ info.put("usage", subCommandUsageHandler.getArgumentAdditionalInfo(subCommand, a, nameOption));
} else {
- info.put("default", REF_DEFAULT.get(a.getDefaultValue()));
+ String defaultValue = a.getDefaultValue();
+ info.put("default", defaultValue != null ? REF_DEFAULT.get(defaultValue) : null);
// If there is a supplement to the description for this argument,
// then it is already DocBook XML, so use it as is.
@@ -1177,8 +1234,11 @@
}
if (subCommandUsageHandler != null) {
- map.put("properties", subCommandUsageHandler.getProperties(sc));
+ map.put("propertiesInfo", subCommandUsageHandler.getProperties(subCommand));
}
+
+ StringBuilder sb = new StringBuilder();
applyTemplate(sb, "refSect2.ftl", map);
+ return sb.toString();
}
}
diff --git a/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java b/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java
new file mode 100644
index 0000000..36aa9d2
--- /dev/null
+++ b/opendj-cli/src/main/java/com/forgerock/opendj/cli/ToolRefDocContainer.java
@@ -0,0 +1,162 @@
+/*
+ * 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 legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * 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 legal-notices/CDDLv1_0.txt.
+ * 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
+ *
+ *
+ * Copyright 2015 ForgeRock AS.
+ */
+package com.forgerock.opendj.cli;
+
+import org.forgerock.i18n.LocalizableMessage;
+
+/**
+ * An interface for an object that holds reference documentation for a command-line tool.
+ */
+public interface ToolRefDocContainer {
+
+ /**
+ * Gets a short description for this tool, suitable in a man page summary line.
+ *
+ * @return A short description for this tool,
+ * suitable in a man page summary line,
+ * or LocalizableMessage.EMPTY if there is no short description.
+ */
+ LocalizableMessage getShortToolDescription();
+
+ /**
+ * Sets a short description for this tool, suitable in a man page summary line.
+ *
+ * @param shortDescription The short description for this tool,
+ * suitable in a man page summary line.
+ */
+ void setShortToolDescription(final LocalizableMessage shortDescription);
+
+ /**
+ * Retrieves a supplement to the description for this tool,
+ * intended for use in generated reference documentation.
+ *
+ * @return A supplement to the description for this tool
+ * intended for use in generated reference documentation,
+ * or LocalizableMessage.EMPTY if there is no supplement.
+ */
+ LocalizableMessage getDocToolDescriptionSupplement();
+
+ /**
+ * Sets a supplement to the description for this tool,
+ * intended for use in generated reference documentation.
+ *
+ * @param docToolDescriptionSupplement The supplement to the description for this tool
+ * intended for use in generated reference documentation.
+ */
+ void setDocToolDescriptionSupplement(final LocalizableMessage docToolDescriptionSupplement);
+
+ /**
+ * Retrieves a supplement to the description for all subcommands of this tool,
+ * intended for use in generated reference documentation.
+ *
+ * @return A supplement to the description for all subcommands of this tool
+ * intended for use in generated reference documentation,
+ * or LocalizableMessage.EMPTY if there is no supplement.
+ */
+ LocalizableMessage getDocSubcommandsDescriptionSupplement();
+
+ /**
+ * Sets a supplement to the description for all subcommands of this tool,
+ * intended for use in generated reference documentation.
+ *
+ * @param docSubcommandsDescriptionSupplement
+ * The supplement to the description for all subcommands of this tool
+ * intended for use in generated reference documentation.
+ */
+ void setDocSubcommandsDescriptionSupplement(final LocalizableMessage docSubcommandsDescriptionSupplement);
+
+ /**
+ * Get additional paths to DocBook XML {@code RefSect1} documents
+ * to be appended after generated content in reference documentation.
+ *
+ * <br>
+ *
+ * DocBook represents a reference manual page with the {@code RefEntry}.
+ * See <a href="http://www.docbook.org/tdg51/en/html/refentry.html">refentry</a>.
+ *
+ * <br>
+ *
+ * A {@code RefEntry} describing an OpenDJ tool contains
+ * block elements in the following order:
+ *
+ * <pre>
+ * RefMeta
+ * RefNameDiv
+ * RefSynopsisDiv
+ * RefSect1 - Description (generated, potentially with a hand-written supplement)
+ * RefSect1 - Options (generated)
+ * RefSect1 - Subcommands (optional, hand-written intro + generated RefSect2s)
+ * RefSect1 - Filter (optional, hand-written)
+ * RefSect1 - Attribute (optional, hand-written)
+ * RefSect1 - Exit Codes (hand-written)
+ * RefSect1 - Files (optional, hand-written)
+ * RefSect1 - Examples (hand-written)
+ * RefSect1 - See Also (hand-written)
+ * </pre>
+ *
+ * As the trailing RefSect1s following Subcommands are hand-written,
+ * they are included in the generated content as XIncludes elements.
+ *
+ * @return The paths to trailing {@code RefSect1} documents.
+ */
+ String[] getPathsToTrailingRefSect1s();
+
+ /**
+ * Set additional paths to DocBook XML {@code RefSect1} documents
+ * to be appended after generated content in reference documentation.
+ *
+ * <br>
+ *
+ * DocBook represents a reference manual page with the {@code RefEntry}.
+ * See <a href="http://www.docbook.org/tdg51/en/html/refentry.html">refentry</a>.
+ *
+ * <br>
+ *
+ * A {@code RefEntry} describing an OpenDJ tool contains
+ * block elements in the following order:
+ *
+ * <pre>
+ * RefMeta
+ * RefNameDiv
+ * RefSynopsisDiv
+ * RefSect1 - Description (generated, potentially with a hand-written supplement)
+ * RefSect1 - Options (generated)
+ * RefSect1 - Subcommands (optional, hand-written intro + generated RefSect2s)
+ * RefSect1 - Filter (optional, hand-written)
+ * RefSect1 - Attribute (optional, hand-written)
+ * RefSect1 - Exit Codes (hand-written)
+ * RefSect1 - Files (optional, hand-written)
+ * RefSect1 - Examples (hand-written)
+ * RefSect1 - See Also (hand-written)
+ * </pre>
+ *
+ * As the trailing RefSect1s following Subcommands are hand-written,
+ * they are included in the generated content as XIncludes elements.
+ *
+ * @param paths The paths to trailing {@code RefSect1} documents.
+ */
+ public void setPathsToTrailingRefSect1s(final String... paths);
+}
diff --git a/opendj-cli/src/main/resources/templates/optionsRefSect1.ftl b/opendj-cli/src/main/resources/templates/optionsRefSect1.ftl
new file mode 100644
index 0000000..ee7a085
--- /dev/null
+++ b/opendj-cli/src/main/resources/templates/optionsRefSect1.ftl
@@ -0,0 +1,62 @@
+<#--
+ # 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 legal-notices/CDDLv1_0.txt
+ # or http://forgerock.org/license/CDDLv1.0.html.
+ # 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 legal-notices/CDDLv1_0.txt.
+ # 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
+ #
+ # Copyright 2015 ForgeRock AS.
+ #
+ #-->
+<refsect1 xml:id="${name}-options">
+ <title>${title}</title>
+
+ <para>
+ ${intro}
+ </para>
+
+ <#list groups as group>
+ <variablelist>
+ <#if group.description??>
+ <para>
+ ${group.description}
+ </para>
+ </#if>
+
+ <#list group.options as option>
+ <varlistentry>
+ <term><option>${option.synopsis?xml}</option></term>
+ <listitem>
+ <para>
+ ${option.description}
+ </para>
+
+ <#if option.default??>
+ <para>
+ ${option.default}
+ </para>
+ </#if>
+
+ <#if option.info??>${option.info}</#if>
+ </listitem>
+ </varlistentry>
+ </#list>
+ </variablelist>
+ </#list>
+</refsect1>
diff --git a/opendj-cli/src/main/resources/templates/refEntry.ftl b/opendj-cli/src/main/resources/templates/refEntry.ftl
index 13b3908..db23699 100644
--- a/opendj-cli/src/main/resources/templates/refEntry.ftl
+++ b/opendj-cli/src/main/resources/templates/refEntry.ftl
@@ -78,7 +78,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>${name}</command>
- <arg choice="plain">${args}</arg>
+ <#if args??><arg choice="plain">${args}</arg></#if>
</cmdsynopsis>
</refsynopsisdiv>
@@ -92,44 +92,17 @@
<#if info??>${info}</#if>
</refsect1>
- <#if options??>
- <refsect1>
- <title>${optsTitle}</title>
-
- <variablelist>
- <para>
- ${optsIntro}
- </para>
-
- <#list options as option>
- <varlistentry>
- <term><option>${option.synopsis?xml}</option></term>
- <listitem>
- <para>
- ${option.description}
- </para>
-
- <#if option.default??>
- <para>
- ${option.default}
- </para>
- </#if>
-
- <#if option.info??>${option.info}</#if>
- </listitem>
- </varlistentry>
-
- </#list>
-
- </variablelist>
- </refsect1>
+ <#if optionSection??>
+ ${optionSection}
</#if>
- <!-- TODO: subcommands -->
- <!-- TODO: filter -->
- <!-- TODO: attribute -->
- <!-- TODO: exitCodes -->
- <!-- TODO: files -->
- <!-- TODO: examples -->
- <!-- TODO: seeAlso -->
+ <#if subcommands??>
+ ${subcommands}
+ </#if>
+
+ <#if trailingSections??>
+ <#list trailingSections as section>
+ ${section}
+ </#list>
+ </#if>
</refentry>
diff --git a/opendj-cli/src/main/resources/templates/refSect1.ftl b/opendj-cli/src/main/resources/templates/refSect1.ftl
new file mode 100644
index 0000000..c4e71fe
--- /dev/null
+++ b/opendj-cli/src/main/resources/templates/refSect1.ftl
@@ -0,0 +1,41 @@
+<#--
+ # 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 legal-notices/CDDLv1_0.txt
+ # or http://forgerock.org/license/CDDLv1.0.html.
+ # 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 legal-notices/CDDLv1_0.txt.
+ # 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
+ #
+ # Copyright 2015 ForgeRock AS.
+ #
+ #-->
+<refsect1 xml:id="${name}-subcommands">
+ <title>Subcommands</title>
+
+ <#if info??>
+ ${info}
+ </#if>
+
+ <para>
+ The <command>${name}</command> utility supports the following subcommands.
+ </para>
+
+ <#list subcommands as subcommand>
+ ${subcommand}
+ </#list>
+</refsect1>
diff --git a/opendj-cli/src/main/resources/templates/refSect2.ftl b/opendj-cli/src/main/resources/templates/refSect2.ftl
index 2529f3d..059aa49 100644
--- a/opendj-cli/src/main/resources/templates/refSect2.ftl
+++ b/opendj-cli/src/main/resources/templates/refSect2.ftl
@@ -35,42 +35,42 @@
<#if options??>
<refsect3 xml:id="${id}-options">
- <title>${optsTitle}</title>
+ <title>${optionsTitle}</title>
<variablelist>
<para>
- ${optsIntro}
+ ${optionsIntro}
</para>
<#list options as option>
- <varlistentry>
- <term><option>${option.synopsis?xml}</option></term>
- <listitem>
- <para>
- ${option.description}
- </para>
+ <varlistentry>
+ <term><option>${option.synopsis?xml}</option></term>
+ <listitem>
+ <para>
+ ${option.description}
+ </para>
- <#if option.info??>
- <#if info.usage??>${option.info.usage}</#if>
+ <#if option.info??>
+ <#if option.info.usage??>${option.info.usage}</#if>
- <#if info.default??>
- <para>
- ${option.info.default}
- </para>
+ <#if option.info.default??>
+ <para>
+ ${option.info.default}
+ </para>
+ </#if>
+
+ <#if option.info.doc??>${option.info.doc}</#if>
</#if>
-
- <#if info.doc??>${option.info.doc}</#if>
- </#if>
- </listitem>
- </varlistentry>
+ </listitem>
+ </varlistentry>
</#list>
</variablelist>
</refsect3>
</#if>
- <#if properties??>
- ${properties}
+ <#if propertiesInfo??>
+ ${propertiesInfo}
</#if>
</refsect2>
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 9ee400c..925f9fe 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
@@ -487,7 +487,7 @@
final Object[] constants = en.getEnumConstants();
for (Object enumConstant : constants) {
final LocalizableMessage valueSynopsis = prop.getValueSynopsis((Enum) enumConstant);
- appendVarListEntry(b, enumConstant.toString(), valueSynopsis);
+ appendVarListEntry(b, enumConstant.toString(), op + valueSynopsis + cp);
}
b.append("</variablelist>").append(EOL);
return null;
@@ -864,6 +864,8 @@
this.parser = new SubCommandArgumentParser(getClass().getName(), INFO_DSCFG_TOOL_DESCRIPTION.get(), false);
this.parser.setShortToolDescription(REF_SHORT_DESC_DSCONFIG.get());
+ this.parser.setDocToolDescriptionSupplement(REF_DSCFG_DOC_TOOL_DESCRIPTION.get());
+ this.parser.setDocSubcommandsDescriptionSupplement(REF_DSCFG_DOC_SUBCOMMANDS_DESCRIPTION.get());
this.parser.setVersionHandler(new VersionHandler() {
@Override
public void printVersion() {
diff --git a/opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties b/opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties
index 71d729c..290e2ba 100644
--- a/opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties
+++ b/opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties
@@ -504,3 +504,243 @@
REF_DSCFG_STRING_1038=A String
REF_DSCFG_UNKNOWN_1039=Unknown
REF_SHORT_DESC_DSCONFIG_1040=manage OpenDJ directory server configuration
+REF_DSCFG_DOC_TOOL_DESCRIPTION_1041=<para> \
+ The <command>dsconfig</command> command is the primary command-line tool \
+ for viewing and editing OpenDJ configuration. \
+ When started without arguments, \
+ <command>dsconfig</command> prompts you for administration connection information, \
+ including the host name, administration port number, \
+ administrator bind DN and administrator password. \
+ The <command>dsconfig</command> command then connects securely \
+ to the directory server over the administration port. \
+ Once connected it presents you with a menu-driven interface to the server configuration. \
+</para> \
+ \
+<para> \
+ When you pass connection information, subcommands, and additional options \
+ to <command>dsconfig</command>, \
+ the command runs in script mode and so is not interactive, \
+ though it can prompt you to ask whether to apply changes \
+ and whether to trust certificates \
+ (unless you use the <option>--no-prompt</option> \
+ and <option>--trustAll</option> options, respectively). \
+</para> \
+ \
+<para> \
+ You can prepare <command>dsconfig</command> batch scripts \
+ by running the tool with the <option>--commandFilePath</option> option \
+ in interactive mode, \
+ then reading from the batch file with the <option>--batchFilePath</option> option \
+ in script mode. \
+ Batch files can be useful when you have many <command>dsconfig</command> commands to run \
+ and want to avoid starting the JVM and setting up a new connection for each command. \
+</para> \
+ \
+<para> \
+ The <command>dsconfig</command> command categorizes \
+ directory server configuration into <firstterm>components</firstterm>, \
+ also called <firstterm>managed objects</firstterm>. \
+ Actual components often inherit from a parent component type. \
+ For example, one component is a Connection Handler. \
+ An LDAP Connection Handler is a type of Connection Handler. \
+ You configure the LDAP Connection Handler component \
+ to specify how OpenDJ directory server handles LDAP connections \
+ coming from client applications. \
+</para> \
+ \
+<para> \
+ Configuration components have <firstterm>properties</firstterm>. \
+ For example, the LDAP Connection Handler component has properties \
+ such as <literal>listen-port</literal> and <literal>allow-start-tls</literal>. \
+ You can set the component's <literal>listen-port</literal> property \
+ to <literal>389</literal> to use the default LDAP port number. \
+ You can set the component's <literal>allow-start-tls</literal> property \
+ to <literal>true</literal> to permit LDAP client applications to use StartTLS. \
+ Much of the configuration you do with <command>dsconfig</command> \
+ involves setting component properties. \
+</para>
+REF_DSCFG_DOC_SUBCOMMANDS_DESCRIPTION_1042=<para> \
+ The <command>dsconfig</command> command provides many subcommands. \
+ </para> \
+ \
+ <para> \
+ Subcommands let you create, list, and delete entire configuration components, \
+ and also let you get and set component properties. \
+ Subcommands therefore have names that reflect these five actions. \
+ </para> \
+ \
+ <itemizedlist> \
+ <listitem><para>create-<replaceable>component</replaceable></para></listitem> \
+ <listitem><para>list-<replaceable>component</replaceable>s</para></listitem> \
+ <listitem><para>delete-<replaceable>component</replaceable></para></listitem> \
+ <listitem><para>get-<replaceable>component</replaceable>-prop</para></listitem> \
+ <listitem><para>set-<replaceable>component</replaceable>-prop</para></listitem> \
+ </itemizedlist> \
+ \
+ <para> \
+ Here, <replaceable>component</replaceable> names are names of managed object types. \
+ Subcommand <replaceable>component</replaceable> names \
+ are lower-case, hyphenated versions of the friendly names. \
+ When you act on an actual configuration component, \
+ you provide the name of the component as an option argument. \
+ </para> \
+ \
+ <itemizedlist> \
+ <para> \
+ For example, the Log Publisher component has these corresponding subcommands. \
+ </para> \
+ \
+ <listitem><para><command>create-log-publisher</command></para></listitem> \
+ <listitem><para><command>list-log-publishers</command></para></listitem> \
+ <listitem><para><command>delete-log-publisher</command></para></listitem> \
+ <listitem><para><command>get-log-publisher-prop</command></para></listitem> \
+ <listitem><para><command>set-log-publisher-prop</command></para></listitem> \
+ </itemizedlist> \
+ \
+ <para> \
+ When you create or delete Log Publisher components \
+ and when you get and set their configuration properties, \
+ you provide the name of the actual log publisher, \
+ which you can find by using the <command>list-log-publishers</command> subcommand. \
+ </para> \
+ \
+ <screen> \n \
+$ <userinput>dsconfig \\ \n \
+ list-log-publishers \\ \n \
+ --hostname opendj.example.com \\ \n \
+ --port 4444 \\ \n \
+ --bindDN "cn=Directory Manager" \\ \n \
+ --bindPassword password \\ \n \
+ --trustAll</userinput> \n \
+<computeroutput> \n \
+Log Publisher : Type : enabled \n \
+------------------------------:------------------------:-------- \n \
+File-Based Access Logger : file-based-access : true \n \
+File-Based Audit Logger : file-based-audit : false \n \
+File-Based Debug Logger : file-based-debug : false \n \
+File-Based Error Logger : file-based-error : true \n \
+File-Based HTTP Access Logger : file-based-http-access : false \n \
+Replication Repair Logger : file-based-error : true</computeroutput> \n \
+ \n \
+$ <userinput>dsconfig \\ \n \
+ get-log-publisher-prop \\ \n \
+ --publisher-name "File-Based Access Logger" \\ \n \
+ --property rotation-policy \\ \n \
+ --hostname opendj.example.com \\ \n \
+ --port 4444 \\ \n \
+ --bindDN "cn=Directory Manager" \\ \n \
+ --bindPassword password \\ \n \
+ --trustAll</userinput> \n \
+<computeroutput>Property : Value(s) \n \
+----------------:-------------------------------------------------------------- \n \
+rotation-policy : 24 Hours Time Limit Rotation Policy, Size Limit Rotation \n \
+ : Policy</computeroutput> \n \
+ </screen> \
+ \
+ <para> \
+ Many subcommands let you set property values. \
+ Notice in the reference for the subcommands below \
+ that specific options are available for handling multi-valued properties. \
+ Whereas you can assign a single property value \
+ by using the <option>--set</option> option, \
+ you assign multiple values to a multi-valued property \
+ by using the <option>--add</option> option. \
+ You can reset the values of the multi-valued property \
+ by using the <option>--reset</option> option. \
+ </para> \
+ \
+ <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> \
+ \
+ <para> \
+ Use the following options to view help for subcommands. \
+ </para> \
+ \
+ <variablelist> \
+ <varlistentry> \
+ <term><command>dsconfig --help-all</command></term> \
+ <listitem> \
+ <para> \
+ Display all subcommands \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-core-server</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to core server \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-database</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to caching and back-ends \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-logging</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to logging \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-replication</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to replication \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-security</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to authentication and authorization \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ <varlistentry> \
+ <term><command>dsconfig --help-user-management</command></term> \
+ <listitem> \
+ <para> \
+ Display subcommands relating to user management \
+ </para> \
+ </listitem> \
+ </varlistentry> \
+ </variablelist> \
+ \
+ <para> \
+ For help with individual subcommands, \
+ either use <command>dsconfig <replaceable>subcommand</replaceable> --help</command>, \
+ or start <command>dsconfig</command> in interactive mode, \
+ without specifying a subcommand. \
+ </para> \
+ \
+ <para> \
+ To view all component properties, \
+ use the <command>dsconfig list-properties</command> command. \
+ </para>
+
--
Gitblit v1.10.0