mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gaetan Boismal
26.03.2016 9b1384eb5e70df3e6bc1fec5aed5c841adbd094b
opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java
@@ -28,130 +28,87 @@
import static com.forgerock.opendj.cli.CliMessages.ERR_MCARG_VALUE_NOT_ALLOWED;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageBuilder;
/**
 * This class defines an argument type that will only accept one or more of a
 * specific set of string values.
 *
 * @param <T>
 * @param <V>
 *            The type of values returned by this argument.
 */
public final class MultiChoiceArgument<T> extends Argument {
    /**
     * Indicates whether argument values should be treated in a
     * case-sensitive manner.
     */
    private final boolean caseSensitive;
    /** The set of values that will be allowed for use with this argument. */
    private final Collection<T> allowedValues;
public final class MultiChoiceArgument<V> extends Argument {
    /**
     * Creates a new string argument with the provided information.
     * Returns a builder which can be used for incrementally constructing a new
     * {@link MultiChoiceArgument<V>}.
     *
     * @param name
     *            The generic name that should be used to refer to this
     *            argument.
     * @param shortIdentifier
     *            The single-character identifier for this argument, or
     *            <CODE>null</CODE> if there is none.
     * @param <V>
     *         The type of values returned by this argument.
     * @param longIdentifier
     *            The long identifier for this argument, or <CODE>null</CODE> if
     *            there is none.
     * @param isRequired
     *            Indicates whether this argument must be specified on the
     *            command line.
     * @param isMultiValued
     *            Indicates whether this argument may be specified more than
     *            once to provide multiple values.
     * @param needsValue
     *            Indicates whether this argument requires a value.
     * @param valuePlaceholder
     *            The placeholder for the argument value that will be displayed
     *            in usage information, or <CODE>null</CODE> if this argument
     *            does not require a value.
     * @param defaultValue
     *            The default value that should be used for this argument if
     *            none is provided in a properties file or on the command line.
     *            This may be <CODE>null</CODE> if there is no generic default.
     * @param propertyName
     *            The name of the property in a property file that may be used
     *            to override the default value but will be overridden by a
     *            command-line argument.
     * @param allowedValues
     *            The set of values that are allowed for use for this argument.
     *            If they are not to be treated in a case-sensitive value then
     *            they should all be formatted in lowercase.
     * @param caseSensitive
     *            Indicates whether the set of allowed values should be treated
     *            in a case-sensitive manner.
     * @param description
     *            LocalizableMessage for the description of this argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to
     *             create this argument.
     *         The generic long identifier that will be used to refer to this argument.
     * @return A builder to continue building the {@link MultiChoiceArgument}.
     */
    public MultiChoiceArgument(final String name, final Character shortIdentifier,
            final String longIdentifier, final boolean isRequired, final boolean isMultiValued,
            final boolean needsValue, final LocalizableMessage valuePlaceholder,
            final String defaultValue, final String propertyName,
            final Collection<T> allowedValues, final boolean caseSensitive,
            final LocalizableMessage description) throws ArgumentException {
        super(name, shortIdentifier, longIdentifier, isRequired, isMultiValued, needsValue,
                valuePlaceholder, defaultValue, propertyName, description);
        this.allowedValues = allowedValues;
        this.caseSensitive = caseSensitive;
    public static <V> Builder<V> builder(final String longIdentifier) {
        return new Builder<>(longIdentifier);
    }
    /**
     * Creates a new string argument with the provided information.
     *
     * @param name
     *            The generic name that should be used to refer to this
     *            argument.
     * @param shortIdentifier
     *            The single-character identifier for this argument, or
     *            <CODE>null</CODE> if there is none.
     * @param longIdentifier
     *            The long identifier for this argument, or <CODE>null</CODE> if
     *            there is none.
     * @param isRequired
     *            Indicates whether this argument must be specified on the
     *            command line.
     * @param needsValue
     *            Indicates whether this argument requires a value.
     * @param valuePlaceholder
     *            The placeholder for the argument value that will be displayed
     *            in usage information, or <CODE>null</CODE> if this argument
     *            does not require a value.
     * @param allowedValues
     *            The set of values that are allowed for use for this argument.
     *            If they are not to be treated in a case-sensitive value then
     *            they should all be formatted in lowercase.
     * @param caseSensitive
     *            Indicates whether the set of allowed values should be treated
     *            in a case-sensitive manner.
     * @param description
     *            LocalizableMessage for the description of this argument.
     * @throws ArgumentException
     *             If there is a problem with any of the parameters used to
     *             create this argument.
     */
    public MultiChoiceArgument(final String name, final Character shortIdentifier,
            final String longIdentifier, final boolean isRequired, final boolean needsValue,
            final LocalizableMessage valuePlaceholder, final Collection<T> allowedValues,
            final boolean caseSensitive, final LocalizableMessage description)
            throws ArgumentException {
        super(name, shortIdentifier, longIdentifier, isRequired, false, needsValue,
                valuePlaceholder, null, null, description);
    /** A fluent API for incrementally constructing {@link MultiChoiceArgument<V>}. */
    public static final class Builder<V> extends ArgumentBuilder<Builder<V>, V, MultiChoiceArgument<V>> {
        private final List<V> allowedValues = new LinkedList<>();
        private Builder(final String longIdentifier) {
            super(longIdentifier);
        }
        @Override
        Builder<V> getThis() {
            return this;
        }
        /**
         * Specifies the set of values that are allowed for the {@link MultiChoiceArgument<V>}.
         *
         * @param allowedValues
         *         The {@link MultiChoiceArgument<V>} allowed values.
         * @return This builder.
         */
        public Builder<V> allowedValues(final Collection<V> allowedValues) {
            this.allowedValues.addAll(allowedValues);
            return getThis();
        }
        /**
         * Specifies the set of values that are allowed for the {@link MultiChoiceArgument<V>}.
         *
         * @param allowedValues
         *         The {@link MultiChoiceArgument<V>} allowed values.
         * @return This builder.
         */
        @SuppressWarnings("unchecked")
        public final Builder<V> allowedValues(final V... allowedValues) {
            this.allowedValues.addAll(Arrays.asList(allowedValues));
            return getThis();
        }
        @Override
        public MultiChoiceArgument<V> buildArgument() throws ArgumentException {
            return new MultiChoiceArgument<>(this, allowedValues);
        }
    }
    /** The set of values that will be allowed for use with this argument. */
    private final Collection<V> allowedValues;
    private <V1> MultiChoiceArgument(final Builder<V1> builder, final Collection<V> allowedValues)
            throws ArgumentException {
        super(builder);
        this.allowedValues = allowedValues;
        this.caseSensitive = caseSensitive;
    }
    /**
@@ -164,32 +121,17 @@
     * @throws ArgumentException
     *             The value cannot be parsed.
     */
    public T getTypedValue() throws ArgumentException {
    public V getTypedValue() throws ArgumentException {
        final String v = super.getValue();
        if (v == null) {
            return null;
        }
        for (final T o : allowedValues) {
            if ((caseSensitive && o.toString().equals(v)) || o.toString().equalsIgnoreCase(v)) {
                return o;
        for (final V allowedValue : allowedValues) {
            if (allowedValue.toString().equalsIgnoreCase(v)) {
                return allowedValue;
            }
        }
        // TODO: Some message
        throw new ArgumentException(null);
    }
    /**
     * Specifies the default value that will be used for this argument if it is
     * not specified on the command line and it is not set from a properties
     * file.
     *
     * @param defaultValue
     *            The default value that will be used for this argument if it is
     *            not specified on the command line and it is not set from a
     *            properties file.
     */
    public void setDefaultValue(final T defaultValue) {
        super.setDefaultValue(defaultValue.toString());
        throw new IllegalStateException("This MultiChoiceArgument value is not part of the allowed values.");
    }
    /**
@@ -205,15 +147,13 @@
     *         <CODE>false</CODE> if it is not.
     */
    @Override
    public boolean valueIsAcceptable(final String valueString,
            final LocalizableMessageBuilder invalidReason) {
        for (final T o : allowedValues) {
            if ((caseSensitive && o.toString().equals(valueString))
                    || o.toString().equalsIgnoreCase(valueString)) {
    public boolean valueIsAcceptable(final String valueString, final LocalizableMessageBuilder invalidReason) {
        for (final V allowedValue : allowedValues) {
            if (allowedValue.toString().equalsIgnoreCase(valueString)) {
                return true;
            }
        }
        invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED.get(getName(), valueString));
        invalidReason.append(ERR_MCARG_VALUE_NOT_ALLOWED.get(longIdentifier, valueString));
        return false;
    }