From 263d085885df024dca9250cc03c807912b0a7662 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Tue, 24 Apr 2012 22:33:21 +0000
Subject: [PATCH] Reformat to comply with new Checkstyle rules.
---
opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ArgumentParser.java | 3289 +++++++++++++++++++++++++++--------------------------------
1 files changed, 1,488 insertions(+), 1,801 deletions(-)
diff --git a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ArgumentParser.java b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ArgumentParser.java
index 66a0283..c1207f6 100644
--- a/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ArgumentParser.java
+++ b/opendj3/opendj-ldap-toolkit/src/main/java/com/forgerock/opendj/ldap/tools/ArgumentParser.java
@@ -6,17 +6,16 @@
* (the "License"). You may not use this file except in compliance
* with the License.
*
- * You can obtain a copy of the license at
- * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * 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
- * trunk/opendj3/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:
+ * 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
@@ -27,10 +26,8 @@
*/
package com.forgerock.opendj.ldap.tools;
-
-
-import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.ToolConstants.*;
+import static com.forgerock.opendj.ldap.tools.ToolsMessages.*;
import static com.forgerock.opendj.ldap.tools.Utils.PROPERTY_SCRIPT_NAME;
import static com.forgerock.opendj.ldap.tools.Utils.wrapText;
import static com.forgerock.opendj.util.StaticUtils.EOL;
@@ -42,13 +39,19 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
-
-
/**
* This class defines a utility that can be used to deal with command-line
* arguments for applications in a CLIP-compliant manner using either short
@@ -59,1853 +62,1537 @@
* file to obtain default values for arguments there if they are not specified
* on the command-line.
*/
-final class ArgumentParser
-{
- /**
- * The argument that will be used to indicate the file properties.
- */
- private StringArgument filePropertiesPathArgument;
+final class ArgumentParser {
+ /**
+ * The argument that will be used to indicate the file properties.
+ */
+ private StringArgument filePropertiesPathArgument;
- /**
- * The argument that will be used to indicate that we'll not look for default
- * properties file.
- */
- private BooleanArgument noPropertiesFileArgument;
+ /**
+ * The argument that will be used to indicate that we'll not look for
+ * default properties file.
+ */
+ private BooleanArgument noPropertiesFileArgument;
- // The argument that will be used to trigger the display of usage
- // information.
- private Argument usageArgument;
+ // The argument that will be used to trigger the display of usage
+ // information.
+ private Argument usageArgument;
- // The argument that will be used to trigger the display of the OpenDJ
- // version.
- private Argument versionArgument;
+ // The argument that will be used to trigger the display of the OpenDJ
+ // version.
+ private Argument versionArgument;
- // The set of unnamed trailing arguments that were provided for this
- // parser.
- private final ArrayList<String> trailingArguments;
+ // The set of unnamed trailing arguments that were provided for this
+ // parser.
+ private final ArrayList<String> trailingArguments;
- // Indicates whether this parser will allow additional unnamed
- // arguments at the end of the list.
- private final boolean allowsTrailingArguments;
+ // Indicates whether this parser will allow additional unnamed
+ // arguments at the end of the list.
+ private final boolean allowsTrailingArguments;
- // Indicates whether long arguments should be treated in a
- // case-sensitive manner.
- private final boolean longArgumentsCaseSensitive;
+ // Indicates whether long arguments should be treated in a
+ // case-sensitive manner.
+ private final boolean longArgumentsCaseSensitive;
- // Indicates whether the usage or version information has been
- // displayed.
- private boolean usageOrVersionDisplayed;
+ // Indicates whether the usage or version information has been
+ // displayed.
+ private boolean usageOrVersionDisplayed;
- // Indicates whether the version argument was provided.
- private boolean versionPresent;
+ // Indicates whether the version argument was provided.
+ private boolean versionPresent;
- // The set of arguments defined for this parser, referenced by short
- // ID.
- private final HashMap<Character, Argument> shortIDMap;
+ // The set of arguments defined for this parser, referenced by short
+ // ID.
+ private final HashMap<Character, Argument> shortIDMap;
- // The set of arguments defined for this parser, referenced by
- // argument name.
- private final HashMap<String, Argument> argumentMap;
+ // The set of arguments defined for this parser, referenced by
+ // argument name.
+ private final HashMap<String, Argument> argumentMap;
- // The set of arguments defined for this parser, referenced by long
- // ID.
- private final HashMap<String, Argument> longIDMap;
+ // The set of arguments defined for this parser, referenced by long
+ // ID.
+ private final HashMap<String, Argument> longIDMap;
- // The maximum number of unnamed trailing arguments that may be
- // provided.
- private final int maxTrailingArguments;
+ // The maximum number of unnamed trailing arguments that may be
+ // provided.
+ private final int maxTrailingArguments;
- // The minimum number of unnamed trailing arguments that may be
- // provided.
- private final int minTrailingArguments;
+ // The minimum number of unnamed trailing arguments that may be
+ // provided.
+ private final int minTrailingArguments;
- // The total set of arguments defined for this parser.
- private final LinkedList<Argument> argumentList;
+ // The total set of arguments defined for this parser.
+ private final LinkedList<Argument> argumentList;
- // The output stream to which usage information should be printed.
- private OutputStream usageOutputStream;
+ // The output stream to which usage information should be printed.
+ private OutputStream usageOutputStream;
- // The fully-qualified name of the Java class that should be invoked
- // to launch the program with which this argument parser is associated.
- private final String mainClassName;
+ // The fully-qualified name of the Java class that should be invoked
+ // to launch the program with which this argument parser is associated.
+ private final String mainClassName;
- // A human-readable description for the tool, which will be included
- // when displaying usage information.
- private final LocalizableMessage toolDescription;
+ // A human-readable description for the tool, which will be included
+ // when displaying usage information.
+ private final LocalizableMessage toolDescription;
- // The display name that will be used for the trailing arguments in
- // the usage information.
- private final String trailingArgsDisplayName;
+ // The display name that will be used for the trailing arguments in
+ // the usage information.
+ private final String trailingArgsDisplayName;
- // The raw set of command-line arguments that were provided.
- private String[] rawArguments;
+ // The raw set of command-line arguments that were provided.
+ private String[] rawArguments;
- /** Set of argument groups. */
- private Set<ArgumentGroup> argumentGroups;
+ /** Set of argument groups. */
+ private Set<ArgumentGroup> argumentGroups;
- /**
- * Group for arguments that have not been explicitly grouped. These will
- * appear at the top of the usage statement without a header.
- */
- private final ArgumentGroup defaultArgGroup = new ArgumentGroup(
- LocalizableMessage.EMPTY, Integer.MAX_VALUE);
+ /**
+ * Group for arguments that have not been explicitly grouped. These will
+ * appear at the top of the usage statement without a header.
+ */
+ private final ArgumentGroup defaultArgGroup = new ArgumentGroup(LocalizableMessage.EMPTY,
+ Integer.MAX_VALUE);
- /**
- * Group for arguments that are related to connection through LDAP. This
- * includes options like the bind DN, the port, etc.
- */
- private final ArgumentGroup ldapArgGroup = new ArgumentGroup(
- INFO_DESCRIPTION_LDAP_CONNECTION_ARGS.get(), Integer.MIN_VALUE + 2);
+ /**
+ * Group for arguments that are related to connection through LDAP. This
+ * includes options like the bind DN, the port, etc.
+ */
+ private final ArgumentGroup ldapArgGroup = new ArgumentGroup(
+ INFO_DESCRIPTION_LDAP_CONNECTION_ARGS.get(), Integer.MIN_VALUE + 2);
- /**
- * Group for arguments that are related to utility input/output like
- * properties file, no-prompt etc. These will appear toward the bottom of the
- * usage statement.
- */
- private final ArgumentGroup ioArgGroup = new ArgumentGroup(
- INFO_DESCRIPTION_IO_ARGS.get(), Integer.MIN_VALUE + 1);
+ /**
+ * Group for arguments that are related to utility input/output like
+ * properties file, no-prompt etc. These will appear toward the bottom of
+ * the usage statement.
+ */
+ private final ArgumentGroup ioArgGroup = new ArgumentGroup(INFO_DESCRIPTION_IO_ARGS.get(),
+ Integer.MIN_VALUE + 1);
- /**
- * Group for arguments that are general like help, version etc. These will
- * appear at the end of the usage statement.
- */
- private final ArgumentGroup generalArgGroup = new ArgumentGroup(
- INFO_DESCRIPTION_GENERAL_ARGS.get(), Integer.MIN_VALUE);
+ /**
+ * Group for arguments that are general like help, version etc. These will
+ * appear at the end of the usage statement.
+ */
+ private final ArgumentGroup generalArgGroup = new ArgumentGroup(INFO_DESCRIPTION_GENERAL_ARGS
+ .get(), Integer.MIN_VALUE);
- private final static String INDENT = " ";
+ private final static String INDENT = " ";
- private final static int MAX_LENGTH = 80;
+ private final static int MAX_LENGTH = 80;
+ /**
+ * Creates a new instance of this argument parser with no arguments. Unnamed
+ * trailing arguments will not be allowed.
+ *
+ * @param mainClassName
+ * The fully-qualified name of the Java class that should be
+ * invoked to launch the program with which this argument parser
+ * is associated.
+ * @param toolDescription
+ * A human-readable description for the tool, which will be
+ * included when displaying usage information.
+ * @param longArgumentsCaseSensitive
+ * Indicates whether long arguments should be treated in a
+ * case-sensitive manner.
+ */
+ ArgumentParser(final String mainClassName, final LocalizableMessage toolDescription,
+ final boolean longArgumentsCaseSensitive) {
+ this.mainClassName = mainClassName;
+ this.toolDescription = toolDescription;
+ this.longArgumentsCaseSensitive = longArgumentsCaseSensitive;
-
- /**
- * Creates a new instance of this argument parser with no arguments. Unnamed
- * trailing arguments will not be allowed.
- *
- * @param mainClassName
- * The fully-qualified name of the Java class that should be invoked
- * to launch the program with which this argument parser is
- * associated.
- * @param toolDescription
- * A human-readable description for the tool, which will be included
- * when displaying usage information.
- * @param longArgumentsCaseSensitive
- * Indicates whether long arguments should be treated in a
- * case-sensitive manner.
- */
- ArgumentParser(final String mainClassName,
- final LocalizableMessage toolDescription,
- final boolean longArgumentsCaseSensitive)
- {
- this.mainClassName = mainClassName;
- this.toolDescription = toolDescription;
- this.longArgumentsCaseSensitive = longArgumentsCaseSensitive;
-
- argumentList = new LinkedList<Argument>();
- argumentMap = new HashMap<String, Argument>();
- shortIDMap = new HashMap<Character, Argument>();
- longIDMap = new HashMap<String, Argument>();
- allowsTrailingArguments = false;
- usageOrVersionDisplayed = false;
- versionPresent = false;
- trailingArgsDisplayName = null;
- maxTrailingArguments = 0;
- minTrailingArguments = 0;
- trailingArguments = new ArrayList<String>();
- rawArguments = null;
- usageArgument = null;
- filePropertiesPathArgument = null;
- noPropertiesFileArgument = null;
- usageOutputStream = System.out;
- initGroups();
- }
-
-
-
- /**
- * Creates a new instance of this argument parser with no arguments that may
- * or may not be allowed to have unnamed trailing arguments.
- *
- * @param mainClassName
- * The fully-qualified name of the Java class that should be invoked
- * to launch the program with which this argument parser is
- * associated.
- * @param toolDescription
- * A human-readable description for the tool, which will be included
- * when displaying usage information.
- * @param longArgumentsCaseSensitive
- * Indicates whether long arguments should be treated in a
- * case-sensitive manner.
- * @param allowsTrailingArguments
- * Indicates whether this parser allows unnamed trailing arguments to
- * be provided.
- * @param minTrailingArguments
- * The minimum number of unnamed trailing arguments that must be
- * provided. A value less than or equal to zero indicates that no
- * minimum will be enforced.
- * @param maxTrailingArguments
- * The maximum number of unnamed trailing arguments that may be
- * provided. A value less than or equal to zero indicates that no
- * maximum will be enforced.
- * @param trailingArgsDisplayName
- * The display name that should be used as a placeholder for unnamed
- * trailing arguments in the generated usage information.
- */
- ArgumentParser(final String mainClassName,
- final LocalizableMessage toolDescription,
- final boolean longArgumentsCaseSensitive,
- final boolean allowsTrailingArguments, final int minTrailingArguments,
- final int maxTrailingArguments, final String trailingArgsDisplayName)
- {
- this.mainClassName = mainClassName;
- this.toolDescription = toolDescription;
- this.longArgumentsCaseSensitive = longArgumentsCaseSensitive;
- this.allowsTrailingArguments = allowsTrailingArguments;
- this.minTrailingArguments = minTrailingArguments;
- this.maxTrailingArguments = maxTrailingArguments;
- this.trailingArgsDisplayName = trailingArgsDisplayName;
-
- argumentList = new LinkedList<Argument>();
- argumentMap = new HashMap<String, Argument>();
- shortIDMap = new HashMap<Character, Argument>();
- longIDMap = new HashMap<String, Argument>();
- trailingArguments = new ArrayList<String>();
- usageOrVersionDisplayed = false;
- versionPresent = false;
- rawArguments = null;
- usageArgument = null;
- usageOutputStream = System.out;
- initGroups();
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser.
- *
- * @param argument
- * The argument to be added.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addArgument(final Argument argument) throws ArgumentException
- {
- addArgument(argument, null);
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser.
- *
- * @param argument
- * The argument to be added.
- * @param group
- * The argument group to which the argument belongs.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addArgument(final Argument argument, ArgumentGroup group)
- throws ArgumentException
- {
-
- final Character shortID = argument.getShortIdentifier();
- if ((shortID != null) && shortIDMap.containsKey(shortID))
- {
- final String conflictingName = shortIDMap.get(shortID).getName();
-
- final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get(
- argument.getName(), String.valueOf(shortID), conflictingName);
- throw new ArgumentException(message);
+ argumentList = new LinkedList<Argument>();
+ argumentMap = new HashMap<String, Argument>();
+ shortIDMap = new HashMap<Character, Argument>();
+ longIDMap = new HashMap<String, Argument>();
+ allowsTrailingArguments = false;
+ usageOrVersionDisplayed = false;
+ versionPresent = false;
+ trailingArgsDisplayName = null;
+ maxTrailingArguments = 0;
+ minTrailingArguments = 0;
+ trailingArguments = new ArrayList<String>();
+ rawArguments = null;
+ usageArgument = null;
+ filePropertiesPathArgument = null;
+ noPropertiesFileArgument = null;
+ usageOutputStream = System.out;
+ initGroups();
}
- if (versionArgument != null)
- {
- if (shortID != null &&
- shortID.equals(versionArgument.getShortIdentifier()))
- {
- // Update the version argument to not display its short
- // identifier.
- try
- {
- versionArgument = new BooleanArgument(OPTION_LONG_PRODUCT_VERSION,
- null, OPTION_LONG_PRODUCT_VERSION,
- INFO_DESCRIPTION_PRODUCT_VERSION.get());
- this.generalArgGroup.addArgument(versionArgument);
- }
- catch (final ArgumentException e)
- {
- // ignore
- }
- }
+ /**
+ * Creates a new instance of this argument parser with no arguments that may
+ * or may not be allowed to have unnamed trailing arguments.
+ *
+ * @param mainClassName
+ * The fully-qualified name of the Java class that should be
+ * invoked to launch the program with which this argument parser
+ * is associated.
+ * @param toolDescription
+ * A human-readable description for the tool, which will be
+ * included when displaying usage information.
+ * @param longArgumentsCaseSensitive
+ * Indicates whether long arguments should be treated in a
+ * case-sensitive manner.
+ * @param allowsTrailingArguments
+ * Indicates whether this parser allows unnamed trailing
+ * arguments to be provided.
+ * @param minTrailingArguments
+ * The minimum number of unnamed trailing arguments that must be
+ * provided. A value less than or equal to zero indicates that no
+ * minimum will be enforced.
+ * @param maxTrailingArguments
+ * The maximum number of unnamed trailing arguments that may be
+ * provided. A value less than or equal to zero indicates that no
+ * maximum will be enforced.
+ * @param trailingArgsDisplayName
+ * The display name that should be used as a placeholder for
+ * unnamed trailing arguments in the generated usage information.
+ */
+ ArgumentParser(final String mainClassName, final LocalizableMessage toolDescription,
+ final boolean longArgumentsCaseSensitive, final boolean allowsTrailingArguments,
+ final int minTrailingArguments, final int maxTrailingArguments,
+ final String trailingArgsDisplayName) {
+ this.mainClassName = mainClassName;
+ this.toolDescription = toolDescription;
+ this.longArgumentsCaseSensitive = longArgumentsCaseSensitive;
+ this.allowsTrailingArguments = allowsTrailingArguments;
+ this.minTrailingArguments = minTrailingArguments;
+ this.maxTrailingArguments = maxTrailingArguments;
+ this.trailingArgsDisplayName = trailingArgsDisplayName;
+
+ argumentList = new LinkedList<Argument>();
+ argumentMap = new HashMap<String, Argument>();
+ shortIDMap = new HashMap<Character, Argument>();
+ longIDMap = new HashMap<String, Argument>();
+ trailingArguments = new ArrayList<String>();
+ usageOrVersionDisplayed = false;
+ versionPresent = false;
+ rawArguments = null;
+ usageArgument = null;
+ usageOutputStream = System.out;
+ initGroups();
}
- String longID = argument.getLongIdentifier();
- if (longID != null)
- {
- if (!longArgumentsCaseSensitive)
- {
- longID = toLowerCase(longID);
- }
- if (longIDMap.containsKey(longID))
- {
- final String conflictingName = longIDMap.get(longID).getName();
-
- final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get(
- argument.getName(), argument.getLongIdentifier(), conflictingName);
- throw new ArgumentException(message);
- }
+ /**
+ * Adds the provided argument to the set of arguments handled by this
+ * parser.
+ *
+ * @param argument
+ * The argument to be added.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addArgument(final Argument argument) throws ArgumentException {
+ addArgument(argument, null);
}
- if (shortID != null)
- {
- shortIDMap.put(shortID, argument);
- }
+ /**
+ * Adds the provided argument to the set of arguments handled by this
+ * parser.
+ *
+ * @param argument
+ * The argument to be added.
+ * @param group
+ * The argument group to which the argument belongs.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addArgument(final Argument argument, ArgumentGroup group) throws ArgumentException {
- if (longID != null)
- {
- longIDMap.put(longID, argument);
- }
+ final Character shortID = argument.getShortIdentifier();
+ if ((shortID != null) && shortIDMap.containsKey(shortID)) {
+ final String conflictingName = shortIDMap.get(shortID).getName();
- argumentList.add(argument);
-
- if (group == null)
- {
- group = getStandardGroup(argument);
- }
- group.addArgument(argument);
- argumentGroups.add(group);
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser
- * and puts the arguement in the default group.
- *
- * @param argument
- * The argument to be added.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addDefaultArgument(final Argument argument) throws ArgumentException
- {
- addArgument(argument, defaultArgGroup);
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser
- * and puts the arguement in the general group.
- *
- * @param argument
- * The argument to be added.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addGeneralArgument(final Argument argument) throws ArgumentException
- {
- addArgument(argument, generalArgGroup);
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser
- * and puts the argument in the input/output group.
- *
- * @param argument
- * The argument to be added.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addInputOutputArgument(final Argument argument) throws ArgumentException
- {
- addArgument(argument, ioArgGroup);
- }
-
-
-
- /**
- * Adds the provided argument to the set of arguments handled by this parser
- * and puts the argument in the LDAP connection group.
- *
- * @param argument
- * The argument to be added.
- * @throws ArgumentException
- * If the provided argument conflicts with another argument that has
- * already been defined.
- */
- void addLdapConnectionArgument(final Argument argument)
- throws ArgumentException
- {
- addArgument(argument, ldapArgGroup);
- }
-
-
-
- /**
- * Indicates whether this parser will allow unnamed trailing arguments. These
- * will be arguments at the end of the list that are not preceded by either a
- * long or short identifier and will need to be manually parsed by the
- * application using this parser. Note that once an unnamed trailing argument
- * has been identified, all remaining arguments will be classified as such.
- *
- * @return <CODE>true</CODE> if this parser allows unnamed trailing arguments,
- * or <CODE>false</CODE> if it does not.
- */
- boolean allowsTrailingArguments()
- {
- return allowsTrailingArguments;
- }
-
-
-
- /**
- * Check if we have a properties file.
- *
- * @return The properties found in the properties file or null.
- * @throws ArgumentException
- * If a problem was encountered while parsing the provided
- * arguments.
- */
- Properties checkExternalProperties() throws ArgumentException
- {
- // We don't look for properties file.
- if ((noPropertiesFileArgument != null)
- && (noPropertiesFileArgument.isPresent()))
- {
- return null;
- }
-
- // Check if we have a properties file argument
- if (filePropertiesPathArgument == null)
- {
- return null;
- }
-
- // check if the properties file argument has been set. If not
- // look for default location.
- String propertiesFilePath = null;
- if (filePropertiesPathArgument.isPresent())
- {
- propertiesFilePath = filePropertiesPathArgument.getValue();
- }
- else
- {
- // Check in "user home"/.opendj directory
- final String userDir = System.getProperty("user.home");
- propertiesFilePath = findPropertiesFile(userDir + File.separator
- + DEFAULT_OPENDJ_CONFIG_DIR);
- }
-
- // We don't have a properties file location
- if (propertiesFilePath == null)
- {
- return null;
- }
-
- // We have a location for the properties file.
- final Properties argumentProperties = new Properties();
- final String scriptName = System.getProperty(Utils.PROPERTY_SCRIPT_NAME);
- try
- {
- final Properties p = new Properties();
- final FileInputStream fis = new FileInputStream(propertiesFilePath);
- p.load(fis);
- fis.close();
-
- for (final Enumeration<?> e = p.propertyNames(); e.hasMoreElements();)
- {
- final String currentPropertyName = (String) e.nextElement();
- String propertyName = currentPropertyName;
-
- // Property name form <script name>.<property name> has the
- // precedence to <property name>
- if (scriptName != null)
- {
- if (currentPropertyName.startsWith(scriptName))
- {
- propertyName = currentPropertyName
- .substring(scriptName.length() + 1);
- }
- else
- {
- if (p.containsKey(scriptName + "." + currentPropertyName))
- {
- continue;
- }
- }
- }
- argumentProperties.setProperty(propertyName.toLowerCase(), p
- .getProperty(currentPropertyName));
- }
- }
- catch (final Exception e)
- {
- final LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE
- .get(String.valueOf(propertiesFilePath), getExceptionMessage(e));
- throw new ArgumentException(message, e);
- }
- return argumentProperties;
- }
-
-
-
- /**
- * Retrieves the argument with the specified name.
- *
- * @param name
- * The name of the argument to retrieve.
- * @return The argument with the specified name, or <CODE>null</CODE> if there
- * is no such argument.
- */
- Argument getArgument(final String name)
- {
- return argumentMap.get(name);
- }
-
-
-
- /**
- * Retrieves the argument with the specified long identifier.
- *
- * @param longID
- * The long identifier of the argument to retrieve.
- * @return The argument with the specified long identifier, or
- * <CODE>null</CODE> if there is no such argument.
- */
- Argument getArgumentForLongID(final String longID)
- {
- return longIDMap.get(longID);
- }
-
-
-
- /**
- * Retrieves the argument with the specified short identifier.
- *
- * @param shortID
- * The short ID for the argument to retrieve.
- * @return The argument with the specified short identifier, or
- * <CODE>null</CODE> if there is no such argument.
- */
- Argument getArgumentForShortID(final Character shortID)
- {
- return shortIDMap.get(shortID);
- }
-
-
-
- /**
- * Retrieves the list of all arguments that have been defined for this
- * argument parser.
- *
- * @return The list of all arguments that have been defined for this argument
- * parser.
- */
- LinkedList<Argument> getArgumentList()
- {
- return argumentList;
- }
-
-
-
- /**
- * Retrieves the set of arguments mapped by the long identifier that may be
- * used to reference them. Note that arguments that do not have a long
- * identifier will not be present in this list.
- *
- * @return The set of arguments mapped by the long identifier that may be used
- * to reference them.
- */
- HashMap<String, Argument> getArgumentsByLongID()
- {
- return longIDMap;
- }
-
-
-
- /**
- * Retrieves the set of arguments mapped by the short identifier that may be
- * used to reference them. Note that arguments that do not have a short
- * identifier will not be present in this list.
- *
- * @return The set of arguments mapped by the short identifier that may be
- * used to reference them.
- */
- HashMap<Character, Argument> getArgumentsByShortID()
- {
- return shortIDMap;
- }
-
-
-
- /**
- * Retrieves the fully-qualified name of the Java class that should be invoked
- * to launch the program with which this argument parser is associated.
- *
- * @return The fully-qualified name of the Java class that should be invoked
- * to launch the program with which this argument parser is
- * associated.
- */
- String getMainClassName()
- {
- return mainClassName;
- }
-
-
-
- /**
- * Retrieves the maximum number of unnamed trailing arguments that may be
- * provided.
- *
- * @return The maximum number of unnamed trailing arguments that may be
- * provided, or a value less than or equal to zero if no maximum will
- * be enforced.
- */
- int getMaxTrailingArguments()
- {
- return maxTrailingArguments;
- }
-
-
-
- /**
- * Retrieves the minimum number of unnamed trailing arguments that must be
- * provided.
- *
- * @return The minimum number of unnamed trailing arguments that must be
- * provided, or a value less than or equal to zero if no minimum will
- * be enforced.
- */
- int getMinTrailingArguments()
- {
- return minTrailingArguments;
- }
-
-
-
- /**
- * Retrieves the raw set of arguments that were provided.
- *
- * @return The raw set of arguments that were provided, or <CODE>null</CODE>
- * if the argument list has not yet been parsed.
- */
- String[] getRawArguments()
- {
- return rawArguments;
- }
-
-
-
- /**
- * Given an argument, returns an appropriate group. Arguments may be part of
- * one of the special groups or the default group.
- *
- * @param argument
- * for which a group is requested
- * @return argument group appropriate for <code>argument</code>
- */
- ArgumentGroup getStandardGroup(final Argument argument)
- {
- ArgumentGroup group;
- if (isInputOutputArgument(argument))
- {
- group = ioArgGroup;
- }
- else if (isGeneralArgument(argument))
- {
- group = generalArgGroup;
- }
- else if (isLdapConnectionArgument(argument))
- {
- group = ldapArgGroup;
- }
- else
- {
- group = defaultArgGroup;
- }
- return group;
- }
-
-
-
- /**
- * Retrieves a human-readable description for this tool, which should be
- * included at the top of the command-line usage information.
- *
- * @return A human-readable description for this tool, or {@code null} if none
- * is available.
- */
- LocalizableMessage getToolDescription()
- {
- return toolDescription;
- }
-
-
-
- /**
- * Retrieves the set of unnamed trailing arguments that were provided on the
- * command line.
- *
- * @return The set of unnamed trailing arguments that were provided on the
- * command line.
- */
- ArrayList<String> getTrailingArguments()
- {
- return trailingArguments;
- }
-
-
-
- /**
- * Retrieves a string containing usage information based on the defined
- * arguments.
- *
- * @return A string containing usage information based on the defined
- * arguments.
- */
- String getUsage()
- {
- final StringBuilder buffer = new StringBuilder();
- getUsage(buffer);
-
- return buffer.toString();
- }
-
-
-
- /**
- * Writes usage information based on the defined arguments to the provided
- * output stream.
- *
- * @param outputStream
- * The output stream to which the usage information should be
- * written.
- * @throws IOException
- * If a problem occurs while attempting to write the usage
- * information to the provided output stream.
- */
- void getUsage(final OutputStream outputStream) throws IOException
- {
- final StringBuilder buffer = new StringBuilder();
- getUsage(buffer);
-
- outputStream.write(getBytes(buffer.toString()));
- }
-
-
-
- /**
- * Appends usage information based on the defined arguments to the provided
- * buffer.
- *
- * @param buffer
- * The buffer to which the usage information should be appended.
- */
- void getUsage(final StringBuilder buffer)
- {
- usageOrVersionDisplayed = true;
- final String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME);
- if ((scriptName == null) || (scriptName.length() == 0))
- {
- buffer.append(INFO_ARGPARSER_USAGE_JAVA_CLASSNAME.get(mainClassName));
- }
- else
- {
- buffer.append(INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME.get(scriptName));
- }
-
- if (allowsTrailingArguments)
- {
- if (trailingArgsDisplayName == null)
- {
- buffer.append(" " + INFO_ARGPARSER_USAGE_TRAILINGARGS.get());
- }
- else
- {
- buffer.append(" ");
- buffer.append(trailingArgsDisplayName);
- }
- }
- buffer.append(EOL);
- buffer.append(EOL);
- if ((toolDescription != null) && (toolDescription.length() > 0))
- {
- buffer.append(wrapText(toolDescription.toString(), MAX_LENGTH - 1));
- buffer.append(EOL);
- buffer.append(EOL);
- }
- buffer.append(INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get());
- buffer.append(EOL);
- buffer.append(EOL);
-
- Argument helpArgument = null;
-
- final boolean printHeaders = printUsageGroupHeaders();
- for (final ArgumentGroup argGroup : argumentGroups)
- {
- if (argGroup.containsArguments() && printHeaders)
- {
- // Print the groups description if any
- final LocalizableMessage groupDesc = argGroup.getDescription();
- if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc))
- {
- buffer.append(EOL);
- buffer.append(wrapText(groupDesc.toString(), MAX_LENGTH - 1));
- buffer.append(EOL);
- buffer.append(EOL);
- }
- }
-
- final SortedSet<Argument> args = new TreeSet<Argument>(
- new Comparator<Argument>()
- {
-
- /**
- * {@inheritDoc}
- */
- public int compare(final Argument o1, final Argument o2)
- {
- final String s1;
- final String s2;
-
- if (o1.getShortIdentifier() != null)
- {
- s1 = o1.getShortIdentifier().toString();
- }
- else
- {
- s1 = o1.getLongIdentifier();
- }
-
- if (o2.getShortIdentifier() != null)
- {
- s2 = o2.getShortIdentifier().toString();
- }
- else
- {
- s2 = o2.getLongIdentifier();
- }
-
- final int res = s1.compareToIgnoreCase(s2);
- if (res != 0)
- {
- return res;
- }
- else
- {
- // Lowercase options first then uppercase.
- return -s1.compareTo(s2);
- }
- }
-
- });
- args.addAll(argGroup.getArguments());
-
- for (final Argument a : args)
- {
- // If this argument is hidden, then skip it.
- if (a.isHidden())
- {
- continue;
- }
-
- // Help argument should be printed at the end
- if ((usageArgument != null)
- && usageArgument.getName().equals(a.getName()))
- {
- helpArgument = a;
- continue;
- }
- printArgumentUsage(a, buffer);
- }
- }
- if (helpArgument != null)
- {
- printArgumentUsage(helpArgument, buffer);
- }
- else
- {
- buffer.append(EOL);
- buffer.append("-?");
- buffer.append(EOL);
- }
- }
-
-
-
- /**
- * Retrieves a message containing usage information based on the defined
- * arguments.
- *
- * @return A string containing usage information based on the defined
- * arguments.
- */
- LocalizableMessage getUsageMessage()
- {
- final StringBuilder buffer = new StringBuilder();
- getUsage(buffer);
-
- // TODO: rework getUsage(OutputStream) to work with messages
- // framework
- return LocalizableMessage.raw(buffer.toString());
- }
-
-
-
- /**
- * Returns whether the usage argument was provided or not. This method should
- * be called after a call to parseArguments.
- *
- * @return <CODE>true</CODE> if the usage argument was provided and
- * <CODE>false</CODE> otherwise.
- */
- boolean isUsageArgumentPresent()
- {
- boolean isUsageArgumentPresent = false;
- if (usageArgument != null)
- {
- isUsageArgumentPresent = usageArgument.isPresent();
- }
- return isUsageArgumentPresent;
- }
-
-
-
- /**
- * Returns whether the version argument was provided or not. This method
- * should be called after a call to parseArguments.
- *
- * @return <CODE>true</CODE> if the version argument was provided and
- * <CODE>false</CODE> otherwise.
- */
- boolean isVersionArgumentPresent()
- {
- return versionPresent;
- }
-
-
-
- /**
- * Parses the provided set of arguments and updates the information associated
- * with this parser accordingly.
- *
- * @param rawArguments
- * The raw set of arguments to parse.
- * @throws ArgumentException
- * If a problem was encountered while parsing the provided
- * arguments.
- */
- void parseArguments(final String[] rawArguments) throws ArgumentException
- {
- parseArguments(rawArguments, null);
- }
-
-
-
- /**
- * Parses the provided set of arguments and updates the information associated
- * with this parser accordingly. Default values for unspecified arguments may
- * be read from the specified properties if any are provided.
- *
- * @param rawArguments
- * The set of raw arguments to parse.
- * @param argumentProperties
- * A set of properties that may be used to provide default values for
- * arguments not included in the given raw arguments.
- * @throws ArgumentException
- * If a problem was encountered while parsing the provided
- * arguments.
- */
- void parseArguments(final String[] rawArguments, Properties argumentProperties)
- throws ArgumentException
- {
- this.rawArguments = rawArguments;
-
- boolean inTrailingArgs = false;
-
- final int numArguments = rawArguments.length;
- for (int i = 0; i < numArguments; i++)
- {
- final String arg = rawArguments[i];
-
- if (inTrailingArgs)
- {
- trailingArguments.add(arg);
- if ((maxTrailingArguments > 0)
- && (trailingArguments.size() > maxTrailingArguments))
- {
- final LocalizableMessage message = ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS
- .get(maxTrailingArguments);
- throw new ArgumentException(message);
- }
-
- continue;
- }
-
- if (arg.equals("--"))
- {
- // This is a special indicator that we have reached the end of
- // the named arguments and that everything that follows after this
- // should be considered trailing arguments.
- inTrailingArgs = true;
- }
- else if (arg.startsWith("--"))
- {
- // This indicates that we are using the long name to reference
- // the argument. It may be in any of the following forms:
- // --name
- // --name value
- // --name=value
-
- String argName = arg.substring(2);
- String argValue = null;
- final int equalPos = argName.indexOf('=');
- if (equalPos < 0)
- {
- // This is fine. The value is not part of the argument name
- // token.
- }
- else if (equalPos == 0)
- {
- // The argument starts with "--=", which is not acceptable.
- final LocalizableMessage message = ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME
- .get(arg);
- throw new ArgumentException(message);
- }
- else
- {
- // The argument is in the form --name=value, so parse them
- // both out.
- argValue = argName.substring(equalPos + 1);
- argName = argName.substring(0, equalPos);
- }
-
- // If we're not case-sensitive, then convert the name to
- // lowercase.
- final String origArgName = argName;
- if (!longArgumentsCaseSensitive)
- {
- argName = toLowerCase(argName);
- }
-
- // Get the argument with the specified name.
- final Argument a = longIDMap.get(argName);
- if (a == null)
- {
- if (argName.equals(OPTION_LONG_HELP))
- {
- // "--help" will always be interpreted as requesting usage
- // information.
- try
- {
- getUsage(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
- }
- else if (argName.equals(OPTION_LONG_PRODUCT_VERSION))
- {
- // "--version" will always be interpreted as requesting
- // version information.
- usageOrVersionDisplayed = true;
- versionPresent = true;
- try
- {
- // TODO
- // DirectoryServer.printVersion(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
- }
- else
- {
- // There is no such argument registered.
- final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID
- .get(origArgName);
+ final LocalizableMessage message =
+ ERR_ARGPARSER_DUPLICATE_SHORT_ID.get(argument.getName(), String
+ .valueOf(shortID), conflictingName);
throw new ArgumentException(message);
- }
- }
- else
- {
- a.setPresent(true);
-
- // If this is the usage argument, then immediately stop and
- // print usage information.
- if ((usageArgument != null)
- && usageArgument.getName().equals(a.getName()))
- {
- try
- {
- getUsage(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
- }
}
- // See if the argument takes a value. If so, then make sure one
- // was provided. If not, then make sure none was provided.
- if (a.needsValue())
- {
- if (argValue == null)
- {
- if ((i + 1) == numArguments)
- {
- final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID
- .get(origArgName);
- throw new ArgumentException(message);
- }
-
- argValue = rawArguments[++i];
- }
-
- final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
- if (!a.valueIsAcceptable(argValue, invalidReason))
- {
- final LocalizableMessage message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID
- .get(argValue, origArgName, invalidReason.toString());
- throw new ArgumentException(message);
- }
-
- // If the argument already has a value, then make sure it is
- // acceptable to have more than one.
- if (a.hasValue() && (!a.isMultiValued()))
- {
- final LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID
- .get(origArgName);
- throw new ArgumentException(message);
- }
-
- a.addValue(argValue);
- }
- else
- {
- if (argValue != null)
- {
- final LocalizableMessage message = ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE
- .get(origArgName);
- throw new ArgumentException(message);
- }
- }
- }
- else if (arg.startsWith("-"))
- {
- // This indicates that we are using the 1-character name to
- // reference the argument. It may be in any of the following forms:
- // -n
- // -nvalue
- // -n value
- if (arg.equals("-"))
- {
- final LocalizableMessage message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT
- .get();
- throw new ArgumentException(message);
- }
-
- final char argCharacter = arg.charAt(1);
- String argValue;
- if (arg.length() > 2)
- {
- argValue = arg.substring(2);
- }
- else
- {
- argValue = null;
- }
-
- // Get the argument with the specified short ID.
- final Argument a = shortIDMap.get(argCharacter);
- if (a == null)
- {
- if (argCharacter == '?')
- {
- // "-?" will always be interpreted as requesting usage
- // information.
- try
- {
- getUsage(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
- }
- else if ((argCharacter == OPTION_SHORT_PRODUCT_VERSION)
- && (!shortIDMap.containsKey(OPTION_SHORT_PRODUCT_VERSION)))
- {
- // "-V" will always be interpreted as requesting
- // version information except if it's already defined (e.g
- // in ldap tools).
- usageOrVersionDisplayed = true;
- versionPresent = true;
- try
- {
- // TODO
- // DirectoryServer.printVersion(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
- return;
- }
- else
- {
- // There is no such argument registered.
- final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID
- .get(String.valueOf(argCharacter));
- throw new ArgumentException(message);
- }
- }
- else
- {
- a.setPresent(true);
-
- // If this is the usage argument, then immediately stop and
- // print usage information.
- if ((usageArgument != null)
- && usageArgument.getName().equals(a.getName()))
- {
- try
- {
- getUsage(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
- }
- }
-
- // See if the argument takes a value. If so, then make sure one
- // was provided. If not, then make sure none was provided.
- if (a.needsValue())
- {
- if (argValue == null)
- {
- if ((i + 1) == numArguments)
- {
- final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID
- .get(String.valueOf(argCharacter));
- throw new ArgumentException(message);
- }
-
- argValue = rawArguments[++i];
- }
-
- final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
- if (!a.valueIsAcceptable(argValue, invalidReason))
- {
- final LocalizableMessage message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID
- .get(argValue, String.valueOf(argCharacter), invalidReason
- .toString());
- throw new ArgumentException(message);
- }
-
- // If the argument already has a value, then make sure it is
- // acceptable to have more than one.
- if (a.hasValue() && (!a.isMultiValued()))
- {
- final LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID
- .get(String.valueOf(argCharacter));
- throw new ArgumentException(message);
- }
-
- a.addValue(argValue);
- }
- else
- {
- if (argValue != null)
- {
- // If we've gotten here, then it means that we're in a scenario like
- // "-abc" where "a" is a valid argument that doesn't take a
- // value. However, this could still be valid if all remaining
- // characters in the value are also valid argument characters that
- // don't take values.
- final int valueLength = argValue.length();
- for (int j = 0; j < valueLength; j++)
- {
- final char c = argValue.charAt(j);
- final Argument b = shortIDMap.get(c);
- if (b == null)
- {
- // There is no such argument registered.
- final LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID
- .get(String.valueOf(argCharacter));
- throw new ArgumentException(message);
- }
- else if (b.needsValue())
- {
- // This means we're in a scenario like "-abc" where b is
- // a valid argument that takes a value. We don't support
- // that.
- final LocalizableMessage message = ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES
- .get(String.valueOf(argCharacter), argValue, String
- .valueOf(c));
- throw new ArgumentException(message);
- }
- else
- {
- b.setPresent(true);
-
- // If this is the usage argument, then immediately stop
- // and print usage information.
- if ((usageArgument != null)
- && usageArgument.getName().equals(b.getName()))
- {
- try
- {
- getUsage(usageOutputStream);
- }
- catch (final Exception e)
- {
- }
-
- return;
+ if (versionArgument != null) {
+ if (shortID != null && shortID.equals(versionArgument.getShortIdentifier())) {
+ // Update the version argument to not display its short
+ // identifier.
+ try {
+ versionArgument =
+ new BooleanArgument(OPTION_LONG_PRODUCT_VERSION, null,
+ OPTION_LONG_PRODUCT_VERSION, INFO_DESCRIPTION_PRODUCT_VERSION
+ .get());
+ this.generalArgGroup.addArgument(versionArgument);
+ } catch (final ArgumentException e) {
+ // ignore
}
- }
}
- }
}
- }
- else if (allowsTrailingArguments)
- {
- // It doesn't start with a dash, so it must be a trailing
- // argument if that is acceptable.
- inTrailingArgs = true;
- trailingArguments.add(arg);
- }
- else
- {
- // It doesn't start with a dash and we don't allow trailing
- // arguments, so this is illegal.
- final LocalizableMessage message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT
- .get(arg);
- throw new ArgumentException(message);
- }
- }
- // If we allow trailing arguments and there is a minimum number,
- // then make sure at least that many were provided.
- if (allowsTrailingArguments && (minTrailingArguments > 0))
- {
- if (trailingArguments.size() < minTrailingArguments)
- {
- final LocalizableMessage message = ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS
- .get(minTrailingArguments);
- throw new ArgumentException(message);
- }
- }
-
- // If we don't have the argumentProperties, try to load a properties
- // file.
- if (argumentProperties == null)
- {
- argumentProperties = checkExternalProperties();
- }
-
- // Iterate through all of the arguments. For any that were not
- // provided on the command line, see if there is an alternate default that
- // can be used. For cases where there is not, see that argument is required.
- for (final Argument a : argumentList)
- {
- if (!a.isPresent())
- {
- // See if there is a value in the properties that can be used
- if ((argumentProperties != null) && (a.getPropertyName() != null))
- {
- final String value = argumentProperties.getProperty(a
- .getPropertyName().toLowerCase());
- final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
- if (value != null)
- {
- Boolean addValue = true;
- if (!(a instanceof BooleanArgument))
- {
- addValue = a.valueIsAcceptable(value, invalidReason);
+ String longID = argument.getLongIdentifier();
+ if (longID != null) {
+ if (!longArgumentsCaseSensitive) {
+ longID = toLowerCase(longID);
}
- if (addValue)
- {
- a.addValue(value);
- if (a.needsValue())
- {
- a.setPresent(true);
- }
- a.setValueSetByProperty(true);
+ if (longIDMap.containsKey(longID)) {
+ final String conflictingName = longIDMap.get(longID).getName();
+
+ final LocalizableMessage message =
+ ERR_ARGPARSER_DUPLICATE_LONG_ID.get(argument.getName(), argument
+ .getLongIdentifier(), conflictingName);
+ throw new ArgumentException(message);
}
- }
- }
- }
-
- if ((!a.isPresent()) && a.needsValue())
- {
- // See if the argument defines a default.
- if (a.getDefaultValue() != null)
- {
- a.addValue(a.getDefaultValue());
}
- // If there is still no value and the argument is required, then
- // that's a problem.
- if ((!a.hasValue()) && a.isRequired())
- {
- final LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG
- .get(a.getName());
- throw new ArgumentException(message);
- }
- }
- }
- }
-
-
-
- /**
- * Parses the provided set of arguments and updates the information associated
- * with this parser accordingly. Default values for unspecified arguments may
- * be read from the specified properties file.
- *
- * @param rawArguments
- * The set of raw arguments to parse.
- * @param propertiesFile
- * The path to the properties file to use to obtain default values
- * for unspecified properties.
- * @param requirePropertiesFile
- * Indicates whether the parsing should fail if the provided
- * properties file does not exist or is not accessible.
- * @throws ArgumentException
- * If a problem was encountered while parsing the provided arguments
- * or interacting with the properties file.
- */
- void parseArguments(final String[] rawArguments, final String propertiesFile,
- final boolean requirePropertiesFile) throws ArgumentException
- {
- this.rawArguments = rawArguments;
-
- Properties argumentProperties = null;
-
- try
- {
- final Properties p = new Properties();
- final FileInputStream fis = new FileInputStream(propertiesFile);
- p.load(fis);
- fis.close();
- argumentProperties = p;
- }
- catch (final Exception e)
- {
- if (requirePropertiesFile)
- {
- final LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE
- .get(String.valueOf(propertiesFile), getExceptionMessage(e));
- throw new ArgumentException(message, e);
- }
- }
-
- parseArguments(rawArguments, argumentProperties);
- }
-
-
-
- /**
- * Indicates whether or not argument group description headers should be
- * printed.
- *
- * @return boolean where true means print the descriptions
- */
- boolean printUsageGroupHeaders()
- {
- // If there is only a single group then we won't print them.
- int groupsContainingArgs = 0;
- for (final ArgumentGroup argGroup : argumentGroups)
- {
- if (argGroup.containsNonHiddenArguments())
- {
- groupsContainingArgs++;
- }
- }
- return groupsContainingArgs > 1;
- }
-
-
-
- /**
- * Sets the usage group description for the default argument group.
- *
- * @param description
- * for the default group
- */
- void setDefaultArgumentGroupDescription(final LocalizableMessage description)
- {
- this.defaultArgGroup.setDescription(description);
- }
-
-
-
- /**
- * Sets the provided argument which will be used to identify the file
- * properties.
- *
- * @param argument
- * The argument which will be used to identify the file properties.
- */
- void setFilePropertiesArgument(final StringArgument argument)
- {
- filePropertiesPathArgument = argument;
- }
-
-
-
- /**
- * Sets the usage group description for the general argument group.
- *
- * @param description
- * for the general group
- */
- void setGeneralArgumentGroupDescription(final LocalizableMessage description)
- {
- this.generalArgGroup.setDescription(description);
- }
-
-
-
- /**
- * Sets the usage group description for the input/output argument group.
- *
- * @param description
- * for the input/output group
- */
- void setInputOutputArgumentGroupDescription(
- final LocalizableMessage description)
- {
- this.ioArgGroup.setDescription(description);
- }
-
-
-
- /**
- * Sets the usage group description for the LDAP argument group.
- *
- * @param description
- * for the LDAP group
- */
- void setLdapArgumentGroupDescription(final LocalizableMessage description)
- {
- this.ldapArgGroup.setDescription(description);
- }
-
-
-
- /**
- * Sets the provided argument which will be used to identify the file
- * properties.
- *
- * @param argument
- * The argument which will be used to indicate if we have to look for
- * properties file.
- */
- void setNoPropertiesFileArgument(final BooleanArgument argument)
- {
- noPropertiesFileArgument = argument;
- }
-
-
-
- /**
- * Sets the provided argument as one which will automatically trigger the
- * output of usage information if it is provided on the command line and no
- * further argument validation will be performed. Note that the caller will
- * still need to add this argument to the parser with the
- * <CODE>addArgument</CODE> method, and the argument should not be required
- * and should not take a value. Also, the caller will still need to check for
- * the presence of the usage argument after calling
- * <CODE>parseArguments</CODE> to know that no further processing will be
- * required.
- *
- * @param argument
- * The argument whose presence should automatically trigger the
- * display of usage information.
- */
- void setUsageArgument(final Argument argument)
- {
- usageArgument = argument;
- usageOutputStream = System.out;
- }
-
-
-
- /**
- * Sets the provided argument as one which will automatically trigger the
- * output of usage information if it is provided on the command line and no
- * further argument validation will be performed. Note that the caller will
- * still need to add this argument to the parser with the
- * <CODE>addArgument</CODE> method, and the argument should not be required
- * and should not take a value. Also, the caller will still need to check for
- * the presence of the usage argument after calling
- * <CODE>parseArguments</CODE> to know that no further processing will be
- * required.
- *
- * @param argument
- * The argument whose presence should automatically trigger the
- * display of usage information.
- * @param outputStream
- * The output stream to which the usage information should be
- * written.
- */
- void setUsageArgument(final Argument argument, final OutputStream outputStream)
- {
- usageArgument = argument;
- usageOutputStream = outputStream;
- }
-
-
-
- /**
- * Indicates whether the version or the usage information has been displayed
- * to the end user either by an explicit argument like "-H" or "--help", or by
- * a built-in argument like "-?".
- *
- * @return {@code true} if the usage information has been displayed, or
- * {@code false} if not.
- */
- boolean usageOrVersionDisplayed()
- {
- return usageOrVersionDisplayed;
- }
-
-
-
- /**
- * Get the absolute path of the properties file.
- *
- * @param directory
- * The location in which we should look for properties file
- * @return The absolute path of the properties file or null
- */
- private String findPropertiesFile(final String directory)
- {
- // Look for the tools properties file
- final File f = new File(directory, DEFAULT_OPENDJ_PROPERTIES_FILE_NAME
- + DEFAULT_OPENDJ_PROPERTIES_FILE_EXTENSION);
- if (f.exists() && f.canRead())
- {
- return f.getAbsolutePath();
- }
- else
- {
- return null;
- }
- }
-
-
-
- private void initGroups()
- {
- this.argumentGroups = new TreeSet<ArgumentGroup>();
- this.argumentGroups.add(defaultArgGroup);
- this.argumentGroups.add(ldapArgGroup);
- this.argumentGroups.add(generalArgGroup);
- this.argumentGroups.add(ioArgGroup);
-
- try
- {
- versionArgument = new BooleanArgument(OPTION_LONG_PRODUCT_VERSION,
- OPTION_SHORT_PRODUCT_VERSION, OPTION_LONG_PRODUCT_VERSION,
- INFO_DESCRIPTION_PRODUCT_VERSION.get());
- this.generalArgGroup.addArgument(versionArgument);
- }
- catch (final ArgumentException e)
- {
- // ignore
- }
- }
-
-
-
- private boolean isGeneralArgument(final Argument arg)
- {
- boolean general = false;
- if (arg != null)
- {
- final String longId = arg.getLongIdentifier();
- general = OPTION_LONG_HELP.equals(longId)
- || OPTION_LONG_PRODUCT_VERSION.equals(longId);
- }
- return general;
- }
-
-
-
- private boolean isInputOutputArgument(final Argument arg)
- {
- boolean io = false;
- if (arg != null)
- {
- final String longId = arg.getLongIdentifier();
- io = OPTION_LONG_VERBOSE.equals(longId)
- || OPTION_LONG_QUIET.equals(longId)
- || OPTION_LONG_NO_PROMPT.equals(longId)
- || OPTION_LONG_PROP_FILE_PATH.equals(longId)
- || OPTION_LONG_NO_PROP_FILE.equals(longId)
- || OPTION_LONG_SCRIPT_FRIENDLY.equals(longId)
- || OPTION_LONG_DONT_WRAP.equals(longId)
- || OPTION_LONG_ENCODING.equals(longId)
- || OPTION_LONG_BATCH_FILE_PATH.equals(longId);
- }
- return io;
- }
-
-
-
- private boolean isLdapConnectionArgument(final Argument arg)
- {
- boolean ldap = false;
- if (arg != null)
- {
- final String longId = arg.getLongIdentifier();
- ldap = OPTION_LONG_USE_SSL.equals(longId)
- || OPTION_LONG_START_TLS.equals(longId)
- || OPTION_LONG_HOST.equals(longId) || OPTION_LONG_PORT.equals(longId)
- || OPTION_LONG_BINDDN.equals(longId)
- || OPTION_LONG_BINDPWD.equals(longId)
- || OPTION_LONG_BINDPWD_FILE.equals(longId)
- || OPTION_LONG_SASLOPTION.equals(longId)
- || OPTION_LONG_TRUSTALL.equals(longId)
- || OPTION_LONG_TRUSTSTOREPATH.equals(longId)
- || OPTION_LONG_TRUSTSTORE_PWD.equals(longId)
- || OPTION_LONG_TRUSTSTORE_PWD_FILE.equals(longId)
- || OPTION_LONG_KEYSTOREPATH.equals(longId)
- || OPTION_LONG_KEYSTORE_PWD.equals(longId)
- || OPTION_LONG_KEYSTORE_PWD_FILE.equals(longId)
- || OPTION_LONG_CERT_NICKNAME.equals(longId)
- || OPTION_LONG_REFERENCED_HOST_NAME.equals(longId)
- || OPTION_LONG_ADMIN_UID.equals(longId)
- || OPTION_LONG_REPORT_AUTHZ_ID.equals(longId)
- || OPTION_LONG_USE_PW_POLICY_CTL.equals(longId)
- || OPTION_LONG_USE_SASL_EXTERNAL.equals(longId)
- || OPTION_LONG_PROTOCOL_VERSION.equals(longId);
- }
- return ldap;
- }
-
-
-
- /**
- * Appends argument usage information to the provided buffer.
- *
- * @param a
- * The argument to handle.
- * @param buffer
- * The buffer to which the usage information should be appended.
- */
- private void printArgumentUsage(final Argument a, final StringBuilder buffer)
- {
- // Write a line with the short and/or long identifiers that may be
- // used
- // for the argument.
- final int indentLength = INDENT.length();
- final Character shortID = a.getShortIdentifier();
- final String longID = a.getLongIdentifier();
- if (shortID != null)
- {
- final int currentLength = buffer.length();
-
- if (usageArgument.getName().equals(a.getName()))
- {
- buffer.append("-?, ");
- }
-
- buffer.append("-");
- buffer.append(shortID.charValue());
-
- if (a.needsValue() && longID == null)
- {
- buffer.append(" ");
- buffer.append(a.getValuePlaceholder());
- }
-
- if (longID != null)
- {
- final StringBuilder newBuffer = new StringBuilder();
- newBuffer.append(", --");
- newBuffer.append(longID);
-
- if (a.needsValue())
- {
- newBuffer.append(" ");
- newBuffer.append(a.getValuePlaceholder());
+ if (shortID != null) {
+ shortIDMap.put(shortID, argument);
}
- final int lineLength = (buffer.length() - currentLength)
- + newBuffer.length();
- if (lineLength > MAX_LENGTH)
- {
- buffer.append(EOL);
- buffer.append(newBuffer.toString());
+ if (longID != null) {
+ longIDMap.put(longID, argument);
}
- else
- {
- buffer.append(newBuffer.toString());
- }
- }
- buffer.append(EOL);
+ argumentList.add(argument);
+
+ if (group == null) {
+ group = getStandardGroup(argument);
+ }
+ group.addArgument(argument);
+ argumentGroups.add(group);
}
- else
- {
- if (longID != null)
- {
- if (usageArgument.getName().equals(a.getName()))
- {
- buffer.append("-?, ");
- }
- buffer.append("--");
- buffer.append(longID);
- if (a.needsValue())
- {
- buffer.append(" ");
- buffer.append(a.getValuePlaceholder());
+ /**
+ * Adds the provided argument to the set of arguments handled by this parser
+ * and puts the arguement in the default group.
+ *
+ * @param argument
+ * The argument to be added.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addDefaultArgument(final Argument argument) throws ArgumentException {
+ addArgument(argument, defaultArgGroup);
+ }
+
+ /**
+ * Adds the provided argument to the set of arguments handled by this parser
+ * and puts the arguement in the general group.
+ *
+ * @param argument
+ * The argument to be added.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addGeneralArgument(final Argument argument) throws ArgumentException {
+ addArgument(argument, generalArgGroup);
+ }
+
+ /**
+ * Adds the provided argument to the set of arguments handled by this parser
+ * and puts the argument in the input/output group.
+ *
+ * @param argument
+ * The argument to be added.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addInputOutputArgument(final Argument argument) throws ArgumentException {
+ addArgument(argument, ioArgGroup);
+ }
+
+ /**
+ * Adds the provided argument to the set of arguments handled by this parser
+ * and puts the argument in the LDAP connection group.
+ *
+ * @param argument
+ * The argument to be added.
+ * @throws ArgumentException
+ * If the provided argument conflicts with another argument that
+ * has already been defined.
+ */
+ void addLdapConnectionArgument(final Argument argument) throws ArgumentException {
+ addArgument(argument, ldapArgGroup);
+ }
+
+ /**
+ * Indicates whether this parser will allow unnamed trailing arguments.
+ * These will be arguments at the end of the list that are not preceded by
+ * either a long or short identifier and will need to be manually parsed by
+ * the application using this parser. Note that once an unnamed trailing
+ * argument has been identified, all remaining arguments will be classified
+ * as such.
+ *
+ * @return <CODE>true</CODE> if this parser allows unnamed trailing
+ * arguments, or <CODE>false</CODE> if it does not.
+ */
+ boolean allowsTrailingArguments() {
+ return allowsTrailingArguments;
+ }
+
+ /**
+ * Check if we have a properties file.
+ *
+ * @return The properties found in the properties file or null.
+ * @throws ArgumentException
+ * If a problem was encountered while parsing the provided
+ * arguments.
+ */
+ Properties checkExternalProperties() throws ArgumentException {
+ // We don't look for properties file.
+ if ((noPropertiesFileArgument != null) && (noPropertiesFileArgument.isPresent())) {
+ return null;
}
+ // Check if we have a properties file argument
+ if (filePropertiesPathArgument == null) {
+ return null;
+ }
+
+ // check if the properties file argument has been set. If not
+ // look for default location.
+ String propertiesFilePath = null;
+ if (filePropertiesPathArgument.isPresent()) {
+ propertiesFilePath = filePropertiesPathArgument.getValue();
+ } else {
+ // Check in "user home"/.opendj directory
+ final String userDir = System.getProperty("user.home");
+ propertiesFilePath =
+ findPropertiesFile(userDir + File.separator + DEFAULT_OPENDJ_CONFIG_DIR);
+ }
+
+ // We don't have a properties file location
+ if (propertiesFilePath == null) {
+ return null;
+ }
+
+ // We have a location for the properties file.
+ final Properties argumentProperties = new Properties();
+ final String scriptName = System.getProperty(Utils.PROPERTY_SCRIPT_NAME);
+ try {
+ final Properties p = new Properties();
+ final FileInputStream fis = new FileInputStream(propertiesFilePath);
+ p.load(fis);
+ fis.close();
+
+ for (final Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) {
+ final String currentPropertyName = (String) e.nextElement();
+ String propertyName = currentPropertyName;
+
+ // Property name form <script name>.<property name> has the
+ // precedence to <property name>
+ if (scriptName != null) {
+ if (currentPropertyName.startsWith(scriptName)) {
+ propertyName = currentPropertyName.substring(scriptName.length() + 1);
+ } else {
+ if (p.containsKey(scriptName + "." + currentPropertyName)) {
+ continue;
+ }
+ }
+ }
+ argumentProperties.setProperty(propertyName.toLowerCase(), p
+ .getProperty(currentPropertyName));
+ }
+ } catch (final Exception e) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(String
+ .valueOf(propertiesFilePath), getExceptionMessage(e));
+ throw new ArgumentException(message, e);
+ }
+ return argumentProperties;
+ }
+
+ /**
+ * Retrieves the argument with the specified name.
+ *
+ * @param name
+ * The name of the argument to retrieve.
+ * @return The argument with the specified name, or <CODE>null</CODE> if
+ * there is no such argument.
+ */
+ Argument getArgument(final String name) {
+ return argumentMap.get(name);
+ }
+
+ /**
+ * Retrieves the argument with the specified long identifier.
+ *
+ * @param longID
+ * The long identifier of the argument to retrieve.
+ * @return The argument with the specified long identifier, or
+ * <CODE>null</CODE> if there is no such argument.
+ */
+ Argument getArgumentForLongID(final String longID) {
+ return longIDMap.get(longID);
+ }
+
+ /**
+ * Retrieves the argument with the specified short identifier.
+ *
+ * @param shortID
+ * The short ID for the argument to retrieve.
+ * @return The argument with the specified short identifier, or
+ * <CODE>null</CODE> if there is no such argument.
+ */
+ Argument getArgumentForShortID(final Character shortID) {
+ return shortIDMap.get(shortID);
+ }
+
+ /**
+ * Retrieves the list of all arguments that have been defined for this
+ * argument parser.
+ *
+ * @return The list of all arguments that have been defined for this
+ * argument parser.
+ */
+ LinkedList<Argument> getArgumentList() {
+ return argumentList;
+ }
+
+ /**
+ * Retrieves the set of arguments mapped by the long identifier that may be
+ * used to reference them. Note that arguments that do not have a long
+ * identifier will not be present in this list.
+ *
+ * @return The set of arguments mapped by the long identifier that may be
+ * used to reference them.
+ */
+ HashMap<String, Argument> getArgumentsByLongID() {
+ return longIDMap;
+ }
+
+ /**
+ * Retrieves the set of arguments mapped by the short identifier that may be
+ * used to reference them. Note that arguments that do not have a short
+ * identifier will not be present in this list.
+ *
+ * @return The set of arguments mapped by the short identifier that may be
+ * used to reference them.
+ */
+ HashMap<Character, Argument> getArgumentsByShortID() {
+ return shortIDMap;
+ }
+
+ /**
+ * Retrieves the fully-qualified name of the Java class that should be
+ * invoked to launch the program with which this argument parser is
+ * associated.
+ *
+ * @return The fully-qualified name of the Java class that should be invoked
+ * to launch the program with which this argument parser is
+ * associated.
+ */
+ String getMainClassName() {
+ return mainClassName;
+ }
+
+ /**
+ * Retrieves the maximum number of unnamed trailing arguments that may be
+ * provided.
+ *
+ * @return The maximum number of unnamed trailing arguments that may be
+ * provided, or a value less than or equal to zero if no maximum
+ * will be enforced.
+ */
+ int getMaxTrailingArguments() {
+ return maxTrailingArguments;
+ }
+
+ /**
+ * Retrieves the minimum number of unnamed trailing arguments that must be
+ * provided.
+ *
+ * @return The minimum number of unnamed trailing arguments that must be
+ * provided, or a value less than or equal to zero if no minimum
+ * will be enforced.
+ */
+ int getMinTrailingArguments() {
+ return minTrailingArguments;
+ }
+
+ /**
+ * Retrieves the raw set of arguments that were provided.
+ *
+ * @return The raw set of arguments that were provided, or <CODE>null</CODE>
+ * if the argument list has not yet been parsed.
+ */
+ String[] getRawArguments() {
+ return rawArguments;
+ }
+
+ /**
+ * Given an argument, returns an appropriate group. Arguments may be part of
+ * one of the special groups or the default group.
+ *
+ * @param argument
+ * for which a group is requested
+ * @return argument group appropriate for <code>argument</code>
+ */
+ ArgumentGroup getStandardGroup(final Argument argument) {
+ ArgumentGroup group;
+ if (isInputOutputArgument(argument)) {
+ group = ioArgGroup;
+ } else if (isGeneralArgument(argument)) {
+ group = generalArgGroup;
+ } else if (isLdapConnectionArgument(argument)) {
+ group = ldapArgGroup;
+ } else {
+ group = defaultArgGroup;
+ }
+ return group;
+ }
+
+ /**
+ * Retrieves a human-readable description for this tool, which should be
+ * included at the top of the command-line usage information.
+ *
+ * @return A human-readable description for this tool, or {@code null} if
+ * none is available.
+ */
+ LocalizableMessage getToolDescription() {
+ return toolDescription;
+ }
+
+ /**
+ * Retrieves the set of unnamed trailing arguments that were provided on the
+ * command line.
+ *
+ * @return The set of unnamed trailing arguments that were provided on the
+ * command line.
+ */
+ ArrayList<String> getTrailingArguments() {
+ return trailingArguments;
+ }
+
+ /**
+ * Retrieves a string containing usage information based on the defined
+ * arguments.
+ *
+ * @return A string containing usage information based on the defined
+ * arguments.
+ */
+ String getUsage() {
+ final StringBuilder buffer = new StringBuilder();
+ getUsage(buffer);
+
+ return buffer.toString();
+ }
+
+ /**
+ * Writes usage information based on the defined arguments to the provided
+ * output stream.
+ *
+ * @param outputStream
+ * The output stream to which the usage information should be
+ * written.
+ * @throws IOException
+ * If a problem occurs while attempting to write the usage
+ * information to the provided output stream.
+ */
+ void getUsage(final OutputStream outputStream) throws IOException {
+ final StringBuilder buffer = new StringBuilder();
+ getUsage(buffer);
+
+ outputStream.write(getBytes(buffer.toString()));
+ }
+
+ /**
+ * Appends usage information based on the defined arguments to the provided
+ * buffer.
+ *
+ * @param buffer
+ * The buffer to which the usage information should be appended.
+ */
+ void getUsage(final StringBuilder buffer) {
+ usageOrVersionDisplayed = true;
+ final String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME);
+ if ((scriptName == null) || (scriptName.length() == 0)) {
+ buffer.append(INFO_ARGPARSER_USAGE_JAVA_CLASSNAME.get(mainClassName));
+ } else {
+ buffer.append(INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME.get(scriptName));
+ }
+
+ if (allowsTrailingArguments) {
+ if (trailingArgsDisplayName == null) {
+ buffer.append(" " + INFO_ARGPARSER_USAGE_TRAILINGARGS.get());
+ } else {
+ buffer.append(" ");
+ buffer.append(trailingArgsDisplayName);
+ }
+ }
buffer.append(EOL);
- }
+ buffer.append(EOL);
+ if ((toolDescription != null) && (toolDescription.length() > 0)) {
+ buffer.append(wrapText(toolDescription.toString(), MAX_LENGTH - 1));
+ buffer.append(EOL);
+ buffer.append(EOL);
+ }
+ buffer.append(INFO_SUBCMDPARSER_WHERE_OPTIONS_INCLUDE.get());
+ buffer.append(EOL);
+ buffer.append(EOL);
+
+ Argument helpArgument = null;
+
+ final boolean printHeaders = printUsageGroupHeaders();
+ for (final ArgumentGroup argGroup : argumentGroups) {
+ if (argGroup.containsArguments() && printHeaders) {
+ // Print the groups description if any
+ final LocalizableMessage groupDesc = argGroup.getDescription();
+ if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc)) {
+ buffer.append(EOL);
+ buffer.append(wrapText(groupDesc.toString(), MAX_LENGTH - 1));
+ buffer.append(EOL);
+ buffer.append(EOL);
+ }
+ }
+
+ final SortedSet<Argument> args = new TreeSet<Argument>(new Comparator<Argument>() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compare(final Argument o1, final Argument o2) {
+ final String s1;
+ final String s2;
+
+ if (o1.getShortIdentifier() != null) {
+ s1 = o1.getShortIdentifier().toString();
+ } else {
+ s1 = o1.getLongIdentifier();
+ }
+
+ if (o2.getShortIdentifier() != null) {
+ s2 = o2.getShortIdentifier().toString();
+ } else {
+ s2 = o2.getLongIdentifier();
+ }
+
+ final int res = s1.compareToIgnoreCase(s2);
+ if (res != 0) {
+ return res;
+ } else {
+ // Lowercase options first then uppercase.
+ return -s1.compareTo(s2);
+ }
+ }
+
+ });
+ args.addAll(argGroup.getArguments());
+
+ for (final Argument a : args) {
+ // If this argument is hidden, then skip it.
+ if (a.isHidden()) {
+ continue;
+ }
+
+ // Help argument should be printed at the end
+ if ((usageArgument != null) && usageArgument.getName().equals(a.getName())) {
+ helpArgument = a;
+ continue;
+ }
+ printArgumentUsage(a, buffer);
+ }
+ }
+ if (helpArgument != null) {
+ printArgumentUsage(helpArgument, buffer);
+ } else {
+ buffer.append(EOL);
+ buffer.append("-?");
+ buffer.append(EOL);
+ }
}
- // Write one or more lines with the description of the argument.
- // We will
- // indent the description five characters and try our best to wrap
- // at or
- // before column 79 so it will be friendly to 80-column displays.
- buffer.append(
- Utils.wrapText(a.getDescription(), MAX_LENGTH, indentLength));
- buffer.append(EOL);
+ /**
+ * Retrieves a message containing usage information based on the defined
+ * arguments.
+ *
+ * @return A string containing usage information based on the defined
+ * arguments.
+ */
+ LocalizableMessage getUsageMessage() {
+ final StringBuilder buffer = new StringBuilder();
+ getUsage(buffer);
- if (a.needsValue() && (a.getDefaultValue() != null)
- && (a.getDefaultValue().length() > 0))
- {
- buffer.append(INDENT);
- buffer.append(INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue())
- .toString());
- buffer.append(EOL);
+ // TODO: rework getUsage(OutputStream) to work with messages
+ // framework
+ return LocalizableMessage.raw(buffer.toString());
}
- }
+
+ /**
+ * Returns whether the usage argument was provided or not. This method
+ * should be called after a call to parseArguments.
+ *
+ * @return <CODE>true</CODE> if the usage argument was provided and
+ * <CODE>false</CODE> otherwise.
+ */
+ boolean isUsageArgumentPresent() {
+ boolean isUsageArgumentPresent = false;
+ if (usageArgument != null) {
+ isUsageArgumentPresent = usageArgument.isPresent();
+ }
+ return isUsageArgumentPresent;
+ }
+
+ /**
+ * Returns whether the version argument was provided or not. This method
+ * should be called after a call to parseArguments.
+ *
+ * @return <CODE>true</CODE> if the version argument was provided and
+ * <CODE>false</CODE> otherwise.
+ */
+ boolean isVersionArgumentPresent() {
+ return versionPresent;
+ }
+
+ /**
+ * Parses the provided set of arguments and updates the information
+ * associated with this parser accordingly.
+ *
+ * @param rawArguments
+ * The raw set of arguments to parse.
+ * @throws ArgumentException
+ * If a problem was encountered while parsing the provided
+ * arguments.
+ */
+ void parseArguments(final String[] rawArguments) throws ArgumentException {
+ parseArguments(rawArguments, null);
+ }
+
+ /**
+ * Parses the provided set of arguments and updates the information
+ * associated with this parser accordingly. Default values for unspecified
+ * arguments may be read from the specified properties if any are provided.
+ *
+ * @param rawArguments
+ * The set of raw arguments to parse.
+ * @param argumentProperties
+ * A set of properties that may be used to provide default values
+ * for arguments not included in the given raw arguments.
+ * @throws ArgumentException
+ * If a problem was encountered while parsing the provided
+ * arguments.
+ */
+ void parseArguments(final String[] rawArguments, Properties argumentProperties)
+ throws ArgumentException {
+ this.rawArguments = rawArguments;
+
+ boolean inTrailingArgs = false;
+
+ final int numArguments = rawArguments.length;
+ for (int i = 0; i < numArguments; i++) {
+ final String arg = rawArguments[i];
+
+ if (inTrailingArgs) {
+ trailingArguments.add(arg);
+ if ((maxTrailingArguments > 0) && (trailingArguments.size() > maxTrailingArguments)) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS.get(maxTrailingArguments);
+ throw new ArgumentException(message);
+ }
+
+ continue;
+ }
+
+ if (arg.equals("--")) {
+ // This is a special indicator that we have reached the end of
+ // the named arguments and that everything that follows after
+ // this
+ // should be considered trailing arguments.
+ inTrailingArgs = true;
+ } else if (arg.startsWith("--")) {
+ // This indicates that we are using the long name to reference
+ // the argument. It may be in any of the following forms:
+ // --name
+ // --name value
+ // --name=value
+
+ String argName = arg.substring(2);
+ String argValue = null;
+ final int equalPos = argName.indexOf('=');
+ if (equalPos < 0) {
+ // This is fine. The value is not part of the argument name
+ // token.
+ } else if (equalPos == 0) {
+ // The argument starts with "--=", which is not acceptable.
+ final LocalizableMessage message = ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME.get(arg);
+ throw new ArgumentException(message);
+ } else {
+ // The argument is in the form --name=value, so parse them
+ // both out.
+ argValue = argName.substring(equalPos + 1);
+ argName = argName.substring(0, equalPos);
+ }
+
+ // If we're not case-sensitive, then convert the name to
+ // lowercase.
+ final String origArgName = argName;
+ if (!longArgumentsCaseSensitive) {
+ argName = toLowerCase(argName);
+ }
+
+ // Get the argument with the specified name.
+ final Argument a = longIDMap.get(argName);
+ if (a == null) {
+ if (argName.equals(OPTION_LONG_HELP)) {
+ // "--help" will always be interpreted as requesting
+ // usage
+ // information.
+ try {
+ getUsage(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ } else if (argName.equals(OPTION_LONG_PRODUCT_VERSION)) {
+ // "--version" will always be interpreted as requesting
+ // version information.
+ usageOrVersionDisplayed = true;
+ versionPresent = true;
+ try {
+ // TODO
+ // DirectoryServer.printVersion(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ } else {
+ // There is no such argument registered.
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID.get(origArgName);
+ throw new ArgumentException(message);
+ }
+ } else {
+ a.setPresent(true);
+
+ // If this is the usage argument, then immediately stop and
+ // print usage information.
+ if ((usageArgument != null) && usageArgument.getName().equals(a.getName())) {
+ try {
+ getUsage(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ }
+ }
+
+ // See if the argument takes a value. If so, then make sure one
+ // was provided. If not, then make sure none was provided.
+ if (a.needsValue()) {
+ if (argValue == null) {
+ if ((i + 1) == numArguments) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID
+ .get(origArgName);
+ throw new ArgumentException(message);
+ }
+
+ argValue = rawArguments[++i];
+ }
+
+ final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
+ if (!a.valueIsAcceptable(argValue, invalidReason)) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID.get(argValue,
+ origArgName, invalidReason.toString());
+ throw new ArgumentException(message);
+ }
+
+ // If the argument already has a value, then make sure it is
+ // acceptable to have more than one.
+ if (a.hasValue() && (!a.isMultiValued())) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID.get(origArgName);
+ throw new ArgumentException(message);
+ }
+
+ a.addValue(argValue);
+ } else {
+ if (argValue != null) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE.get(origArgName);
+ throw new ArgumentException(message);
+ }
+ }
+ } else if (arg.startsWith("-")) {
+ // This indicates that we are using the 1-character name to
+ // reference the argument. It may be in any of the following
+ // forms:
+ // -n
+ // -nvalue
+ // -n value
+ if (arg.equals("-")) {
+ final LocalizableMessage message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT.get();
+ throw new ArgumentException(message);
+ }
+
+ final char argCharacter = arg.charAt(1);
+ String argValue;
+ if (arg.length() > 2) {
+ argValue = arg.substring(2);
+ } else {
+ argValue = null;
+ }
+
+ // Get the argument with the specified short ID.
+ final Argument a = shortIDMap.get(argCharacter);
+ if (a == null) {
+ if (argCharacter == '?') {
+ // "-?" will always be interpreted as requesting usage
+ // information.
+ try {
+ getUsage(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ } else if ((argCharacter == OPTION_SHORT_PRODUCT_VERSION)
+ && (!shortIDMap.containsKey(OPTION_SHORT_PRODUCT_VERSION))) {
+ // "-V" will always be interpreted as requesting
+ // version information except if it's already defined
+ // (e.g
+ // in ldap tools).
+ usageOrVersionDisplayed = true;
+ versionPresent = true;
+ try {
+ // TODO
+ // DirectoryServer.printVersion(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+ return;
+ } else {
+ // There is no such argument registered.
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get(String
+ .valueOf(argCharacter));
+ throw new ArgumentException(message);
+ }
+ } else {
+ a.setPresent(true);
+
+ // If this is the usage argument, then immediately stop and
+ // print usage information.
+ if ((usageArgument != null) && usageArgument.getName().equals(a.getName())) {
+ try {
+ getUsage(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ }
+ }
+
+ // See if the argument takes a value. If so, then make sure one
+ // was provided. If not, then make sure none was provided.
+ if (a.needsValue()) {
+ if (argValue == null) {
+ if ((i + 1) == numArguments) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID.get(String
+ .valueOf(argCharacter));
+ throw new ArgumentException(message);
+ }
+
+ argValue = rawArguments[++i];
+ }
+
+ final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
+ if (!a.valueIsAcceptable(argValue, invalidReason)) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID.get(argValue, String
+ .valueOf(argCharacter), invalidReason.toString());
+ throw new ArgumentException(message);
+ }
+
+ // If the argument already has a value, then make sure it is
+ // acceptable to have more than one.
+ if (a.hasValue() && (!a.isMultiValued())) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get(String
+ .valueOf(argCharacter));
+ throw new ArgumentException(message);
+ }
+
+ a.addValue(argValue);
+ } else {
+ if (argValue != null) {
+ // If we've gotten here, then it means that we're in a
+ // scenario like
+ // "-abc" where "a" is a valid argument that doesn't
+ // take a
+ // value. However, this could still be valid if all
+ // remaining
+ // characters in the value are also valid argument
+ // characters that
+ // don't take values.
+ final int valueLength = argValue.length();
+ for (int j = 0; j < valueLength; j++) {
+ final char c = argValue.charAt(j);
+ final Argument b = shortIDMap.get(c);
+ if (b == null) {
+ // There is no such argument registered.
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get(String
+ .valueOf(argCharacter));
+ throw new ArgumentException(message);
+ } else if (b.needsValue()) {
+ // This means we're in a scenario like "-abc"
+ // where b is
+ // a valid argument that takes a value. We don't
+ // support
+ // that.
+ final LocalizableMessage message =
+ ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES
+ .get(String.valueOf(argCharacter), argValue, String
+ .valueOf(c));
+ throw new ArgumentException(message);
+ } else {
+ b.setPresent(true);
+
+ // If this is the usage argument, then
+ // immediately stop
+ // and print usage information.
+ if ((usageArgument != null)
+ && usageArgument.getName().equals(b.getName())) {
+ try {
+ getUsage(usageOutputStream);
+ } catch (final Exception e) {
+ // Ignored.
+ }
+
+ return;
+ }
+ }
+ }
+ }
+ }
+ } else if (allowsTrailingArguments) {
+ // It doesn't start with a dash, so it must be a trailing
+ // argument if that is acceptable.
+ inTrailingArgs = true;
+ trailingArguments.add(arg);
+ } else {
+ // It doesn't start with a dash and we don't allow trailing
+ // arguments, so this is illegal.
+ final LocalizableMessage message =
+ ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg);
+ throw new ArgumentException(message);
+ }
+ }
+
+ // If we allow trailing arguments and there is a minimum number,
+ // then make sure at least that many were provided.
+ if (allowsTrailingArguments && (minTrailingArguments > 0)) {
+ if (trailingArguments.size() < minTrailingArguments) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(minTrailingArguments);
+ throw new ArgumentException(message);
+ }
+ }
+
+ // If we don't have the argumentProperties, try to load a properties
+ // file.
+ if (argumentProperties == null) {
+ argumentProperties = checkExternalProperties();
+ }
+
+ // Iterate through all of the arguments. For any that were not
+ // provided on the command line, see if there is an alternate default
+ // that
+ // can be used. For cases where there is not, see that argument is
+ // required.
+ for (final Argument a : argumentList) {
+ if (!a.isPresent()) {
+ // See if there is a value in the properties that can be used
+ if ((argumentProperties != null) && (a.getPropertyName() != null)) {
+ final String value =
+ argumentProperties.getProperty(a.getPropertyName().toLowerCase());
+ final LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder();
+ if (value != null) {
+ Boolean addValue = true;
+ if (!(a instanceof BooleanArgument)) {
+ addValue = a.valueIsAcceptable(value, invalidReason);
+ }
+ if (addValue) {
+ a.addValue(value);
+ if (a.needsValue()) {
+ a.setPresent(true);
+ }
+ a.setValueSetByProperty(true);
+ }
+ }
+ }
+ }
+
+ if ((!a.isPresent()) && a.needsValue()) {
+ // See if the argument defines a default.
+ if (a.getDefaultValue() != null) {
+ a.addValue(a.getDefaultValue());
+ }
+
+ // If there is still no value and the argument is required, then
+ // that's a problem.
+ if ((!a.hasValue()) && a.isRequired()) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG.get(a.getName());
+ throw new ArgumentException(message);
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses the provided set of arguments and updates the information
+ * associated with this parser accordingly. Default values for unspecified
+ * arguments may be read from the specified properties file.
+ *
+ * @param rawArguments
+ * The set of raw arguments to parse.
+ * @param propertiesFile
+ * The path to the properties file to use to obtain default
+ * values for unspecified properties.
+ * @param requirePropertiesFile
+ * Indicates whether the parsing should fail if the provided
+ * properties file does not exist or is not accessible.
+ * @throws ArgumentException
+ * If a problem was encountered while parsing the provided
+ * arguments or interacting with the properties file.
+ */
+ void parseArguments(final String[] rawArguments, final String propertiesFile,
+ final boolean requirePropertiesFile) throws ArgumentException {
+ this.rawArguments = rawArguments;
+
+ Properties argumentProperties = null;
+
+ try {
+ final Properties p = new Properties();
+ final FileInputStream fis = new FileInputStream(propertiesFile);
+ p.load(fis);
+ fis.close();
+ argumentProperties = p;
+ } catch (final Exception e) {
+ if (requirePropertiesFile) {
+ final LocalizableMessage message =
+ ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(String
+ .valueOf(propertiesFile), getExceptionMessage(e));
+ throw new ArgumentException(message, e);
+ }
+ }
+
+ parseArguments(rawArguments, argumentProperties);
+ }
+
+ /**
+ * Indicates whether or not argument group description headers should be
+ * printed.
+ *
+ * @return boolean where true means print the descriptions
+ */
+ boolean printUsageGroupHeaders() {
+ // If there is only a single group then we won't print them.
+ int groupsContainingArgs = 0;
+ for (final ArgumentGroup argGroup : argumentGroups) {
+ if (argGroup.containsNonHiddenArguments()) {
+ groupsContainingArgs++;
+ }
+ }
+ return groupsContainingArgs > 1;
+ }
+
+ /**
+ * Sets the usage group description for the default argument group.
+ *
+ * @param description
+ * for the default group
+ */
+ void setDefaultArgumentGroupDescription(final LocalizableMessage description) {
+ this.defaultArgGroup.setDescription(description);
+ }
+
+ /**
+ * Sets the provided argument which will be used to identify the file
+ * properties.
+ *
+ * @param argument
+ * The argument which will be used to identify the file
+ * properties.
+ */
+ void setFilePropertiesArgument(final StringArgument argument) {
+ filePropertiesPathArgument = argument;
+ }
+
+ /**
+ * Sets the usage group description for the general argument group.
+ *
+ * @param description
+ * for the general group
+ */
+ void setGeneralArgumentGroupDescription(final LocalizableMessage description) {
+ this.generalArgGroup.setDescription(description);
+ }
+
+ /**
+ * Sets the usage group description for the input/output argument group.
+ *
+ * @param description
+ * for the input/output group
+ */
+ void setInputOutputArgumentGroupDescription(final LocalizableMessage description) {
+ this.ioArgGroup.setDescription(description);
+ }
+
+ /**
+ * Sets the usage group description for the LDAP argument group.
+ *
+ * @param description
+ * for the LDAP group
+ */
+ void setLdapArgumentGroupDescription(final LocalizableMessage description) {
+ this.ldapArgGroup.setDescription(description);
+ }
+
+ /**
+ * Sets the provided argument which will be used to identify the file
+ * properties.
+ *
+ * @param argument
+ * The argument which will be used to indicate if we have to look
+ * for properties file.
+ */
+ void setNoPropertiesFileArgument(final BooleanArgument argument) {
+ noPropertiesFileArgument = argument;
+ }
+
+ /**
+ * Sets the provided argument as one which will automatically trigger the
+ * output of usage information if it is provided on the command line and no
+ * further argument validation will be performed. Note that the caller will
+ * still need to add this argument to the parser with the
+ * <CODE>addArgument</CODE> method, and the argument should not be required
+ * and should not take a value. Also, the caller will still need to check
+ * for the presence of the usage argument after calling
+ * <CODE>parseArguments</CODE> to know that no further processing will be
+ * required.
+ *
+ * @param argument
+ * The argument whose presence should automatically trigger the
+ * display of usage information.
+ */
+ void setUsageArgument(final Argument argument) {
+ usageArgument = argument;
+ usageOutputStream = System.out;
+ }
+
+ /**
+ * Sets the provided argument as one which will automatically trigger the
+ * output of usage information if it is provided on the command line and no
+ * further argument validation will be performed. Note that the caller will
+ * still need to add this argument to the parser with the
+ * <CODE>addArgument</CODE> method, and the argument should not be required
+ * and should not take a value. Also, the caller will still need to check
+ * for the presence of the usage argument after calling
+ * <CODE>parseArguments</CODE> to know that no further processing will be
+ * required.
+ *
+ * @param argument
+ * The argument whose presence should automatically trigger the
+ * display of usage information.
+ * @param outputStream
+ * The output stream to which the usage information should be
+ * written.
+ */
+ void setUsageArgument(final Argument argument, final OutputStream outputStream) {
+ usageArgument = argument;
+ usageOutputStream = outputStream;
+ }
+
+ /**
+ * Indicates whether the version or the usage information has been displayed
+ * to the end user either by an explicit argument like "-H" or "--help", or
+ * by a built-in argument like "-?".
+ *
+ * @return {@code true} if the usage information has been displayed, or
+ * {@code false} if not.
+ */
+ boolean usageOrVersionDisplayed() {
+ return usageOrVersionDisplayed;
+ }
+
+ /**
+ * Get the absolute path of the properties file.
+ *
+ * @param directory
+ * The location in which we should look for properties file
+ * @return The absolute path of the properties file or null
+ */
+ private String findPropertiesFile(final String directory) {
+ // Look for the tools properties file
+ final File f =
+ new File(directory, DEFAULT_OPENDJ_PROPERTIES_FILE_NAME
+ + DEFAULT_OPENDJ_PROPERTIES_FILE_EXTENSION);
+ if (f.exists() && f.canRead()) {
+ return f.getAbsolutePath();
+ } else {
+ return null;
+ }
+ }
+
+ private void initGroups() {
+ this.argumentGroups = new TreeSet<ArgumentGroup>();
+ this.argumentGroups.add(defaultArgGroup);
+ this.argumentGroups.add(ldapArgGroup);
+ this.argumentGroups.add(generalArgGroup);
+ this.argumentGroups.add(ioArgGroup);
+
+ try {
+ versionArgument =
+ new BooleanArgument(OPTION_LONG_PRODUCT_VERSION, OPTION_SHORT_PRODUCT_VERSION,
+ OPTION_LONG_PRODUCT_VERSION, INFO_DESCRIPTION_PRODUCT_VERSION.get());
+ this.generalArgGroup.addArgument(versionArgument);
+ } catch (final ArgumentException e) {
+ // ignore
+ }
+ }
+
+ private boolean isGeneralArgument(final Argument arg) {
+ boolean general = false;
+ if (arg != null) {
+ final String longId = arg.getLongIdentifier();
+ general = OPTION_LONG_HELP.equals(longId) || OPTION_LONG_PRODUCT_VERSION.equals(longId);
+ }
+ return general;
+ }
+
+ private boolean isInputOutputArgument(final Argument arg) {
+ boolean io = false;
+ if (arg != null) {
+ final String longId = arg.getLongIdentifier();
+ io =
+ OPTION_LONG_VERBOSE.equals(longId) || OPTION_LONG_QUIET.equals(longId)
+ || OPTION_LONG_NO_PROMPT.equals(longId)
+ || OPTION_LONG_PROP_FILE_PATH.equals(longId)
+ || OPTION_LONG_NO_PROP_FILE.equals(longId)
+ || OPTION_LONG_SCRIPT_FRIENDLY.equals(longId)
+ || OPTION_LONG_DONT_WRAP.equals(longId)
+ || OPTION_LONG_ENCODING.equals(longId)
+ || OPTION_LONG_BATCH_FILE_PATH.equals(longId);
+ }
+ return io;
+ }
+
+ private boolean isLdapConnectionArgument(final Argument arg) {
+ boolean ldap = false;
+ if (arg != null) {
+ final String longId = arg.getLongIdentifier();
+ ldap =
+ OPTION_LONG_USE_SSL.equals(longId) || OPTION_LONG_START_TLS.equals(longId)
+ || OPTION_LONG_HOST.equals(longId) || OPTION_LONG_PORT.equals(longId)
+ || OPTION_LONG_BINDDN.equals(longId)
+ || OPTION_LONG_BINDPWD.equals(longId)
+ || OPTION_LONG_BINDPWD_FILE.equals(longId)
+ || OPTION_LONG_SASLOPTION.equals(longId)
+ || OPTION_LONG_TRUSTALL.equals(longId)
+ || OPTION_LONG_TRUSTSTOREPATH.equals(longId)
+ || OPTION_LONG_TRUSTSTORE_PWD.equals(longId)
+ || OPTION_LONG_TRUSTSTORE_PWD_FILE.equals(longId)
+ || OPTION_LONG_KEYSTOREPATH.equals(longId)
+ || OPTION_LONG_KEYSTORE_PWD.equals(longId)
+ || OPTION_LONG_KEYSTORE_PWD_FILE.equals(longId)
+ || OPTION_LONG_CERT_NICKNAME.equals(longId)
+ || OPTION_LONG_REFERENCED_HOST_NAME.equals(longId)
+ || OPTION_LONG_ADMIN_UID.equals(longId)
+ || OPTION_LONG_REPORT_AUTHZ_ID.equals(longId)
+ || OPTION_LONG_USE_PW_POLICY_CTL.equals(longId)
+ || OPTION_LONG_USE_SASL_EXTERNAL.equals(longId)
+ || OPTION_LONG_PROTOCOL_VERSION.equals(longId);
+ }
+ return ldap;
+ }
+
+ /**
+ * Appends argument usage information to the provided buffer.
+ *
+ * @param a
+ * The argument to handle.
+ * @param buffer
+ * The buffer to which the usage information should be appended.
+ */
+ private void printArgumentUsage(final Argument a, final StringBuilder buffer) {
+ // Write a line with the short and/or long identifiers that may be
+ // used
+ // for the argument.
+ final int indentLength = INDENT.length();
+ final Character shortID = a.getShortIdentifier();
+ final String longID = a.getLongIdentifier();
+ if (shortID != null) {
+ final int currentLength = buffer.length();
+
+ if (usageArgument.getName().equals(a.getName())) {
+ buffer.append("-?, ");
+ }
+
+ buffer.append("-");
+ buffer.append(shortID.charValue());
+
+ if (a.needsValue() && longID == null) {
+ buffer.append(" ");
+ buffer.append(a.getValuePlaceholder());
+ }
+
+ if (longID != null) {
+ final StringBuilder newBuffer = new StringBuilder();
+ newBuffer.append(", --");
+ newBuffer.append(longID);
+
+ if (a.needsValue()) {
+ newBuffer.append(" ");
+ newBuffer.append(a.getValuePlaceholder());
+ }
+
+ final int lineLength = (buffer.length() - currentLength) + newBuffer.length();
+ if (lineLength > MAX_LENGTH) {
+ buffer.append(EOL);
+ buffer.append(newBuffer.toString());
+ } else {
+ buffer.append(newBuffer.toString());
+ }
+ }
+
+ buffer.append(EOL);
+ } else {
+ if (longID != null) {
+ if (usageArgument.getName().equals(a.getName())) {
+ buffer.append("-?, ");
+ }
+ buffer.append("--");
+ buffer.append(longID);
+
+ if (a.needsValue()) {
+ buffer.append(" ");
+ buffer.append(a.getValuePlaceholder());
+ }
+
+ buffer.append(EOL);
+ }
+ }
+
+ // Write one or more lines with the description of the argument.
+ // We will
+ // indent the description five characters and try our best to wrap
+ // at or
+ // before column 79 so it will be friendly to 80-column displays.
+ buffer.append(Utils.wrapText(a.getDescription(), MAX_LENGTH, indentLength));
+ buffer.append(EOL);
+
+ if (a.needsValue() && (a.getDefaultValue() != null) && (a.getDefaultValue().length() > 0)) {
+ buffer.append(INDENT);
+ buffer.append(INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()).toString());
+ buffer.append(EOL);
+ }
+ }
}
--
Gitblit v1.10.0