This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch action-context-boost in repository https://gitbox.apache.org/repos/asf/struts.git
The following commit(s) were added to refs/heads/action-context-boost by this push: new adcc67d WW-4789 WW-3788 Marks VALUE_STACK, APPLICATION and SESSION as deprecated on behalf using helper methods adcc67d is described below commit adcc67d9dc40782c5df04e33282440749e977548 Author: Lukasz Lenart <lukaszlen...@apache.org> AuthorDate: Mon Apr 13 17:24:16 2020 +0200 WW-4789 WW-3788 Marks VALUE_STACK, APPLICATION and SESSION as deprecated on behalf using helper methods --- .../com/opensymphony/xwork2/ActionChainResult.java | 9 +- .../com/opensymphony/xwork2/ActionContext.java | 18 ++ .../xwork2/DefaultActionInvocation.java | 4 +- .../apache/struts2/components/ActionComponent.java | 15 +- .../org/apache/struts2/dispatcher/Dispatcher.java | 46 +++--- .../debugging/DebuggingInterceptor.java | 14 +- .../com/opensymphony/xwork2/ActionNestingTest.java | 38 +++-- .../interceptor/ExecuteAndWaitInterceptorTest.java | 41 +++-- .../struts2/interceptor/TokenInterceptorTest.java | 28 ++-- .../apache/struts2/validators/DWRValidator.java | 8 +- .../portlet/dispatcher/Jsr168Dispatcher.java | 183 ++++++++++----------- .../struts2/views/jsp/PortletUrlTagTest.java | 17 +- 12 files changed, 225 insertions(+), 196 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java index 6094f4b..06ab021 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java @@ -221,10 +221,11 @@ public class ActionChainResult implements Result { } addToHistory(finalNamespace, finalActionName, finalMethodName); - HashMap<String, Object> extraContext = new HashMap<>(); - extraContext.put(ActionContext.VALUE_STACK, invocation.getInvocationContext().getValueStack()); - extraContext.put(ActionContext.PARAMETERS, invocation.getInvocationContext().getParameters()); - extraContext.put(CHAIN_HISTORY, ActionChainResult.getChainHistory()); + Map<String, Object> extraContext = ActionContext.of(new HashMap<>()) + .withValueStack(invocation.getInvocationContext().getValueStack()) + .withParameters(invocation.getInvocationContext().getParameters()) + .with(CHAIN_HISTORY, ActionChainResult.getChainHistory()) + .getContextMap(); LOG.debug("Chaining to action {}", finalActionName); diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java index e4d9f73..8900aef 100644 --- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java +++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.PageContext; import java.io.Serializable; import java.util.HashMap; +import java.util.LinkedList; import java.util.Locale; import java.util.Map; @@ -70,22 +71,30 @@ public class ActionContext implements Serializable { /** * Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}. + * @deprecated scope will be narrowed to "private", use helper methods instead */ + @Deprecated public static final String VALUE_STACK = ValueStack.VALUE_STACK; /** * Constant for the action's session. + * @deprecated scope will be narrowed to "private", use helper methods instead */ + @Deprecated public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session"; /** * Constant for the action's application context. + * @deprecated scope will be narrowed to "private", use helper methods instead */ + @Deprecated public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application"; /** * Constant for the action's parameters. + * @deprecated scope will be narrowed to "private", use helper methods instead */ + @Deprecated public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters"; /** @@ -150,6 +159,10 @@ public class ActionContext implements Serializable { return ActionContext.getContext(); } + public static boolean containsValueStack(Map<String, Object> context) { + return context != null && context.containsKey(VALUE_STACK); + } + /** * Binds this context with the current thread * @@ -533,4 +546,9 @@ public class ActionContext implements Serializable { put(LOCALE, locale); return this; } + + public ActionContext with(String key, Object value) { + put(key, value); + return this; + } } diff --git a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java index 6ca0c92..ea2076d 100644 --- a/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java +++ b/core/src/main/java/com/opensymphony/xwork2/DefaultActionInvocation.java @@ -326,9 +326,9 @@ public class DefaultActionInvocation implements ActionInvocation { protected Map<String, Object> createContextMap() { ActionContext actionContext; - if (extraContext != null && extraContext.containsKey(ActionContext.VALUE_STACK)) { + if (ActionContext.containsValueStack(extraContext)) { // In case the ValueStack was passed in - stack = (ValueStack) extraContext.get(ActionContext.VALUE_STACK); + stack = ActionContext.of(extraContext).getValueStack(); if (stack == null) { throw new IllegalStateException("There was a null Stack set into the extra params."); diff --git a/core/src/main/java/org/apache/struts2/components/ActionComponent.java b/core/src/main/java/org/apache/struts2/components/ActionComponent.java index 727a216..98251ba 100644 --- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java +++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java @@ -175,7 +175,7 @@ public class ActionComponent extends ContextBean { return end; } - protected Map createExtraContext() { + protected Map<String, Object> createExtraContext() { HttpParameters newParams = createParametersForContext(); ActionContext ctx = stack.getActionContext(); @@ -184,7 +184,8 @@ public class ActionComponent extends ContextBean { Map<String, Object> application = ctx.getApplication(); Dispatcher du = Dispatcher.getInstance(); - Map<String, Object> extraContext = du.createContextMap(new RequestMap(req), + Map<String, Object> extraContext = du.createContextMap( + new RequestMap(req), newParams, session, application, @@ -192,12 +193,12 @@ public class ActionComponent extends ContextBean { res); ValueStack newStack = valueStackFactory.createValueStack(stack); - extraContext.put(ActionContext.VALUE_STACK, newStack); - // add page context, such that ServletDispatcherResult will do an include - extraContext.put(ServletActionContext.PAGE_CONTEXT, pageContext); - - return extraContext; + return ActionContext.of(extraContext) + .withValueStack(newStack) + // add page context, such that ServletDispatcherResult will do an include + .withPageContext(pageContext) + .getContextMap(); } /** diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java index 44c7b91..b2951ad 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java @@ -606,7 +606,9 @@ public class Dispatcher { } } if (stack != null) { - extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack)); + extraContext = ActionContext.of(extraContext) + .withValueStack(valueStackFactory.createValueStack(stack)) + .getContextMap(); } try { @@ -718,28 +720,26 @@ public class Dispatcher { * @return a HashMap representing the <tt>Action</tt> context. * @since 2.3.17 */ - public HashMap<String, Object> createContextMap(Map requestMap, - HttpParameters parameters, - Map sessionMap, - Map applicationMap, - HttpServletRequest request, - HttpServletResponse response) { - HashMap<String, Object> extraContext = new HashMap<>(); - extraContext.put(ActionContext.PARAMETERS, parameters); - extraContext.put(ActionContext.SESSION, sessionMap); - extraContext.put(ActionContext.APPLICATION, applicationMap); - - extraContext.put(ActionContext.LOCALE, getLocale(request)); - - extraContext.put(StrutsStatics.HTTP_REQUEST, request); - extraContext.put(StrutsStatics.HTTP_RESPONSE, response); - extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext); - - // helpers to get access to request/session/application scope - extraContext.put("request", requestMap); - extraContext.put("session", sessionMap); - extraContext.put("application", applicationMap); - extraContext.put("parameters", parameters); + public Map<String, Object> createContextMap(Map<String, Object> requestMap, + HttpParameters parameters, + Map<String, Object> sessionMap, + Map<String, Object> applicationMap, + HttpServletRequest request, + HttpServletResponse response) { + Map<String, Object> extraContext = ActionContext.of(new HashMap<>()) + .withParameters(parameters) + .withSession(sessionMap) + .withApplication(applicationMap) + .withLocale(getLocale(request)) + .withServletRequest(request) + .withServletResponse(response) + .withServletContext(servletContext) + // helpers to get access to request/session/application scope + .with("request", requestMap) + .with("session", sessionMap) + .with("application", applicationMap) + .with("parameters", parameters) + .getContextMap(); AttributeMap attrMap = new AttributeMap(extraContext); extraContext.put("attr", attrMap); diff --git a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java index 1cff710..62f8716 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java @@ -304,14 +304,12 @@ public class DebuggingInterceptor extends AbstractInterceptor { writer.startNode(DEBUG_PARAM); serializeIt(ctx.getParameters(), "parameters", writer, new ArrayList<>()); writer.startNode("context"); - String key; - Map ctxMap = ctx.getContextMap(); - for (Object o : ctxMap.keySet()) { - key = o.toString(); + Map<String, Object> ctxMap = ctx.getContextMap(); + for (String key : ctxMap.keySet()) { boolean print = !ignoreKeys.contains(key); - for (String ignorePrefixe : ignorePrefixes) { - if (key.startsWith(ignorePrefixe)) { + for (String ignorePrefix : ignorePrefixes) { + if (key.startsWith(ignorePrefix)) { print = false; break; } @@ -321,11 +319,11 @@ public class DebuggingInterceptor extends AbstractInterceptor { } } writer.endNode(); - Map requestMap = (Map) ctx.get("request"); + Map<String, Object> requestMap = (Map<String, Object>) ctx.get("request"); serializeIt(requestMap, "request", writer, filterValueStack(requestMap)); serializeIt(ctx.getSession(), "session", writer, new ArrayList<>()); - ValueStack stack = (ValueStack) ctx.get(ActionContext.VALUE_STACK); + ValueStack stack = ctx.getValueStack(); serializeIt(stack.getRoot(), "valueStack", writer, new ArrayList<>()); writer.endNode(); } diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java index 3344ee5..cc4f017 100644 --- a/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java +++ b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java @@ -29,13 +29,14 @@ import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.location.LocatableProperties; import java.util.HashMap; +import java.util.Map; /** * ActionNestingTest * * @author Jason Carreira - * Created Mar 5, 2003 2:02:01 PM + * Created Mar 5, 2003 2:02:01 PM */ public class ActionNestingTest extends XWorkTestCase { @@ -56,7 +57,8 @@ public class ActionNestingTest extends XWorkTestCase { return VALUE; } - @Override public void setUp() throws Exception { + @Override + public void setUp() throws Exception { super.setUp(); loadConfigurationProviders(new NestedTestConfigurationProvider()); @@ -64,7 +66,8 @@ public class ActionNestingTest extends XWorkTestCase { context.getValueStack().push(this); } - @Override protected void tearDown() throws Exception { + @Override + protected void tearDown() throws Exception { super.tearDown(); } @@ -90,8 +93,9 @@ public class ActionNestingTest extends XWorkTestCase { ValueStack stack = ActionContext.getContext().getValueStack(); assertEquals(VALUE, stack.findValue(KEY)); - HashMap<String, Object> extraContext = new HashMap<>(); - extraContext.put(ActionContext.VALUE_STACK, stack); + Map<String, Object> extraContext = ActionContext.of(new HashMap<>()) + .withValueStack(stack) + .getContextMap(); ActionProxy proxy = actionProxyFactory.createActionProxy(NAMESPACE, STACK_ACTION_NAME, null, extraContext); proxy.execute(); @@ -105,30 +109,32 @@ public class ActionNestingTest extends XWorkTestCase { class NestedTestConfigurationProvider implements ConfigurationProvider { private Configuration configuration; + public void destroy() { } + public void init(Configuration configuration) { this.configuration = configuration; } public void register(ContainerBuilder builder, LocatableProperties props) { } - + public void loadPackages() { - + PackageConfig packageContext = new PackageConfig.Builder("nestedActionTest") .addActionConfig(SIMPLE_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", SIMPLE_ACTION_NAME, SimpleAction.class.getName()) - .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) - .addResultConfig(new ResultConfig.Builder(Action.ERROR, MockResult.class.getName()).build()) - .build()) + .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) + .addResultConfig(new ResultConfig.Builder(Action.ERROR, MockResult.class.getName()).build()) + .build()) .addActionConfig(NO_STACK_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", NO_STACK_ACTION_NAME, NestedAction.class.getName()) - .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) - .methodName("noStack") - .build()) + .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) + .methodName("noStack") + .build()) .addActionConfig(STACK_ACTION_NAME, new ActionConfig.Builder("nestedActionTest", STACK_ACTION_NAME, NestedAction.class.getName()) - .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) - .methodName("stack") - .build()) + .addResultConfig(new ResultConfig.Builder(Action.SUCCESS, MockResult.class.getName()).build()) + .methodName("stack") + .build()) .namespace(NAMESPACE) .build(); configuration.addPackageConfig("nestedActionTest", packageContext); diff --git a/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java index 1372a5a..08c034b 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java @@ -18,7 +18,12 @@ */ package org.apache.struts2.interceptor; -import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.DefaultActionProxyFactory; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.ConfigurationProvider; @@ -52,9 +57,9 @@ public class ExecuteAndWaitInterceptorTest extends StrutsInternalTestCase { private StrutsMockHttpServletRequest request; private HttpSession httpSession; - private Map context; - private Map params; - private Map session; + private Map<String, Object> context; + private Map<String, Object> params; + private Map<String, Object> session; private ExecuteAndWaitInterceptor waitInterceptor; private ParametersInterceptor parametersInterceptor; @@ -175,13 +180,13 @@ public class ExecuteAndWaitInterceptorTest extends StrutsInternalTestCase { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(session);//WW-4900 action1 and invocation are not serializable but we should not fail at this line oos.close(); - byte b[] = baos.toByteArray(); + byte[] b = baos.toByteArray(); baos.close(); ByteArrayInputStream bais = new ByteArrayInputStream(b); ObjectInputStream ois = new ObjectInputStream(bais); - session = (Map) ois.readObject(); - context.put(ActionContext.SESSION, session); + session = (Map<String, Object>) ois.readObject(); + context = ActionContext.of(context).withSession(session).getContextMap(); ois.close(); bais.close(); @@ -203,19 +208,24 @@ public class ExecuteAndWaitInterceptorTest extends StrutsInternalTestCase { } protected void setUp() throws Exception { + super.setUp(); loadConfigurationProviders(new WaitConfigurationProvider()); - session = new HashMap(); - params = new HashMap(); - context = new HashMap(); - context.put(ActionContext.SESSION, session); - context.put(ActionContext.PARAMETERS, HttpParameters.create().build()); + session = new HashMap<>(); + params = new HashMap<>(); + context = new HashMap<>(); request = new StrutsMockHttpServletRequest(); httpSession = new StrutsMockHttpSession(); request.setSession(httpSession); request.setParameterMap(params); - context.put(ServletActionContext.HTTP_REQUEST, request); + + context = ActionContext.of(context) + .withSession(session) + .withParameters(HttpParameters.create().build()) + .withServletRequest(request) + .getContextMap(); + container.inject(parametersInterceptor); } @@ -226,6 +236,7 @@ public class ExecuteAndWaitInterceptorTest extends StrutsInternalTestCase { private class WaitConfigurationProvider implements ConfigurationProvider { Configuration configuration; + public void destroy() { waitInterceptor.destroy(); } @@ -250,8 +261,8 @@ public class ExecuteAndWaitInterceptorTest extends StrutsInternalTestCase { .addResultConfig(new ResultConfig.Builder(ExecuteAndWaitInterceptor.WAIT, MockResult.class.getName()).build()) .addInterceptor(new InterceptorMapping("params", parametersInterceptor)) .addInterceptor(new InterceptorMapping("execAndWait", waitInterceptor)) - .build()) - .build(); + .build()) + .build(); configuration.addPackageConfig("", wait); } diff --git a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java index f10e5e5..2208047 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java @@ -18,12 +18,10 @@ */ package org.apache.struts2.interceptor; -import java.util.Map; -import java.util.TreeMap; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsInternalTestCase; import org.apache.struts2.TestConfigurationProvider; @@ -32,10 +30,10 @@ import org.apache.struts2.util.TokenHelper; import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest; import org.apache.struts2.views.jsp.StrutsMockHttpSession; -import com.opensymphony.xwork2.Action; -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.util.ValueStack; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.Map; +import java.util.TreeMap; /** @@ -95,10 +93,10 @@ public class TokenInterceptorTest extends StrutsInternalTestCase { protected void setToken(String token) { request.getParameterMap().put(TokenHelper.TOKEN_NAME_FIELD, new String[]{ - TokenHelper.DEFAULT_TOKEN_NAME + TokenHelper.DEFAULT_TOKEN_NAME }); request.getParameterMap().put(TokenHelper.DEFAULT_TOKEN_NAME, new String[]{ - token + token }); extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build()); } @@ -111,8 +109,10 @@ public class TokenInterceptorTest extends StrutsInternalTestCase { session = new TreeMap<>(); params = new TreeMap<>(); extraContext = new TreeMap<>(); - extraContext.put(ActionContext.SESSION, session); - extraContext.put(ActionContext.PARAMETERS, HttpParameters.create().build()); + extraContext = ActionContext.of(extraContext) + .withSession(session) + .withParameters(HttpParameters.create().build()) + .getContextMap(); request = new StrutsMockHttpServletRequest(); httpSession = new StrutsMockHttpSession(); diff --git a/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java b/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java index 60edf4b..c8cc669 100644 --- a/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java +++ b/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java @@ -75,11 +75,11 @@ public class DWRValidator { if (params != null) { requestParams = requestParams.withExtraParams(params); } - Map requestMap = new RequestMap(req); - Map session = new SessionMap(req); - Map application = new ApplicationMap(servletContext); + Map<String, Object> requestMap = new RequestMap(req); + Map<String, Object> session = new SessionMap<>(req); + Map<String, Object> application = new ApplicationMap(servletContext); Dispatcher du = Dispatcher.getInstance(); - HashMap<String, Object> ctx = du.createContextMap(requestMap, + Map<String, Object> ctx = du.createContextMap(requestMap, requestParams.build(), session, application, diff --git a/plugins/portlet/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java b/plugins/portlet/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java index 6b985ff..cc7b00c 100644 --- a/plugins/portlet/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java +++ b/plugins/portlet/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java @@ -24,9 +24,9 @@ import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.inject.Container; import org.apache.commons.lang3.LocaleUtils; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; import org.apache.commons.lang3.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsException; @@ -214,21 +214,21 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { LOG.debug("PortletNamespace: {}", portletNamespace); parseModeConfig(actionMap, cfg, PortletMode.VIEW, "viewNamespace", - "defaultViewAction"); + "defaultViewAction"); parseModeConfig(actionMap, cfg, PortletMode.EDIT, "editNamespace", - "defaultEditAction"); + "defaultEditAction"); parseModeConfig(actionMap, cfg, PortletMode.HELP, "helpNamespace", - "defaultHelpAction"); + "defaultHelpAction"); parseModeConfig(actionMap, cfg, new PortletMode("config"), "configNamespace", - "defaultConfigAction"); + "defaultConfigAction"); parseModeConfig(actionMap, cfg, new PortletMode("about"), "aboutNamespace", - "defaultAboutAction"); + "defaultAboutAction"); parseModeConfig(actionMap, cfg, new PortletMode("print"), "printNamespace", - "defaultPrintAction"); + "defaultPrintAction"); parseModeConfig(actionMap, cfg, new PortletMode("preview"), "previewNamespace", - "defaultPreviewAction"); + "defaultPreviewAction"); parseModeConfig(actionMap, cfg, new PortletMode("edit_defaults"), - "editDefaultsNamespace", "defaultEditDefaultsAction"); + "editDefaultsNamespace", "defaultEditDefaultsAction"); if (StringUtils.isEmpty(portletNamespace)) { portletNamespace = ""; } @@ -239,13 +239,14 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Parse the mode to namespace mappings configured in portlet.xml - * @param actionMap The map with mode <-> default action mapping. - * @param portletConfig The PortletConfig. - * @param portletMode The PortletMode. - * @param nameSpaceParam Name of the init parameter where the namespace for the mode - * is configured. + * + * @param actionMap The map with mode <-> default action mapping. + * @param portletConfig The PortletConfig. + * @param portletMode The PortletMode. + * @param nameSpaceParam Name of the init parameter where the namespace for the mode + * is configured. * @param defaultActionParam Name of the init parameter where the default action to - * execute for the mode is configured. + * execute for the mode is configured. */ void parseModeConfig(Map<PortletMode, ActionMapping> actionMap, PortletConfig portletConfig, PortletMode portletMode, String nameSpaceParam, @@ -286,25 +287,23 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Service an action from the <tt>event</tt> phase. * - * @param request action request - * @param response action response - * + * @param request action request + * @param response action response * @throws PortletException in case of errors - * @throws IOException in case of IO errors - * + * @throws IOException in case of IO errors * @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest, - * javax.portlet.ActionResponse) + * javax.portlet.ActionResponse) */ public void processAction(ActionRequest request, ActionResponse response) - throws PortletException, IOException { + throws PortletException, IOException { if (LOG.isDebugEnabled()) { LOG.debug("Entering processAction in mode ", request.getPortletMode().toString()); } resetActionContext(); try { serviceAction(request, response, getRequestMap(request), getParameterMap(request), - getSessionMap(request), getApplicationMap(), - portletNamespace, PortletPhase.ACTION_PHASE); + getSessionMap(request), getApplicationMap(), + portletNamespace, PortletPhase.ACTION_PHASE); if (LOG.isDebugEnabled()) LOG.debug("Leaving processAction"); } finally { ActionContext.clear(); @@ -314,17 +313,15 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Service an action from the <tt>render</tt> phase. * - * @param request render request - * @param response render response - * + * @param request render request + * @param response render response * @throws PortletException in case of errors - * @throws IOException in case of IO errors - * + * @throws IOException in case of IO errors * @see javax.portlet.Portlet#render(javax.portlet.RenderRequest, - * javax.portlet.RenderResponse) + * javax.portlet.RenderResponse) */ public void render(RenderRequest request, RenderResponse response) - throws PortletException, IOException { + throws PortletException, IOException { if (LOG.isDebugEnabled()) { LOG.debug("Entering render in mode ", request.getPortletMode().toString()); @@ -335,8 +332,8 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { try { // Check to see if an event set the render to be included directly serviceAction(request, response, getRequestMap(request), getParameterMap(request), - getSessionMap(request), getApplicationMap(), - portletNamespace, PortletPhase.RENDER_PHASE); + getSessionMap(request), getApplicationMap(), + portletNamespace, PortletPhase.RENDER_PHASE); if (LOG.isDebugEnabled()) LOG.debug("Leaving render"); } finally { resetActionContext(); @@ -345,7 +342,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { } /** - * Reset the action context. + * Reset the action context. */ void resetActionContext() { ActionContext.clear(); @@ -355,59 +352,54 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * Merges all application and portlet attributes into a single * <tt>HashMap</tt> to represent the entire <tt>Action</tt> context. * - * @param requestMap a Map of all request attributes. - * @param parameterMap a Map of all request parameters. - * @param sessionMap a Map of all session attributes. - * @param applicationMap a Map of all servlet context attributes. - * @param request the PortletRequest object. - * @param response the PortletResponse object. - * @param servletRequest the HttpServletRequest object. + * @param requestMap a Map of all request attributes. + * @param parameterMap a Map of all request parameters. + * @param sessionMap a Map of all session attributes. + * @param applicationMap a Map of all servlet context attributes. + * @param request the PortletRequest object. + * @param response the PortletResponse object. + * @param servletRequest the HttpServletRequest object. * @param servletResponse the HttpServletResponse object. - * @param servletContext the ServletContext object. - * @param portletConfig the PortletConfig object. - * @param phase The portlet phase (render or action, see - * {@link PortletConstants}) + * @param servletContext the ServletContext object. + * @param portletConfig the PortletConfig object. + * @param phase The portlet phase (render or action, see + * {@link PortletConstants}) * @return a HashMap representing the <tt>Action</tt> context. - * * @throws IOException in case of IO errors */ - public HashMap<String, Object> createContextMap(Map<String, Object> requestMap, Map<String, String[]> parameterMap, - Map<String, Object> sessionMap, Map<String, Object> applicationMap, - PortletRequest request, PortletResponse response, HttpServletRequest servletRequest, - HttpServletResponse servletResponse, ServletContext servletContext, - PortletConfig portletConfig, PortletPhase phase) throws IOException { + public Map<String, Object> createContextMap(Map<String, Object> requestMap, Map<String, String[]> parameterMap, + Map<String, Object> sessionMap, Map<String, Object> applicationMap, + PortletRequest request, PortletResponse response, HttpServletRequest servletRequest, + HttpServletResponse servletResponse, ServletContext servletContext, + PortletConfig portletConfig, PortletPhase phase) throws IOException { // TODO Must put http request/response objects into map for use with container.inject(servletRequest); // ServletActionContext - HashMap<String, Object> extraContext = new HashMap<String, Object>(); - // The dummy servlet objects. Eases reuse of existing interceptors that uses the servlet objects. - extraContext.put(StrutsStatics.HTTP_REQUEST, servletRequest); - extraContext.put(StrutsStatics.HTTP_RESPONSE, servletResponse); - extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext); - // End dummy servlet objects - extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(parameterMap).build()); - extraContext.put(ActionContext.SESSION, sessionMap); - extraContext.put(ActionContext.APPLICATION, applicationMap); - - extraContext.put(ActionContext.LOCALE, getLocale(request)); - - extraContext.put(StrutsStatics.STRUTS_PORTLET_CONTEXT, getPortletContext()); - extraContext.put(REQUEST, request); - extraContext.put(RESPONSE, response); - extraContext.put(PORTLET_CONFIG, portletConfig); - extraContext.put(PORTLET_NAMESPACE, portletNamespace); - extraContext.put(DEFAULT_ACTION_FOR_MODE, actionMap.get(request.getPortletMode())); - // helpers to get access to request/session/application scope - extraContext.put("request", requestMap); - extraContext.put("session", sessionMap); - extraContext.put("application", applicationMap); - extraContext.put("parameters", parameterMap); - extraContext.put(MODE_NAMESPACE_MAP, modeMap); - extraContext.put(PortletConstants.DEFAULT_ACTION_MAP, actionMap); - - extraContext.put(PortletConstants.PHASE, phase); + Map<String, Object> extraContext = ActionContext.of(new HashMap<String, Object>()) + .withServletRequest(servletRequest) + .withServletResponse(servletResponse) + .withServletContext(servletContext) + .withParameters(HttpParameters.create(parameterMap).build()) + .withSession(sessionMap) + .withApplication(applicationMap) + .withLocale(getLocale(request)) + .with(StrutsStatics.STRUTS_PORTLET_CONTEXT, getPortletContext()) + .with(REQUEST, request) + .with(RESPONSE, response) + .with(PORTLET_CONFIG, portletConfig) + .with(PORTLET_NAMESPACE, portletNamespace) + .with(DEFAULT_ACTION_FOR_MODE, actionMap.get(request.getPortletMode())) + // helpers to get access to request/session/application scope + .with("request", requestMap) + .with("session", sessionMap) + .with("application", applicationMap) + .with("parameters", parameterMap) + .with(MODE_NAMESPACE_MAP, modeMap) + .with(PortletConstants.DEFAULT_ACTION_MAP, actionMap) + .with(PortletConstants.PHASE, phase) + .getContextMap(); AttributeMap attrMap = new AttributeMap(extraContext); extraContext.put("attr", attrMap); @@ -423,7 +415,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { locale = LocaleUtils.toLocale(defaultLocale); } catch (IllegalArgumentException e) { LOG.warn(new ParameterizedMessage("Cannot convert 'struts.locale' = [{}] to proper locale, defaulting to request locale [{}]", - defaultLocale, request.getLocale()), e); + defaultLocale, request.getLocale()), e); locale = request.getLocale(); } } else { @@ -438,15 +430,14 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * from the given action name and namespace. After that, the action is * executed and output channels throught the response object. * - * @param request the HttpServletRequest object. - * @param response the HttpServletResponse object. - * @param requestMap a Map of request attributes. - * @param parameterMap a Map of request parameters. - * @param sessionMap a Map of all session attributes. - * @param applicationMap a Map of all application attributes. + * @param request the HttpServletRequest object. + * @param response the HttpServletResponse object. + * @param requestMap a Map of request attributes. + * @param parameterMap a Map of request parameters. + * @param sessionMap a Map of all session attributes. + * @param applicationMap a Map of all application attributes. * @param portletNamespace the namespace or context of the action. - * @param phase The portlet phase (render or action, see {@link PortletConstants}) - * + * @param phase The portlet phase (render or action, see {@link PortletConstants}) * @throws PortletException in case of errors */ public void serviceAction(PortletRequest request, PortletResponse response, Map<String, Object> requestMap, Map<String, String[]> parameterMap, @@ -475,9 +466,9 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { } else { namespace = mapping.getNamespace(); } - HashMap<String, Object> extraContext = createContextMap(requestMap, parameterMap, - sessionMap, applicationMap, request, response, servletRequest, servletResponse, - servletContext, getPortletConfig(), phase); + Map<String, Object> extraContext = createContextMap(requestMap, parameterMap, + sessionMap, applicationMap, request, response, servletRequest, servletResponse, + servletContext, getPortletConfig(), phase); extraContext.put(PortletConstants.ACTION_MAPPING, mapping); if (LOG.isDebugEnabled()) { LOG.debug("Creating action proxy for name = " + actionName + ", namespace = " + namespace); @@ -518,7 +509,6 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * * @param portletRequest the PortletRequest object. * @param servletRequest the ServletRequest to use - * * @return the namespace of the action. */ protected ActionMapping getActionMapping(final PortletRequest portletRequest, final HttpServletRequest servletRequest) { @@ -551,6 +541,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Get the namespace part of the action path. + * * @param actionPath Full path to action * @return The namespace part. */ @@ -565,6 +556,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Get the action name part of the action path. + * * @param actionPath Full path to action * @return The action name. */ @@ -584,7 +576,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * @param request the PortletRequest object. * @return a Map of all request parameters. * @throws IOException if an exception occurs while retrieving the parameter - * map. + * map. */ protected Map<String, String[]> getParameterMap(PortletRequest request) throws IOException { return new HashMap<String, String[]>(request.getParameterMap()); @@ -616,6 +608,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { /** * Convenience method to ease testing. + * * @param factory action proxy factory */ protected void setActionProxyFactory(ActionProxyFactory factory) { @@ -627,6 +620,7 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * mode has been changed with the portal widgets, the action name is invalid, since the * action name belongs to the previous executing portlet mode. If this method evaluates to * <code>true</code> the <code>default<Mode>Action</code> is used instead. + * * @param request The portlet request. * @return <code>true</code> if the action should be reset. */ @@ -670,10 +664,9 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics { * Method to create a PortletServletResponse matching the used Portlet API, to be overridden for JSR286 Dispatcher. * * @param response The Response used for building the wrapper. - * * @return The wrapper response for Servlet bound usage. */ - protected PortletServletResponse createPortletServletResponse( PortletResponse response ) { + protected PortletServletResponse createPortletServletResponse(PortletResponse response) { return new PortletServletResponse(response); } diff --git a/plugins/portlet/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java b/plugins/portlet/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java index a1e5598..9beef5d 100644 --- a/plugins/portlet/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java +++ b/plugins/portlet/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java @@ -144,14 +144,15 @@ public class PortletUrlTagTest extends MockObjectTestCase { actionMap.put(PortletMode.HELP, new ActionMapping("defaultHelp", "/help", "execute", new HashMap<>())); actionMap.put(PortletMode.EDIT, new ActionMapping("defaultEdit", "/edit", "execute", new HashMap<>())); - Map<String, Object> contextMap = stack.getContext(); - contextMap.put(ActionContext.SESSION, new HashMap<String, Object>()); - contextMap.put(PortletConstants.REQUEST, mockPortletReq.proxy()); - contextMap.put(PortletConstants.RESPONSE, mockPortletRes.proxy()); - contextMap.put(PortletConstants.PHASE, PortletPhase.RENDER_PHASE); - contextMap.put(PortletConstants.MODE_NAMESPACE_MAP, modeMap); - contextMap.put(PortletConstants.DEFAULT_ACTION_MAP, actionMap); - contextMap.put(STRUTS_PORTLET_CONTEXT, mockCtx.proxy()); + Map<String, Object> contextMap = stack.getActionContext() + .withSession(new HashMap<>()) + .with(PortletConstants.REQUEST, mockPortletReq.proxy()) + .with(PortletConstants.RESPONSE, mockPortletRes.proxy()) + .with(PortletConstants.PHASE, PortletPhase.RENDER_PHASE) + .with(PortletConstants.MODE_NAMESPACE_MAP, modeMap) + .with(PortletConstants.DEFAULT_ACTION_MAP, actionMap) + .with(STRUTS_PORTLET_CONTEXT, mockCtx.proxy()) + .getContextMap(); ActionInvocation ai = (ActionInvocation) mockActionInvocation.proxy();