Repository: struts Updated Branches: refs/heads/support-2-3 87979d282 -> 9c7b83366
WW-4600 Ports solution with PreResultListener from WW-4605 Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/9c7b8336 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/9c7b8336 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/9c7b8336 Branch: refs/heads/support-2-3 Commit: 9c7b8336685d810a657f3f3c56ad8662dcc85dbf Parents: 87979d2 Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Thu Feb 11 08:21:59 2016 +0100 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Thu Feb 11 08:21:59 2016 +0100 ---------------------------------------------------------------------- .../interceptor/MessageStoreInterceptor.java | 59 +---- .../MessageStorePreResultListener.java | 94 +++++++ .../MessageStoreInterceptorTest.java | 237 +---------------- .../MessageStorePreResultListenerTest.java | 252 +++++++++++++++++++ .../apache/struts2/views/jsp/ActionTagTest.java | 3 +- .../xwork2/DefaultActionInvocation.java | 7 +- .../xwork2/DefaultActionInvocationTest.java | 3 + 7 files changed, 371 insertions(+), 284 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java index 97e1693..25ed3ef 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java @@ -171,6 +171,7 @@ public class MessageStoreInterceptor extends AbstractInterceptor { public void setAllowRequestParameterSwitch(boolean allowRequestParameterSwitch) { this.allowRequestParameterSwitch = allowRequestParameterSwitch; } + public boolean getAllowRequestParameterSwitch() { return this.allowRequestParameterSwitch; } @@ -178,6 +179,7 @@ public class MessageStoreInterceptor extends AbstractInterceptor { public void setRequestParameterSwitch(String requestParameterSwitch) { this.requestParameterSwitch = requestParameterSwitch; } + public String getRequestParameterSwitch() { return this.requestParameterSwitch; } @@ -185,18 +187,23 @@ public class MessageStoreInterceptor extends AbstractInterceptor { public void setOperationMode(String operationMode) { this.operationMode = operationMode; } + public String getOperationModel() { return this.operationMode; } public String intercept(ActionInvocation invocation) throws Exception { + LOG.trace("entering MessageStoreInterceptor ..."); if (LOG.isDebugEnabled()) { LOG.debug("entering MessageStoreInterceptor ..."); } before(invocation); + + LOG.trace("Registering listener to store messages before result will be executed"); + invocation.addPreResultListener(new MessageStorePreResultListener(this)); + String result = invocation.invoke(); - after(invocation, result); if (LOG.isDebugEnabled()) { LOG.debug("exit executing MessageStoreInterceptor"); @@ -263,56 +270,6 @@ public class MessageStoreInterceptor extends AbstractInterceptor { } /** - * Handle the storing of field errors / action messages / field errors, which is - * done after action invocation, and the <code>operationMode</code> is in 'STORE'. - * - * @param invocation - * @param result - * @throws Exception - */ - protected void after(ActionInvocation invocation, String result) throws Exception { - - boolean isCommitted = ServletActionContext.getResponse().isCommitted(); - if (isCommitted) { - LOG.trace("Response was already committed, cannot store messages!"); - return; - } - - boolean isInvalidated = ServletActionContext.getRequest().getSession(false) == null; - if (isInvalidated) { - LOG.trace("Session was invalidated or never created, cannot store messages!"); - return; - } - - Map<String, Object> session = invocation.getInvocationContext().getSession(); - if (session == null) { - LOG.trace("Could not store action [#0] error/messages into session, because session hasn't been opened yet.", invocation.getAction()); - return; - } - - String reqOperationMode = getRequestOperationMode(invocation); - boolean isRedirect = invocation.getResult() instanceof ServletRedirectResult; - - if (STORE_MODE.equalsIgnoreCase(reqOperationMode) || - STORE_MODE.equalsIgnoreCase(operationMode) || - (AUTOMATIC_MODE.equalsIgnoreCase(operationMode) && isRedirect)) { - - Object action = invocation.getAction(); - if (action instanceof ValidationAware) { - LOG.debug("Storing action [#0] error/messages into session ", action); - - ValidationAware validationAwareAction = (ValidationAware) action; - session.put(actionErrorsSessionKey, validationAwareAction.getActionErrors()); - session.put(actionMessagesSessionKey, validationAwareAction.getActionMessages()); - session.put(fieldErrorsSessionKey, validationAwareAction.getFieldErrors()); - - } else { - LOG.debug("Action [#0] is not ValidationAware, no message / error that are storeable", action); - } - } - } - - /** * Get the operationMode through request paramter, if <code>allowRequestParameterSwitch</code> * is 'true', else it simply returns 'NONE', meaning its neither in the 'STORE_MODE' nor * 'RETRIEVE_MODE'. http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java new file mode 100644 index 0000000..d78313c --- /dev/null +++ b/core/src/main/java/org/apache/struts2/interceptor/MessageStorePreResultListener.java @@ -0,0 +1,94 @@ +/* + * 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.interceptor; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ValidationAware; +import com.opensymphony.xwork2.interceptor.PreResultListener; +import com.opensymphony.xwork2.util.logging.Logger; +import com.opensymphony.xwork2.util.logging.LoggerFactory; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.ServletRedirectResult; + +import java.util.Map; + +/** + * This listener is used by {@link MessageStoreInterceptor} to store messages in HttpSession + * just before result will be executed. It must be done that way as after result will be executed + * HttpSession cannot be modified (response was already sent to browser). + */ +class MessageStorePreResultListener implements PreResultListener { + + private static final Logger LOG = LoggerFactory.getLogger(MessageStorePreResultListener.class); + + private MessageStoreInterceptor interceptor; + + public MessageStorePreResultListener(MessageStoreInterceptor interceptor) { + this.interceptor = interceptor; + } + + public void beforeResult(ActionInvocation invocation, String resultCode) { + + boolean isCommitted = ServletActionContext.getResponse().isCommitted(); + if (isCommitted) { + LOG.trace("Response was already committed, cannot store messages!"); + return; + } + + boolean isInvalidated = ServletActionContext.getRequest().getSession(false) == null; + if (isInvalidated) { + LOG.trace("Session was invalidated or never created, cannot store messages!"); + return; + } + + Map<String, Object> session = invocation.getInvocationContext().getSession(); + if (session == null) { + LOG.trace("Could not store action [#0] error/messages into session, because session hasn't been opened yet.", invocation.getAction()); + return; + } + + String reqOperationMode = interceptor.getRequestOperationMode(invocation); + + boolean isRedirect = false; + try { + isRedirect = invocation.getResult() instanceof ServletRedirectResult; + } catch (Exception e) { + LOG.warn("Cannot read result!", e); + } + + if (MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(reqOperationMode) || + MessageStoreInterceptor.STORE_MODE.equalsIgnoreCase(interceptor.getOperationModel()) || + (MessageStoreInterceptor.AUTOMATIC_MODE.equalsIgnoreCase(interceptor.getOperationModel()) && isRedirect)) { + + Object action = invocation.getAction(); + if (action instanceof ValidationAware) { + LOG.debug("Storing action [#0] error/messages into session ", action); + + ValidationAware validationAwareAction = (ValidationAware) action; + session.put(MessageStoreInterceptor.actionErrorsSessionKey, validationAwareAction.getActionErrors()); + session.put(MessageStoreInterceptor.actionMessagesSessionKey, validationAwareAction.getActionMessages()); + session.put(MessageStoreInterceptor.fieldErrorsSessionKey, validationAwareAction.getFieldErrors()); + + } else { + LOG.debug("Action [#0] is not ValidationAware, no message / error that are storeable", action); + } + } + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java index f85dcbb..420f3c1 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java @@ -27,10 +27,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.interceptor.PreResultListener; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsInternalTestCase; -import org.apache.struts2.dispatcher.ServletActionRedirectResult; import org.easymock.EasyMock; import com.opensymphony.xwork2.Action; @@ -38,7 +37,6 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; -import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -63,84 +61,6 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { ServletActionContext.setResponse(response); } - public void testStoreMessage() throws Exception { - MessageStoreInterceptor interceptor = new MessageStoreInterceptor(); - interceptor.setAllowRequestParameterSwitch(true); - interceptor.setOperationMode(MessageStoreInterceptor.STORE_MODE); - - - Map paramMap = new LinkedHashMap(); - Map sessionMap = new LinkedHashMap(); - - ActionSupport action = new ActionSupport(); - action.addActionError("some action error 1"); - action.addActionError("some action error 2"); - action.addActionMessage("some action message 1"); - action.addActionMessage("some action message 2"); - action.addFieldError("field1", "some field error 1"); - action.addFieldError("field2", "some field error 2"); - - ActionContext actionContext = new ActionContext(new HashMap()); - actionContext.put(ActionContext.PARAMETERS, paramMap); - actionContext.put(ActionContext.SESSION, sessionMap); - - HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class); - HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); - mockedRequest.getSession(false); - EasyMock.expectLastCall().andReturn(mockedSession); - EasyMock.expectLastCall().once(); - ServletActionContext.setRequest(mockedRequest); - - EasyMock.replay(mockedRequest); - - // Mock (ActionInvocation) - ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); - mockActionInvocation.getInvocationContext(); - EasyMock.expectLastCall().andReturn(actionContext); - EasyMock.expectLastCall().anyTimes(); - - mockActionInvocation.invoke(); - EasyMock.expectLastCall().andReturn(Action.SUCCESS); - - mockActionInvocation.getAction(); - EasyMock.expectLastCall().andReturn(action); - - mockActionInvocation.getResult(); - EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); - - EasyMock.replay(mockActionInvocation); - - interceptor.init(); - interceptor.intercept(mockActionInvocation); - interceptor.destroy(); - - assertEquals(sessionMap.size(), 3); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionErrorsSessionKey)); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionMessagesSessionKey)); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.fieldErrorsSessionKey)); - - List actionErrors = (List) sessionMap.get(MessageStoreInterceptor.actionErrorsSessionKey); - List actionMessages = (List) sessionMap.get(MessageStoreInterceptor.actionMessagesSessionKey); - Map fieldErrors = (Map) sessionMap.get(MessageStoreInterceptor.fieldErrorsSessionKey); - - assertEquals(actionErrors.size(), 2); - assertEquals(actionMessages.size(), 2); - assertEquals(fieldErrors.size(), 2); - - assertTrue(actionErrors.contains("some action error 1")); - assertTrue(actionErrors.contains("some action error 2")); - assertTrue(actionMessages.contains("some action message 1")); - assertTrue(actionMessages.contains("some action message 2")); - assertTrue(fieldErrors.containsKey("field1")); - assertTrue(fieldErrors.containsKey("field2")); - assertEquals(((List)fieldErrors.get("field1")).size(), 1); - assertEquals(((List)fieldErrors.get("field2")).size(), 1); - assertEquals(((List)fieldErrors.get("field1")).get(0), "some field error 1"); - assertEquals(((List)fieldErrors.get("field2")).get(0), "some field error 2"); - - EasyMock.verify(mockActionInvocation); - } - public void testIgnoreMessageWithoutSession() throws Exception { MessageStoreInterceptor interceptor = new MessageStoreInterceptor(); interceptor.setAllowRequestParameterSwitch(true); @@ -174,8 +94,8 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { mockActionInvocation.invoke(); EasyMock.expectLastCall().andReturn(Action.SUCCESS); - mockActionInvocation.getAction(); - EasyMock.expectLastCall().andReturn(action); + mockActionInvocation.addPreResultListener(EasyMock.<PreResultListener>anyObject()); + EasyMock.expectLastCall(); EasyMock.replay(mockActionInvocation); @@ -241,8 +161,8 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { EasyMock.expectLastCall().andReturn(action); EasyMock.expectLastCall().anyTimes(); - mockActionInvocation.getResult(); - EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); + mockActionInvocation.addPreResultListener(EasyMock.<PreResultListener>anyObject()); + EasyMock.expectLastCall(); EasyMock.replay(mockActionInvocation); @@ -301,81 +221,15 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { EasyMock.expectLastCall().andReturn(actionContext); EasyMock.expectLastCall().anyTimes(); - mockActionInvocation.invoke(); - EasyMock.expectLastCall().andReturn(Action.SUCCESS); - - mockActionInvocation.getAction(); - EasyMock.expectLastCall().andReturn(action); - EasyMock.expectLastCall().anyTimes(); - - mockActionInvocation.getResult(); - EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); - - EasyMock.replay(mockActionInvocation); + mockActionInvocation.addPreResultListener(EasyMock.<PreResultListener>anyObject()); + EasyMock.expectLastCall(); - interceptor.init(); - interceptor.intercept(mockActionInvocation); - interceptor.destroy(); - - assertEquals(3, sessionMap.size()); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionErrorsSessionKey)); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionMessagesSessionKey)); - assertTrue(sessionMap.containsKey(MessageStoreInterceptor.fieldErrorsSessionKey)); - - List actionErrors = (List) sessionMap.get(MessageStoreInterceptor.actionErrorsSessionKey); - List actionMessages = (List) sessionMap.get(MessageStoreInterceptor.actionMessagesSessionKey); - Map fieldErrors = (Map) sessionMap.get(MessageStoreInterceptor.fieldErrorsSessionKey); - - assertEquals(2, actionErrors.size()); - assertEquals(2, actionMessages.size()); - assertEquals(2, fieldErrors.size()); - - assertTrue(actionErrors.contains("some action error 1")); - assertTrue(actionErrors.contains("some action error 2")); - assertTrue(actionMessages.contains("some action message 1")); - assertTrue(actionMessages.contains("some action message 2")); - assertTrue(fieldErrors.containsKey("field1")); - assertTrue(fieldErrors.containsKey("field2")); - assertEquals(((List)fieldErrors.get("field1")).size(), 1); - assertEquals(((List)fieldErrors.get("field2")).size(), 1); - assertEquals(((List)fieldErrors.get("field1")).get(0), "some field error 1"); - assertEquals(((List)fieldErrors.get("field2")).get(0), "some field error 2"); - - EasyMock.verify(mockActionInvocation); - - action = new ActionSupport(); - - mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); mockActionInvocation.invoke(); EasyMock.expectLastCall().andReturn(Action.SUCCESS); - sessionMap.put(MessageStoreInterceptor.actionErrorsSessionKey, actionErrors); - sessionMap.put(MessageStoreInterceptor.actionMessagesSessionKey, actionMessages); - sessionMap.put(MessageStoreInterceptor.fieldErrorsSessionKey, fieldErrors); - - mockedSession = EasyMock.createControl().createMock(HttpSession.class); - mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); - mockedRequest.getSession(false); - EasyMock.expectLastCall().andReturn(mockedSession); - EasyMock.expectLastCall().once(); - ServletActionContext.setRequest(mockedRequest); - - EasyMock.replay(mockedRequest); - - actionContext = new ActionContext(new HashMap()); - actionContext.put(ActionContext.PARAMETERS, paramMap); - actionContext.put(ActionContext.SESSION, sessionMap); - - mockActionInvocation.getInvocationContext(); - EasyMock.expectLastCall().andReturn(actionContext); - EasyMock.expectLastCall().anyTimes(); - mockActionInvocation.getAction(); EasyMock.expectLastCall().andReturn(action); EasyMock.expectLastCall().anyTimes(); - - mockActionInvocation.getResult(); - EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); EasyMock.replay(mockActionInvocation); @@ -383,18 +237,6 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { interceptor.intercept(mockActionInvocation); interceptor.destroy(); - assertEquals(action.getActionErrors().size(), 2); - assertEquals(action.getActionMessages().size(), 2); - assertEquals(action.getFieldErrors().size(), 2); - assertTrue(action.getActionErrors().contains("some action error 1")); - assertTrue(action.getActionErrors().contains("some action error 2")); - assertTrue(action.getActionMessages().contains("some action message 1")); - assertTrue(action.getActionMessages().contains("some action message 2")); - assertEquals(((List)action.getFieldErrors().get("field1")).size(), 1); - assertEquals(((List)action.getFieldErrors().get("field2")).size(), 1); - assertEquals(((List)action.getFieldErrors().get("field1")).get(0), "some field error 1"); - assertEquals(((List)action.getFieldErrors().get("field2")).get(0), "some field error 2"); - EasyMock.verify(mockActionInvocation); } @@ -467,69 +309,4 @@ public class MessageStoreInterceptorTest extends StrutsInternalTestCase { } - public void testSessionWasInvalidated() throws Exception { - // given - ActionContext actionContext = new ActionContext(new HashMap()); - actionContext.put(ActionContext.PARAMETERS, new LinkedHashMap()); - - ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); - - mockActionInvocation.getInvocationContext(); - EasyMock.expectLastCall().andReturn(actionContext); - EasyMock.expectLastCall().anyTimes(); - - mockActionInvocation.invoke(); - EasyMock.expectLastCall().andReturn(Action.SUCCESS); - - EasyMock.replay(mockActionInvocation); - - HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); - mockedRequest.getSession(false); - EasyMock.expectLastCall().andReturn(null); - EasyMock.expectLastCall().once(); - ServletActionContext.setRequest(mockedRequest); - - EasyMock.replay(mockedRequest); - - // when - MessageStoreInterceptor msi = new MessageStoreInterceptor(); - msi.intercept(mockActionInvocation); - - // then - EasyMock.verify(mockActionInvocation); - EasyMock.verify(mockedRequest); - } - - public void testResponseWasComitted() throws Exception { - // given - ActionContext actionContext = new ActionContext(new HashMap()); - actionContext.put(ActionContext.PARAMETERS, new LinkedHashMap()); - - ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); - - mockActionInvocation.getInvocationContext(); - EasyMock.expectLastCall().andReturn(actionContext); - EasyMock.expectLastCall().anyTimes(); - - mockActionInvocation.invoke(); - EasyMock.expectLastCall().andReturn(Action.SUCCESS); - - EasyMock.replay(mockActionInvocation); - - HttpServletResponse mockedResponse = EasyMock.createControl().createMock(HttpServletResponse.class); - mockedResponse.isCommitted(); - EasyMock.expectLastCall().andReturn(true); - EasyMock.expectLastCall().once(); - ServletActionContext.setResponse(mockedResponse); - - EasyMock.replay(mockedResponse); - - // when - MessageStoreInterceptor msi = new MessageStoreInterceptor(); - msi.intercept(mockActionInvocation); - - // then - EasyMock.verify(mockActionInvocation); - EasyMock.verify(mockedResponse); - } } http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java new file mode 100644 index 0000000..599ab09 --- /dev/null +++ b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java @@ -0,0 +1,252 @@ +package org.apache.struts2.interceptor; + +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionSupport; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsInternalTestCase; +import org.apache.struts2.dispatcher.ServletActionRedirectResult; +import org.easymock.EasyMock; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class MessageStorePreResultListenerTest extends StrutsInternalTestCase { + + public void testSessionWasInvalidated() throws Exception { + // given + ActionContext actionContext = new ActionContext(new HashMap()); + actionContext.put(ActionContext.PARAMETERS, new LinkedHashMap()); + + ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); + + mockActionInvocation.getInvocationContext(); + EasyMock.expectLastCall().andReturn(actionContext); + EasyMock.expectLastCall().anyTimes(); + + EasyMock.replay(mockActionInvocation); + + HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); + mockedRequest.getSession(false); + EasyMock.expectLastCall().andReturn(null); + EasyMock.expectLastCall().once(); + ServletActionContext.setRequest(mockedRequest); + + EasyMock.replay(mockedRequest); + + HttpServletResponse mockedResponse = EasyMock.createControl().createMock(HttpServletResponse.class); + mockedResponse.isCommitted(); + EasyMock.expectLastCall().andReturn(false); + EasyMock.expectLastCall().once(); + ServletActionContext.setResponse(mockedResponse); + + EasyMock.replay(mockedResponse); + + // when + MessageStoreInterceptor msi = new MessageStoreInterceptor(); + MessageStorePreResultListener listener = new MessageStorePreResultListener(msi); + listener.beforeResult(mockActionInvocation, Action.SUCCESS); + + // then + EasyMock.verify(mockActionInvocation); + EasyMock.verify(mockedRequest); + EasyMock.verify(mockedResponse); + } + + public void testResponseWasComitted() throws Exception { + // given + ActionContext actionContext = new ActionContext(new HashMap()); + actionContext.put(ActionContext.PARAMETERS, new LinkedHashMap()); + + ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); + + mockActionInvocation.getInvocationContext(); + EasyMock.expectLastCall().andReturn(actionContext); + EasyMock.expectLastCall().anyTimes(); + + EasyMock.replay(mockActionInvocation); + + HttpServletResponse mockedResponse = EasyMock.createControl().createMock(HttpServletResponse.class); + mockedResponse.isCommitted(); + EasyMock.expectLastCall().andReturn(true); + EasyMock.expectLastCall().once(); + ServletActionContext.setResponse(mockedResponse); + + EasyMock.replay(mockedResponse); + + // when + MessageStoreInterceptor msi = new MessageStoreInterceptor(); + MessageStorePreResultListener listener = new MessageStorePreResultListener(msi); + listener.beforeResult(mockActionInvocation, Action.SUCCESS); + + // then + EasyMock.verify(mockActionInvocation); + EasyMock.verify(mockedResponse); + } + + public void testAutomatic() throws Exception { + MessageStoreInterceptor interceptor = new MessageStoreInterceptor(); + interceptor.setOperationMode(MessageStoreInterceptor.AUTOMATIC_MODE); + + MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor); + + Map paramMap = new LinkedHashMap(); + Map sessionMap = new LinkedHashMap(); + + ActionSupport action = new ActionSupport(); + action.addActionError("some action error 1"); + action.addActionError("some action error 2"); + action.addActionMessage("some action message 1"); + action.addActionMessage("some action message 2"); + action.addFieldError("field1", "some field error 1"); + action.addFieldError("field2", "some field error 2"); + + ActionContext actionContext = new ActionContext(new HashMap()); + actionContext.put(ActionContext.PARAMETERS, paramMap); + actionContext.put(ActionContext.SESSION, sessionMap); + + HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class); + HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); + mockedRequest.getSession(false); + EasyMock.expectLastCall().andReturn(mockedSession); + EasyMock.expectLastCall().once(); + ServletActionContext.setRequest(mockedRequest); + + EasyMock.replay(mockedRequest); + + HttpServletResponse mockedResponse = EasyMock.createControl().createMock(HttpServletResponse.class); + mockedResponse.isCommitted(); + EasyMock.expectLastCall().andReturn(false); + EasyMock.expectLastCall().once(); + ServletActionContext.setResponse(mockedResponse); + + EasyMock.replay(mockedResponse); + + // Mock (ActionInvocation) + ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); + mockActionInvocation.getInvocationContext(); + EasyMock.expectLastCall().andReturn(actionContext); + EasyMock.expectLastCall().anyTimes(); + + mockActionInvocation.getAction(); + EasyMock.expectLastCall().andReturn(action); + EasyMock.expectLastCall().anyTimes(); + + mockActionInvocation.getResult(); + EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); + + EasyMock.replay(mockActionInvocation); + + interceptor.init(); + listener.beforeResult(mockActionInvocation, Action.SUCCESS); + + List actionErrors = (List) sessionMap.get(MessageStoreInterceptor.actionErrorsSessionKey); + List actionMessages = (List) sessionMap.get(MessageStoreInterceptor.actionMessagesSessionKey); + Map fieldErrors = (Map) sessionMap.get(MessageStoreInterceptor.fieldErrorsSessionKey); + + assertEquals(actionErrors.size(), 2); + assertEquals(actionMessages.size(), 2); + assertEquals(fieldErrors.size(), 2); + assertTrue(actionErrors.contains("some action error 1")); + assertTrue(actionErrors.contains("some action error 2")); + assertTrue(actionMessages.contains("some action message 1")); + assertTrue(actionMessages.contains("some action message 2")); + assertEquals(((List) fieldErrors.get("field1")).size(), 1); + assertEquals(((List) fieldErrors.get("field2")).size(), 1); + assertEquals(((List) fieldErrors.get("field1")).get(0), "some field error 1"); + assertEquals(((List) fieldErrors.get("field2")).get(0), "some field error 2"); + + EasyMock.verify(mockActionInvocation); + } + + public void testStoreMessage() throws Exception { + MessageStoreInterceptor interceptor = new MessageStoreInterceptor(); + interceptor.setAllowRequestParameterSwitch(true); + interceptor.setOperationMode(MessageStoreInterceptor.STORE_MODE); + + MessageStorePreResultListener listener = new MessageStorePreResultListener(interceptor); + + Map paramMap = new LinkedHashMap(); + Map sessionMap = new LinkedHashMap(); + + ActionSupport action = new ActionSupport(); + action.addActionError("some action error 1"); + action.addActionError("some action error 2"); + action.addActionMessage("some action message 1"); + action.addActionMessage("some action message 2"); + action.addFieldError("field1", "some field error 1"); + action.addFieldError("field2", "some field error 2"); + + ActionContext actionContext = new ActionContext(new HashMap()); + actionContext.put(ActionContext.PARAMETERS, paramMap); + actionContext.put(ActionContext.SESSION, sessionMap); + + HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class); + HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class); + mockedRequest.getSession(false); + EasyMock.expectLastCall().andReturn(mockedSession); + EasyMock.expectLastCall().once(); + ServletActionContext.setRequest(mockedRequest); + + EasyMock.replay(mockedRequest); + + HttpServletResponse mockedResponse = EasyMock.createControl().createMock(HttpServletResponse.class); + mockedResponse.isCommitted(); + EasyMock.expectLastCall().andReturn(false); + EasyMock.expectLastCall().once(); + ServletActionContext.setResponse(mockedResponse); + + EasyMock.replay(mockedResponse); + + // Mock (ActionInvocation) + ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class); + mockActionInvocation.getInvocationContext(); + EasyMock.expectLastCall().andReturn(actionContext); + EasyMock.expectLastCall().anyTimes(); + + mockActionInvocation.getAction(); + EasyMock.expectLastCall().andReturn(action); + + mockActionInvocation.getResult(); + EasyMock.expectLastCall().andReturn(new ServletActionRedirectResult()); + + EasyMock.replay(mockActionInvocation); + + interceptor.init(); + listener.beforeResult(mockActionInvocation, Action.SUCCESS); + + assertEquals(sessionMap.size(), 3); + assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionErrorsSessionKey)); + assertTrue(sessionMap.containsKey(MessageStoreInterceptor.actionMessagesSessionKey)); + assertTrue(sessionMap.containsKey(MessageStoreInterceptor.fieldErrorsSessionKey)); + + List actionErrors = (List) sessionMap.get(MessageStoreInterceptor.actionErrorsSessionKey); + List actionMessages = (List) sessionMap.get(MessageStoreInterceptor.actionMessagesSessionKey); + Map fieldErrors = (Map) sessionMap.get(MessageStoreInterceptor.fieldErrorsSessionKey); + + assertEquals(actionErrors.size(), 2); + assertEquals(actionMessages.size(), 2); + assertEquals(fieldErrors.size(), 2); + + assertTrue(actionErrors.contains("some action error 1")); + assertTrue(actionErrors.contains("some action error 2")); + assertTrue(actionMessages.contains("some action message 1")); + assertTrue(actionMessages.contains("some action message 2")); + assertTrue(fieldErrors.containsKey("field1")); + assertTrue(fieldErrors.containsKey("field2")); + assertEquals(((List)fieldErrors.get("field1")).size(), 1); + assertEquals(((List)fieldErrors.get("field2")).size(), 1); + assertEquals(((List)fieldErrors.get("field1")).get(0), "some field error 1"); + assertEquals(((List)fieldErrors.get("field2")).get(0), "some field error 2"); + + EasyMock.verify(mockActionInvocation); + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java index d31e498..f7d8a3b 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java @@ -179,7 +179,8 @@ public class ActionTagTest extends AbstractTagTest { assertTrue(stack.getContext().containsKey(ServletActionContext.PAGE_CONTEXT)); assertTrue(stack.getContext().get(ServletActionContext.PAGE_CONTEXT)instanceof PageContext); - assertNull(result); // result is never executed, hence never set into invocation + assertNotNull(result); + assertFalse(result.isExecuted()); } public void testExecuteButResetReturnSameInvocation() throws Exception { http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index e3e13f3..b82efaf 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -184,6 +184,7 @@ public class DefaultActionInvocation implements ActionInvocation { } public Result createResult() throws Exception { + LOG.trace("Creating result related to resultCode [#0]", resultCode); if (explicitResult != null) { Result ret = explicitResult; @@ -253,7 +254,11 @@ public class DefaultActionInvocation implements ActionInvocation { // this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) { + result = createResult(); + if (preResultListeners != null) { + LOG.trace("Executing PreResultListeners for result [#0]", result); + for (Object preResultListener : preResultListeners) { PreResultListener listener = (PreResultListener) preResultListener; @@ -360,8 +365,6 @@ public class DefaultActionInvocation implements ActionInvocation { * @throws ConfigurationException If not result can be found with the returned code */ private void executeResult() throws Exception { - result = createResult(); - String timerKey = "executeResult: " + getResultCode(); try { UtilTimerStack.push(timerKey); http://git-wip-us.apache.org/repos/asf/struts/blob/9c7b8336/xwork-core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java b/xwork-core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java index 4291538..d3eef1b 100644 --- a/xwork-core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java +++ b/xwork-core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java @@ -1,6 +1,8 @@ package com.opensymphony.xwork2; +import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; +import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.mock.MockActionProxy; import com.opensymphony.xwork2.mock.MockContainer; import com.opensymphony.xwork2.mock.MockInterceptor; @@ -348,6 +350,7 @@ class DefaultActionInvocationTester extends DefaultActionInvocation { interceptors = interceptorMappings.iterator(); MockActionProxy actionProxy = new MockActionProxy(); actionProxy.setMethod("execute"); + actionProxy.setConfig(new ActionConfig.Builder("foo", "bar", "clazz").addResultConfig(new ResultConfig.Builder("buzz", "fizz").build()).build()); proxy = actionProxy; action = new ActionSupport(); }