You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2013/02/11 11:14:05 UTC

svn commit: r1444720 - in /commons/proper/cli/trunk/src: changes/ main/java/org/apache/commons/cli/ test/java/org/apache/commons/cli/

Author: tn
Date: Mon Feb 11 10:14:05 2013
New Revision: 1444720

URL: http://svn.apache.org/r1444720
Log:
[CLI-224] Added new fluent builder API to Option, deprecating OptionBuilder, adapting the PatternOptionBuilder to use the new API, thanks to Duncan Jones.

Modified:
    commons/proper/cli/trunk/src/changes/changes.xml
    commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/Option.java
    commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/OptionBuilder.java
    commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java
    commons/proper/cli/trunk/src/test/java/org/apache/commons/cli/OptionTest.java

Modified: commons/proper/cli/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/changes/changes.xml?rev=1444720&r1=1444719&r2=1444720&view=diff
==============================================================================
--- commons/proper/cli/trunk/src/changes/changes.xml (original)
+++ commons/proper/cli/trunk/src/changes/changes.xml Mon Feb 11 10:14:05 2013
@@ -23,6 +23,10 @@
   <body>
     
     <release version="1.3" date="in SVN">
+      <action type="add" dev="tn" issue="CLI-224" due-to="Duncan Jones, Brian Blount">
+        Added new fluent API to create Option instances via builder class Option.Builder.
+        This replaces the now deprecated OptionBuilder.
+      </action>
       <action type="fix" dev="tn" issue="CLI-218" due-to="Sven">
         Clarify javadoc for CommandLine.getOptionValue() that the first specified
         argument will be returned.

Modified: commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/Option.java
URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/Option.java?rev=1444720&r1=1444719&r2=1444720&view=diff
==============================================================================
--- commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/Option.java (original)
+++ commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/Option.java Mon Feb 11 10:14:05 2013
@@ -77,6 +77,24 @@ public class Option implements Cloneable
     private char valuesep;
 
     /**
+     * Private constructor used by the nested Builder class.
+     * 
+     * @param builder builder used to create this option
+     */
+    private Option(final Builder builder)
+    {
+        this.argName = builder.argName;
+        this.description = builder.description;
+        this.longOpt = builder.longOpt;
+        this.numberOfArgs = builder.numberOfArgs;
+        this.opt = builder.opt;
+        this.optionalArg = builder.optionalArg;
+        this.required = builder.required;
+        this.type = builder.type;
+        this.valuesep = builder.valuesep;
+    }
+    
+    /**
      * Creates an Option using the specified parameters.
      * The option does not take an argument.
      *
@@ -727,4 +745,174 @@ public class Option implements Cloneable
             return acceptsArg();
         }
     }
+    
+    /**
+     * A nested builder class to create <code>Option</code> instances
+     * using descriptive methods.
+     * <p>
+     * Example usage:
+     * <pre>
+     * Option option = new Option.Builder("a", "Long description")
+     *     .required(true)
+     *     .longOpt("arg-name")
+     *     .build();
+     * </pre>
+     * 
+     * @since 1.3
+     */
+    public static class Builder 
+    {
+        /** the name of the option */
+        private final String opt;
+
+        /** description of the option */
+        private final String description;
+
+        /** the long representation of the option */
+        private String longOpt;
+
+        /** the name of the argument for this option */
+        private String argName;
+
+        /** specifies whether this option is required to be present */
+        private boolean required;
+
+        /** specifies whether the argument value of this Option is optional */
+        private boolean optionalArg;
+
+        /** the number of argument values this option can have */
+        private int numberOfArgs = UNINITIALIZED;
+
+        /** the type of this Option */
+        private Class<?> type = String.class;
+
+        /** the character that is the value separator */
+        private char valuesep;
+
+        /**
+         * Constructs a new <code>Builder</code> with the minimum
+         * required parameters for an <code>Option</code> instance.
+         * 
+         * @param opt short representation of the option
+         * @param description describes the function of the option
+         * @throws IllegalArgumentException if there are any non valid
+         * Option characters in <code>opt</code>.
+         */
+        public Builder(final String opt, final String description) 
+                throws IllegalArgumentException
+        {
+            OptionValidator.validateOption(opt);
+            this.opt = opt;
+            this.description = description;
+        }
+        
+        /**
+         * Sets the display name for the argument value.
+         *
+         * @param argName the display name for the argument value.
+         * @return this builder, to allow method chaining
+         */
+        public Builder argName(final String argName)
+        {
+            this.argName = argName;
+            return this;
+        }
+        
+        /**
+         * Sets the long name of the Option.
+         *
+         * @param longOpt the long name of the Option
+         * @return this builder, to allow method chaining
+         */        
+        public Builder longOpt(final String longOpt)
+        {
+            this.longOpt = longOpt;
+            return this;
+        }
+        
+        /** 
+         * Sets the number of argument values the Option can take.
+         *
+         * @param numberOfArgs the number of argument values
+         * @return this builder, to allow method chaining
+         */        
+        public Builder numberOfArgs(final int numberOfArgs)
+        {
+            this.numberOfArgs = numberOfArgs;
+            return this;
+        }
+        
+        /**
+         * Sets whether the Option can have an optional argument.
+         *
+         * @param isOptional specifies whether the Option can have
+         * an optional argument.
+         * @return this builder, to allow method chaining
+         */
+        public Builder optionalArg(final boolean isOptional)
+        {
+            this.optionalArg = isOptional;
+            return this;
+        }
+        
+        /**
+         * Sets whether the Option is mandatory.
+         *
+         * @param required specifies whether the Option is mandatory
+         * @return this builder, to allow method chaining
+         */
+        public Builder required(final boolean required)
+        {
+            this.required = required;
+            return this;
+        }
+        
+        /**
+         * Sets the type of the Option.
+         *
+         * @param type the type of the Option
+         * @return this builder, to allow method chaining
+         */
+        public Builder type(final Class<?> type)
+        {
+            this.type = type;
+            return this;
+        }
+        
+        /**
+         * Sets the value separator. For example if the argument value
+         * was a Java property, the value separator would be '='.
+         *
+         * @param sep The value separator.
+         * @return this builder, to allow method chaining
+         */
+        public Builder valueSeparator(final char sep)
+        {
+            valuesep = sep;
+            return this;
+        }
+        
+        /**
+         * Indicates if the Option has an argument or not.
+         * 
+         * @param hasArg specifies whether the Option takes an argument or not
+         * @return this builder, to allow method chaining
+         */
+        public Builder hasArg(final boolean hasArg)
+        {
+            // set to UNINITIALIZED when no arg is specified to be compatible with OptionBuilder
+            numberOfArgs = hasArg ? 1 : Option.UNINITIALIZED;
+            return this;
+        }
+        
+        /**
+         * Constructs an Option.
+         * 
+         * @return the new Option
+         */
+        public Option build()
+        {
+            return new Option(this);
+        }
+    }
 }

Modified: commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/OptionBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/OptionBuilder.java?rev=1444720&r1=1444719&r2=1444720&view=diff
==============================================================================
--- commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/OptionBuilder.java (original)
+++ commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/OptionBuilder.java Mon Feb 11 10:14:05 2013
@@ -27,7 +27,9 @@ package org.apache.commons.cli;
  * 
  * @version $Id$
  * @since 1.0
+ * @deprecated since 1.3, use {@link Option.Builder} instead
  */
+@Deprecated
 public final class OptionBuilder
 {
     /** long option */

Modified: commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java?rev=1444720&r1=1444719&r2=1444720&view=diff
==============================================================================
--- commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java (original)
+++ commons/proper/cli/trunk/src/main/java/org/apache/commons/cli/PatternOptionBuilder.java Mon Feb 11 10:14:05 2013
@@ -64,7 +64,7 @@ public class PatternOptionBuilder
     public static final Class<Date> DATE_VALUE = Date.class;
 
     /** Class class */
-    public static final Class CLASS_VALUE = Class.class;
+    public static final Class<?> CLASS_VALUE = Class.class;
 
     /// can we do this one??
     // is meant to check that the file exists, else it errors.
@@ -160,12 +160,14 @@ public class PatternOptionBuilder
             {
                 if (opt != ' ')
                 {
-                    OptionBuilder.hasArg(type != null);
-                    OptionBuilder.isRequired(required);
-                    OptionBuilder.withType(type);
-
+                    final Option option = new Option.Builder(String.valueOf(opt), null)
+                        .hasArg(type != null)
+                        .required(required)
+                        .type(type)
+                        .build();
+                    
                     // we have a previous one to deal with
-                    options.addOption(OptionBuilder.create(opt));
+                    options.addOption(option);
                     required = false;
                     type = null;
                     opt = ' ';
@@ -185,12 +187,14 @@ public class PatternOptionBuilder
 
         if (opt != ' ')
         {
-            OptionBuilder.hasArg(type != null);
-            OptionBuilder.isRequired(required);
-            OptionBuilder.withType(type);
-
+            final Option option = new Option.Builder(String.valueOf(opt), null)
+                .hasArg(type != null)
+                .required(required)
+                .type(type)
+                .build();
+            
             // we have a final one to deal with
-            options.addOption(OptionBuilder.create(opt));
+            options.addOption(option);
         }
 
         return options;

Modified: commons/proper/cli/trunk/src/test/java/org/apache/commons/cli/OptionTest.java
URL: http://svn.apache.org/viewvc/commons/proper/cli/trunk/src/test/java/org/apache/commons/cli/OptionTest.java?rev=1444720&r1=1444719&r2=1444720&view=diff
==============================================================================
--- commons/proper/cli/trunk/src/test/java/org/apache/commons/cli/OptionTest.java (original)
+++ commons/proper/cli/trunk/src/test/java/org/apache/commons/cli/OptionTest.java Mon Feb 11 10:14:05 2013
@@ -147,4 +147,57 @@ public class OptionTest
         assertEquals("foo", option.getValue(0));
         assertEquals("foo", option.getValue("default"));
     }
+    
+    @Test
+    public void testBuilderMethods()
+    {
+        char defaultSeparator = (char) 0;
+
+        checkOption(new Option.Builder("a",  "desc").build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").longOpt("aaa").build(),
+            "a", "desc", "aaa", Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").hasArg(true).build(),
+            "a", "desc", null, 1, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").hasArg(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").hasArg(true).build(),
+            "a", "desc", null, 1, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").numberOfArgs(3).build(),
+            "a", "desc", null, 3, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").required(true).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, true, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").required(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+
+        checkOption(new Option.Builder("a",  "desc").argName("arg1").build(),
+            "a", "desc", null, Option.UNINITIALIZED, "arg1", false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").optionalArg(false).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").optionalArg(true).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, true, defaultSeparator, String.class);
+        checkOption(new Option.Builder("a",  "desc").valueSeparator(':').build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, ':', String.class);
+        checkOption(new Option.Builder("a",  "desc").type(Integer.class).build(),
+            "a", "desc", null, Option.UNINITIALIZED, null, false, false, defaultSeparator, Integer.class);
+    }
+
+    private static void checkOption(Option option, String opt, String description, String longOpt, int numArgs,
+                                    String argName,  boolean required, boolean optionalArg,
+                                    char valueSeparator, Class<?> cls)
+    {
+        assertEquals(opt, option.getOpt());
+        assertEquals(description, option.getDescription());
+        assertEquals(longOpt, option.getLongOpt());
+        assertEquals(numArgs, option.getArgs());
+        assertEquals(argName, option.getArgName());
+        assertEquals(required, option.isRequired());
+
+        assertEquals(optionalArg, option.hasOptionalArg());
+        assertEquals(valueSeparator, option.getValueSeparator());
+        assertEquals(cls,  option.getType());
+    }
+    
 }