[Stripes-dev] SF.net SVN: stripes: [442] trunk

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[Stripes-dev] SF.net SVN: stripes: [442] trunk

tfenne
Revision: 442
          http://svn.sourceforge.net/stripes/?rev=442&view=rev
Author:   tfenne
Date:     2006-10-14 11:10:45 -0700 (Sat, 14 Oct 2006)

Log Message:
-----------
Fix for STS-244: Redirect/ForwardResolution.addParameter doesn't work correctly if called repeatedly with the same parameter name.

Modified Paths:
--------------
    trunk/stripes/src/net/sourceforge/stripes/action/OnwardResolution.java
    trunk/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java
    trunk/tests/src/net/sourceforge/stripes/util/UrlBuilderTest.java

Modified: trunk/stripes/src/net/sourceforge/stripes/action/OnwardResolution.java
===================================================================
--- trunk/stripes/src/net/sourceforge/stripes/action/OnwardResolution.java 2006-10-14 14:26:20 UTC (rev 441)
+++ trunk/stripes/src/net/sourceforge/stripes/action/OnwardResolution.java 2006-10-14 18:10:45 UTC (rev 442)
@@ -14,10 +14,12 @@
  */
 package net.sourceforge.stripes.action;
 
+import net.sourceforge.stripes.controller.StripesFilter;
 import net.sourceforge.stripes.util.UrlBuilder;
-import net.sourceforge.stripes.controller.StripesFilter;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -89,29 +91,48 @@
     }
 
     /**
-     * Adds a request parameter with zero or more values to the URL.  Values may
+     * <p>Adds a request parameter with zero or more values to the URL.  Values may
      * be supplied using varargs, or alternatively by suppling a single value parameter which is
-     * an instance of Collection.
+     * an instance of Collection.</p>
      *
+     * <p>Note that this method is additive. Therefore writing things like
+     * {@code builder.addParameter("p", "one").addParameter("p", "two");}
+     * will add both {@code p=one} and {@code p=two} to the URL.</p>
+     *
      * @param name the name of the URL parameter
      * @param values zero or more scalar values, or a single Collection
      * @return this Resolution so that methods can be chained
      */
     public T addParameter(String name, Object... values) {
-        this.parameters.put(name, values);
+        if (this.parameters.containsKey(name)) {
+            List<Object> temp = Arrays.asList(values);
+            temp.add(this.parameters.get(name));
+            this.parameters.put(name, temp);
+        }
+        else {
+            this.parameters.put(name, values);
+        }
+
         return (T) this;
     }
 
     /**
-     * Bulk adds one or more request parameters to the URL. Each entry in the Map
+     * <p>Bulk adds one or more request parameters to the URL. Each entry in the Map
      * represents a single named parameter, with the values being either a scalar value,
-     * an array or a Collection.
+     * an array or a Collection.</p>
      *
+     * <p>Note that this method is additive. If a parameter with name X has already been
+     * added and the map contains X as a key, the value(s) in the map will be added to the
+     * URL as well as the previously held values for X.</p>
+     *
      * @param parameters a Map of parameters as described above
      * @return this Resolution so that methods can be chained
      */
     public T addParameters(Map<String,Object> parameters) {
-        this.parameters.putAll(parameters);
+        for (Map.Entry<String,Object> entry : parameters.entrySet()) {
+            addParameter(entry.getKey(), entry.getValue());
+        }
+
         return (T) this;
     }
 

Modified: trunk/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java
===================================================================
--- trunk/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java 2006-10-14 14:26:20 UTC (rev 441)
+++ trunk/stripes/src/net/sourceforge/stripes/util/UrlBuilder.java 2006-10-14 18:10:45 UTC (rev 442)
@@ -93,39 +93,44 @@
      * null, and if so generates a parameter with no value.  URL Encodes the parameter values
      * to make sure that it is safe to insert into the URL.</p>
      *
-     * <p>If a single parameter value is passed, and the value is a Collection, then a parameter
-     * will be added to the URL for each entry in the collection.</p.
+     * <p>If any parameter value passed is a Collection or an Array then this method is called
+     * recursively with the contents of the collection or array. As a result you can pass
+     * arbitrarily nested arrays and collections to this method and it will recurse through them
+     * adding all scalar values as parameters to the URL.</p.
      *
      * @param name the name of the request parameter being added
-     * @param values one or more scalar values for the parameter supplied, or a single Collection
+     * @param values one or more values for the parameter supplied
      */
     public void addParameter(String name, Object... values) {
         try {
-            // Do a little special case checking to see if we were really passed
-            // a collection instead of one or more scalar values
-            if (values != null && values.length == 1 && values[0] instanceof Collection) {
-                values = ((Collection) values[0]).toArray();
-            }
-
             // If values is null or empty, then simply sub in a single empty string
             if (values == null || values.length == 0) {
                 values = Literal.array("");
             }
 
             for (Object v : values) {
-                // Figure out whether we already have params or not
-                if (!this.seenQuestionMark) {
-                    this.url.append('?');
-                    this.seenQuestionMark = true;
+                // Special case: recurse for nested collections and arrays!
+                if (v instanceof Collection) {
+                    addParameter(name, ((Collection) v).toArray());
                 }
+                else if (v.getClass().isArray()) {
+                    addParameter(name, (Object[]) v);
+                }
                 else {
-                    this.url.append(this.parameterSeparator);
-                }
+                    // Figure out whether we already have params or not
+                    if (!this.seenQuestionMark) {
+                        this.url.append('?');
+                        this.seenQuestionMark = true;
+                    }
+                    else {
+                        this.url.append(this.parameterSeparator);
+                    }
 
-                this.url.append(name);
-                this.url.append('=');
-                if (v != null) {
-                    this.url.append( URLEncoder.encode(v.toString(), "UTF-8") );
+                    this.url.append(name);
+                    this.url.append('=');
+                    if (v != null) {
+                        this.url.append( URLEncoder.encode(v.toString(), "UTF-8") );
+                    }
                 }
             }
         }

Modified: trunk/tests/src/net/sourceforge/stripes/util/UrlBuilderTest.java
===================================================================
--- trunk/tests/src/net/sourceforge/stripes/util/UrlBuilderTest.java 2006-10-14 14:26:20 UTC (rev 441)
+++ trunk/tests/src/net/sourceforge/stripes/util/UrlBuilderTest.java 2006-10-14 18:10:45 UTC (rev 442)
@@ -135,4 +135,19 @@
         Assert.assertEquals(result,
                             "/test/page.jsp?one=one&two=2&two=two&three=3&three=three");
     }
+
+    @Test(groups="fast")
+    public void testUrlWithRepeatedParameters() throws Exception {
+        String path = "/test/page.jsp";
+        UrlBuilder builder = new UrlBuilder(path, false);
+        builder.addParameter("one", "one");
+        builder.addParameter("one", "two", "three");
+        builder.addParameter("one", "four");
+
+        String result = builder.toString();
+        Assert.assertTrue(result.contains("one=one"));
+        Assert.assertTrue(result.contains("one=two"));
+        Assert.assertTrue(result.contains("one=three"));
+        Assert.assertTrue(result.contains("one=four"));
+    }
 }


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development