opendj-cli/pom.xml
@@ -21,7 +21,7 @@ ! ! CDDL HEADER END ! ! Copyright 2014 ForgeRock AS ! Copyright 2014-2015 ForgeRock AS. ! --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> @@ -60,6 +60,11 @@ <version>${forgerockBuildToolsVersion}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.21</version> </dependency> </dependencies> <properties> <opendj.osgi.import> opendj-cli/src/main/java/com/forgerock/opendj/cli/ArgumentParser.java
@@ -28,18 +28,23 @@ import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.CliMessages.*; import static com.forgerock.opendj.cli.DocGenerationHelper.*; import static com.forgerock.opendj.cli.Utils.*; import static com.forgerock.opendj.util.StaticUtils.*; import java.io.File; import java.io.FileInputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.Date; import java.util.Enumeration; 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.Set; import java.util.SortedSet; @@ -658,74 +663,63 @@ final StringBuilder buffer = new StringBuilder(); usageOrVersionDisplayed = true; if (System.getProperty("org.forgerock.opendj.gendoc") != null) { toRefSect2(buffer); toRefEntry(buffer); } else { getUsage(buffer); } return buffer.toString(); } private void toRefSect2(StringBuilder sb) { /** * Appends a generated DocBook XML RefEntry (man page) to the StringBuilder. * * @param sb Append the RefEntry element to this. */ private void toRefEntry(StringBuilder sb) { final String scriptName = getScriptName(); if (scriptName == null) { throw new RuntimeException("The script name should have been set via the environment property '" + PROPERTY_SCRIPT_NAME + "'."); } sb.append("<refsect2 xml:id=\"").append(scriptName).append("\">").append(EOL); sb.append(" <title>").append(scriptName).append("</title>").append(EOL); sb.append(" <para>").append(getToolDescription()).append("</para>").append(EOL); // 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("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("description", getToolDescription()); // If there is a supplement to the description for this utility, // then it is formatted for use in generated reference documentation. // In other words, it is already DocBook XML, so append it as is. final LocalizableMessage toolDocDescriptionSupplement = getDocToolDescriptionSupplement(); if (!LocalizableMessage.EMPTY.equals(toolDocDescriptionSupplement)) { sb.append(toolDocDescriptionSupplement.toString()).append(EOL); } // then it is already DocBook XML, so use it as is. map.put("info", getDocToolDescriptionSupplement()); if (!argumentList.isEmpty()) { sb.append(" <variablelist>").append(EOL); List<Map<String, Object>> options = new LinkedList<Map<String, Object>>(); for (Argument a : argumentList) { sb.append(" <varlistentry>").append(EOL); sb.append(" <term><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></term>").append(EOL); sb.append(" <listitem>").append(EOL); sb.append(" <para>").append(a.getDescription()).append("</para>").append(EOL); final String defaultValue = a.getDefaultValue(); if (defaultValue != null && !defaultValue.isEmpty()) { sb.append(" <para>Default: ").append(defaultValue).append("</para>").append(EOL); } 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 for now it is already formatted in DocBook XML. final LocalizableMessage aDocDescriptionSupplement = a.getDocDescriptionSupplement(); if (!LocalizableMessage.EMPTY.equals(aDocDescriptionSupplement)) { sb.append(aDocDescriptionSupplement.toString()).append(EOL); // then it is already DocBook XML, so use it as is. option.put("info", a.getDocDescriptionSupplement()); options.add(option); } sb.append(" </listitem>").append(EOL); sb.append(" </varlistentry>").append(EOL); map.put("options", options); } sb.append(" </variablelist>").append(EOL); } sb.append("</refsect2>").append(EOL); applyTemplate(sb, "refEntry.ftl", map); } /** opendj-cli/src/main/java/com/forgerock/opendj/cli/DocGenerationHelper.java
New file @@ -0,0 +1,137 @@ /* * 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 freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateExceptionHandler; import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Map; /** * This class provides utility functions to help generate reference documentation. */ public final class DocGenerationHelper { /** Prevent instantiation. */ private DocGenerationHelper() { // Do nothing. } /** FreeMarker template configuration. */ private static Configuration configuration; /** * Gets a FreeMarker configuration for applying templates. * * @return A FreeMarker configuration. */ private static Configuration getConfiguration() { if (configuration == null) { configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); configuration.setClassForTemplateLoading(DocGenerationHelper.class, "/templates"); configuration.setDefaultEncoding("UTF-8"); configuration.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER); } return configuration; } /** * Appends the String result from applying a FreeMarker template. * * @param builder Append the result to this. * @param template The name of a template file found in {@code resources/templates/}. * @param map The map holding the data to use in the template. */ public static void applyTemplate(StringBuilder builder, final String template, final Map<String, Object> map) { // FixMe: This method is public so it can be used by the SubCommandUsageHandler // in org.forgerock.opendj.config.dsconfig.DSConfig. // FreeMarker requires a configuration to find the template. configuration = getConfiguration(); // FreeMarker takes the data and a Writer to process the template. ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); Writer writer = new OutputStreamWriter(outputStream); try { Template configurationTemplate = configuration.getTemplate(template); configurationTemplate.process(map, writer); builder.append(outputStream.toString()); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } finally { org.forgerock.util.Utils.closeSilently(writer, outputStream); } } /** * Returns an option synopsis. * * <br> * * Note: The synopsis might contain characters that must be escaped in XML. * * @param argument The argument option. * @return A synopsis. */ static String getOptionSynopsis(final Argument argument) { StringBuilder builder = new StringBuilder(); final Character shortID = argument.getShortIdentifier(); if (shortID != null) { builder.append("-").append(shortID.charValue()); } final String longID = argument.getLongIdentifier(); if (shortID != null && longID != null) { builder.append(" | "); } if (longID != null) { builder.append("--").append(longID); } if (argument.needsValue()) { builder.append(" ").append(argument.getValuePlaceholder()); } return builder.toString(); } /** * Returns true when the argument handles properties. * * @param argument The argument. * @return True if the argument handles properties. */ public static boolean doesHandleProperties(final Argument argument) { // FixMe: This method is public so it can be used by the SubCommandUsageHandler // in org.forgerock.opendj.config.dsconfig.DSConfig. final String id = argument.getLongIdentifier(); return ("add".equals(id) || "remove".equals(id) || "reset".equals(id) || "set".equals(id)); } } opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandArgumentParser.java
@@ -28,6 +28,7 @@ import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.CliMessages.*; import static com.forgerock.opendj.cli.DocGenerationHelper.*; import static com.forgerock.opendj.cli.Utils.*; import static com.forgerock.opendj.util.StaticUtils.*; @@ -1102,7 +1103,17 @@ } } /** Generate reference documentation for dsconfig subcommands. */ /** * Appends a list generated DocBook XML RefSect2 elements to the StringBuilder, one per subcommand. * * <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. */ private void generateReferenceDoc(final StringBuilder builder, Collection<SubCommand> values) { for (SubCommand s : values) { toRefSect2(s, builder); @@ -1110,58 +1121,12 @@ } /** * Generate reference documentation for dsconfig subcommands in DocBook 5 XML format. As the number of categories is * large, the subcommand entries are sorted here by name for inclusion in a <refsect1> covering all dsconfig * Subcommands as part of the <refentry> for dsconfig (in man-dsconfig.xml). * <p> * Although it would be possible to categorize subcommands in the same way as they are categorized in dsconfig * interactive mode, this generator does not use the categories. * <p> * It would also be possible to generate the sort of information provided by the configuration reference, such that * this reference would not stop at simply listing an option like --set {PROP:VAL}, but instead would also provide * the list of PROPs and their possible VALs. A future improvement could no doubt merge the configuration reference * with this content, though perhaps the problem calls for hypertext rather than the linear structure of a * <refentry>. * <p> * Each individual subcommand results in a <refsect2> element similar to the following. * * <pre> * <refsect2 xml:id="dsconfig-create-local-db-index"> * <title>dsconfig create-local-db-index</title> * <para>Creates Local DB Indexes</para> * <variablelist> * <varlistentry> * <term><option>--backend-name {name} * </option></term> * <listitem> * <para>The name of the Local DB Backend</para> * </listitem> * </varlistentry> * <varlistentry> * <term><option>--index-name {OID}</option></term> * <listitem> * <para>The name of the new Local DB Index which will also be used * as the value of the "attribute" property: Specifies the name * of the attribute for which the index is to be maintained.</para> * </listitem> * </varlistentry> * <varlistentry> * <term><option>--set {PROP:VALUE}</option></term> * <listitem> * <para>Assigns a value to a property where PROP is the name of the * property and VALUE is the single value to be assigned. Specify the same * property multiple times in order to assign more than one value to * it</para> * </listitem> * </varlistentry> * </variablelist> * </refsect2> * </pre> * Appends a generated DocBook XML RefSect2 element for a single subcommand to the StringBuilder. * * @param sc * The SubCommand containing reference information. * @param sb * The string builder where to output the Refsect2 representation of the subcommand * Append the RefSect2 element to this. */ private void toRefSect2(SubCommand sc, StringBuilder sb) { final String scriptName = getScriptName(); @@ -1170,90 +1135,50 @@ + PROPERTY_SCRIPT_NAME + "'."); } 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); // 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("name", name); map.put("description", sc.getDescription()); map.put("optsTitle", REF_TITLE_OPTIONS.get()); map.put("optsIntro", REF_INTRO_OPTIONS.get(name)); // If there is a supplement to the description for this subcommand, // then it is formatted for use in generated reference documentation. // In other words, it is already DocBook XML, so append it as is. final LocalizableMessage scDocDescriptionSupplement = sc.getDocDescriptionSupplement(); if (!LocalizableMessage.EMPTY.equals(scDocDescriptionSupplement)) { sb.append(scDocDescriptionSupplement.toString()).append(EOL); } // then it is already DocBook XML, so use it as is. map.put("info", sc.getDocDescriptionSupplement()); if (!sc.getArguments().isEmpty()) { 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); List<Map<String, Object>> options = new LinkedList<Map<String, Object>>(); String nameOption = null; for (Argument a : sc.getArguments()) { 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; } Map<String, Object> option = new HashMap<String, Object>(); String optionSynopsis = getOptionSynopsis(a); option.put("synopsis", optionSynopsis); option.put("description", a.getDescription()); Map<String, Object> info = new HashMap<String, Object>(); if (subCommandUsageHandler != null) { subCommandUsageHandler.appendArgumentAdditionalInfo(sb, sc, a, nameOption); } else { final String defaultValue = a.getDefaultValue(); if (defaultValue != null && !defaultValue.isEmpty()) { sb.append(" <para>Default: ").append(defaultValue).append("</para>").append(EOL); if (!doesHandleProperties(a)) { nameOption = "<option>" + optionSynopsis + "</option>"; } // Let this build its own arbitrarily formatted additional info. info.put("usage", subCommandUsageHandler.getArgumentAdditionalInfo(sc, a, nameOption)); } else { info.put("default", REF_DEFAULT.get(a.getDefaultValue())); // If there is a supplement to the description for this argument, // then for now it is already formatted in DocBook XML. final LocalizableMessage aDocDescriptionSupplement = a.getDocDescriptionSupplement(); if (!LocalizableMessage.EMPTY.equals(aDocDescriptionSupplement)) { sb.append(aDocDescriptionSupplement.toString()).append(EOL); // then it is already DocBook XML, so use it as is. info.put("doc", a.getDocDescriptionSupplement()); } option.put("info", info); options.add(option); } sb.append(" </listitem>").append(EOL); sb.append(" </varlistentry>").append(EOL); map.put("options", options); } sb.append(" </variablelist>").append(EOL); sb.append(" </refsect3>").append(EOL); } if (subCommandUsageHandler != null) { subCommandUsageHandler.appendProperties(sb, sc); map.put("properties", subCommandUsageHandler.getProperties(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(); applyTemplate(sb, "refSect2.ftl", map); } } opendj-cli/src/main/java/com/forgerock/opendj/cli/SubCommandUsageHandler.java
@@ -21,7 +21,7 @@ * CDDL HEADER END * * * Copyright 2015 ForgeRock AS * Copyright 2015 ForgeRock AS. */ package com.forgerock.opendj.cli; @@ -32,27 +32,25 @@ public interface SubCommandUsageHandler { /** * Appends properties information for the sub-command. * Returns properties information for the sub-command. * * @param builder * the string builder where to append * @param subCommand * the sub command for which to print usage information * @return The properties information for the sub-command. */ void appendProperties(StringBuilder builder, SubCommand subCommand); String getProperties(SubCommand subCommand); /** * Appends additional information for the provided sub-command argument. * Returns 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 * @return The additional information for the sub-command argument. */ void appendArgumentAdditionalInfo(StringBuilder builder, SubCommand subCommand, Argument arg, String nameOption); String getArgumentAdditionalInfo(SubCommand subCommand, Argument arg, String nameOption); } opendj-cli/src/main/resources/com/forgerock/opendj/cli/cli.properties
@@ -973,6 +973,13 @@ ERR_ERROR_CANNOT_READ_BIND_NAME=Unable to read bind name ERR_ERROR_CANNOT_READ_HOST_NAME=Cannot read the host name # Strings for generated reference documentation. REF_TITLE_DESCRIPTION=Description REF_TITLE_OPTIONS=Options REF_INTRO_OPTIONS=The <command>%s</command> command takes the following options: REF_DEFAULT=Default: %s REF_TITLE_SUBCOMMANDS=Subcommands # Supplements to descriptions for generated reference documentation. SUPPLEMENT_DESCRIPTION_CONTROLS=<para> \ For some <replaceable>controloid</replaceable> values, \ opendj-cli/src/main/resources/templates/dscfgAppendProps.ftl
New file @@ -0,0 +1,35 @@ <#-- # 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. # #--> <refsect3 xml:id="${id}"> <title>${title}</title> <para> ${intro} </para> ${list} </refsect3> opendj-cli/src/main/resources/templates/dscfgListSubtypes.ftl
New file @@ -0,0 +1,56 @@ <#-- # 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. # #--> <variablelist> <para> ${dependencies} </para> <para> ${typesIntro} </para> <#list children as child> <varlistentry> <term>${child.name}</term> <listitem> <para> ${child.default} </para> <para> ${child.enabled} </para> <para> ${child.link} </para> </listitem> </varlistentry> </#list> </variablelist> opendj-cli/src/main/resources/templates/dscfgVarListEntry.ftl
New file @@ -0,0 +1,32 @@ <#-- # 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. # #--> <varlistentry> <term>${term}</term> <listitem> ${definition} </listitem> </varlistentry> opendj-cli/src/main/resources/templates/dscfgVariableList.ftl
New file @@ -0,0 +1,51 @@ <#-- # 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. # #--> <variablelist> <#list properties as property> <varlistentry xml:id="${property.id}"> <term>${property.term}</term> <listitem> <variablelist> <varlistentry> <term>${property.descTitle}</term> <listitem> <para> ${property.description} </para> </listitem> </varlistentry> ${property.list} </variablelist> </listitem> </varlistentry> </#list> </variablelist> opendj-cli/src/main/resources/templates/refEntry.ftl
New file @@ -0,0 +1,135 @@ <#-- # 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. # #--> <?xml version="1.0" encoding="UTF-8"?> <!-- ! CCPL HEADER START ! ! This work is licensed under the Creative Commons ! Attribution-NonCommercial-NoDerivs 3.0 Unported License. ! To view a copy of this license, visit ! http://creativecommons.org/licenses/by-nc-nd/3.0/ ! or send a letter to Creative Commons, 444 Castro Street, ! Suite 900, Mountain View, California, 94041, USA. ! ! You can also obtain a copy of the license at ! trunk/opendj/legal-notices/CC-BY-NC-ND.txt. ! See the License for the specific language governing permissions ! and limitations under the License. ! ! If applicable, add the following below this CCPL HEADER, with the fields ! enclosed by brackets "[]" replaced with your own identifying information: ! Portions Copyright [yyyy] [name of copyright owner] ! ! CCPL HEADER END ! ! Copyright 2011-${year} ForgeRock AS. ! --> <refentry xml:id="${name}-1" xmlns="http://docbook.org/ns/docbook" version="5.0" xml:lang="${locale}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xinclude="http://www.w3.org/2001/XInclude"> <info> <copyright> <year>2011-${year}</year> <holder>ForgeRock AS.</holder> </copyright> </info> <refmeta> <refentrytitle>${name}</refentrytitle><manvolnum>1</manvolnum> <refmiscinfo class="software">OpenDJ</refmiscinfo> <refmiscinfo class="version">${r"${project.version}"}</refmiscinfo> </refmeta> <refnamediv> <refname>${name}</refname> <refpurpose>TODO short description</refpurpose> </refnamediv> <refsynopsisdiv> <cmdsynopsis> <command>${name}</command> <arg choice="plain">${args}</arg> </cmdsynopsis> </refsynopsisdiv> <refsect1 xml:id="${name}-description"> <title>${descTitle}</title> <para> ${description} </para> <#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> <!-- TODO: subcommands --> <!-- TODO: filter --> <!-- TODO: attribute --> <!-- TODO: exitCodes --> <!-- TODO: files --> <!-- TODO: examples --> <!-- TODO: seeAlso --> </refentry> opendj-cli/src/main/resources/templates/refSect2.ftl
New file @@ -0,0 +1,76 @@ <#-- # 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. # #--> <refsect2 xml:id="${id}"> <title>${name}</title> <para> ${description} </para> <#if info??>${info}</#if> <#if options??> <refsect3 xml:id="${id}-options"> <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.info??> <#if info.usage??>${option.info.usage}</#if> <#if info.default??> <para> ${option.info.default} </para> </#if> <#if info.doc??>${option.info.doc}</#if> </#if> </listitem> </varlistentry> </#list> </variablelist> </refsect3> </#if> <#if properties??> ${properties} </#if> </refsect2> opendj-config/src/main/java/org/forgerock/opendj/config/dsconfig/DSConfig.java
@@ -22,12 +22,13 @@ * * * Copyright 2007-2010 Sun Microsystems, Inc. * Portions Copyright 2012-2015 ForgeRock AS * Portions Copyright 2012-2015 ForgeRock AS. */ package org.forgerock.opendj.config.dsconfig; import static com.forgerock.opendj.cli.ArgumentConstants.*; import static com.forgerock.opendj.cli.CliMessages.*; import static com.forgerock.opendj.cli.DocGenerationHelper.*; import static com.forgerock.opendj.cli.Utils.*; import static com.forgerock.opendj.dsconfig.DsconfigMessages.*; import static com.forgerock.opendj.util.StaticUtils.*; @@ -54,6 +55,7 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -127,93 +129,61 @@ */ 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 /** * This class provides additional information about subcommands for generated reference documentation. */ private final class DSConfigSubCommandUsageHandler implements SubCommandUsageHandler { /** Marker to open a DocBook XML paragraph. */ private String op = "<para>"; /** Marker to close a DocBook XML paragraph. */ private String cp = "</para>"; /** {@inheritDoc} */ @Override public void appendArgumentAdditionalInfo(StringBuilder sb, SubCommand sc, Argument a, String nameOption) { public String getArgumentAdditionalInfo(SubCommand sc, Argument a, String nameOption) { StringBuilder sb = new StringBuilder(); final AbstractManagedObjectDefinition<?, ?> defn = getManagedObjectDefinition(sc); if (defn == null) { return; return ""; } final String longID = a.getLongIdentifier(); if ("set".equals(longID) || "reset".equals(longID) || "add".equals(longID) || "remove".equals(longID)) { sb.append(" <para>").append(EOL); if (doesHandleProperties(a)) { 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); sb.append(op).append(REF_DSCFG_ARG_ADDITIONAL_INFO.get(name, name, nameOption)).append(cp).append(EOL); } else { listSubtypes(sb, a, defn); } return; return sb.toString(); } private void listSubtypes(StringBuilder sb, Argument a, AbstractManagedObjectDefinition<?, ?> defn) { final LocalizableMessage placeholder = a.getValuePlaceholder(); 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(name).append(" types:").append(EOL); sb.append(" </para>").append(EOL); Map<String, Object> map = new HashMap<String, Object>(); final LocalizableMessage name = defn.getUserFriendlyName(); map.put("dependencies", REF_DSCFG_SUBTYPE_DEPENDENCIES.get(name, name, placeholder)); map.put("typesIntro", REF_DSCFG_SUBTYPE_TYPES_INTRO.get(name)); List<Map<String, Object>> children = new LinkedList<Map<String, Object>>(); 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); sb.append(" See <xref linkend=\"") .append(getScriptName()).append("-") .append(a.getLongIdentifier()).append("-") .append(defn.getName()).append("-prop-").append(childDefn.getName()) .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); Map<String, Object> child = new HashMap<String, Object>(); child.put("name", childDefn.getName()); child.put("default", REF_DSCFG_CHILD_DEFAULT.get(placeholder, childDefn.getUserFriendlyName())); child.put("enabled", REF_DSCFG_CHILD_ENABLED_BY_DEFAULT.get(propertyExists(childDefn, "enabled"))); final String link = getLink(getScriptName() + "-" + a.getLongIdentifier() + "-" + defn.getName() + "-prop-" + childDefn.getName()); child.put("link", REF_DSCFG_CHILD_LINK.get(link, defn.getUserFriendlyName())); children.add(child); } sb.append(" </variablelist>").append(EOL); map.put("children", children); applyTemplate(sb, "dscfgListSubtypes.ftl", map); } private boolean propertyExists(AbstractManagedObjectDefinition<?, ?> defn, String name) { @@ -226,27 +196,26 @@ /** {@inheritDoc} */ @Override public void appendProperties(StringBuilder sb, SubCommand sc) { public String getProperties(SubCommand sc) { StringBuilder sb = new StringBuilder(); final AbstractManagedObjectDefinition<?, ?> defn = getManagedObjectDefinition(sc); if (defn == null) { return; return ""; } for (AbstractManagedObjectDefinition<?, ?> childDefn : getLeafChildren(defn)) { final List<PropertyDefinition<?>> props = new ArrayList<PropertyDefinition<?>>(childDefn.getAllPropertyDefinitions()); Collections.sort(props); Map<String, Object> map = new HashMap<String, Object>(); 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); map.put("id", propPrefix); map.put("title", childDefn.getUserFriendlyName()); map.put("intro", REF_DSCFG_PROPS_INTRO.get(defn.getUserFriendlyPluralName(), childDefn.getName())); map.put("list", toVariableList(props, defn, propPrefix)); applyTemplate(sb, "dscfgAppendProps.ftl", map); } return sb.toString(); } private AbstractManagedObjectDefinition<?, ?> getManagedObjectDefinition(SubCommand sc) { @@ -298,57 +267,57 @@ return null; } private void toVariableList(List<PropertyDefinition<?>> props, AbstractManagedObjectDefinition<?, ?> defn, String propPrefix, StringBuilder b) { final String indent = " "; b.append(" <variablelist>").append(EOL); private String toVariableList(List<PropertyDefinition<?>> props, AbstractManagedObjectDefinition<?, ?> defn, String propPrefix) { StringBuilder b = new StringBuilder(); Map<String, Object> map = new HashMap<String, Object>(); List<Map<String, Object>> properties = new LinkedList<Map<String, Object>>(); for (PropertyDefinition<?> prop : props) { b.append(" <varlistentry xml:id=\"") .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); appendVarlistentry(b, "Description", getDescriptionString(prop), indent); appendDefaultBehavior(b, indent, prop); appendAllowedValues(b, prop, indent); appendVarlistentry(b, "Multi-valued", getYN(prop, MULTI_VALUED), indent); appendVarlistentry(b, "Required", getYN(prop, MANDATORY), indent); appendVarlistentry(b, "Admin Action Required", getAdminActionRequired(prop, defn), indent); appendVarlistentry(b, "Advanced Property", getYNAdvanced(prop, ADVANCED), indent); appendVarlistentry(b, "Read-only", getYN(prop, READ_ONLY), indent); b.append(" </variablelist>").append(EOL); b.append(" </listitem>").append(EOL); b.append(" </varlistentry>").append(EOL); Map<String, Object> property = new HashMap<String, Object>(); property.put("id", propPrefix + "-" + prop.getName()); property.put("term", prop.getName()); property.put("descTitle", REF_TITLE_DESCRIPTION.get()); property.put("description", getDescriptionString(prop)); final StringBuilder sb = new StringBuilder(); appendDefaultBehavior(sb, prop); appendAllowedValues(sb, prop); appendVarListEntry(sb, REF_DSCFG_PROPS_LABEL_MULTI_VALUED.get().toString(), getYN(prop, MULTI_VALUED)); appendVarListEntry(sb, REF_DSCFG_PROPS_LABEL_REQUIRED.get().toString(), getYN(prop, MANDATORY)); appendVarListEntry(sb, REF_DSCFG_PROPS_LABEL_ADMIN_ACTION_REQUIRED.get().toString(), getAdminActionRequired(prop, defn)); appendVarListEntry(sb, REF_DSCFG_PROPS_LABEL_ADVANCED_PROPERTY.get().toString(), getYNAdvanced(prop, ADVANCED)); appendVarListEntry(sb, REF_DSCFG_PROPS_LABEL_READ_ONLY.get().toString(), getYN(prop, READ_ONLY)); property.put("list", sb.toString()); properties.add(property); } b.append(" </variablelist>").append(EOL); map.put("properties", properties); applyTemplate(b, "dscfgVariableList.ftl", map); return b.toString(); } private StringBuilder appendVarlistentry(StringBuilder b, String term, Object para, String indent) { b.append(indent).append("<varlistentry>").append(EOL); b.append(indent).append(" <term>").append(term).append("</term>").append(EOL); b.append(indent).append(" <listitem>").append(EOL); b.append(indent).append(" <para>").append(para).append("</para>").append(EOL); b.append(indent).append(" </listitem>").append(EOL); b.append(indent).append("</varlistentry>").append(EOL); private StringBuilder appendVarListEntry(StringBuilder b, String term, Object definition) { Map<String, Object> map = new HashMap<String, Object>(); map.put("term", term); map.put("definition", definition); applyTemplate(b, "dscfgVarListEntry.ftl", map); return b; } private void appendDefaultBehavior(StringBuilder b, final String indent, PropertyDefinition<?> prop) { b.append(indent).append("<varlistentry>").append(EOL); b.append(indent).append(" <term>").append("Default Value").append("</term>").append(EOL); b.append(indent).append(" <listitem>").append(EOL); appendDefaultBehaviorString(b, indent + " ", prop); b.append(indent).append(" </listitem>").append(EOL); b.append(indent).append("</varlistentry>").append(EOL); private void appendDefaultBehavior(StringBuilder b, PropertyDefinition<?> prop) { StringBuilder sb = new StringBuilder(); appendDefaultBehaviorString(sb, prop); appendVarListEntry(b, REF_DSCFG_PROPS_LABEL_DEFAULT_VALUE.get().toString(), sb.toString()); } 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); appendSyntax(b, prop, indent + " "); b.append(indent).append(" </listitem>").append(EOL); b.append(indent).append("</varlistentry>").append(EOL); private void appendAllowedValues(StringBuilder b, PropertyDefinition<?> prop) { StringBuilder sb = new StringBuilder(); appendSyntax(sb, prop); appendVarListEntry(b, REF_DSCFG_PROPS_LABEL_ALLOWED_VALUES.get().toString(), sb.toString()); } private Object getDescriptionString(PropertyDefinition<?> prop) { @@ -363,152 +332,146 @@ final Type actionType = adminAction.getType(); final StringBuilder action = new StringBuilder(); if (actionType == Type.COMPONENT_RESTART) { action.append("The ").append(defn.getUserFriendlyName()) .append(" must be disabled and re-enabled for changes to this setting to take effect"); action.append(op) .append(REF_DSCFG_ADMIN_ACTION_COMPONENT_RESTART.get(defn.getUserFriendlyName())) .append(cp); } else if (actionType == Type.SERVER_RESTART) { action.append("Restart the server"); action.append(op).append(REF_DSCFG_ADMIN_ACTION_SERVER_RESTART.get()).append(cp); } else if (actionType == Type.NONE) { action.append("None"); action.append(op).append(REF_DSCFG_ADMIN_ACTION_NONE.get()).append(cp); } if (synopsis != null) { if (action.length() > 0) { action.append(". "); } action.append(synopsis); action.append(op).append(synopsis).append(cp); } return action.toString(); } return "None"; return op + REF_DSCFG_ADMIN_ACTION_NONE.get() + cp; } private String getYN(PropertyDefinition<?> prop, PropertyOption option) { return prop.hasOption(option) ? "Yes" : "No"; LocalizableMessage msg = prop.hasOption(option) ? REF_DSCFG_PROP_YES.get() : REF_DSCFG_PROP_NO.get(); return op + msg + cp; } private String getYNAdvanced(PropertyDefinition<?> prop, PropertyOption option) { return prop.hasOption(option) ? "Yes (Use --advanced in interactive mode.)" : "No"; LocalizableMessage msg = prop.hasOption(option) ? REF_DSCFG_PROP_YES_ADVANCED.get() : REF_DSCFG_PROP_NO.get(); return op + msg + cp; } private void appendDefaultBehaviorString(StringBuilder b, String indent, PropertyDefinition<?> prop) { b.append(indent); private void appendDefaultBehaviorString(StringBuilder b, PropertyDefinition<?> prop) { final DefaultBehaviorProvider<?> defaultBehavior = prop.getDefaultBehaviorProvider(); if (defaultBehavior instanceof UndefinedDefaultBehaviorProvider) { b.append("<para>None</para>").append(EOL); return; b.append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR_NONE.get()).append(cp).append(EOL); } else if (defaultBehavior instanceof DefinedDefaultBehaviorProvider) { DefinedDefaultBehaviorProvider<?> behavior = (DefinedDefaultBehaviorProvider<?>) defaultBehavior; final Collection<String> defaultValues = behavior.getDefaultValues(); if (defaultValues.size() == 0) { b.append("<para>None</para>").append(EOL); b.append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR_NONE.get()).append(cp).append(EOL); } else if (defaultValues.size() == 1) { b.append("<para>").append(defaultValues.iterator().next()).append("</para>").append(EOL); b.append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR.get(defaultValues.iterator().next())) .append(cp).append(EOL); } else { final Iterator<String> it = defaultValues.iterator(); b.append("<para>").append(it.next()).append("</para>"); b.append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR.get(it.next())).append(cp); for (; it.hasNext();) { final String str = it.next(); b.append(EOL).append(indent).append("<para>").append(str).append("</para>"); b.append(EOL).append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR.get(it.next())).append(cp); } b.append(EOL); } return; } else if (defaultBehavior instanceof AliasDefaultBehaviorProvider) { AliasDefaultBehaviorProvider<?> behavior = (AliasDefaultBehaviorProvider<?>) defaultBehavior; b.append("<para>").append(behavior.getSynopsis()).append("</para>").append(EOL); return; b.append(op).append(REF_DSCFG_DEFAULT_BEHAVIOR.get(behavior.getSynopsis())).append(cp).append(EOL); } else if (defaultBehavior instanceof RelativeInheritedDefaultBehaviorProvider) { final RelativeInheritedDefaultBehaviorProvider<?> behavior = (RelativeInheritedDefaultBehaviorProvider<?>) defaultBehavior; appendDefaultBehaviorString(b, indent, appendDefaultBehaviorString(b, behavior.getManagedObjectDefinition().getPropertyDefinition(behavior.getPropertyName())); return; } else if (defaultBehavior instanceof AbsoluteInheritedDefaultBehaviorProvider) { final AbsoluteInheritedDefaultBehaviorProvider<?> behavior = (AbsoluteInheritedDefaultBehaviorProvider<?>) defaultBehavior; appendDefaultBehaviorString(b, indent, appendDefaultBehaviorString(b, behavior.getManagedObjectDefinition().getPropertyDefinition(behavior.getPropertyName())); return; } } private void appendSyntax(final StringBuilder b, PropertyDefinition<?> prop, final String indent) { private void appendSyntax(final StringBuilder b, PropertyDefinition<?> prop) { // Create a visitor for performing syntax specific processing. PropertyDefinitionVisitor<String, Void> visitor = new PropertyDefinitionVisitor<String, Void>() { @Override public String visitACI(ACIPropertyDefinition prop, Void p) { b.append(indent).append("<para>").append(ACI_SYNTAX_REL_URL).append("</para>").append(EOL); b.append(op).append(REF_DSCFG_ACI_SYNTAX_REL_URL.get()).append(cp).append(EOL); return null; } @Override public String visitAggregation(AggregationPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append(op); final RelationDefinition<?, ?> rel = prop.getRelationDefinition(); final String linkStr = getLink(rel.getName() + ".html"); b.append("The DN of any ").append(linkStr).append(". "); final String linkStr = getLink(rel.getName()); b.append(REF_DSCFG_AGGREGATION.get(linkStr)).append(". "); final LocalizableMessage synopsis = prop.getSourceConstraintSynopsis(); if (synopsis != null) { b.append(synopsis); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @Override public String visitAttributeType(AttributeTypePropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append("The name of an attribute type defined in the server schema."); b.append("</para>").append(EOL); b.append(op).append(REF_DSCFG_ANY_ATTRIBUTE.get()).append(".").append(cp).append(EOL); return null; } @Override public String visitBoolean(BooleanPropertyDefinition prop, Void p) { b.append(indent).append("<para>true</para>").append(EOL); b.append(indent).append("<para>false</para>").append(EOL); b.append(op).append("true").append(cp).append(EOL); b.append(op).append("false").append(cp).append(EOL); return null; } @Override public String visitClass(ClassPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append("A java class that implements or extends the class(es) :") .append(Utils.joinAsString(EOL, prop.getInstanceOfInterface())); b.append("</para>").append(EOL); b.append(op).append(REF_DSCFG_JAVA_PLUGIN.get()).append(" ") .append(Utils.joinAsString(EOL, prop.getInstanceOfInterface())).append(cp).append(EOL); return null; } @Override public String visitDN(DNPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append("A valid DN."); b.append(op).append(REF_DSCFG_VALID_DN.get()); final DN baseDN = prop.getBaseDN(); if (baseDN != null) { b.append(" ").append(baseDN); b.append(": ").append(baseDN); } else { b.append("."); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @Override public String visitDuration(DurationPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append(DURATION_SYNTAX_REL_URL).append(". "); b.append(REF_DSCFG_DURATION_SYNTAX_REL_URL.get()).append(EOL); b.append(op); if (prop.isAllowUnlimited()) { b.append(ALLOW_UNLIMITED).append(" "); b.append(REF_DSCFG_ALLOW_UNLIMITED.get()).append(" "); } if (prop.getMaximumUnit() != null) { b.append("Maximum unit is \"").append(prop.getMaximumUnit().getLongName()).append("\". "); final String maxUnitName = prop.getMaximumUnit().getLongName(); b.append(REF_DSCFG_DURATION_MAX_UNIT.get(maxUnitName)).append("."); } final DurationUnit baseUnit = prop.getBaseUnit(); b.append("Lower limit is ").append(valueOf(baseUnit, prop.getLowerLimit())) .append(" ").append(baseUnit.getLongName()).append(". "); final long lowerLimit = valueOf(baseUnit, prop.getLowerLimit()); final String unitName = baseUnit.getLongName(); b.append(REF_DSCFG_DURATION_LOWER_LIMIT.get(lowerLimit, unitName)).append("."); if (prop.getUpperLimit() != null) { b.append("Upper limit is ").append(valueOf(baseUnit, prop.getUpperLimit())) .append(" ").append(baseUnit.getLongName()).append(". "); final long upperLimit = valueOf(baseUnit, prop.getUpperLimit()); b.append(REF_DSCFG_DURATION_UPPER_LIMIT.get(upperLimit, unitName)).append("."); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @@ -518,79 +481,77 @@ @Override public String visitEnum(EnumPropertyDefinition prop, Void p) { b.append(indent).append("<para>").append(EOL); b.append(indent).append(" <variablelist>").append(EOL); b.append("<variablelist>").append(EOL); final Class<?> en = prop.getEnumClass(); final Object[] constants = en.getEnumConstants(); for (Object enumConstant : constants) { final LocalizableMessage valueSynopsis = prop.getValueSynopsis((Enum) enumConstant); appendVarlistentry(b, enumConstant.toString(), valueSynopsis, indent + " "); appendVarListEntry(b, enumConstant.toString(), valueSynopsis); } b.append(indent).append(" </variablelist>").append(EOL); b.append(indent).append("</para>").append(EOL); b.append("</variablelist>").append(EOL); return null; } @Override public String visitInteger(IntegerPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append("An integer value. Lower value is ").append(prop.getLowerLimit()).append("."); b.append(op).append(REF_DSCFG_INT.get()).append(". ") .append(REF_DSCFG_INT_LOWER_LIMIT.get(prop.getLowerLimit())).append("."); if (prop.getUpperLimit() != null) { b.append(" Upper value is ").append(prop.getUpperLimit()).append("."); b.append(" ").append(REF_DSCFG_INT_UPPER_LIMIT.get(prop.getUpperLimit())).append("."); } if (prop.isAllowUnlimited()) { b.append(" ").append(ALLOW_UNLIMITED); b.append(" ").append(REF_DSCFG_ALLOW_UNLIMITED.get()); } if (prop.getUnitSynopsis() != null) { b.append(" Unit is ").append(prop.getUnitSynopsis()).append("."); b.append(" ").append(REF_DSCFG_INT_UNIT.get(prop.getUnitSynopsis())).append("."); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @Override public String visitIPAddress(IPAddressPropertyDefinition prop, Void p) { b.append(indent).append("<para>An IP address</para>").append(EOL); b.append(op).append(REF_DSCFG_IP_ADDRESS.get()).append(cp).append(EOL); return null; } @Override public String visitIPAddressMask(IPAddressMaskPropertyDefinition prop, Void p) { b.append(indent).append("<para>An IP address mask</para>").append(EOL); b.append(op).append(REF_DSCFG_IP_ADDRESS_MASK.get()).append(cp).append(EOL); return null; } @Override public String visitSize(SizePropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append(op); if (prop.getLowerLimit() != 0) { b.append(" Lower value is ").append(prop.getLowerLimit()).append("."); b.append(REF_DSCFG_INT_LOWER_LIMIT.get(prop.getLowerLimit())).append("."); } if (prop.getUpperLimit() != null) { b.append(" Upper value is ").append(prop.getUpperLimit()).append(" ."); b.append(REF_DSCFG_INT_UPPER_LIMIT.get(prop.getUpperLimit())).append("."); } if (prop.isAllowUnlimited()) { b.append(" ").append(ALLOW_UNLIMITED); b.append(REF_DSCFG_ALLOW_UNLIMITED.get()); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @Override public String visitString(StringPropertyDefinition prop, Void p) { b.append(indent).append("<para>"); b.append(op); if (prop.getPatternSynopsis() != null) { b.append(prop.getPatternSynopsis()); } else { b.append("A String"); b.append(REF_DSCFG_STRING.get()); } b.append("</para>").append(EOL); b.append(cp).append(EOL); return null; } @Override public String visitUnknown(PropertyDefinition prop, Void p) { b.append(indent).append("<para>Unknown</para>").append(EOL); b.append(op).append(REF_DSCFG_UNKNOWN.get()).append(cp).append(EOL); return null; } }; @@ -600,7 +561,7 @@ } private String getLink(String target) { return " <xref linkend=" + target + " />"; return " <xref linkend=\"" + target + "\" />"; } } opendj-config/src/main/resources/com/forgerock/opendj/dsconfig/dsconfig.properties
@@ -20,7 +20,7 @@ # CDDL HEADER END # # Copyright 2006-2010 Sun Microsystems, Inc. # Portions Copyright 2011-2014 ForgeRock AS # Portions Copyright 2011-2015 ForgeRock AS. # # Format string definitions # @@ -436,3 +436,70 @@ INFO_DSCFG_BATCH_FILE_PATH_256=Path to a batch file containing \ a set of dsconfig commands to be executed # Strings for generated reference documentation. REF_DSCFG_ALLOW_UNLIMITED_1000=A value of "-1" or "unlimited" for no limit. REF_DSCFG_ACI_SYNTAX_REL_URL_1001=<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> REF_DSCFG_DURATION_SYNTAX_REL_URL_1002=<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> REF_DSCFG_ARG_ADDITIONAL_INFO_1003=%s properties depend on the %s type, \ which depends on the %s option. REF_DSCFG_SUBTYPE_DEPENDENCIES_1004=%s properties depend on the %s type, \ which depends on the %s you provide. REF_DSCFG_SUBTYPE_TYPES_INTRO_1005=By default, OpenDJ directory server \ supports the following %s types: REF_DSCFG_CHILD_DEFAULT_1006=Default %s: %s REF_DSCFG_CHILD_ENABLED_BY_DEFAULT_1007=Enabled by default: %b REF_DSCFG_CHILD_LINK_1008=See %s for the properties of this %s type. REF_DSCFG_PROPS_INTRO_1009=%s of type %s have the following properties: REF_DSCFG_PROPS_LABEL_DEFAULT_VALUE_1010=Default Value REF_DSCFG_PROPS_LABEL_ALLOWED_VALUES_1011=Allowed Values REF_DSCFG_PROPS_LABEL_MULTI_VALUED_1012=Multi-valued REF_DSCFG_PROPS_LABEL_REQUIRED_1013=Required REF_DSCFG_PROPS_LABEL_ADMIN_ACTION_REQUIRED_1014=Admin Action Required REF_DSCFG_PROPS_LABEL_ADVANCED_PROPERTY_1015=Advanced Property REF_DSCFG_PROPS_LABEL_READ_ONLY_1016=Read-only REF_DSCFG_ADMIN_ACTION_COMPONENT_RESTART_1017=The %s must be disabled \ and re-enabled for changes to this setting to take effect REF_DSCFG_ADMIN_ACTION_SERVER_RESTART_1018=Restart the server REF_DSCFG_ADMIN_ACTION_NONE_1019=None REF_DSCFG_PROP_YES_1020=Yes REF_DSCFG_PROP_YES_ADVANCED_1021=Yes (Use --advanced in interactive mode.) REF_DSCFG_PROP_NO_1022=No REF_DSCFG_DEFAULT_BEHAVIOR_NONE_1023=None REF_DSCFG_DEFAULT_BEHAVIOR_1024=%s REF_DSCFG_AGGREGATION_1025=The DN of any %s REF_DSCFG_ANY_ATTRIBUTE_1026=The name of an attribute type defined in the server schema REF_DSCFG_JAVA_PLUGIN_1027=A Java class that implements or extends the class(es): REF_DSCFG_VALID_DN_1028=A valid DN REF_DSCFG_DURATION_MAX_UNIT_1029=Maximum unit is "%s" REF_DSCFG_DURATION_LOWER_LIMIT_1030=Lower limit is %d %s REF_DSCFG_DURATION_UPPER_LIMIT_1031=Upper limit is %d %s REF_DSCFG_INT_1032=An integer value REF_DSCFG_INT_LOWER_LIMIT_1033=Lower value is %d REF_DSCFG_INT_UPPER_LIMIT_1034=Upper value is %d REF_DSCFG_INT_UNIT_1035=Unit is %s REF_DSCFG_IP_ADDRESS_1036=An IP address REF_DSCFG_IP_ADDRESS_MASK_1037=An IP address mask REF_DSCFG_STRING_1038=A String REF_DSCFG_UNKNOWN_1039=Unknown