Author: nilsga Date: Wed Aug 15 03:22:56 2007 New Revision: 566092 URL: http://svn.apache.org/viewvc?view=rev&rev=566092 Log: WW-2105 Do not copy the valuestack from event to render when the request cycle has been proper PRG
Added: struts/struts2/trunk/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java Modified: struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletResult.java Modified: struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java?view=diff&rev=566092&r1=566091&r2=566092 ============================================================================== --- struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java (original) +++ struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java Wed Aug 15 03:22:56 2007 @@ -120,4 +120,9 @@ * Key for the dispatch instruction for the [EMAIL PROTECTED] DispatcherServlet} */ String DISPATCH_TO = "struts.portlet.dispatchTo"; + + /** + * Session key where the value stack from the event phase is stored. + */ + String STACK_FROM_EVENT_PHASE = "struts.portlet.valueStackFromEventPhase"; } Modified: struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java?view=diff&rev=566092&r1=566091&r2=566092 ============================================================================== --- struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java (original) +++ struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptor.java Wed Aug 15 03:22:56 2007 @@ -28,6 +28,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.portlet.PortletActionConstants; +import org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; @@ -58,27 +59,39 @@ } } + @SuppressWarnings("unchecked") private void saveStack(ActionInvocation invocation) { Map session = invocation.getInvocationContext().getSession(); - session.put("struts.portlet.valueStackFromEventPhase", invocation.getStack()); + session.put(STACK_FROM_EVENT_PHASE, invocation.getStack()); ActionResponse actionResponse = (ActionResponse) invocation.getInvocationContext().get(RESPONSE); actionResponse.setRenderParameter(EVENT_ACTION, "true"); } + @SuppressWarnings("unchecked") private void restoreStack(ActionInvocation invocation) { RenderRequest request = (RenderRequest) invocation.getInvocationContext().get(REQUEST); if (TextUtils.stringSet(request.getParameter(EVENT_ACTION))) { - LOG.debug("Restoring value stack from event phase"); - ValueStack oldStack = (ValueStack) invocation.getInvocationContext().getSession().get( - "struts.portlet.valueStackFromEventPhase"); - if (oldStack != null) { - CompoundRoot oldRoot = oldStack.getRoot(); - ValueStack currentStack = invocation.getStack(); - CompoundRoot root = currentStack.getRoot(); - root.addAll(oldRoot); - LOG.debug("Restored stack"); + Map session = invocation.getInvocationContext().getSession(); + if(!isProperPrg(invocation)) { + LOG.debug("Restoring value stack from event phase"); + ValueStack oldStack = (ValueStack) invocation.getInvocationContext().getSession().get( + STACK_FROM_EVENT_PHASE); + if (oldStack != null) { + CompoundRoot oldRoot = oldStack.getRoot(); + ValueStack currentStack = invocation.getStack(); + CompoundRoot root = currentStack.getRoot(); + root.addAll(oldRoot); + LOG.debug("Restored stack"); + } + } + else { + LOG.debug("Won't restore stack from event phase since it's a proper PRG request"); } } + } + + private boolean isProperPrg(ActionInvocation invocation) { + return !(invocation.getAction() instanceof DirectRenderFromEventAction); } } Modified: struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletResult.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletResult.java?view=diff&rev=566092&r1=566091&r2=566092 ============================================================================== --- struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletResult.java (original) +++ struts/struts2/trunk/plugins/portlet/src/main/java/org/apache/struts2/portlet/result/PortletResult.java Wed Aug 15 03:22:56 2007 @@ -122,6 +122,7 @@ protected void executeActionResult(String finalLocation, ActionInvocation invocation) { LOG.debug("Executing result in Event phase"); ActionResponse res = PortletActionContext.getActionResponse(); + Map sessionMap = invocation.getInvocationContext().getSession(); LOG.debug("Setting event render parameter: " + finalLocation); if (finalLocation.indexOf('?') != -1) { convertQueryParamsToRenderParams(res, finalLocation.substring(finalLocation.indexOf('?') + 1)); @@ -134,7 +135,6 @@ } else { // View is rendered outside an action...uh oh... res.setRenderParameter(ACTION_PARAM, "renderDirect"); - Map sessionMap = invocation.getInvocationContext().getSession(); sessionMap.put(RENDER_DIRECT_LOCATION, finalLocation); } res.setRenderParameter(PortletActionConstants.MODE_PARAM, PortletActionContext.getRequest().getPortletMode() Added: struts/struts2/trunk/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java?view=auto&rev=566092 ============================================================================== --- struts/struts2/trunk/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java (added) +++ struts/struts2/trunk/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java Wed Aug 15 03:22:56 2007 @@ -0,0 +1,156 @@ +/* + * $Id: $ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.struts2.portlet.interceptor; + +import java.util.HashMap; +import java.util.Map; + +import javax.portlet.ActionResponse; +import javax.portlet.RenderRequest; + +import junit.framework.TestCase; + +import org.apache.struts2.dispatcher.DefaultActionSupport; +import org.apache.struts2.portlet.PortletActionConstants; +import org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction; +import org.easymock.EasyMock; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; + +public class PortletStateInterceptorTest extends TestCase implements PortletActionConstants { + + private PortletStateInterceptor interceptor; + + public void setUp() throws Exception { + interceptor = new PortletStateInterceptor(); + } + + public void testCopyValueStackFromEventToRenderPhase() throws Exception { + ActionResponse actionResponse = EasyMock.createNiceMock(ActionResponse.class); + ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class); + + Map<String, Object> ctxMap = new HashMap<String, Object>(); + ctxMap.put(PHASE, EVENT_PHASE); + ctxMap.put(RESPONSE, actionResponse); + Map<String, Object> session = new HashMap<String, Object>(); + + ActionContext ctx = new ActionContext(ctxMap); + ctx.setSession(session); + EasyMock.expect(invocation.getInvocationContext()).andStubReturn(ctx); + actionResponse.setRenderParameter(EVENT_ACTION, "true"); + + ValueStack stack = ValueStackFactory.getFactory().createValueStack(); + EasyMock.expect(invocation.getStack()).andStubReturn(stack); + + EasyMock.replay(actionResponse); + EasyMock.replay(invocation); + + interceptor.intercept(invocation); + + EasyMock.verify(actionResponse); + EasyMock.verify(invocation); + + assertSame(stack, session.get(STACK_FROM_EVENT_PHASE)); + + } + + public void testDoNotRestoreValueStackInRenderPhaseWhenProperPrg() throws Exception { + RenderRequest renderRequest = EasyMock.createNiceMock(RenderRequest.class); + ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class); + + ValueStack eventPhaseStack = ValueStackFactory.getFactory().createValueStack(); + eventPhaseStack.set("testKey", "testValue"); + + ValueStack currentStack = ValueStackFactory.getFactory().createValueStack(); + currentStack.set("anotherTestKey", "anotherTestValue"); + + Map<String, Object> ctxMap = new HashMap<String, Object>(); + Map<String, Object> session = new HashMap<String, Object>(); + + session.put(STACK_FROM_EVENT_PHASE, eventPhaseStack); + + ctxMap.put(PHASE, RENDER_PHASE); + ctxMap.put(REQUEST, renderRequest); + + ActionContext ctx = new ActionContext(ctxMap); + ctx.setSession(session); + + EasyMock.expect(invocation.getInvocationContext()).andStubReturn(ctx); + EasyMock.expect(invocation.getStack()).andStubReturn(currentStack); + EasyMock.expect(invocation.getAction()).andStubReturn(new DefaultActionSupport()); + EasyMock.expect(renderRequest.getParameter(EVENT_ACTION)).andStubReturn("true"); + + EasyMock.replay(renderRequest); + EasyMock.replay(invocation); + + interceptor.intercept(invocation); + + ValueStack resultingStack = invocation.getStack(); + + assertNull(resultingStack.findValue("testKey")); + assertEquals("anotherTestValue", resultingStack.findValue("anotherTestKey")); + + + } + + public void testRestoreValueStackInRenderPhaseWhenNotProperPrg() throws Exception { + RenderRequest renderRequest = EasyMock.createNiceMock(RenderRequest.class); + ActionInvocation invocation = EasyMock.createNiceMock(ActionInvocation.class); + + ValueStack eventPhaseStack = ValueStackFactory.getFactory().createValueStack(); + eventPhaseStack.set("testKey", "testValue"); + + ValueStack currentStack = ValueStackFactory.getFactory().createValueStack(); + currentStack.set("anotherTestKey", "anotherTestValue"); + + EasyMock.expect(invocation.getStack()).andStubReturn(currentStack); + + Map<String, Object> ctxMap = new HashMap<String, Object>(); + Map<String, Object> session = new HashMap<String, Object>(); + + session.put(STACK_FROM_EVENT_PHASE, eventPhaseStack); + + ctxMap.put(PHASE, RENDER_PHASE); + ctxMap.put(REQUEST, renderRequest); + + ActionContext ctx = new ActionContext(ctxMap); + ctx.setSession(session); + + EasyMock.expect(invocation.getInvocationContext()).andStubReturn(ctx); + EasyMock.expect(invocation.getStack()).andStubReturn(currentStack); + EasyMock.expect(invocation.getAction()).andStubReturn(new DirectRenderFromEventAction()); + EasyMock.expect(renderRequest.getParameter(EVENT_ACTION)).andStubReturn("true"); + + EasyMock.replay(renderRequest); + EasyMock.replay(invocation); + + interceptor.intercept(invocation); + + ValueStack resultingStack = invocation.getStack(); + assertEquals("testValue", resultingStack.findValue("testKey")); + assertEquals("anotherTestValue", resultingStack.findValue("anotherTestKey")); + + + } +}