| | |
| | | * |
| | | * |
| | | * 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.core.DirectoryServer; |
| | | import org.opends.server.util.SetupUtils; |
| | | |
| | |
| | | * A human-readable description for the tool, which will be included when |
| | | * displaying usage information. |
| | | */ |
| | | private Message toolDescription; |
| | | private LocalizableMessage toolDescription; |
| | | |
| | | /** |
| | | * The display name that will be used for the trailing arguments in the usage |
| | |
| | | * a header. |
| | | */ |
| | | protected ArgumentGroup defaultArgGroup = new ArgumentGroup( |
| | | Message.EMPTY, Integer.MAX_VALUE); |
| | | LocalizableMessage.EMPTY, Integer.MAX_VALUE); |
| | | |
| | | |
| | | /** |
| | |
| | | * @param longArgumentsCaseSensitive Indicates whether long arguments should |
| | | * be treated in a case-sensitive manner. |
| | | */ |
| | | public ArgumentParser(String mainClassName, Message toolDescription, |
| | | public ArgumentParser(String mainClassName, LocalizableMessage toolDescription, |
| | | boolean longArgumentsCaseSensitive) |
| | | { |
| | | this.mainClassName = mainClassName; |
| | |
| | | * arguments in the generated usage |
| | | * information. |
| | | */ |
| | | public ArgumentParser(String mainClassName, Message toolDescription, |
| | | public ArgumentParser(String mainClassName, LocalizableMessage toolDescription, |
| | | boolean longArgumentsCaseSensitive, |
| | | boolean allowsTrailingArguments, |
| | | int minTrailingArguments, int maxTrailingArguments, |
| | |
| | | * @return A human-readable description for this tool, or {@code null} if |
| | | * none is available. |
| | | */ |
| | | public Message getToolDescription() |
| | | public LocalizableMessage getToolDescription() |
| | | { |
| | | return toolDescription; |
| | | } |
| | |
| | | * |
| | | * @param description for the default group |
| | | */ |
| | | public void setDefaultArgumentGroupDescription(Message description) |
| | | public void setDefaultArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.defaultArgGroup.setDescription(description); |
| | | } |
| | |
| | | * |
| | | * @param description for the LDAP group |
| | | */ |
| | | public void setLdapArgumentGroupDescription(Message description) |
| | | public void setLdapArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.ldapArgGroup.setDescription(description); |
| | | } |
| | |
| | | * |
| | | * @param description for the input/output group |
| | | */ |
| | | public void setInputOutputArgumentGroupDescription(Message description) |
| | | public void setInputOutputArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.ioArgGroup.setDescription(description); |
| | | } |
| | |
| | | * |
| | | * @param description for the general group |
| | | */ |
| | | public void setGeneralArgumentGroupDescription(Message description) |
| | | public void setGeneralArgumentGroupDescription(LocalizableMessage description) |
| | | { |
| | | this.generalArgGroup.setDescription(description); |
| | | } |
| | |
| | | { |
| | | String conflictingName = shortIDMap.get(shortID).getName(); |
| | | |
| | | Message message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_SHORT_ID.get( |
| | | argument.getName(), String.valueOf(shortID), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | String conflictingName = longIDMap.get(longID).getName(); |
| | | |
| | | Message message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_DUPLICATE_LONG_ID.get( |
| | | argument.getName(), argument.getLongIdentifier(), conflictingName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | if (maxTrailingArguments > 0 && |
| | | trailingArguments.size() > maxTrailingArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_TOO_MANY_TRAILING_ARGS.get(maxTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | else if (equalPos == 0) |
| | | { |
| | | // The argument starts with "--=", which is not acceptable. |
| | | Message message = ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME.get(arg); |
| | | LocalizableMessage message = ERR_ARGPARSER_LONG_ARG_WITHOUT_NAME.get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | else |
| | |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_NO_ARGUMENT_WITH_LONG_ID.get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if ((i+1) == numArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_NO_VALUE_FOR_ARGUMENT_WITH_LONG_ID.get( |
| | | origArgName); |
| | | throw new ArgumentException(message); |
| | |
| | | argValue = rawArguments[++i]; |
| | | } |
| | | |
| | | MessageBuilder invalidReason = new MessageBuilder(); |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (! a.valueIsAcceptable(argValue, invalidReason)) |
| | | { |
| | | Message message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_VALUE_UNACCEPTABLE_FOR_LONG_ID.get( |
| | | argValue, origArgName, invalidReason.toString()); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | // acceptable to have more than one. |
| | | if (a.hasValue() && !a.isMultiValued()) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_NOT_MULTIVALUED_FOR_LONG_ID.get(origArgName); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if (argValue != null) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_ARG_FOR_LONG_ID_DOESNT_TAKE_VALUE.get( |
| | | origArgName); |
| | | throw new ArgumentException(message); |
| | |
| | | // -n value |
| | | if (arg.equals("-")) |
| | | { |
| | | Message message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT.get(); |
| | | LocalizableMessage message = ERR_ARGPARSER_INVALID_DASH_AS_ARGUMENT.get(); |
| | | throw new ArgumentException(message); |
| | | } |
| | | |
| | |
| | | else |
| | | { |
| | | // There is no such argument registered. |
| | | Message message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get( |
| | | String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | if ((i+1) == numArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_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_ARGPARSER_VALUE_UNACCEPTABLE_FOR_SHORT_ID. |
| | | LocalizableMessage message = ERR_ARGPARSER_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_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_NOT_MULTIVALUED_FOR_SHORT_ID.get( |
| | | String.valueOf(argCharacter)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | if (b == null) |
| | | { |
| | | // There is no such argument registered. |
| | | Message message = ERR_ARGPARSER_NO_ARGUMENT_WITH_SHORT_ID.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_NO_ARGUMENT_WITH_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_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES.get( |
| | | LocalizableMessage message = ERR_ARGPARSER_CANT_MIX_ARGS_WITH_VALUES.get( |
| | | String.valueOf(argCharacter), argValue, String.valueOf(c)); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | // It doesn't start with a dash and we don't allow trailing arguments, |
| | | // so this is illegal. |
| | | Message message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg); |
| | | LocalizableMessage message = ERR_ARGPARSER_DISALLOWED_TRAILING_ARGUMENT.get(arg); |
| | | throw new ArgumentException(message); |
| | | } |
| | | } |
| | |
| | | && minTrailingArguments > 0 |
| | | && trailingArguments.size() < minTrailingArguments) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_TOO_FEW_TRAILING_ARGUMENTS.get(minTrailingArguments); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | { |
| | | String value = |
| | | argumentProperties.getProperty(a.getPropertyName().toLowerCase()); |
| | | MessageBuilder invalidReason = new MessageBuilder(); |
| | | LocalizableMessageBuilder invalidReason = new LocalizableMessageBuilder(); |
| | | if (value != null) |
| | | { |
| | | Boolean addValue = true; |
| | |
| | | // a problem. |
| | | if (!a.hasValue() && a.isRequired()) |
| | | { |
| | | Message message = |
| | | LocalizableMessage message = |
| | | ERR_ARGPARSER_NO_VALUE_FOR_REQUIRED_ARG.get(a.getName()); |
| | | throw new ArgumentException(message); |
| | | } |
| | |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(String |
| | | LocalizableMessage message = ERR_ARGPARSER_CANNOT_READ_PROPERTIES_FILE.get(String |
| | | .valueOf(propertiesFilePath), getExceptionMessage(e)); |
| | | throw new ArgumentException(message, e); |
| | | } |
| | |
| | | if (argGroup.containsArguments() && printHeaders) |
| | | { |
| | | // 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); |
| | |
| | | * @return A string containing usage information based on the defined |
| | | * arguments. |
| | | */ |
| | | public Message getUsageMessage() |
| | | public LocalizableMessage getUsageMessage() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | | getUsage(buffer); |
| | | |
| | | // TODO: rework getUsage(OutputStream) to work with messages framework |
| | | return Message.raw(buffer.toString()); |
| | | return LocalizableMessage.raw(buffer.toString()); |
| | | } |
| | | |
| | | /** |
| | |
| | | * 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(String indent, Message text, StringBuilder buffer) |
| | | private void indentAndWrap(String indent, LocalizableMessage text, StringBuilder buffer) |
| | | { |
| | | int actualSize = MAX_LENGTH - indent.length() - 1; |
| | | if (text.length() <= actualSize) |