Author: jholmes
Date: Tue Jul 24 11:15:13 2007
New Revision: 559146

URL: http://svn.apache.org/viewvc?view=rev&rev=559146
Log:
WW-1938 Bug with multiple s:param tags inside s:url tag

Modified:
    
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/Component.java
    
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/URL.java
    
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
    
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
    struts/struts2/branches/STRUTS_2_0_X/core/src/site/resources/tags/url.html
    
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
    
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/Component.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/Component.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/Component.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/Component.java
 Tue Jul 24 11:15:13 2007
@@ -338,12 +338,13 @@
      */
     protected String determineActionURL(String action, String namespace, 
String method,
                                         HttpServletRequest req, 
HttpServletResponse res, Map parameters, String scheme,
-                                        boolean includeContext, boolean 
encodeResult) {
+                                        boolean includeContext, boolean 
encodeResult, boolean forceAddSchemeHostAndPort,
+                                        boolean escapeAmp) {
         String finalAction = findString(action);
         String finalNamespace = determineNamespace(namespace, getStack(), req);
         ActionMapping mapping = new ActionMapping(finalAction, finalNamespace, 
method, parameters);
         String uri = actionMapper.getUriFromActionMapping(mapping);
-        return UrlHelper.buildUrl(uri, req, res, parameters, scheme, 
includeContext, encodeResult);
+        return UrlHelper.buildUrl(uri, req, res, parameters, scheme, 
includeContext, encodeResult, forceAddSchemeHostAndPort, escapeAmp);
     }
 
     /**

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/URL.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/URL.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/URL.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/components/URL.java
 Tue Jul 24 11:15:13 2007
@@ -53,6 +53,12 @@
  * additional request parameters.</p>
  *
  * <b>NOTE:</b>
+ * <p>By default request parameters will be separated using escaped ampersands 
(i.e., &amp;amp;).
+ * This is necessary for XHTML compliance, however, when using the URL 
generated by this tag
+ * with the &lt;s:property&gt; tag, the <b>escapeAmp</b> attribute should be 
used to disable
+ * ampersand escaping.</p>
+ *
+ * <b>NOTE:</b>
  * <p>When includeParams is 'all' or 'get', the parameter defined in param tag 
will take
  * precedence and will not be overriden if they exists in the parameter 
submitted. For
  * example, in Example 3 below, if there is a id parameter in the url where 
the page this
@@ -68,16 +74,20 @@
  * <ul>
  *      <li>action (String) - (value or action choose either one, if both 
exist value takes precedence) action's name (alias) <li>
  *      <li>value (String) - (value or action choose either one, if both exist 
value takes precedence) the url itself</li>
- *      <li>scheme (String) - http scheme (http, https) default to the scheme 
this request is in</li>
+ *      <li>scheme (String) - http scheme (http, https) defaults to the scheme 
this request is in</li>
  *      <li>namespace - action's namespace</li>
- *      <li>method (String) - action's method, default to execute() </li>
- *      <li>encode (Boolean) - url encode the generated url. Default is 
true</li>
- *      <li>includeParams (String) - The includeParams attribute may have the 
value 'none', 'get' or 'all'. Default is 'get'.
+ *      <li>method (String) - action's method name, defaults to 'execute'</li>
+ *      <li>encode (Boolean) - url encode the generated url. Defaults to 
'true'.</li>
+ *      <li>includeParams (String) - The includeParams attribute may have the 
value 'none', 'get' or 'all'. Defaults to 'get'.
  *                                   none - include no parameters in the URL
  *                                   get  - include only GET parameters in the 
URL (default)
  *                                   all  - include both GET and POST 
parameters in the URL
  *      </li>
- *      <li>includeContext (Boolean) - determine wheather to include the web 
app context path. Default is true.</li>
+ *      <li>includeContext (Boolean) - Specifies whether to include the web 
app context path. Defaults to 'true'.</li>
+ *      <li>escapeAmp (Boolean) - Specifies whether to escape ampersand 
(&amp;) to (&amp;amp;) or not. Defaults to 'true'.</li>
+ *      <li>portletMode (String) - The resulting portlet mode.</li>
+ *      <li>windowState (String) - The resulting portlet window state.</li>
+ *      <li>portletUrlType (String) - Specifies if this should be a portlet 
render or action URL.</li>
  * </ul>
  *
  * <!-- END SNIPPET: params -->
@@ -135,6 +145,7 @@
     protected String method;
     protected boolean encode = true;
     protected boolean includeContext = true;
+    protected boolean escapeAmp = true;
     protected String portletMode;
     protected String windowState;
     protected String portletUrlType;
@@ -240,7 +251,7 @@
                 result = PortletUrlHelper.buildUrl(action, namespace, 
parameters, portletUrlType, portletMode, windowState);
             }
             else {
-                result = determineActionURL(action, namespace, method, req, 
res, parameters, scheme, includeContext, encode);
+                result = determineActionURL(action, namespace, method, req, 
res, parameters, scheme, includeContext, encode, false, escapeAmp);
             }
         } else {
             if(Dispatcher.getInstance().isPortletSupportActive() && 
PortletActionContext.isPortletRequest()) {
@@ -254,7 +265,7 @@
                 if (_value != null && _value.indexOf("?") > 0) {
                     _value = _value.substring(0, _value.indexOf("?"));
                 }
-                result = UrlHelper.buildUrl(_value, req, res, parameters, 
scheme, includeContext, encode);
+                result = UrlHelper.buildUrl(_value, req, res, parameters, 
scheme, includeContext, encode, false, escapeAmp);
             }
         }
         if ( anchor != null && anchor.length() > 0 ) {
@@ -336,6 +347,11 @@
     @StrutsTagAttribute(description="The anchor for this URL")
     public void setAnchor(String anchor) {
         this.anchor = anchor;
+    }
+
+    @StrutsTagAttribute(description="Specifies whether to escape ampersand 
(&amp;) to (&amp;amp;) or not", type="Boolean", defaultValue="true")
+    public void setEscapeAmp(boolean escapeAmp) {
+        this.escapeAmp = escapeAmp;
     }
 
 

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
 Tue Jul 24 11:15:13 2007
@@ -44,6 +44,7 @@
     protected String method;
     protected String encode;
     protected String includeContext;
+    protected String escapeAmp;
     protected String portletMode;
     protected String windowState;
     protected String portletUrlType;
@@ -74,6 +75,9 @@
         if (includeContext != null) {
             
url.setIncludeContext(Boolean.valueOf(includeContext).booleanValue());
         }
+        if (escapeAmp != null) {
+            url.setEscapeAmp(Boolean.valueOf(escapeAmp).booleanValue());
+        }
     }
 
     public void setEncode(String encode) {
@@ -82,6 +86,10 @@
 
     public void setIncludeContext(String includeContext) {
         this.includeContext = includeContext;
+    }
+
+    public void setEscapeAmp(String escapeAmp) {
+        this.escapeAmp = escapeAmp;
     }
 
     public void setIncludeParams(String name) {

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
 Tue Jul 24 11:15:13 2007
@@ -91,6 +91,10 @@
     }
 
     public static String buildUrl(String action, HttpServletRequest request, 
HttpServletResponse response, Map params, String scheme, boolean 
includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort) {
+        return buildUrl(action, request, response, params, scheme, 
includeContext, encodeResult, forceAddSchemeHostAndPort, true);
+    }
+
+    public static String buildUrl(String action, HttpServletRequest request, 
HttpServletResponse response, Map params, String scheme, boolean 
includeContext, boolean encodeResult, boolean forceAddSchemeHostAndPort, 
boolean escapeAmp) {
         StringBuffer link = new StringBuffer();
 
         boolean changedScheme = false;
@@ -169,7 +173,11 @@
         }
 
         //if the action was not explicitly set grab the params from the request
-        buildParametersString(params, link);
+        if (escapeAmp) {
+            buildParametersString(params, link);
+        } else {
+            buildParametersString(params, link, "&");
+        }
 
         String result;
 

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/site/resources/tags/url.html
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/site/resources/tags/url.html?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- struts/struts2/branches/STRUTS_2_0_X/core/src/site/resources/tags/url.html 
(original)
+++ struts/struts2/branches/STRUTS_2_0_X/core/src/site/resources/tags/url.html 
Tue Jul 24 11:15:13 2007
@@ -52,6 +52,14 @@
                                        <td align="left" valign="top">Whether 
to encode parameters</td>
                                </tr>
                                <tr>
+                                       <td align="left" 
valign="top">escapeAmp</td>
+                                       <td align="left" valign="top">false</td>
+                                       <td align="left" valign="top">true</td>
+                                       <td align="left" valign="top">true</td>
+                                       <td align="left" 
valign="top">Boolean</td>
+                                       <td align="left" valign="top">Specifies 
whether to escape ampersand (&amp;) to (&amp;amp;) or not</td>
+                               </tr>
+                               <tr>
                                        <td align="left" valign="top">id</td>
                                        <td align="left" valign="top">false</td>
                                        <td align="left" valign="top"></td>

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
 Tue Jul 24 11:15:13 2007
@@ -348,6 +348,19 @@
         assertEquals("/team.action?section=team&amp;company=acme+inc", 
writer.toString());
     }
 
+    public void testRequestURIActionIncludeGetDoNotEscapeAmp() throws 
Exception {
+        request.setRequestURI("/public/about");
+        request.setQueryString("section=team&company=acme inc");
+
+        tag.setAction("team");
+        tag.setIncludeParams("get");
+        tag.setEscapeAmp("false");
+        tag.doStartTag();
+        tag.doEndTag();
+
+        assertEquals("/team.action?section=team&company=acme+inc", 
writer.toString());
+    }
+    
     public void testRequestURINoActionIncludeNone() throws Exception {
         request.setRequestURI("/public/about");
         request.setQueryString("section=team&company=acme inc");

Modified: 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java?view=diff&rev=559146&r1=559145&r2=559146
==============================================================================
--- 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
 (original)
+++ 
struts/struts2/branches/STRUTS_2_0_X/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
 Tue Jul 24 11:15:13 2007
@@ -144,6 +144,22 @@
         assertEquals(expectedString, urlString);
     }
 
+    public void testBuildUrlCorrectlyAddsDoNotEscapeAmp() {
+        String expectedString = "my.actionName?foo=bar&hello=world";
+        Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);
+        mockHttpServletRequest.expectAndReturn("getScheme", "http");
+        Mock mockHttpServletResponse = new Mock(HttpServletResponse.class);
+        mockHttpServletResponse.expectAndReturn("encodeURL", expectedString, 
expectedString);
+
+        String actionName = "my.actionName";
+        TreeMap params = new TreeMap();
+        params.put("hello", "world");
+        params.put("foo", "bar");
+
+        String urlString = UrlHelper.buildUrl(actionName, (HttpServletRequest) 
mockHttpServletRequest.proxy(), (HttpServletResponse) 
mockHttpServletResponse.proxy(), params, null, true, true, false, false);
+        assertEquals(expectedString, urlString);
+    }
+
     public void testBuildUrlWithStringArray() {
         String expectedString = 
"my.actionName?foo=bar&amp;hello=earth&amp;hello=mars";
         Mock mockHttpServletRequest = new Mock(HttpServletRequest.class);


Reply via email to