Author: lukaszlenart Date: Wed May 5 15:44:28 2010 New Revision: 941355 URL: http://svn.apache.org/viewvc?rev=941355&view=rev Log: resolved WW-3426 - added posibility to define anchor for result
Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java?rev=941355&r1=941354&r2=941355&view=diff ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java Wed May 5 15:44:28 2010 @@ -21,22 +21,15 @@ package org.apache.struts2.dispatcher; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapping; -import org.apache.struts2.views.util.UrlHelper; - import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.util.logging.Logger; import com.opensymphony.xwork2.util.logging.LoggerFactory; -import com.opensymphony.xwork2.util.reflection.ReflectionException; import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import org.apache.struts2.dispatcher.mapper.ActionMapping; + +import java.util.Arrays; +import java.util.List; /** * <!-- START SNIPPET: description --> @@ -137,15 +130,20 @@ public class ServletActionRedirectResult } public ServletActionRedirectResult(String actionName) { - this(null, actionName, null); + this(null, actionName, null, null); } public ServletActionRedirectResult(String actionName, String method) { - this(null, actionName, method); + this(null, actionName, method, null); } + public ServletActionRedirectResult(String namespace, String actionName, String method) { - super(null); + this(namespace, actionName, method, null); + } + + public ServletActionRedirectResult(String namespace, String actionName, String method, String anchor) { + super(null, anchor); this.namespace = namespace; this.actionName = actionName; this.method = method; @@ -206,6 +204,6 @@ public class ServletActionRedirectResult protected List<String> getProhibitedResultParams() { return Arrays.asList(new String[]{ DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", - "prependServletContext", "supressEmptyParameters"}); + "prependServletContext", "supressEmptyParameters", "anchor"}); } } Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java?rev=941355&r1=941354&r2=941355&view=diff ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java Wed May 5 15:44:28 2010 @@ -21,15 +21,6 @@ package org.apache.struts2.dispatcher; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import static javax.servlet.http.HttpServletResponse.*; - -import org.apache.struts2.ServletActionContext; -import org.apache.struts2.views.util.UrlHelper; -import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapping; - import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ResultConfig; @@ -38,13 +29,21 @@ import com.opensymphony.xwork2.util.logg import com.opensymphony.xwork2.util.logging.LoggerFactory; import com.opensymphony.xwork2.util.reflection.ReflectionException; import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import org.apache.struts2.dispatcher.mapper.ActionMapping; +import org.apache.struts2.views.util.UrlHelper; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.Map; -import java.util.LinkedHashMap; +import java.util.Arrays; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; -import java.util.Arrays; +import java.util.Map; + +import static javax.servlet.http.HttpServletResponse.SC_FOUND; /** @@ -72,6 +71,8 @@ import java.util.Arrays; * <li><b>parse</b> - true by default. If set to false, the location param will * not be parsed for Ognl expressions.</li> * + * <li><b>anchor</b> - optional, you can specify an anchor for result.</li> + * * </ul> * * <p> @@ -86,6 +87,7 @@ import java.util.Arrays; * <result name="success" type="redirect"> * <param name="location">foo.jsp</param> * <param name="parse">false</param> + * <param name="anchor">FRAGMENT</param> * </result> * <!-- END SNIPPET: example --></pre> * @@ -105,13 +107,20 @@ public class ServletRedirectResult exten protected boolean supressEmptyParameters = false; protected Map<String, String> requestParameters = new LinkedHashMap<String, String>(); + + protected String anchor; public ServletRedirectResult() { super(); } public ServletRedirectResult(String location) { + this(location, null); + } + + public ServletRedirectResult(String location, String anchor) { super(location); + this.anchor = anchor; } @Inject @@ -124,6 +133,14 @@ public class ServletRedirectResult exten } /** + * Set the optional anchor value. + * @param anchor + */ + public void setAnchor(String anchor) { + this.anchor = anchor; + } + + /** * Sets whether or not to prepend the servlet context path to the redirected URL. * * @param prependServletContext <tt>true</tt> to prepend the location with the servlet context path, @@ -132,6 +149,14 @@ public class ServletRedirectResult exten public void setPrependServletContext(boolean prependServletContext) { this.prependServletContext = prependServletContext; } + + public void execute(ActionInvocation invocation) throws Exception { + if (anchor != null) { + anchor = conditionalParse(anchor, invocation); + } + + super.execute(invocation); + } /** * Redirects to the location specified by calling {...@link HttpServletResponse#sendRedirect(String)}. @@ -187,6 +212,11 @@ public class ServletRedirectResult exten StringBuilder tmpLocation = new StringBuilder(finalLocation); UrlHelper.buildParametersString(requestParameters, tmpLocation, "&"); + // add the anchor + if (anchor != null) { + tmpLocation.append('#').append(anchor); + } + finalLocation = response.encodeRedirectURL(tmpLocation.toString()); } @@ -200,7 +230,7 @@ public class ServletRedirectResult exten protected List<String> getProhibitedResultParams() { return Arrays.asList(new String[]{ DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", - "prependServletContext", "supressEmptyParameters"}); + "prependServletContext", "supressEmptyParameters", "anchor"}); } Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java?rev=941355&r1=941354&r2=941355&view=diff ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java (original) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java Wed May 5 15:44:28 2010 @@ -31,8 +31,6 @@ import com.opensymphony.xwork2.util.Valu import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsTestCase; import org.apache.struts2.dispatcher.mapper.ActionMapper; -import static org.easymock.EasyMock.createControl; -import static org.easymock.EasyMock.expect; import org.easymock.IMocksControl; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -40,6 +38,9 @@ import org.springframework.mock.web.Mock import java.util.HashMap; import java.util.Map; +import static org.easymock.EasyMock.createControl; +import static org.easymock.EasyMock.expect; + /** * @version $Date$ $Id$ @@ -59,6 +60,7 @@ public class ServletActionRedirectResult .addParam("param1", "${#value1}") .addParam("param2", "${#value2}") .addParam("param3", "${#value3}") + .addParam("anchor", "${#fragment}") .build(); @@ -86,6 +88,7 @@ public class ServletActionRedirectResult result.setParse(true); result.setEncode(false); result.setPrependServletContext(false); + result.setAnchor("fragment"); IMocksControl control = createControl(); ActionProxy mockActionProxy = control.createMock(ActionProxy.class); @@ -99,7 +102,7 @@ public class ServletActionRedirectResult control.replay(); result.setActionMapper(container.getInstance(ActionMapper.class)); result.execute(mockInvocation); - assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3", res.getRedirectedUrl()); + assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3#fragment", res.getRedirectedUrl()); control.verify(); } @@ -117,6 +120,7 @@ public class ServletActionRedirectResult .addParam("param1", "value 1") .addParam("param2", "value 2") .addParam("param3", "value 3") + .addParam("anchor", "fragment") .build(); ActionContext context = ActionContext.getContext(); @@ -138,6 +142,7 @@ public class ServletActionRedirectResult result.setParse(false); result.setEncode(false); result.setPrependServletContext(false); + result.setAnchor("fragment"); IMocksControl control = createControl(); ActionProxy mockActionProxy = control.createMock(ActionProxy.class); @@ -150,7 +155,7 @@ public class ServletActionRedirectResult control.replay(); result.setActionMapper(container.getInstance(ActionMapper.class)); result.execute(mockInvocation); - assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3", res.getRedirectedUrl()); + assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3#fragment", res.getRedirectedUrl()); control.verify(); } @@ -168,10 +173,12 @@ public class ServletActionRedirectResult .addParam("param1", "value 1") .addParam("param2", "value 2") .addParam("param3", "value 3") + .addParam("anchor", "fragment") .build(); ObjectFactory factory = container.getInstance(ObjectFactory.class); ServletActionRedirectResult result = (ServletActionRedirectResult) factory.buildResult(resultConfig, new HashMap()); assertNotNull(result); } + } Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java?rev=941355&r1=941354&r2=941355&view=diff ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java (original) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java Wed May 5 15:44:28 2010 @@ -94,6 +94,21 @@ public class ServletRedirectResultTest e assertEquals("/context/bar/foo.jsp", writer.toString()); } + public void testAbsoluteRedirectAnchor() { + view.setLocation("/bar/foo.jsp"); + view.setAnchor("fragment"); + responseMock.expectAndReturn("encodeRedirectURL", "/context/bar/foo.jsp#fragment", "/context/bar/foo.jsp#fragment"); + responseMock.expect("sendRedirect", C.args(C.eq("/context/bar/foo.jsp#fragment"))); + + try { + view.execute(ai); + requestMock.verify(); + responseMock.verify(); + } catch (Exception e) { + e.printStackTrace(); + fail(); + } + } public void testPrependServletContextFalse() { view.setLocation("/bar/foo.jsp"); view.setPrependServletContext(false); @@ -172,6 +187,7 @@ public class ServletRedirectResultTest e result.setParse(false); result.setEncode(false); result.setPrependServletContext(false); + result.setAnchor("fragment"); IMocksControl control = createControl(); ActionProxy mockActionProxy = control.createMock(ActionProxy.class); @@ -184,7 +200,7 @@ public class ServletRedirectResultTest e control.replay(); result.setActionMapper(container.getInstance(ActionMapper.class)); result.execute(mockInvocation); - assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3", res.getRedirectedUrl()); + assertEquals("/myNamespace/myAction.action?param1=value+1¶m2=value+2¶m3=value+3#fragment", res.getRedirectedUrl()); control.verify(); }