Commits

Anonymous committed 88641d9

WW-1477 RestfulActionMapper getMapping and getUriFromMapping methods conflicts
WW-1478 URL and Form Tag doesn't generate url properly when using ActionMapper other that DefaultActionMapper like RestfulActionMapper

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@2962573baa09-0c28-0410-bef9-dab3c582ae83

Comments (0)

Files changed (12)

src/java/com/opensymphony/webwork/components/Component.java

  */
 package com.opensymphony.webwork.components;
 
+import com.opensymphony.webwork.WebWorkException;
+import com.opensymphony.webwork.dispatcher.mapper.ActionMapper;
+import com.opensymphony.webwork.dispatcher.mapper.ActionMapperFactory;
+import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
+import com.opensymphony.webwork.dispatcher.mapper.ActionMappingEx;
 import com.opensymphony.webwork.util.FastByteArrayOutputStream;
 import com.opensymphony.webwork.views.jsp.TagUtils;
 import com.opensymphony.webwork.views.util.ContextUtil;
-import com.opensymphony.webwork.views.util.UrlHelper;
-import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
-import com.opensymphony.webwork.dispatcher.mapper.ActionMapper;
-import com.opensymphony.webwork.dispatcher.mapper.ActionMapperFactory;
-import com.opensymphony.webwork.WebWorkException;
 import com.opensymphony.xwork.util.OgnlValueStack;
 import com.opensymphony.xwork.util.TextParseUtil;
 import org.apache.commons.logging.Log;
      */
     protected String determineActionURL(String action, String namespace, String method,
                                         HttpServletRequest req, HttpServletResponse res, Map parameters, String scheme,
-                                        boolean includeContext, boolean encodeResult, boolean escapeXml) {
+                                        boolean includeContext, boolean encodeResult, boolean escapeAmp) {
         String finalAction = findString(action);
         String finalNamespace = determineNamespace(namespace, getStack(), req);
-        ActionMapping mapping = new ActionMapping(finalAction, finalNamespace, method, parameters);
+
+        ActionMapping mapping = new ActionMappingEx(finalAction, finalNamespace, method, parameters, scheme,
+                                                    includeContext, encodeResult, escapeAmp, req, res);
+
         ActionMapper mapper = ActionMapperFactory.getMapper();
         String uri = mapper.getUriFromActionMapping(mapping);
-        return UrlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult, false, escapeXml);
+
+        return uri;
     }
 
     /**

src/java/com/opensymphony/webwork/components/Form.java

         String actionName = action;
         if (actionConfig != null) {
 
-            ActionMapping mapping = new ActionMapping(action, namespace, actionMethod, parameters);
-            String result = UrlHelper.buildUrl(ActionMapperFactory.getMapper().getUriFromActionMapping(mapping), request, response, null);
+            String result = determineActionURL(action, namespace, actionMethod, request, response, Collections.EMPTY_MAP, null, true, true, true);
+
             addParameter("action", result);
 
             // let's try to get the actual action class and name

src/java/com/opensymphony/webwork/dispatcher/mapper/ActionMapper.java

      * Implementation should return null if it cannot handle the format of request (eg. if it is bad etc.) such that
      * we could cascade {@link ActionMapping} together using
      * {@link com.opensymphony.webwork.dispatcher.mapper.CompositeActionMapper}
+     * <p/>
+     * The parameter <code>mapping</code> is an instance of {@link ActionMappingEx}.
      *
      * @param mapping
      * @return String

src/java/com/opensymphony/webwork/dispatcher/mapper/ActionMappingEx.java

+package com.opensymphony.webwork.dispatcher.mapper;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * An extension of {@link ActionMapping} including arguments like :-
+ * <ul>
+ *      <li>scheme</li>
+ *      <li>includeContext</li>
+ *      <li>encodeResult</li>
+ *      <li>escapeAmp</li>
+ *      <li>HttpServletRequest</li>
+ *      <li>JttpServletResponse</li>
+ * </ul>
+ * such that {@link ActionMapper}'s implementation could used it to generate
+ * url through {@link ActionMapper#getUriFromActionMapping(ActionMapping)}. 
+ *
+ * @author tmjee
+ * @version $Date$ $Id$
+ */
+public class ActionMappingEx extends ActionMapping {
+
+    private String scheme;
+    private boolean includeContext;
+    private boolean encodeResult;
+    private boolean escapeAmp;
+    private HttpServletRequest request;
+    private HttpServletResponse response;
+
+    public ActionMappingEx(String name, String namespace, String method, Map params,
+                           String scheme, boolean includeContext, boolean encodeResult,
+                           boolean escapeAmp, HttpServletRequest request,
+                           HttpServletResponse response) {
+        super(name, namespace, method, params);
+        this.scheme = scheme;
+        this.includeContext = includeContext;
+        this.encodeResult = encodeResult;
+        this.escapeAmp = escapeAmp;
+        this.request = request;
+        this.response = response;
+    }
+
+    /**
+     * Get request scheme.
+     * @return String
+     */
+    public String getScheme() {
+        return scheme;
+    }
+
+    /**
+     * Do we need to include context?
+     * @return boolean
+     */
+    public boolean isIncludeContext() {
+        return includeContext;
+    }
+
+    /**
+     * Do we need to encode result?
+     * @return boolean
+     */
+    public boolean isEncodeResult() {
+        return encodeResult;
+    }
+
+    /**
+     * Get {@link HttpServletRequest}.
+     * @return HttpServletRequest
+     */
+    public HttpServletRequest getRequest() {
+        return request;
+    }
+
+    /**
+     * Get {@link HttpServletResponse}.
+     * @return HttpServletResponse.
+     */
+    public HttpServletResponse getResponse() {
+        return response;
+    }
+
+    /**
+     * Do we need to escape the ampersand?
+     * @return boolean.
+     */
+    public boolean isEscapeAmp() {
+        return escapeAmp;
+    }
+}

src/java/com/opensymphony/webwork/dispatcher/mapper/DefaultActionMapper.java

 import com.opensymphony.webwork.config.Configuration;
 import com.opensymphony.webwork.dispatcher.ServletRedirectResult;
 import com.opensymphony.webwork.util.PrefixTrie;
+import com.opensymphony.webwork.views.util.UrlHelper;
 
 import javax.servlet.http.HttpServletRequest;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * <!-- START SNIPPET: javadoc -->
             mapping.setName(name.substring(0, exclamation));
             mapping.setMethod(name.substring(exclamation + 1));
         }
+        mapping.setParams(new LinkedHashMap(request.getParameterMap()));
         return mapping;
     }
 
             }
         }
 
-        return uri.toString();
+        if (mapping instanceof ActionMappingEx) {
+            ActionMappingEx mappingEx = (ActionMappingEx)mapping;
+            return UrlHelper.buildUrl(uri.toString(), mappingEx.getRequest(), mappingEx.getResponse(),
+                                      mappingEx.getParams(), mappingEx.getScheme(),
+                                      mappingEx.isIncludeContext(),mappingEx.isEncodeResult(), false,
+                                      mappingEx.isEscapeAmp());
+        }
+        else {
+            return UrlHelper.buildUrl(uri.toString(), null, null, mapping.getParams(), null, false, false, false, true);
+        }
     }
 
+
     interface ParameterAction {
         void execute(String key, ActionMapping mapping);
     }

src/java/com/opensymphony/webwork/dispatcher/mapper/RestfulActionMapper.java

         // return null, and let the next ActionMapper kicks in if say if a CompositeActionMapper
         // is being used.
         if ((mapping.getNamespace() == null) || (mapping.getNamespace().trim().length() <= 0)) {
-            String base = mapping.getName();
+            String base = "/"+mapping.getName();
 
             // let's see if we have the <actionName>Id first, if so this should go first,
             // cause in {#link #getMapping(HttpServletRequest) the <actionName>Id is expected to be
                     base = base + "/" + entry.getKey() + "/" + entry.getValue();
                 }
             }
-            return base;
+            return base+"/";
         }
         return null;
     }

src/java/com/opensymphony/webwork/views/util/UrlHelper.java

                 }
             }
         }
-        else if (  
-           (scheme != null) && !scheme.equals(request.getScheme())) {
+        else if (
+           (scheme != null) && (scheme.trim().length() > 0) && (!scheme.equals(request.getScheme()))) {
             changedScheme = true;
             link.append(scheme);
             link.append("://");

src/test/com/opensymphony/webwork/dispatcher/ServletRedirectResultTest.java

 
 
 /**
- * DOCUMENT ME!
- *
- * @author $author$
- * @version $Revision$
+ * @author jcarreira
+ * @author tmjee
+ * @version $Date$ $Id$
  */
 public class ServletRedirectResultTest extends WebWorkTestCase implements WebWorkStatics {
 
 
         requestMock = new Mock(HttpServletRequest.class);
         requestMock.matchAndReturn("getContextPath", "/context");
+        requestMock.matchAndReturn("getParameterMap", new HashMap());
 
         ActionContext ac = new ActionContext(Ognl.createDefaultContext(null));
         ac.put(ServletActionContext.HTTP_REQUEST, requestMock.proxy());

src/test/com/opensymphony/webwork/dispatcher/mapper/DefaultActionMapperTest.java

  */
 package com.opensymphony.webwork.dispatcher.mapper;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import com.opensymphony.webwork.dispatcher.ServletRedirectResult;
 import com.opensymphony.webwork.views.jsp.WebWorkMockHttpServletRequest;
 import com.opensymphony.xwork.Result;
-
 import junit.framework.TestCase;
 
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
 /**
  * DefaultActionMapper test case.
  * 
         assertEquals("/myActionName.action?test=bla", uri);
     }
 
+    // ==================================================
+	// === test action?param1=value1&param2=value2 ... ===
+	// ==================================================
+
+    public void testGetUriWithParamsFromActionMapper() throws Exception {
+        DefaultActionMapper mapper = new DefaultActionMapper();
+        ActionMapping actionMapping = new ActionMapping();
+        actionMapping.setName("myAction");
+        actionMapping.setNamespace("/myNamespace");
+        actionMapping.setParams(new LinkedHashMap() {
+            {
+                put("param1", "value1");
+                put("param2", "value2");
+            }
+        });
+        String uri = mapper.getUriFromActionMapping(actionMapping);
+        assertEquals("/myNamespace/myAction.action?param1=value1&amp;param2=value2", uri);
+    }
+
+
 }

src/test/com/opensymphony/webwork/dispatcher/mapper/RestfulActionMapperTest.java

         am.setName("view");
         am.setParams(Collections.EMPTY_MAP);
 
-        assertEquals("view", mapper.getUriFromActionMapping(am));
+        assertEquals("/view/", mapper.getUriFromActionMapping(am));
     }
 
     public void testGetUriParam() {
         am.setName("view");
         am.setParams(param);
 
-        assertEquals("view/article/123", mapper.getUriFromActionMapping(am));
+        assertEquals("/view/article/123/", mapper.getUriFromActionMapping(am));
     }
 
     public void testGetUriParamId() {
         am.setName("view");
         am.setParams(param);
 
-        assertEquals("view/456/article/123", mapper.getUriFromActionMapping(am));
+        assertEquals("/view/456/article/123/", mapper.getUriFromActionMapping(am));
     }
 
     public void testGetMappingNoSlash() throws Exception {
 
     public void testGetMapping() throws Exception {
         WebWorkMockHttpServletRequest request = new WebWorkMockHttpServletRequest();
-        request.setupGetServletPath("/myapp/view/12");
+        request.setupGetServletPath("/myapp/view/12/");
 
         ActionMapping am = mapper.getMapping(request);
         assertEquals("myapp", am.getName());
 
     public void testGetMapping2() throws Exception {
         WebWorkMockHttpServletRequest request = new WebWorkMockHttpServletRequest();
-        request.setupGetServletPath("/myapp/12/region/europe");
+        request.setupGetServletPath("/myapp/12/region/europe/");
 
         ActionMapping am = mapper.getMapping(request);
         assertEquals("myapp", am.getName());
 
     public void testGetMapping3() throws Exception {
         WebWorkMockHttpServletRequest request = new WebWorkMockHttpServletRequest();
-        request.setupGetServletPath("/myapp/view/12/region/europe");
+        request.setupGetServletPath("/myapp/view/12/region/europe/");
 
         ActionMapping am = mapper.getMapping(request);
         assertEquals("myapp", am.getName());

src/test/com/opensymphony/webwork/views/jsp/WebWorkMockPageContext.java

 import com.mockobjects.servlet.MockPageContext;
 
 import javax.servlet.ServletResponse;
+import javax.servlet.ServletException;
+import javax.servlet.jsp.el.ExpressionEvaluator;
+import javax.servlet.jsp.el.VariableResolver;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
 import java.util.HashMap;
 import java.util.Map;
+import java.io.IOException;
 
 
 /**
         return response;
     }
 
+    public void include(String s, boolean b) throws ServletException, IOException {
+        include(s);
+    }
+
     public HttpSession getSession() {
         HttpSession session = super.getSession();
 
     public void removeAttribute(String key) {
         this.attributes.remove(key);
     }
+
+    public ExpressionEvaluator getExpressionEvaluator() {
+        return null;
+    }
+
+    public VariableResolver getVariableResolver() {
+        return null;
+    }
 }

src/test/com/opensymphony/webwork/views/jsp/ui/FormTagTest.java

  * FormTagTest
  *
  * @author Jason Carreira
- *         Created Apr 3, 2003 10:28:58 AM
- *         
+ * @author tmjee
  * @version $Date$ $Id$
  */
 public class FormTagTest extends AbstractUITagTest {
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-9.txt"));
+        verify(FormTagTest.class.getResource("Formtag-9.txt"));
 	}
 
 
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-10.txt"));
+        verify(FormTagTest.class.getResource("Formtag-10.txt"));
 	}
 
 
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-1.txt"));
+        verify(FormTagTest.class.getResource("Formtag-1.txt"));
     }
 
         /**
         t.doEndTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-2.txt"));
+        verify(FormTagTest.class.getResource("Formtag-2.txt"));
     	}
     	finally {
     		ConfigurationManager.setConfiguration(originalConfiguration);
         t.doEndTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-11.txt"));
+        verify(FormTagTest.class.getResource("Formtag-11.txt"));
     	}
     	finally {
     		ConfigurationManager.setConfiguration(originalConfiguration);
         t.doEndTag();
         tag.doEndTag();
     	
-        verify(FormTag.class.getResource("Formtag-6.txt"));
+        verify(FormTagTest.class.getResource("Formtag-6.txt"));
     }
     
     
 
         Configuration.set(WebWorkConstants.WEBWORK_ACTION_EXTENSION, oldConfiguration);
 
-        verify(FormTag.class.getResource("Formtag-5.txt"));
+        verify(FormTagTest.class.getResource("Formtag-5.txt"));
 
         // set it back to the default
         Configuration.set(WebWorkConstants.WEBWORK_ACTION_EXTENSION, "action");
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-5.txt"));
+        verify(FormTagTest.class.getResource("Formtag-5.txt"));
     }
 
     public void testFormWithNamespaceDefaulting() throws Exception {
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-3.txt"));
+        verify(FormTagTest.class.getResource("Formtag-3.txt"));
     }
     
     public void testFormTagForStackOverflowException1() throws Exception {
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-4.txt"));
+        verify(FormTagTest.class.getResource("Formtag-4.txt"));
     }
 
     public void testFormWithStaticAction() throws Exception {
         tag.doStartTag();
         tag.doEndTag();
 
-        verify(FormTag.class.getResource("Formtag-7.txt"));
+        verify(FormTagTest.class.getResource("Formtag-7.txt"));
     }
 
     public void testFormWithActionAndExtension() throws Exception {
         tag.doEndTag();
         Configuration.set(WebWorkConstants.WEBWORK_ACTION_EXTENSION, oldConfiguration);
 
-        verify(FormTag.class.getResource("Formtag-8.txt"));
+        verify(FormTagTest.class.getResource("Formtag-8.txt"));
 
         // set it back to the default
         Configuration.set(WebWorkConstants.WEBWORK_ACTION_EXTENSION, "action");