| | |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2013 ForgeRock AS |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | package org.opends.server.util.args; |
| | | |
| | |
| | | import java.io.OutputStream; |
| | | import java.util.*; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.MessageBuilder; |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.i18n.LocalizableMessageBuilder; |
| | | import org.opends.server.util.SetupUtils; |
| | | |
| | | import static org.opends.messages.UtilityMessages.*; |
| | |
| | | * A human-readable description for the tool, which will be included when |
| | | * displaying usage information. |
| | | */ |
| | | private final Message toolDescription; |
| | | private final LocalizableMessage toolDescription; |
| | | |
| | | /** The raw set of command-line arguments that were provided. */ |
| | | private String[] rawArguments; |
| | |
| | | * argument names should be treated in a |
| | | * case-sensitive manner. |
| | | */ |
| | | public SubCommandArgumentParser(String mainClassName, Message toolDescription, |
| | | public SubCommandArgumentParser(String mainClassName, LocalizableMessage toolDescription, |
| | | boolean longArgumentsCaseSensitive) |
| | | { |
| | | super(mainClassName, toolDescription, longArgumentsCaseSensitive); |
| | |
| | | * none is available. |
| | | */ |
| | | @Override |
| | | public Message getToolDescription() |
| | | public LocalizableMessage getToolDescription() |
| | | { |
| | | return toolDescription; |
| | | } |
| | |
| | | String argumentName = argument.getName(); |
| | | if (globalArgumentMap.containsKey(argumentName)) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_NAME.get(argumentName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if (s.getArgumentForName(argumentName) != null) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_GLOBAL_ARG_NAME_SUBCMD_CONFLICT.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_GLOBAL_ARG_NAME_SUBCMD_CONFLICT.get( |
| | | argumentName, s.getName()); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | String name = globalShortIDMap.get(shortID).getName(); |
| | | |
| | | Message message = ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_SHORT_ID.get( |
| | | String.valueOf(shortID), argumentName, name); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | String cmdName = s.getName(); |
| | | String name = s.getArgument(shortID).getName(); |
| | | |
| | | Message message = ERR_SUBCMDPARSER_GLOBAL_ARG_SHORT_ID_CONFLICT.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_GLOBAL_ARG_SHORT_ID_CONFLICT.get( |
| | | String.valueOf(shortID), argumentName, name, cmdName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | String name = globalLongIDMap.get(longID).getName(); |
| | | |
| | | Message message = ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_LONG_ID.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_DUPLICATE_GLOBAL_ARG_LONG_ID.get( |
| | | argument.getLongIdentifier(), argumentName, name); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | String cmdName = s.getName(); |
| | | String name = s.getArgument(longID).getName(); |
| | | |
| | | Message message = ERR_SUBCMDPARSER_GLOBAL_ARG_LONG_ID_CONFLICT.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_GLOBAL_ARG_LONG_ID_CONFLICT.get( |
| | | argument.getLongIdentifier(), argumentName, name, cmdName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | if (subCommand.getMaxTrailingArguments() > 0 |
| | | && trailingArguments.size() > subCommand.getMaxTrailingArguments()) |
| | | { |
| | | Message message = ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS.get( |
| | | subCommand.getMaxTrailingArguments()); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | else if (equalPos == 0) |
| | | { |
| | | // The argument starts with "--=", which is not acceptable. |
| | | Message message = ERR_SUBCMDPARSER_LONG_ARG_WITHOUT_NAME.get(arg); |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_LONG_ARG_WITHOUT_NAME.get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | |
| | | else |
| | | { |
| | | // There is no such global argument. |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_LONG_ID.get( |
| | | origArgName); |
| | | throw new ArgumentException(message); |
| | |
| | | else |
| | | { |
| | | // There is no such global or subcommand argument. |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_LONG_ID.get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if ((i+1) == numArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID. |
| | | get(argName); |
| | | throw new ArgumentException(message); |
| | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | MessageBuilder invalidReason = new MessageBuilder(); |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (! a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID. |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID. |
| | | get(argValue, argName, invalidReason.toString()); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | // acceptable to have more than one. |
| | | if (a.hasValue() && !a.isMultiValued()) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_LONG_ID.get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if (argValue != null) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE.get( |
| | | origArgName); |
| | | throw new ArgumentException(message); |
| | |
| | | // -n value |
| | | if (arg.equals("-")) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_INVALID_DASH_AS_ARGUMENT.get(); |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_INVALID_DASH_AS_ARGUMENT.get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | |
| | | { |
| | | // -V is defined in another suncommand, so we can |
| | | // accepted it as the version information argument |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID. |
| | | get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID. |
| | | get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | Message message = ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID.get( |
| | | String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if ((i+1) == numArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_VALUE_FOR_ARGUMENT_WITH_SHORT_ID. |
| | | get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | MessageBuilder invalidReason = new MessageBuilder(); |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (! a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID. |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID. |
| | | get(argValue, String.valueOf(argCharacter), |
| | | invalidReason.toString()); |
| | | throw new ArgumentException(message); |
| | |
| | | // acceptable to have more than one. |
| | | if (a.hasValue() && !a.isMultiValued()) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get( |
| | | String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if (subCommand == null) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_SUBCMDPARSER_NO_GLOBAL_ARGUMENT_FOR_SHORT_ID. |
| | | get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | |
| | | b = subCommand.getArgument(c); |
| | | if (b == null) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID. |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_NO_ARGUMENT_FOR_SHORT_ID. |
| | | get(String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | // This means we're in a scenario like "-abc" where b is a |
| | | // valid argument that takes a value. We don't support that. |
| | | Message message = ERR_SUBCMDPARSER_CANT_MIX_ARGS_WITH_VALUES. |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_CANT_MIX_ARGS_WITH_VALUES. |
| | | get(String.valueOf(argCharacter), argValue, |
| | | String.valueOf(c)); |
| | | throw new ArgumentException(message); |
| | |
| | | else |
| | | { |
| | | // Trailing arguments are not allowed for this sub-command. |
| | | Message message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg); |
| | | LocalizableMessage message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | |
| | | SubCommand sc = subCommands.get(nameToCheck); |
| | | if (sc == null) |
| | | { |
| | | Message message = ERR_SUBCMDPARSER_INVALID_ARGUMENT.get(arg); |
| | | LocalizableMessage message = ERR_SUBCMDPARSER_INVALID_ARGUMENT.get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | |
| | | if (subCommand.allowsTrailingArguments() && minTrailingArguments > 0 |
| | | && trailingArguments.size() < minTrailingArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(minTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | * @param subCommand The subcommand for which to display the usage |
| | | * information. |
| | | */ |
| | | public void getSubCommandUsage(MessageBuilder buffer, SubCommand subCommand) |
| | | public void getSubCommandUsage(LocalizableMessageBuilder buffer, SubCommand subCommand) |
| | | { |
| | | usageOrVersionDisplayed = true; |
| | | String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | |
| | | * 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. |
| | | * <p> |
| | | * FIXME Try to merge with #indentAndWrap(Message, Message, MessageBuilder). |
| | | * FIXME Try to merge with #indentAndWrap(LocalizableMessage, LocalizableMessage, LocalizableMessageBuilder). |
| | | */ |
| | | private void indentAndWrap2(String indent, Message text, |
| | | MessageBuilder buffer) |
| | | private void indentAndWrap2(String indent, LocalizableMessage text, |
| | | LocalizableMessageBuilder buffer) |
| | | { |
| | | int actualSize = MAX_LENGTH - indent.length() - 1; |
| | | if (text.length() <= actualSize) |
| | |
| | | @Override |
| | | public String getUsage() |
| | | { |
| | | MessageBuilder buffer = new MessageBuilder(); |
| | | LocalizableMessageBuilder buffer = new LocalizableMessageBuilder(); |
| | | |
| | | if (subCommand == null) { |
| | | if (System.getProperty("org.forgerock.opendj.gendoc") != null) { |
| | |
| | | * |
| | | * @return A string describing how the user can get more help. |
| | | */ |
| | | public Message getHelpUsageReference() |
| | | public LocalizableMessage getHelpUsageReference() |
| | | { |
| | | usageOrVersionDisplayed = true; |
| | | String scriptName = System.getProperty(PROPERTY_SCRIPT_NAME); |
| | |
| | | scriptName = "java " + mainClassName; |
| | | } |
| | | |
| | | MessageBuilder buffer = new MessageBuilder(); |
| | | LocalizableMessageBuilder buffer = new LocalizableMessageBuilder(); |
| | | buffer.append(INFO_GLOBAL_HELP_REFERENCE.get(scriptName)); |
| | | buffer.append(EOL); |
| | | return buffer.toMessage(); |
| | |
| | | |
| | | /** Get usage for a specific usage argument. */ |
| | | private void getUsage(Argument a, OutputStream outputStream) { |
| | | MessageBuilder buffer = new MessageBuilder(); |
| | | LocalizableMessageBuilder buffer = new LocalizableMessageBuilder(); |
| | | |
| | | if (a.equals(usageArgument) && subCommand != null) { |
| | | getSubCommandUsage(buffer, subCommand); |
| | |
| | | * Appends complete usage information for the specified set of sub-commands. |
| | | */ |
| | | private void getFullUsage(Collection<SubCommand> c, |
| | | boolean showGlobalOptions, MessageBuilder buffer) { |
| | | boolean showGlobalOptions, LocalizableMessageBuilder buffer) { |
| | | usageOrVersionDisplayed = true; |
| | | if (toolDescription != null && toolDescription.length() > 0) |
| | | { |
| | |
| | | } |
| | | buffer.append(sc.getName()); |
| | | buffer.append(EOL); |
| | | indentAndWrap(Message.raw(INDENT), sc.getDescription(), buffer); |
| | | indentAndWrap(LocalizableMessage.raw(INDENT), sc.getDescription(), buffer); |
| | | buffer.append(EOL); |
| | | isFirst = false; |
| | | } |
| | |
| | | if (argGroup.containsArguments() && printGroupHeaders) |
| | | { |
| | | // Print the groups description if any |
| | | Message groupDesc = argGroup.getDescription(); |
| | | if (groupDesc != null && !Message.EMPTY.equals(groupDesc)) { |
| | | LocalizableMessage groupDesc = argGroup.getDescription(); |
| | | if (groupDesc != null && !LocalizableMessage.EMPTY.equals(groupDesc)) { |
| | | buffer.append(EOL); |
| | | buffer.append(wrapText(groupDesc.toString(), MAX_LENGTH - 1)); |
| | | buffer.append(EOL); |
| | |
| | | * The buffer to which the usage information should be |
| | | * appended. |
| | | */ |
| | | private void printArgumentUsage(Argument a, MessageBuilder buffer) { |
| | | private void printArgumentUsage(Argument a, LocalizableMessageBuilder buffer) { |
| | | String value; |
| | | if (a.needsValue()) |
| | | { |
| | | Message pHolder = a.getValuePlaceholder(); |
| | | LocalizableMessage pHolder = a.getValuePlaceholder(); |
| | | if (pHolder == null) |
| | | { |
| | | value = " {value}"; |
| | |
| | | |
| | | buffer.append(EOL); |
| | | |
| | | indentAndWrap(Message.raw(INDENT), a.getDescription(), buffer); |
| | | indentAndWrap(LocalizableMessage.raw(INDENT), a.getDescription(), buffer); |
| | | if (a.needsValue() |
| | | && a.getDefaultValue() != null |
| | | && a.getDefaultValue().length() > 0) |
| | | { |
| | | indentAndWrap(Message.raw(INDENT), |
| | | indentAndWrap(LocalizableMessage.raw(INDENT), |
| | | INFO_ARGPARSER_USAGE_DEFAULT_VALUE.get(a.getDefaultValue()), |
| | | buffer); |
| | | } |
| | |
| | | * 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. |
| | | */ |
| | | private void indentAndWrap(Message indent, Message text, |
| | | MessageBuilder buffer) |
| | | private void indentAndWrap(LocalizableMessage indent, LocalizableMessage text, |
| | | LocalizableMessageBuilder buffer) |
| | | { |
| | | int actualSize = MAX_LENGTH - indent.length(); |
| | | if (text.length() <= actualSize) |