You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2006/03/31 07:44:05 UTC

svn commit: r390335 - in /struts/action/trunk/src: java/org/apache/struts/action/ActionRedirect.java test/org/apache/struts/action/TestActionRedirect.java

Author: mrdon
Date: Thu Mar 30 21:43:56 2006
New Revision: 390335

URL: http://svn.apache.org/viewcvs?rev=390335&view=rev
Log:
Adding anchor support, method chaining, and better ActionForward copying to ActionRedirect.
Thanks to Frank W. Zammetti and Christopher Schultz for the analysis and patches!
PR: 36037
BTW, sorry about the ActionRedirect diff, had problems with line endings

Modified:
    struts/action/trunk/src/java/org/apache/struts/action/ActionRedirect.java
    struts/action/trunk/src/test/org/apache/struts/action/TestActionRedirect.java

Modified: struts/action/trunk/src/java/org/apache/struts/action/ActionRedirect.java
URL: http://svn.apache.org/viewcvs/struts/action/trunk/src/java/org/apache/struts/action/ActionRedirect.java?rev=390335&r1=390334&r2=390335&view=diff
==============================================================================
--- struts/action/trunk/src/java/org/apache/struts/action/ActionRedirect.java (original)
+++ struts/action/trunk/src/java/org/apache/struts/action/ActionRedirect.java Thu Mar 30 21:43:56 2006
@@ -1,300 +1,344 @@
-/*
- * $Id$
- *
- * Copyright 2000-2004 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.struts.action;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.struts.config.ForwardConfig;
-import org.apache.struts.util.ResponseUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * <p> A subclass of {@link ActionForward} which is designed for use in
- * redirecting requests, with support for adding parameters at runtime. <br/>
- * An {@link ForwardConfig} (or subclass) can be passed to the constructor to
- * copy its configuration: </p> <p>
- * <pre>
- * public ActionForward execute(ActionMapping mapping,
- *                              ActionForm form,
- *                              HttpServletRequest request,
- *                              HttpServletResponse response)
- *         throws Exception {
- *     ActionRedirect redirect =
- *             new ActionRedirect(mapping.findForward("doRedirect"));
- *     redirect.addParameter("param1","value1");
- *     redirect.addParameter("param2","2");
- *     redirect.addParameter("param3","3.0");
- *     return redirect;
- * }
- * </pre>
- * </p>
- *
- * @version $Rev$ $Date$
- */
-public class ActionRedirect extends ActionForward {
-    // ----------------------------------------------------- Manifest constants
-
-    /**
-     * <p>Default allocation size for string buffers.</p>
-     */
-    private static final int DEFAULT_BUFFER_SIZE = 256;
-
-    // ----------------------------------------------------- Static variables
-
-    /**
-     * <p>Commons logging instance.</p>
-     */
-    protected static final Log LOG = LogFactory.getLog(ActionRedirect.class);
-
-    // ----------------------------------------------------- Instance variables
-
-    /**
-     * <p>Holds the redirect parameters. Each entry is either a String or a
-     * String[] depending on whether it has one or more entries.</p>
-     */
-    protected Map parameterValues = null;
-
-    // ----------------------------------------------------- Constructors
-
-    /**
-     * <p>Construct a new instance with redirect set to true and initialize
-     * parameter lists.</p>
-     */
-    public ActionRedirect() {
-        setRedirect(true);
-        initializeParameters();
-    }
-
-    /**
-     * <p>Construct a new instance with the specified path and initialize
-     * parameter lists.</p>
-     *
-     * @param path Path for this instance
-     */
-    public ActionRedirect(String path) {
-        super(path);
-        setRedirect(true);
-        initializeParameters();
-    }
-
-    /**
-     * <p>Construct a new instance with the specified values and initialize
-     * parameter lists.</p>
-     *
-     * @param name   Name of this instance
-     * @param path   Path for this instance
-     * @param module Module prefix, if any
-     */
-    public ActionRedirect(String name, String path, String module) {
-        super(name, path, true);
-        setModule(module);
-        initializeParameters();
-    }
-
-    /**
-     * <p>Construct a new instance with a {@link ForwardConfig} object to copy
-     * name, path, and contextRelative values from.</p>
-     *
-     * @param baseConfig the {@link ForwardConfig} to copy configuration
-     *                   values from
-     */
-    public ActionRedirect(ForwardConfig baseConfig) {
-        setName(baseConfig.getName());
-        setPath(baseConfig.getPath());
-        setModule(baseConfig.getModule());
-        setRedirect(true);
-        initializeParameters();
-    }
-
-    // ----------------------------------------------------- Private methods
-
-    /**
-     * <p>Initializes the internal objects used to hold parameter values.</p>
-     */
-    private void initializeParameters() {
-        parameterValues = new HashMap();
-    }
-
-    // ----------------------------------------------------- Public methods
-
-    /**
-     * <p>Adds the object's toString() to the list of parameters if it's not
-     * null, or an empty string with the given fieldName if it is.</p>
-     *
-     * @param fieldName the name to use for the parameter
-     * @param valueObj  the value for this parameter
-     */
-    public void addParameter(String fieldName, Object valueObj) {
-        String value = (valueObj != null) ? valueObj.toString() : "";
-
-        if (parameterValues == null) {
-            initializeParameters();
-        }
-
-        //try {
-        value = ResponseUtils.encodeURL(value);
-
-        //} catch (UnsupportedEncodingException uce) {
-        // this shouldn't happen since UTF-8 is the W3C Recommendation
-        //     String errorMsg = "UTF-8 Character Encoding not supported";
-        //     LOG.error(errorMsg, uce);
-        //     throw new RuntimeException(errorMsg, uce);
-        // }
-        Object currentValue = parameterValues.get(fieldName);
-
-        if (currentValue == null) {
-            // there's no value for this param yet; add it to the map
-            parameterValues.put(fieldName, value);
-        } else if (currentValue instanceof String) {
-            // there's already a value; let's use an array for these parameters
-            String[] newValue = new String[2];
-
-            newValue[0] = (String) currentValue;
-            newValue[1] = value;
-            parameterValues.put(fieldName, newValue);
-        } else if (currentValue instanceof String[]) {
-            // add the value to the list of existing values
-            List newValues =
-                new ArrayList(Arrays.asList((Object[]) currentValue));
-
-            newValues.add(value);
-            parameterValues.put(fieldName,
-                newValues.toArray(new String[newValues.size()]));
-        }
-    }
-
-    /**
-     * <p>Get the original path without the parameters added at runtime.</p>
-     *
-     * @return the original path as configured.
-     */
-    public String getOriginalPath() {
-        return super.getPath();
-    }
-
-    /**
-     * <p>Get the path for this object, including any parameters that may have
-     * been added at runtime.</p>
-     *
-     * @return The path for this object.
-     */
-    public String getPath() {
-        // get the original path and the parameter string that was formed
-        String originalPath = getOriginalPath();
-        String parameterString = getParameterString();
-
-        StringBuffer result = new StringBuffer(originalPath);
-
-        if ((parameterString != null) && (parameterString.length() > 0)) {
-            // the parameter separator we're going to use
-            String paramSeparator = "?";
-
-            // true if we need to use a parameter separator after originalPath
-            boolean needsParamSeparator = true;
-
-            // does the original path already have a "?"?
-            int paramStartIndex = originalPath.indexOf("?");
-
-            if (paramStartIndex > 0) {
-                // did the path end with "?"?
-                needsParamSeparator = (paramStartIndex != (originalPath.length()
-                    - 1));
-
-                if (needsParamSeparator) {
-                    paramSeparator = "&";
-                }
-            }
-
-            if (needsParamSeparator) {
-                result.append(paramSeparator);
-            }
-
-            result.append(parameterString);
-        }
-
-        return result.toString();
-    }
-
-    /**
-     * <p>Forms the string containing the parameters passed onto this object
-     * thru calls to addParameter().</p>
-     *
-     * @return a string which can be appended to the URLs.  The return string
-     *         does not include a leading question mark (?).
-     */
-    public String getParameterString() {
-        StringBuffer strParam = new StringBuffer(DEFAULT_BUFFER_SIZE);
-
-        // loop through all parameters
-        Iterator iterator = parameterValues.keySet().iterator();
-
-        while (iterator.hasNext()) {
-            // get the parameter name
-            String paramName = (String) iterator.next();
-
-            // get the value for this parameter
-            Object value = parameterValues.get(paramName);
-
-            if (value instanceof String) {
-                // just one value for this param
-                strParam.append(paramName).append("=").append(value);
-            } else if (value instanceof String[]) {
-                // loop through all values for this param
-                String[] values = (String[]) value;
-
-                for (int i = 0; i < values.length; i++) {
-                    strParam.append(paramName).append("=").append(values[i]);
-
-                    if (i < (values.length - 1)) {
-                        strParam.append("&");
-                    }
-                }
-            }
-
-            if (iterator.hasNext()) {
-                strParam.append("&");
-            }
-        }
-
-        return strParam.toString();
-    }
-
-    // ----------------------------------------------------- toString()
-
-    /**
-     * <p>Return a string description of this object.</p>
-     *
-     * @return a string containing the original path for this object and the
-     *         parameters it currently holds
-     */
-    public String toString() {
-        StringBuffer result = new StringBuffer(DEFAULT_BUFFER_SIZE);
-
-        result.append("ActionRedirect [");
-        result.append("originalPath=").append(getOriginalPath()).append(";");
-        result.append("parameterString=").append(getParameterString()).append("]");
-
-        return result.toString();
-    }
-}
+/*
+ * $Id$
+ *
+ * Copyright 2000-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.action;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.config.ForwardConfig;
+import org.apache.struts.util.ResponseUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p> A subclass of {@link ActionForward} which is designed for use in
+ * redirecting requests, with support for adding parameters at runtime. <br/>
+ * An {@link ForwardConfig} (or subclass) can be passed to the constructor to
+ * copy its configuration: </p> <p>
+ * <pre>
+ * public ActionForward execute(ActionMapping mapping,
+ *                              ActionForm form,
+ *                              HttpServletRequest request,
+ *                              HttpServletResponse response)
+ *         throws Exception {
+ *     ActionRedirect redirect =
+ *             new ActionRedirect(mapping.findForward("doRedirect"));
+ *     redirect.addParameter("param1","value1");
+ *     redirect.addParameter("param2","2");
+ *     redirect.addParameter("param3","3.0");
+ *     return redirect;
+ * }
+ * </pre>
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class ActionRedirect extends ActionForward {
+    // ----------------------------------------------------- Manifest constants
+
+    /**
+     * <p>Default allocation size for string buffers.</p>
+     */
+    private static final int DEFAULT_BUFFER_SIZE = 256;
+
+    // ----------------------------------------------------- Static variables
+
+    /**
+     * <p>Commons logging instance.</p>
+     */
+    protected static final Log LOG = LogFactory.getLog(ActionRedirect.class);
+
+    // ----------------------------------------------------- Instance variables
+
+    /**
+     * <p>Holds the redirect parameters. Each entry is either a String or a
+     * String[] depending on whether it has one or more entries.</p>
+     */
+    protected Map parameterValues = null;
+    
+    /**
+     * <p>Holds the anchor value.</p>
+     */
+    protected String anchorValue = null;
+
+    // ----------------------------------------------------- Constructors
+
+    /**
+     * <p>Construct a new instance with redirect set to true and initialize
+     * parameter lists.</p>
+     */
+    public ActionRedirect() {
+        setRedirect(true);
+        initializeParameters();
+    }
+
+    /**
+     * <p>Construct a new instance with the specified path and initialize
+     * parameter lists.</p>
+     *
+     * @param path Path for this instance
+     */
+    public ActionRedirect(String path) {
+        super(path);
+        setRedirect(true);
+        initializeParameters();
+    }
+
+    /**
+     * <p>Construct a new instance with the specified values and initialize
+     * parameter lists.</p>
+     *
+     * @param name   Name of this instance
+     * @param path   Path for this instance
+     * @param module Module prefix, if any
+     */
+    public ActionRedirect(String name, String path, String module) {
+        super(name, path, true);
+        setModule(module);
+        initializeParameters();
+    }
+
+    /**
+     * <p>Construct a new instance with a {@link ForwardConfig} object to copy
+     * name, path, and contextRelative values from.</p>
+     *
+     * @param baseConfig the {@link ForwardConfig} to copy configuration
+     *                   values from
+     */
+    public ActionRedirect(ForwardConfig baseConfig) {
+        setName(baseConfig.getName());
+        setPath(baseConfig.getPath());
+        setModule(baseConfig.getModule());
+        setRedirect(baseConfig.getRedirect());
+        initializeParameters();
+    }
+
+    // ----------------------------------------------------- Private methods
+
+    /**
+     * <p>Initializes the internal objects used to hold parameter values.</p>
+     */
+    private void initializeParameters() {
+        parameterValues = new HashMap();
+    }
+
+    // ----------------------------------------------------- Public methods
+
+    /**
+     * <p>Adds the object's toString() to the list of parameters if it's not
+     * null, or an empty string with the given fieldName if it is.</p>
+     *
+     * @param fieldName the name to use for the parameter
+     * @param valueObj  the value for this parameter
+     */
+    public ActionRedirect addParameter(String fieldName, Object valueObj) {
+        String value = (valueObj != null) ? valueObj.toString() : "";
+
+        if (parameterValues == null) {
+            initializeParameters();
+        }
+
+        //try {
+        value = ResponseUtils.encodeURL(value);
+
+        //} catch (UnsupportedEncodingException uce) {
+        // this shouldn't happen since UTF-8 is the W3C Recommendation
+        //     String errorMsg = "UTF-8 Character Encoding not supported";
+        //     LOG.error(errorMsg, uce);
+        //     throw new RuntimeException(errorMsg, uce);
+        // }
+        Object currentValue = parameterValues.get(fieldName);
+
+        if (currentValue == null) {
+            // there's no value for this param yet; add it to the map
+            parameterValues.put(fieldName, value);
+        } else if (currentValue instanceof String) {
+            // there's already a value; let's use an array for these parameters
+            String[] newValue = new String[2];
+
+            newValue[0] = (String) currentValue;
+            newValue[1] = value;
+            parameterValues.put(fieldName, newValue);
+        } else if (currentValue instanceof String[]) {
+            // add the value to the list of existing values
+            List newValues =
+                new ArrayList(Arrays.asList((Object[]) currentValue));
+
+            newValues.add(value);
+            parameterValues.put(fieldName,
+                newValues.toArray(new String[newValues.size()]));
+        }
+        return this;
+    }
+    
+    /**
+     * <p>Adds an anchor to the path.  Technically, the anchor value is
+     * just stored for later and will be added to the path in getPath().
+     * Note that this is a considerably simpler method than the
+     * addParmaeter method because aside from encoding the value, there
+     * isn't really anything to do.  Passing in null is fine because that
+     * is the value that will be checked for later to determine whether
+     * to append an anchor to the path or not.</p>
+     *
+     * @param anchorValue The anchor to append to the path
+     */
+    public ActionRedirect setAnchor(String anchorValue) {
+        this.anchorValue = ResponseUtils.encodeURL(anchorValue);
+        return this;
+    }
+
+    /**
+     * <p>Get the original path without the parameters added at runtime.</p>
+     *
+     * @return the original path as configured.
+     */
+    public String getOriginalPath() {
+        return super.getPath();
+    }
+
+    /**
+     * <p>Get the path for this object, including any parameters that may have
+     * been added at runtime.</p>
+     *
+     * @return The path for this object.
+     */
+    public String getPath() {
+        // get the original path and the parameter string that was formed
+        String originalPath = getOriginalPath();
+        String parameterString = getParameterString();
+        String anchorString = getAnchorString();
+
+        StringBuffer result = new StringBuffer(originalPath);
+
+        if ((parameterString != null) && (parameterString.length() > 0)) {
+            // the parameter separator we're going to use
+            String paramSeparator = "?";
+
+            // true if we need to use a parameter separator after originalPath
+            boolean needsParamSeparator = true;
+
+            // does the original path already have a "?"?
+            int paramStartIndex = originalPath.indexOf("?");
+
+            if (paramStartIndex > 0) {
+                // did the path end with "?"?
+                needsParamSeparator = (paramStartIndex != (originalPath.length()
+                    - 1));
+
+                if (needsParamSeparator) {
+                    paramSeparator = "&";
+                }
+            }
+
+            if (needsParamSeparator) {
+                result.append(paramSeparator);
+            }
+
+            result.append(parameterString);
+        }
+        
+        // append anchor string (or blank if none was set)
+        result.append(anchorString);
+
+
+        return result.toString();
+    }
+    
+    /**
+     * <p>Forms the string containing the parameters
+     *  passed onto this object thru calls to addParameter().</p>
+     *
+     * @return a string which can be appended to the URLs.  The
+     *    return string includes a leading hash
+     *    mark (#).
+     */
+    public String getAnchorString() {
+        String retVal = "";
+        if (anchorValue != null) {
+            retVal = "#" + anchorValue;
+        }
+        return retVal;
+    }
+
+    /**
+     * <p>Forms the string containing the parameters passed onto this object
+     * thru calls to addParameter().</p>
+     *
+     * @return a string which can be appended to the URLs.  The return string
+     *         does not include a leading question mark (?).
+     */
+    public String getParameterString() {
+        StringBuffer strParam = new StringBuffer(DEFAULT_BUFFER_SIZE);
+
+        // loop through all parameters
+        Iterator iterator = parameterValues.keySet().iterator();
+
+        while (iterator.hasNext()) {
+            // get the parameter name
+            String paramName = (String) iterator.next();
+
+            // get the value for this parameter
+            Object value = parameterValues.get(paramName);
+
+            if (value instanceof String) {
+                // just one value for this param
+                strParam.append(paramName).append("=").append(value);
+            } else if (value instanceof String[]) {
+                // loop through all values for this param
+                String[] values = (String[]) value;
+
+                for (int i = 0; i < values.length; i++) {
+                    strParam.append(paramName).append("=").append(values[i]);
+
+                    if (i < (values.length - 1)) {
+                        strParam.append("&");
+                    }
+                }
+            }
+
+            if (iterator.hasNext()) {
+                strParam.append("&");
+            }
+        }
+
+        return strParam.toString();
+    }
+
+    // ----------------------------------------------------- toString()
+
+    /**
+     * <p>Return a string description of this object.</p>
+     *
+     * @return a string containing the original path for this object and the
+     *         parameters it currently holds
+     */
+    public String toString() {
+        StringBuffer result = new StringBuffer(DEFAULT_BUFFER_SIZE);
+
+        result.append("ActionRedirect [");
+        result.append("originalPath=").append(getOriginalPath()).append(";");
+        result.append("parameterString=").append(getParameterString()).append("]");
+        result.append("anchorString=").append(getAnchorString()).append("]");
+
+        return result.toString();
+    }
+}

Modified: struts/action/trunk/src/test/org/apache/struts/action/TestActionRedirect.java
URL: http://svn.apache.org/viewcvs/struts/action/trunk/src/test/org/apache/struts/action/TestActionRedirect.java?rev=390335&r1=390334&r2=390335&view=diff
==============================================================================
--- struts/action/trunk/src/test/org/apache/struts/action/TestActionRedirect.java (original)
+++ struts/action/trunk/src/test/org/apache/struts/action/TestActionRedirect.java Thu Mar 30 21:43:56 2006
@@ -70,6 +70,18 @@
     }
 
     /**
+     * Test redirect with anchor.
+     */
+    public void testActionRedirectWithAnchor() {
+        ActionRedirect ar = new ActionRedirect("/path.do");
+
+        ar.addParameter("st", "test");
+        ar.setAnchor("foo");
+
+        assertTrue("Incorrect path", "/path.do?st=test#foo".equals(ar.getPath()));
+    }
+
+    /**
      * Test adding parameters with the same name.
      */
     public void testActionRedirectAddSameNameParameter() {
@@ -93,6 +105,7 @@
      */
     public void testActionRedirectFromExistingForward() {
         ActionForward forward = new ActionForward("/path.do?param=param1");
+        forward.setRedirect(false);
 
         ActionRedirect ar = new ActionRedirect(forward);
 
@@ -104,6 +117,7 @@
         assertHasParameter(ar.parameterValues, "object1", "someString");
         assertEquals("Incorrect original path.", forward.getPath(),
             ar.getOriginalPath());
+        assertTrue("Original had redirect to false", !ar.getRedirect());    
     }
 
     /**



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org