From 9b1384eb5e70df3e6bc1fec5aed5c841adbd094b Mon Sep 17 00:00:00 2001
From: Gaetan Boismal <gaetan.boismal@forgerock.com>
Date: Thu, 11 Feb 2016 13:46:57 +0000
Subject: [PATCH] OPENDJSDK-42 Cli arguments fluent builder

---
 opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java |  202 +++++++++++++++++--------------------------------
 1 files changed, 71 insertions(+), 131 deletions(-)

diff --git a/opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java b/opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java
index 92b3b9e..05542ef 100644
--- a/opendj-sdk/opendj-cli/src/main/java/com/forgerock/opendj/cli/MultiChoiceArgument.java
+++ b/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;
     }

--
Gitblit v1.10.0