| | |
| | | |
| | | import static com.sun.opends.sdk.messages.Messages.*; |
| | | import static com.sun.opends.sdk.tools.ToolConstants.*; |
| | | import static com.sun.opends.sdk.tools.Utils.*; |
| | | import static com.sun.opends.sdk.util.StaticUtils.*; |
| | | import static com.sun.opends.sdk.tools.Utils.PROPERTY_SCRIPT_NAME; |
| | | import static com.sun.opends.sdk.tools.Utils.wrapText; |
| | | import static com.sun.opends.sdk.util.StaticUtils.EOL; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getBytes; |
| | | import static com.sun.opends.sdk.util.StaticUtils.getExceptionMessage; |
| | | import static com.sun.opends.sdk.util.StaticUtils.toLowerCase; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 one-character or longer word-based arguments. It |
| | | * is also integrated with the Directory Server message catalog so that |
| | | * it can display messages in an internationalizeable format, can |
| | | * automatically generate usage information, can detect conflicts |
| | | * between arguments, and can interact with a properties file to obtain |
| | | * default values for arguments there if they are not specified on the |
| | | * command-line. |
| | | * 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 |
| | | * one-character or longer word-based arguments. It is also integrated with the |
| | | * Directory Server message catalog so that it can display messages in an |
| | | * internationalizeable format, can automatically generate usage information, |
| | | * can detect conflicts between arguments, and can interact with a properties |
| | | * file to obtain default values for arguments there if they are not specified |
| | | * on the command-line. |
| | | */ |
| | | final class ArgumentParser |
| | | { |
| | |
| | | private StringArgument filePropertiesPathArgument; |
| | | |
| | | /** |
| | | * The argument that will be used to indicate that we'll not look for |
| | | * default properties file. |
| | | * The argument that will be used to indicate that we'll not look for default |
| | | * properties file. |
| | | */ |
| | | private BooleanArgument noPropertiesFileArgument; |
| | | |
| | |
| | | |
| | | // The set of unnamed trailing arguments that were provided for this |
| | | // parser. |
| | | private ArrayList<String> trailingArguments; |
| | | private final ArrayList<String> trailingArguments; |
| | | |
| | | // Indicates whether this parser will allow additional unnamed |
| | | // arguments at |
| | | // the end of the list. |
| | | private boolean allowsTrailingArguments; |
| | | private final boolean allowsTrailingArguments; |
| | | |
| | | // Indicates whether long arguments should be treated in a |
| | | // case-sensitive |
| | | // manner. |
| | | private boolean longArgumentsCaseSensitive; |
| | | private final boolean longArgumentsCaseSensitive; |
| | | |
| | | // Indicates whether the usage or version information has been |
| | | // displayed. |
| | |
| | | |
| | | // The set of arguments defined for this parser, referenced by short |
| | | // ID. |
| | | private HashMap<Character, Argument> shortIDMap; |
| | | private final HashMap<Character, Argument> shortIDMap; |
| | | |
| | | // The set of arguments defined for this parser, referenced by |
| | | // argument name. |
| | | private HashMap<String, Argument> argumentMap; |
| | | private final HashMap<String, Argument> argumentMap; |
| | | |
| | | // The set of arguments defined for this parser, referenced by long |
| | | // ID. |
| | | private HashMap<String, Argument> longIDMap; |
| | | private final HashMap<String, Argument> longIDMap; |
| | | |
| | | // The maximum number of unnamed trailing arguments that may be |
| | | // provided. |
| | | private int maxTrailingArguments; |
| | | private final int maxTrailingArguments; |
| | | |
| | | // The minimum number of unnamed trailing arguments that may be |
| | | // provided. |
| | | private int minTrailingArguments; |
| | | private final int minTrailingArguments; |
| | | |
| | | // The total set of arguments defined for this parser. |
| | | private LinkedList<Argument> argumentList; |
| | | private final LinkedList<Argument> argumentList; |
| | | |
| | | // 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 String mainClassName; |
| | | private final String mainClassName; |
| | | |
| | | // A human-readable description for the tool, which will be included |
| | | // when |
| | | // displaying usage information. |
| | | private LocalizableMessage toolDescription; |
| | | private final LocalizableMessage toolDescription; |
| | | |
| | | // The display name that will be used for the trailing arguments in |
| | | // the usage |
| | | // information. |
| | | private String trailingArgsDisplayName; |
| | | private final String trailingArgsDisplayName; |
| | | |
| | | // The raw set of command-line arguments that were provided. |
| | | private String[] rawArguments; |
| | |
| | | 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. |
| | | * Group for arguments that have not been explicitly grouped. These will |
| | | * appear at the top of the usage statement without a header. |
| | | */ |
| | | private ArgumentGroup defaultArgGroup = new ArgumentGroup( |
| | | 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. |
| | | * Group for arguments that are related to connection through LDAP. This |
| | | * includes options like the bind DN, the port, etc. |
| | | */ |
| | | private ArgumentGroup ldapArgGroup = new ArgumentGroup( |
| | | INFO_DESCRIPTION_LDAP_CONNECTION_ARGS.get(), |
| | | Integer.MIN_VALUE + 2); |
| | | 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. |
| | | * properties file, no-prompt etc. These will appear toward the bottom of the |
| | | * usage statement. |
| | | */ |
| | | private ArgumentGroup ioArgGroup = new ArgumentGroup( |
| | | 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. |
| | | * Group for arguments that are general like help, version etc. These will |
| | | * appear at the end of the usage statement. |
| | | */ |
| | | private ArgumentGroup generalArgGroup = new ArgumentGroup( |
| | | private final ArgumentGroup generalArgGroup = new ArgumentGroup( |
| | | INFO_DESCRIPTION_GENERAL_ARGS.get(), Integer.MIN_VALUE); |
| | | |
| | | private final static String INDENT = " "; |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this argument parser with no arguments. |
| | | * Unnamed trailing arguments will not be allowed. |
| | | * 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. |
| | | * 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. |
| | | * 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(String mainClassName, LocalizableMessage toolDescription, |
| | | boolean longArgumentsCaseSensitive) |
| | | ArgumentParser(final String mainClassName, |
| | | final LocalizableMessage toolDescription, |
| | | final boolean longArgumentsCaseSensitive) |
| | | { |
| | | this.mainClassName = mainClassName; |
| | | this.toolDescription = toolDescription; |
| | |
| | | |
| | | |
| | | /** |
| | | * Creates a new instance of this argument parser with no arguments |
| | | * that may or may not be allowed to have unnamed trailing arguments. |
| | | * 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. |
| | | * 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. |
| | | * 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. |
| | | * 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. |
| | | * 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. |
| | | * 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. |
| | | * The display name that should be used as a placeholder for unnamed |
| | | * trailing arguments in the generated usage information. |
| | | */ |
| | | ArgumentParser(String mainClassName, LocalizableMessage toolDescription, |
| | | boolean longArgumentsCaseSensitive, |
| | | boolean allowsTrailingArguments, int minTrailingArguments, |
| | | int maxTrailingArguments, String trailingArgsDisplayName) |
| | | 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; |
| | |
| | | |
| | | |
| | | /** |
| | | * 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 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; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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 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 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(String name) |
| | | { |
| | | return argumentMap.get(name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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(Character shortID) |
| | | { |
| | | return shortIDMap.get(shortID); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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(String longID) |
| | | { |
| | | return longIDMap.get(longID); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 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; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the default argument group. |
| | | * |
| | | * @param description |
| | | * for the default group |
| | | */ |
| | | void setDefaultArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.defaultArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the LDAP argument group. |
| | | * |
| | | * @param description |
| | | * for the LDAP group |
| | | */ |
| | | void setLdapArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.ldapArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the input/output argument |
| | | * group. |
| | | * |
| | | * @param description |
| | | * for the input/output group |
| | | */ |
| | | void setInputOutputArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.ioArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Sets the usage group description for the general argument group. |
| | | * |
| | | * @param description |
| | | * for the general group |
| | | */ |
| | | void setGeneralArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.generalArgGroup.setDescription(description); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this |
| | | * parser. |
| | | * 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. |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addArgument(Argument argument) throws ArgumentException |
| | | void addArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, null); |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * 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(Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, defaultArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(Argument argument) |
| | | throws ArgumentException |
| | | { |
| | | addArgument(argument, ldapArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(Argument argument) |
| | | throws ArgumentException |
| | | { |
| | | addArgument(argument, ioArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(Argument argument) throws ArgumentException |
| | | { |
| | | addArgument(argument, generalArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Adds the provided argument to the set of arguments handled by this |
| | | * parser. |
| | | * 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. |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void addArgument(Argument argument, ArgumentGroup group) |
| | | void addArgument(final Argument argument, ArgumentGroup group) |
| | | throws ArgumentException |
| | | { |
| | | |
| | | Character shortID = argument.getShortIdentifier(); |
| | | final Character shortID = argument.getShortIdentifier(); |
| | | if ((shortID != null) && shortIDMap.containsKey(shortID)) |
| | | { |
| | | String conflictingName = shortIDMap.get(shortID).getName(); |
| | | final String conflictingName = shortIDMap.get(shortID).getName(); |
| | | |
| | | LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get(argument |
| | | .getName(), String.valueOf(shortID), conflictingName); |
| | | final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get( |
| | | argument.getName(), String.valueOf(shortID), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | |
| | | // identifier. |
| | | try |
| | | { |
| | | versionArgument = new BooleanArgument( |
| | | OPTION_LONG_PRODUCT_VERSION, null, |
| | | OPTION_LONG_PRODUCT_VERSION, |
| | | versionArgument = new BooleanArgument(OPTION_LONG_PRODUCT_VERSION, |
| | | null, OPTION_LONG_PRODUCT_VERSION, |
| | | INFO_DESCRIPTION_PRODUCT_VERSION.get()); |
| | | this.generalArgGroup.addArgument(versionArgument); |
| | | } |
| | | catch (ArgumentException e) |
| | | catch (final ArgumentException e) |
| | | { |
| | | // ignore |
| | | } |
| | |
| | | } |
| | | if (longIDMap.containsKey(longID)) |
| | | { |
| | | String conflictingName = longIDMap.get(longID).getName(); |
| | | final String conflictingName = longIDMap.get(longID).getName(); |
| | | |
| | | LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get(argument |
| | | .getName(), argument.getLongIdentifier(), conflictingName); |
| | | final LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get( |
| | | argument.getName(), argument.getLongIdentifier(), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * 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 whose presence should automatically trigger |
| | | * the display of usage information. |
| | | */ |
| | | void setUsageArgument(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(Argument argument, OutputStream outputStream) |
| | | { |
| | | usageArgument = argument; |
| | | usageOutputStream = outputStream; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(StringArgument argument) |
| | | { |
| | | filePropertiesPathArgument = argument; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(BooleanArgument argument) |
| | | { |
| | | noPropertiesFileArgument = argument; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Parses the provided set of arguments and updates the information |
| | | * associated with this parser accordingly. |
| | | * |
| | | * @param rawArguments |
| | | * The raw set of arguments to parse. |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments. |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void parseArguments(String[] rawArguments) throws ArgumentException |
| | | void addDefaultArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | parseArguments(rawArguments, null); |
| | | addArgument(argument, defaultArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the arguement in the general group. |
| | | * |
| | | * @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. |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments or interacting with the properties file. |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void parseArguments(String[] rawArguments, String propertiesFile, |
| | | boolean requirePropertiesFile) throws ArgumentException |
| | | void addGeneralArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | this.rawArguments = rawArguments; |
| | | |
| | | Properties argumentProperties = null; |
| | | |
| | | try |
| | | { |
| | | Properties p = new Properties(); |
| | | FileInputStream fis = new FileInputStream(propertiesFile); |
| | | p.load(fis); |
| | | fis.close(); |
| | | argumentProperties = p; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (requirePropertiesFile) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE |
| | | .get(String.valueOf(propertiesFile), getExceptionMessage(e)); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | } |
| | | |
| | | parseArguments(rawArguments, argumentProperties); |
| | | addArgument(argument, generalArgGroup); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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. |
| | | * Adds the provided argument to the set of arguments handled by this parser |
| | | * and puts the argument in the input/output group. |
| | | * |
| | | * @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. |
| | | * @param argument |
| | | * The argument to be added. |
| | | * @throws ArgumentException |
| | | * If a problem was encountered while parsing the provided |
| | | * arguments. |
| | | * If the provided argument conflicts with another argument that has |
| | | * already been defined. |
| | | */ |
| | | void parseArguments(String[] rawArguments, |
| | | Properties argumentProperties) throws ArgumentException |
| | | void addInputOutputArgument(final Argument argument) throws ArgumentException |
| | | { |
| | | this.rawArguments = rawArguments; |
| | | addArgument(argument, ioArgGroup); |
| | | } |
| | | |
| | | boolean inTrailingArgs = false; |
| | | |
| | | int numArguments = rawArguments.length; |
| | | for (int i = 0; i < numArguments; i++) |
| | | { |
| | | String arg = rawArguments[i]; |
| | | |
| | | if (inTrailingArgs) |
| | | { |
| | | trailingArguments.add(arg); |
| | | if ((maxTrailingArguments > 0) |
| | | && (trailingArguments.size() > maxTrailingArguments)) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS |
| | | .get(maxTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | | /** |
| | | * 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); |
| | | } |
| | | |
| | | 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; |
| | | 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. |
| | | 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. |
| | | String origArgName = argName; |
| | | if (!longArgumentsCaseSensitive) |
| | | { |
| | | argName = toLowerCase(argName); |
| | | } |
| | | |
| | | // Get the argument with the specified name. |
| | | 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 (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 (Exception e) |
| | | { |
| | | } |
| | | |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | 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 (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) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (!a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | 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())) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID |
| | | .get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | a.addValue(argValue); |
| | | } |
| | | else |
| | | { |
| | | if (argValue != null) |
| | | { |
| | | 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("-")) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT |
| | | .get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | 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. |
| | | Argument a = shortIDMap.get(argCharacter); |
| | | if (a == null) |
| | | { |
| | | if (argCharacter == '?') |
| | | { |
| | | // "-?" will always be interpreted as requesting usage |
| | | // information. |
| | | try |
| | | { |
| | | getUsage(usageOutputStream); |
| | | } |
| | | catch (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 (Exception e) |
| | | { |
| | | } |
| | | return; |
| | | } |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | 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 (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) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID |
| | | .get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (!a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | 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())) |
| | | { |
| | | 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. |
| | | int valueLength = argValue.length(); |
| | | for (int j = 0; j < valueLength; j++) |
| | | { |
| | | char c = argValue.charAt(j); |
| | | Argument b = shortIDMap.get(c); |
| | | if (b == null) |
| | | { |
| | | // There is no such argument registered. |
| | | 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. |
| | | 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 (Exception e) |
| | | { |
| | | } |
| | | |
| | | 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. |
| | | 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) |
| | | { |
| | | 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 (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)) |
| | | { |
| | | String value = argumentProperties.getProperty(a |
| | | .getPropertyName().toLowerCase()); |
| | | 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()) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG |
| | | .get(a.getName()); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | | |
| | |
| | | else |
| | | { |
| | | // Check in "user home"/.opends directory |
| | | String userDir = System.getProperty("user.home"); |
| | | final String userDir = System.getProperty("user.home"); |
| | | propertiesFilePath = findPropertiesFile(userDir + File.separator |
| | | + DEFAULT_OPENDS_CONFIG_DIR); |
| | | |
| | | // TODO |
| | | /* |
| | | * if (propertiesFilePath == null) { // check |
| | | * "Opends instance"/config directory String instanceDir = |
| | | * DirectoryServer.getInstanceRoot(); propertiesFilePath = |
| | | * findPropertiesFile(instanceDir+ File.separator + "config"); } |
| | | * if (propertiesFilePath == null) { // check "Opends instance"/config |
| | | * directory String instanceDir = DirectoryServer.getInstanceRoot(); |
| | | * propertiesFilePath = findPropertiesFile(instanceDir+ File.separator + |
| | | * "config"); } |
| | | */ |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // We have a location for the properties file. |
| | | Properties argumentProperties = new Properties(); |
| | | String scriptName = System.getProperty(Utils.PROPERTY_SCRIPT_NAME); |
| | | final Properties argumentProperties = new Properties(); |
| | | final String scriptName = System.getProperty(Utils.PROPERTY_SCRIPT_NAME); |
| | | try |
| | | { |
| | | Properties p = new Properties(); |
| | | FileInputStream fis = new FileInputStream(propertiesFilePath); |
| | | final Properties p = new Properties(); |
| | | final FileInputStream fis = new FileInputStream(propertiesFilePath); |
| | | p.load(fis); |
| | | fis.close(); |
| | | |
| | | for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) |
| | | for (final Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) |
| | | { |
| | | String currentPropertyName = (String) e.nextElement(); |
| | | final String currentPropertyName = (String) e.nextElement(); |
| | | String propertyName = currentPropertyName; |
| | | |
| | | // Property name form <script name>.<property name> has the |
| | |
| | | { |
| | | if (currentPropertyName.startsWith(scriptName)) |
| | | { |
| | | propertyName = currentPropertyName.substring(scriptName |
| | | .length() + 1); |
| | | propertyName = currentPropertyName |
| | | .substring(scriptName.length() + 1); |
| | | } |
| | | else |
| | | { |
| | |
| | | .getProperty(currentPropertyName)); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | catch (final Exception e) |
| | | { |
| | | LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get( |
| | | String.valueOf(propertiesFilePath), getExceptionMessage(e)); |
| | | final LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE |
| | | .get(String.valueOf(propertiesFilePath), getExceptionMessage(e)); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | | return argumentProperties; |
| | |
| | | |
| | | |
| | | /** |
| | | * Get the absolute path of the properties file. |
| | | * Retrieves the argument with the specified name. |
| | | * |
| | | * @param directory |
| | | * The location in which we should look for properties file |
| | | * @return The absolute path of the properties file or null |
| | | * @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. |
| | | */ |
| | | private String findPropertiesFile(String directory) |
| | | Argument getArgument(final String name) |
| | | { |
| | | // Look for the tools properties file |
| | | File f = new File(directory, DEFAULT_OPENDS_PROPERTIES_FILE_NAME |
| | | + DEFAULT_OPENDS_PROPERTIES_FILE_EXTENSION); |
| | | if (f.exists() && f.canRead()) |
| | | { |
| | | return f.getAbsolutePath(); |
| | | } |
| | | else |
| | | { |
| | | return null; |
| | | } |
| | | return argumentMap.get(name); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Appends usage information based on the defined arguments to the |
| | | * provided buffer. |
| | | * 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. |
| | | * The buffer to which the usage information should be appended. |
| | | */ |
| | | void getUsage(StringBuilder buffer) |
| | | void getUsage(final StringBuilder buffer) |
| | | { |
| | | usageOrVersionDisplayed = true; |
| | | if ((toolDescription != null) && (toolDescription.length() > 0)) |
| | | { |
| | | buffer |
| | | .append(wrapText(toolDescription.toString(), MAX_LENGTH - 1)); |
| | | buffer.append(wrapText(toolDescription.toString(), MAX_LENGTH - 1)); |
| | | buffer.append(EOL); |
| | | buffer.append(EOL); |
| | | } |
| | | |
| | | String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | | final String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | | if ((scriptName == null) || (scriptName.length() == 0)) |
| | | { |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_CLASSNAME |
| | | .get(mainClassName)); |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_CLASSNAME.get(mainClassName)); |
| | | } |
| | | else |
| | | { |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME |
| | | .get(scriptName)); |
| | | buffer.append(INFO_ARGPARSER_USAGE_JAVA_SCRIPTNAME.get(scriptName)); |
| | | } |
| | | |
| | | if (allowsTrailingArguments) |
| | |
| | | |
| | | Argument helpArgument = null; |
| | | |
| | | boolean printHeaders = printUsageGroupHeaders(); |
| | | for (ArgumentGroup argGroup : argumentGroups) |
| | | final boolean printHeaders = printUsageGroupHeaders(); |
| | | for (final ArgumentGroup argGroup : argumentGroups) |
| | | { |
| | | if (argGroup.containsArguments() && printHeaders) |
| | | { |
| | | // Print the groups description if any |
| | | LocalizableMessage groupDesc = argGroup.getDescription(); |
| | | final LocalizableMessage groupDesc = argGroup.getDescription(); |
| | | if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc)) |
| | | { |
| | | buffer.append(EOL); |
| | |
| | | } |
| | | } |
| | | |
| | | for (Argument a : argGroup.getArguments()) |
| | | for (final Argument a : argGroup.getArguments()) |
| | | { |
| | | // If this argument is hidden, then skip it. |
| | | if (a.isHidden()) |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a message containing usage information based on the |
| | | * defined arguments. |
| | | * Retrieves a message containing usage information based on the defined |
| | | * arguments. |
| | | * |
| | | * @return A string containing usage information based on the defined |
| | | * arguments. |
| | | */ |
| | | LocalizableMessage getUsageMessage() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | // TODO: rework getUsage(OutputStream) to work with messages |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves a string containing usage information based on the |
| | | * defined arguments. |
| | | * Returns whether the usage argument was provided or not. This method should |
| | | * be called after a call to parseArguments. |
| | | * |
| | | * @return A string containing usage information based on the defined |
| | | * arguments. |
| | | * @return <CODE>true</CODE> if the usage argument was provided and |
| | | * <CODE>false</CODE> otherwise. |
| | | */ |
| | | String getUsage() |
| | | boolean isUsageArgumentPresent() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | return buffer.toString(); |
| | | boolean isUsageArgumentPresent = false; |
| | | if (usageArgument != null) |
| | | { |
| | | isUsageArgumentPresent = usageArgument.isPresent(); |
| | | } |
| | | return isUsageArgumentPresent; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Writes usage information based on the defined arguments to the |
| | | * provided output stream. |
| | | * 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); |
| | | 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; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | 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. |
| | | * @throws IOException |
| | | * If a problem occurs while attempting to write the usage |
| | | * information to the provided output stream. |
| | | */ |
| | | void getUsage(OutputStream outputStream) throws IOException |
| | | void setUsageArgument(final Argument argument, final OutputStream outputStream) |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | outputStream.write(getBytes(buffer.toString())); |
| | | 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 "-?". |
| | | * 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. |
| | | * @return {@code true} if the usage information has been displayed, or |
| | | * {@code false} if not. |
| | | */ |
| | | boolean 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_OPENDS_PROPERTIES_FILE_NAME |
| | | + DEFAULT_OPENDS_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. |
| | | * The buffer to which the usage information should be appended. |
| | | */ |
| | | private void printArgumentUsage(Argument a, StringBuilder buffer) |
| | | 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(); |
| | | Character shortID = a.getShortIdentifier(); |
| | | String longID = a.getLongIdentifier(); |
| | | final Character shortID = a.getShortIdentifier(); |
| | | final String longID = a.getLongIdentifier(); |
| | | if (shortID != null) |
| | | { |
| | | int currentLength = buffer.length(); |
| | | final int currentLength = buffer.length(); |
| | | |
| | | if (usageArgument.getName().equals(a.getName())) |
| | | { |
| | |
| | | |
| | | if (longID != null) |
| | | { |
| | | StringBuilder newBuffer = new StringBuilder(); |
| | | final StringBuilder newBuffer = new StringBuilder(); |
| | | newBuffer.append(", --"); |
| | | newBuffer.append(longID); |
| | | |
| | |
| | | newBuffer.append(a.getValuePlaceholder()); |
| | | } |
| | | |
| | | int lineLength = (buffer.length() - currentLength) |
| | | final int lineLength = (buffer.length() - currentLength) |
| | | + newBuffer.length(); |
| | | if (lineLength > MAX_LENGTH) |
| | | { |
| | |
| | | // 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. |
| | | LocalizableMessage description = a.getDescription(); |
| | | int descMaxLength = MAX_LENGTH - indentLength - 1; |
| | | final LocalizableMessage description = a.getDescription(); |
| | | final int descMaxLength = MAX_LENGTH - indentLength - 1; |
| | | if (description.length() <= descMaxLength) |
| | | { |
| | | buffer.append(INDENT); |
| | |
| | | && (a.getDefaultValue().length() > 0)) |
| | | { |
| | | buffer.append(INDENT); |
| | | buffer.append(INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get( |
| | | a.getDefaultValue()).toString()); |
| | | buffer.append(INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()) |
| | | .toString()); |
| | | buffer.append(EOL); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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(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; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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 (ArgumentGroup argGroup : argumentGroups) |
| | | { |
| | | if (argGroup.containsNonHiddenArguments()) |
| | | { |
| | | groupsContainingArgs++; |
| | | } |
| | | } |
| | | return groupsContainingArgs > 1; |
| | | } |
| | | |
| | | |
| | | |
| | | 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 (ArgumentException e) |
| | | { |
| | | // ignore |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean isInputOutputArgument(Argument arg) |
| | | { |
| | | boolean io = false; |
| | | if (arg != null) |
| | | { |
| | | 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(Argument arg) |
| | | { |
| | | boolean ldap = false; |
| | | if (arg != null) |
| | | { |
| | | 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; |
| | | } |
| | | |
| | | |
| | | |
| | | private boolean isGeneralArgument(Argument arg) |
| | | { |
| | | boolean general = false; |
| | | if (arg != null) |
| | | { |
| | | String longId = arg.getLongIdentifier(); |
| | | general = OPTION_LONG_HELP.equals(longId) |
| | | || OPTION_LONG_PRODUCT_VERSION.equals(longId); |
| | | } |
| | | return general; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | } |