From 5508352ddb46417ccd44033064ea337da509c021 Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Mon, 5 Oct 2015 09:32:10 +0200 Subject: [PATCH] Uses HttpParameters class instead of a generic Map --- .../ExceptionMappingInterceptor.java | 7 ++- .../xwork2/interceptor/I18nInterceptor.java | 18 +++--- .../ParameterFilterInterceptor.java | 9 ++- .../ParameterRemoverInterceptor.java | 22 +++---- .../interceptor/ParametersInterceptor.java | 58 +++++++------------ .../StaticParametersInterceptor.java | 32 +++++----- .../AnnotationParameterFilterIntereptor.java | 12 ++-- .../struts2/components/ActionComponent.java | 18 +++--- .../apache/struts2/dispatcher/Dispatcher.java | 10 ++-- .../ActionMappingParametersInteceptor.java | 23 +++----- .../interceptor/CheckboxInterceptor.java | 31 +++++----- .../interceptor/DateTextFieldInterceptor.java | 38 ++++++------ .../interceptor/FileUploadInterceptor.java | 10 ++-- .../struts2/interceptor/I18nInterceptor.java | 3 +- .../interceptor/MultiselectInterceptor.java | 33 +++++------ .../TokenSessionStoreInterceptor.java | 4 +- .../debugging/DebuggingInterceptor.java | 8 +-- .../org/apache/struts2/util/TokenHelper.java | 27 ++++----- .../apache/struts2/views/jsp/TagUtils.java | 6 +- 19 files changed, 166 insertions(+), 203 deletions(-) diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java index 50ed88967..38700c064 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java @@ -19,8 +19,8 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; +import org.apache.struts2.dispatcher.HttpParameters; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -198,9 +198,10 @@ public class ExceptionMappingInterceptor extends AbstractInterceptor { List exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e); if (mappingConfig != null && mappingConfig.getResult()!=null) { - Map parameterMap = mappingConfig.getParams(); + Map mappingParams = mappingConfig.getParams(); // create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable - invocation.getInvocationContext().setParameters(new HashMap(parameterMap)); + HttpParameters parameters = HttpParameters.create(mappingParams).build(); + invocation.getInvocationContext().setParameters(parameters); result = mappingConfig.getResult(); publishException(invocation, new ExceptionHolder(e)); } else { diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java index 186e42ec1..a758e45c6 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java @@ -20,6 +20,8 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.util.LocalizedTextUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.Locale; import java.util.Map; @@ -166,7 +168,7 @@ public class I18nInterceptor extends AbstractInterceptor { protected class LocaleFinder { protected String storage = Storage.SESSION.toString(); - protected Object requestedLocale = null; + protected Parameter requestedLocale = null; protected ActionInvocation actionInvocation = null; @@ -177,7 +179,7 @@ public class I18nInterceptor extends AbstractInterceptor { protected void find() { //get requested locale - Map params = actionInvocation.getInvocationContext().getParameters(); + HttpParameters params = actionInvocation.getInvocationContext().getParameters(); storage = Storage.SESSION.toString(); @@ -259,13 +261,11 @@ public class I18nInterceptor extends AbstractInterceptor { return locale; } - protected Object findLocaleParameter(Map params, String parameterName) { - Object requestedLocale = params.remove(parameterName); - if (requestedLocale != null && requestedLocale.getClass().isArray() - && ((Object[]) requestedLocale).length > 0) { - requestedLocale = ((Object[]) requestedLocale)[0]; - - LOG.debug("Requested locale: {}", requestedLocale); + protected Parameter findLocaleParameter(HttpParameters params, String parameterName) { + Parameter requestedLocale = params.get(parameterName); + params.remove(parameterName); + if (requestedLocale.isDefined()) { + LOG.debug("Requested locale: {}", requestedLocale.getValue()); } return requestedLocale; } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java index d3c48a3e0..cac043688 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java @@ -20,6 +20,7 @@ import com.opensymphony.xwork2.util.TextParseUtil; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.Collection; import java.util.HashSet; @@ -107,12 +108,12 @@ public class ParameterFilterInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { - Map parameters = invocation.getInvocationContext().getParameters(); + HttpParameters parameters = invocation.getInvocationContext().getParameters(); HashSet paramsToRemove = new HashSet<>(); Map includesExcludesMap = getIncludesExcludesMap(); - for (String param : parameters.keySet()) { + for (String param : parameters.getNames()) { boolean currentAllowed = !isDefaultBlock(); for (String currRule : includesExcludesMap.keySet()) { @@ -129,9 +130,7 @@ public class ParameterFilterInterceptor extends AbstractInterceptor { LOG.debug("Params to remove: {}", paramsToRemove); - for (Object aParamsToRemove : paramsToRemove) { - parameters.remove(aParamsToRemove); - } + parameters.remove(paramsToRemove); return invocation.invoke(); } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java index 68bb1547a..6155c61f1 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java @@ -20,9 +20,10 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.util.TextParseUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.Collections; -import java.util.Map; import java.util.Set; /** @@ -98,22 +99,17 @@ public class ParameterRemoverInterceptor extends AbstractInterceptor { if (!(invocation.getAction() instanceof NoParameters) && (null != this.paramNames)) { ActionContext ac = invocation.getInvocationContext(); - final Map parameters = ac.getParameters(); + HttpParameters parameters = ac.getParameters(); if (parameters != null) { for (String removeName : paramNames) { - // see if the field is in the parameter map - if (parameters.containsKey(removeName)) { - - try { - String[] values = (String[]) parameters.get(removeName); - String value = values[0]; - if (null != value && this.paramValues.contains(value)) { - parameters.remove(removeName); - } - } catch (Exception e) { - LOG.error("Failed to convert parameter to string", e); + try { + Parameter parameter = parameters.get(removeName); + if (parameter.isDefined() && this.paramValues.contains(parameter.getValue())) { + parameters.remove(removeName); } + } catch (Exception e) { + LOG.error("Failed to convert parameter to string", e); } } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java index 52f4f369e..67288ffb3 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java @@ -18,8 +18,6 @@ package com.opensymphony.xwork2.interceptor; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.XWorkConstants; -import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler; -import com.opensymphony.xwork2.conversion.impl.XWorkConverter; import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.security.AcceptedPatternsChecker; import com.opensymphony.xwork2.security.ExcludedPatternsChecker; @@ -28,6 +26,8 @@ import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import org.apache.commons.lang3.BooleanUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.Collection; import java.util.Comparator; @@ -108,7 +108,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor { Object action = invocation.getAction(); if (!(action instanceof NoParameters)) { ActionContext ac = invocation.getInvocationContext(); - final Map parameters = retrieveParameters(ac); + HttpParameters parameters = retrieveParameters(ac); if (LOG.isDebugEnabled()) { LOG.debug("Setting params {}", getParameterLogMap(parameters)); @@ -139,7 +139,7 @@ public class ParametersInterceptor extends MethodFilterInterceptor { * @param ac The action context * @return The parameter map to apply */ - protected Map retrieveParameters(ActionContext ac) { + protected HttpParameters retrieveParameters(ActionContext ac) { return ac.getParameters(); } @@ -154,26 +154,24 @@ public class ParametersInterceptor extends MethodFilterInterceptor { * In subclasses both retrieveParameters() and addParametersToContext() should be overridden. *

*/ - protected void addParametersToContext(ActionContext ac, Map newParams) { + protected void addParametersToContext(ActionContext ac, Map newParams) { } - protected void setParameters(final Object action, ValueStack stack, final Map parameters) { - Map params; - Map acceptableParameters; + protected void setParameters(final Object action, ValueStack stack, HttpParameters parameters) { + HttpParameters params; + Map acceptableParameters; if (ordered) { - params = new TreeMap<>(getOrderedComparator()); + params = HttpParameters.createEmpty().withComparator(getOrderedComparator()).withParent(parameters).build(); acceptableParameters = new TreeMap<>(getOrderedComparator()); - params.putAll(parameters); } else { - params = new TreeMap<>(parameters); + params = HttpParameters.createEmpty().withParent(parameters).build(); acceptableParameters = new TreeMap<>(); } - for (Map.Entry entry : params.entrySet()) { - String name = entry.getKey(); - Object value = entry.getValue(); - if (isAcceptableParameter(name, action) && isAcceptableValue(value)) { - acceptableParameters.put(name, entry.getValue()); + for (String name : params.getNames()) { + Parameter parameter = params.get(name); + if (isAcceptableParameter(name, action) && isAcceptableValue(parameter.getValue())) { + acceptableParameters.put(name, parameter); } } @@ -201,11 +199,11 @@ public class ParametersInterceptor extends MethodFilterInterceptor { accessValueStack.setExcludeProperties(excludedPatterns.getExcludedPatterns()); } - for (Map.Entry entry : acceptableParameters.entrySet()) { + for (Map.Entry entry : acceptableParameters.entrySet()) { String name = entry.getKey(); - Object value = entry.getValue(); + Parameter value = entry.getValue(); try { - newStack.setParameter(name, value); + newStack.setParameter(name, value.getValue()); } catch (RuntimeException e) { if (devMode) { notifyDeveloperParameterException(action, name, e.getMessage()); @@ -285,30 +283,16 @@ public class ParametersInterceptor extends MethodFilterInterceptor { return rbCollator; } - protected String getParameterLogMap(Map parameters) { + protected String getParameterLogMap(HttpParameters parameters) { if (parameters == null) { return "NONE"; } StringBuilder logEntry = new StringBuilder(); - for (Map.Entry entry : parameters.entrySet()) { - logEntry.append(String.valueOf(entry.getKey())); + for (String name : parameters.getNames()) { + logEntry.append(String.valueOf(name)); logEntry.append(" => "); - if (entry.getValue() instanceof Object[]) { - Object[] valueArray = (Object[]) entry.getValue(); - logEntry.append("[ "); - if (valueArray.length > 0 ) { - for (int indexA = 0; indexA < (valueArray.length - 1); indexA++) { - Object valueAtIndex = valueArray[indexA]; - logEntry.append(String.valueOf(valueAtIndex)); - logEntry.append(", "); - } - logEntry.append(String.valueOf(valueArray[valueArray.length - 1])); - } - logEntry.append(" ] "); - } else { - logEntry.append(String.valueOf(entry.getValue())); - } + logEntry.append(parameters.get(name).getValue()); } return logEntry.toString(); diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java index 914a2a12e..07a5a9bb2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java @@ -21,15 +21,19 @@ import com.opensymphony.xwork2.XWorkConstants; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.Parameterizable; import com.opensymphony.xwork2.inject.Inject; -import com.opensymphony.xwork2.util.*; +import com.opensymphony.xwork2.util.ClearableValueStack; +import com.opensymphony.xwork2.util.LocalizedTextUtil; +import com.opensymphony.xwork2.util.TextParseUtil; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; import com.opensymphony.xwork2.util.reflection.ReflectionContextState; import org.apache.commons.lang3.BooleanUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.Collections; import java.util.Map; -import java.util.TreeMap; /** @@ -212,28 +216,24 @@ public class StaticParametersInterceptor extends AbstractInterceptor { * @param newParams The parameter map to apply */ protected void addParametersToContext(ActionContext ac, Map newParams) { - Map previousParams = ac.getParameters(); + HttpParameters previousParams = ac.getParameters(); - Map combinedParams; - if ( overwrite ) { + HttpParameters.Builder combinedParams = HttpParameters.createEmpty(); + if (overwrite) { if (previousParams != null) { - combinedParams = new TreeMap<>(previousParams); - } else { - combinedParams = new TreeMap<>(); + combinedParams = combinedParams.withParent(previousParams); } - if ( newParams != null) { - combinedParams.putAll(newParams); + if (newParams != null) { + combinedParams = combinedParams.withExtraParams(newParams); } } else { if (newParams != null) { - combinedParams = new TreeMap<>(newParams); - } else { - combinedParams = new TreeMap<>(); + combinedParams = combinedParams.withExtraParams(newParams); } - if ( previousParams != null) { - combinedParams.putAll(previousParams); + if (previousParams != null) { + combinedParams = combinedParams.withParent(previousParams); } } - ac.setParameters(combinedParams); + ac.setParameters(combinedParams.build()); } } diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java index 327d2c6db..d65ebecfc 100644 --- a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java +++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java @@ -8,12 +8,12 @@ import com.opensymphony.xwork2.interceptor.Interceptor; import com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor; import com.opensymphony.xwork2.interceptor.ParametersInterceptor; import com.opensymphony.xwork2.util.AnnotationUtils; +import org.apache.struts2.dispatcher.HttpParameters; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Map; /** * Annotation based version of {@link ParameterFilterInterceptor}. @@ -38,7 +38,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { final Object action = invocation.getAction(); - Map parameters = invocation.getInvocationContext().getParameters(); + HttpParameters parameters = invocation.getInvocationContext().getParameters(); Object model = invocation.getStack().peek(); if (model == action) { @@ -55,7 +55,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor { AnnotationUtils.addAllFields(Allowed.class, model.getClass(), annotatedFields); } - for (String paramName : parameters.keySet()) { + for (String paramName : parameters.getNames()) { boolean allowed = false; for (Field field : annotatedFields) { @@ -77,7 +77,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor { AnnotationUtils.addAllFields(Blocked.class, model.getClass(), annotatedFields); } - for (String paramName : parameters.keySet()) { + for (String paramName : parameters.getNames()) { for (Field field : annotatedFields) { //TODO only matches exact field names. need to change to it matches start of ognl expression //i.e take param name up to first . (period) and match against that @@ -88,9 +88,7 @@ public class AnnotationParameterFilterIntereptor extends AbstractInterceptor { } } - for (String aParamsToRemove : paramsToRemove) { - parameters.remove(aParamsToRemove); - } + parameters.remove(paramsToRemove); return invocation.invoke(); } 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 3e98f6ca5..762aafdbf 100644 --- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java +++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java @@ -35,6 +35,7 @@ import org.apache.struts2.StrutsException; import org.apache.struts2.StrutsStatics; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.RequestMap; +import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.views.annotations.StrutsTag; @@ -178,7 +179,7 @@ public class ActionComponent extends ContextBean { } protected Map createExtraContext() { - Map newParams = createParametersForContext(); + HttpParameters newParams = createParametersForContext(); ActionContext ctx = new ActionContext(stack.getContext()); PageContext pageContext = (PageContext) ctx.get(ServletActionContext.PAGE_CONTEXT); @@ -208,16 +209,17 @@ public class ActionComponent extends ContextBean { * * @return A map of String[] parameters */ - protected Map createParametersForContext() { - Map parentParams = null; + protected HttpParameters createParametersForContext() { + HttpParameters parentParams = null; if (!ignoreContextParams) { parentParams = new ActionContext(getStack().getContext()).getParameters(); } - Map newParams = (parentParams != null) - ? new HashMap(parentParams) - : new HashMap(); + HttpParameters.Builder builder = HttpParameters.createEmpty(); + if (parentParams != null) { + builder = builder.withParent(parentParams); + } if (parameters != null) { Map params = new HashMap<>(); @@ -231,9 +233,9 @@ public class ActionComponent extends ContextBean { params.put(key, new String[]{val.toString()}); } } - newParams.putAll(params); + builder = builder.withExtraParams(params); } - return newParams; + return builder.build(); } public ActionProxy getProxy() { 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 93d38a429..9f6026747 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java @@ -607,7 +607,7 @@ public class Dispatcher { Map requestMap = new RequestMap(request); // parameters map wrapping the http parameters. ActionMapping parameters are now handled and applied separately - Map params = new HashMap(request.getParameterMap()); + HttpParameters params = HttpParameters.create(request.getParameterMap()).build(); // session map wrapping the http session Map session = new SessionMap(request); @@ -628,7 +628,7 @@ public class Dispatcher { * Action context. * * @param requestMap a Map of all request attributes. - * @param parameterMap a Map of all request parameters. + * @param parameters an Object of all request parameters. * @param sessionMap a Map of all session attributes. * @param applicationMap a Map of all servlet context attributes. * @param request the HttpServletRequest object. @@ -638,13 +638,13 @@ public class Dispatcher { * @since 2.3.17 */ public HashMap createContextMap(Map requestMap, - Map parameterMap, + HttpParameters parameters, Map sessionMap, Map applicationMap, HttpServletRequest request, HttpServletResponse response) { HashMap extraContext = new HashMap<>(); - extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap)); + extraContext.put(ActionContext.PARAMETERS, parameters); extraContext.put(ActionContext.SESSION, sessionMap); extraContext.put(ActionContext.APPLICATION, applicationMap); @@ -665,7 +665,7 @@ public class Dispatcher { extraContext.put("request", requestMap); extraContext.put("session", sessionMap); extraContext.put("application", applicationMap); - extraContext.put("parameters", parameterMap); + extraContext.put("parameters", parameters); AttributeMap attrMap = new AttributeMap(extraContext); extraContext.put("attr", attrMap); diff --git a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java index 93f527bfe..01dec1678 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInteceptor.java @@ -24,11 +24,10 @@ package org.apache.struts2.interceptor; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.interceptor.ParametersInterceptor; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.mapper.ActionMapping; -import java.util.Collections; import java.util.Map; -import java.util.TreeMap; /** * @@ -82,12 +81,12 @@ public class ActionMappingParametersInteceptor extends ParametersInterceptor { * @return the parameters from the action mapping in the context. If none found, returns an empty map. */ @Override - protected Map retrieveParameters(ActionContext ac) { + protected HttpParameters retrieveParameters(ActionContext ac) { ActionMapping mapping = (ActionMapping) ac.get(ServletActionContext.ACTION_MAPPING); if (mapping != null) { - return mapping.getParams(); + return HttpParameters.create(mapping.getParams()).build(); } else { - return Collections.emptyMap(); + return HttpParameters.createEmpty().build(); } } @@ -102,16 +101,10 @@ public class ActionMappingParametersInteceptor extends ParametersInterceptor { *

*/ @Override - protected void addParametersToContext(ActionContext ac, Map newParams) { - Map previousParams = ac.getParameters(); - Map combinedParams; - if (previousParams != null) { - combinedParams = new TreeMap(previousParams); - } else { - combinedParams = new TreeMap(); - } - combinedParams.putAll(newParams); + protected void addParametersToContext(ActionContext ac, Map newParams) { + HttpParameters previousParams = ac.getParameters(); + HttpParameters.Builder combinedParams = HttpParameters.createEmpty().withParent(previousParams).withExtraParams(newParams); - ac.setParameters(combinedParams); + ac.setParameters(combinedParams.build()); } } diff --git a/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java index bad1c2529..f6eded530 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java @@ -25,11 +25,11 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Set; /** * @@ -60,33 +60,30 @@ public class CheckboxInterceptor extends AbstractInterceptor { private static final Logger LOG = LogManager.getLogger(CheckboxInterceptor.class); public String intercept(ActionInvocation ai) throws Exception { - Map parameters = ai.getInvocationContext().getParameters(); - Map newParams = new HashMap<>(); - Set> entries = parameters.entrySet(); + HttpParameters parameters = ai.getInvocationContext().getParameters(); + Map extraParams = new HashMap<>(); - for (Iterator> iterator = entries.iterator(); iterator.hasNext();) { - Map.Entry entry = iterator.next(); - String key = entry.getKey(); + for (String name : parameters.getNames()) { + if (name.startsWith("__checkbox_")) { + String checkboxName = name.substring("__checkbox_".length()); - if (key.startsWith("__checkbox_")) { - String name = key.substring("__checkbox_".length()); - - Object values = entry.getValue(); - iterator.remove(); - if (values != null && values instanceof String[] && ((String[])values).length > 1) { + Parameter value = parameters.get(checkboxName); + parameters = parameters.remove(name); + if (value.isMultiple()) { LOG.debug("Bypassing automatic checkbox detection due to multiple checkboxes of the same name: {}", name); continue; } // is this checkbox checked/submitted? - if (!parameters.containsKey(name)) { + if (!parameters.contains(name)) { // if not, let's be sure to default the value to false - newParams.put(name, new String[]{uncheckedValue}); + extraParams.put(name, new String[]{uncheckedValue}); } } } - parameters.putAll(newParams); + + ai.getInvocationContext().setParameters(parameters.clone(extraParams)); return ai.invoke(); } diff --git a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java index 05d38514a..e4ccd6c43 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/DateTextFieldInterceptor.java @@ -4,6 +4,8 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -62,33 +64,30 @@ public class DateTextFieldInterceptor implements Interceptor { } public String intercept(ActionInvocation ai) throws Exception { - Map parameters = ai.getInvocationContext().getParameters(); - Set> entries = parameters.entrySet(); + HttpParameters parameters = ai.getInvocationContext().getParameters(); Map> dates = new HashMap<>(); DateWord[] dateWords = DateWord.getAll(); // Get all the values of date type - for (Iterator> iterator = entries.iterator(); iterator.hasNext();) { - Entry entry = iterator.next(); - String key = entry.getKey(); + for (String name : parameters.getNames()) { for (DateWord dateWord : dateWords) { String dateKey = "__" + dateWord.getDescription() + "_"; - if (key.startsWith(dateKey)) { - String name = key.substring(dateKey.length()); + if (name.startsWith(dateKey)) { + String key = name.substring(dateKey.length()); - if (entry.getValue() instanceof String[]) { - String[] values = (String[])entry.getValue(); - if (values.length > 0 && !"".equals(values[0])) { - iterator.remove(); - Map map = dates.get(name); - if (map == null) { - map = new HashMap<>(); - dates.put(name, map); - } - map.put(dateWord.getDateType(), values[0]); - } + Parameter param = parameters.get(key); + + if (param.isDefined()) { + Map map = dates.get(name); + if (map == null) { + map = new HashMap<>(); + dates.put(name, map); + } + map.put(dateWord.getDateType(), param.getValue()); + + parameters = parameters.remove(name); } break; } @@ -115,7 +114,8 @@ public class DateTextFieldInterceptor implements Interceptor { LOG.warn("Cannot parse the parameter '{}' with format '{}' and with value '{}'", dateEntry.getKey(), dateFormat, dateValue); } } - parameters.putAll(newParams); + + ai.getInvocationContext().setParameters(parameters.clone(newParams)); return ai.invoke(); } diff --git a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java index 15bbabeb4..0ceacc4a4 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java @@ -294,11 +294,11 @@ public class FileUploadInterceptor extends AbstractInterceptor { } if (!acceptedFiles.isEmpty()) { - Map params = ac.getParameters(); - - params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); - params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); - params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); + Map newParams = new HashMap<>(); + newParams.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); + newParams.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); + newParams.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); + ac.setParameters(ac.getParameters().clone(newParams)); } } } else { diff --git a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java index d250a8f61..a5c67f2aa 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/I18nInterceptor.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsStatics; +import org.apache.struts2.dispatcher.HttpParameters; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; @@ -87,7 +88,7 @@ public class I18nInterceptor extends com.opensymphony.xwork2.interceptor.I18nInt @Override protected void find() { //get requested locale - Map params = actionInvocation.getInvocationContext().getParameters(); + HttpParameters params = actionInvocation.getInvocationContext().getParameters(); storage = Storage.SESSION.toString(); requestedLocale = findLocaleParameter(params, parameterName); diff --git a/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java index 4c8b84459..337fd0caa 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/MultiselectInterceptor.java @@ -22,11 +22,10 @@ package org.apache.struts2.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import org.apache.struts2.dispatcher.HttpParameters; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Set; /** * Just as the CheckboxInterceptor checks that if only the hidden field is present, so too does this interceptor. If @@ -41,36 +40,32 @@ public class MultiselectInterceptor extends AbstractInterceptor { * If the "__multiselect_" request parameter is present and its visible counterpart is not, set a new request parameter * to an empty Sting. * - * @param actionInvocation ActionInvocation + * @param ai ActionInvocation * @return the result of the action * @throws Exception if error * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation) */ - public String intercept(ActionInvocation actionInvocation) throws Exception { - Map parameters = actionInvocation.getInvocationContext().getParameters(); + public String intercept(ActionInvocation ai) throws Exception { + HttpParameters parameters = ai.getInvocationContext().getParameters(); Map newParams = new HashMap<>(); - Set keys = parameters.keySet(); - for (Iterator iterator = keys.iterator(); iterator.hasNext();) { - String key = iterator.next(); - - if (key.startsWith("__multiselect_")) { - String name = key.substring("__multiselect_".length()); - - iterator.remove(); + for (String name : parameters.getNames()) { + if (name.startsWith("__multiselect_")) { + String key = name.substring("__multiselect_".length()); // is this multi-select box submitted? - if (!parameters.containsKey(name)) { - + if (!parameters.contains(key)) { // if not, let's be sure to default the value to an empty string array - newParams.put(name, new String[0]); + newParams.put(key, new String[0]); } + + parameters = parameters.remove(name); } } - parameters.putAll(newParams); + ai.getInvocationContext().setParameters(parameters.clone(newParams)); - return actionInvocation.invoke(); + return ai.invoke(); } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java index 4ad443117..4a6874401 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java @@ -26,13 +26,13 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.util.InvocationSessionStore; import org.apache.struts2.util.TokenHelper; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import java.util.Map; /** @@ -126,7 +126,7 @@ public class TokenSessionStoreInterceptor extends TokenInterceptor { String token = TokenHelper.getToken(tokenName); if ((tokenName != null) && (token != null)) { - Map params = ac.getParameters(); + HttpParameters params = ac.getParameters(); params.remove(tokenName); params.remove(TokenHelper.TOKEN_NAME_FIELD); 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 296d4105f..2e9efdddf 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 @@ -32,6 +32,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; +import org.apache.struts2.dispatcher.Parameter; import org.apache.struts2.dispatcher.PrepareOperations; import org.apache.struts2.views.freemarker.FreemarkerManager; import org.apache.struts2.views.freemarker.FreemarkerResult; @@ -269,11 +270,8 @@ public class DebuggingInterceptor extends AbstractInterceptor { * @return The parameter value */ private String getParameter(String key) { - String[] arr = (String[]) ActionContext.getContext().getParameters().get(key); - if (arr != null && arr.length > 0) { - return arr[0]; - } - return null; + Parameter parameter = ActionContext.getContext().getParameters().get(key); + return parameter.getValue(); } /** diff --git a/core/src/main/java/org/apache/struts2/util/TokenHelper.java b/core/src/main/java/org/apache/struts2/util/TokenHelper.java index d6e042ef7..d4ae8aa5f 100644 --- a/core/src/main/java/org/apache/struts2/util/TokenHelper.java +++ b/core/src/main/java/org/apache/struts2/util/TokenHelper.java @@ -25,6 +25,8 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.LocalizedTextUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.struts2.dispatcher.Parameter; +import org.apache.struts2.dispatcher.HttpParameters; import java.math.BigInteger; import java.security.SecureRandom; @@ -128,17 +130,14 @@ public class TokenHelper { if (tokenName == null ) { return null; } - Map params = ActionContext.getContext().getParameters(); - String[] tokens = (String[]) params.get(tokenName); - String token; + HttpParameters params = ActionContext.getContext().getParameters(); + Parameter parameter = params.get(tokenName); - if ((tokens == null) || (tokens.length < 1)) { + if (!parameter.isDefined()) { LOG.warn("Could not find token mapped to token name: {}", tokenName); return null; } - - token = tokens[0]; - return token; + return parameter.getValue(); } /** @@ -147,23 +146,19 @@ public class TokenHelper { * @return the token name found in the params, or null if it could not be found */ public static String getTokenName() { - Map params = ActionContext.getContext().getParameters(); + HttpParameters params = ActionContext.getContext().getParameters(); - if (!params.containsKey(TOKEN_NAME_FIELD)) { + if (!params.contains(TOKEN_NAME_FIELD)) { LOG.warn("Could not find token name in params."); return null; } - String[] tokenNames = (String[]) params.get(TOKEN_NAME_FIELD); - String tokenName; - - if ((tokenNames == null) || (tokenNames.length < 1)) { + Parameter parameter = params.get(TOKEN_NAME_FIELD); + if (!parameter.isDefined()) { LOG.warn("Got a null or empty token name."); return null; } - - tokenName = tokenNames[0]; - return tokenName; + return parameter.getValue(); } /** diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java index ab7abea1f..1a14d662f 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java @@ -30,6 +30,7 @@ import org.apache.struts2.RequestUtils; import org.apache.struts2.ServletActionContext; import org.apache.struts2.dispatcher.ApplicationMap; import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.dispatcher.HttpParameters; import org.apache.struts2.dispatcher.RequestMap; import org.apache.struts2.dispatcher.SessionMap; import org.apache.struts2.dispatcher.mapper.ActionMapper; @@ -60,8 +61,11 @@ public class TagUtils { "has passed through its servlet filter, which initializes the Struts dispatcher needed for this tag."); } stack = du.getContainer().getInstance(ValueStackFactory.class).createValueStack(); + + HttpParameters params = HttpParameters.create(req.getParameterMap()).build(); + Map extraContext = du.createContextMap(new RequestMap(req), - req.getParameterMap(), + params, new SessionMap(req), new ApplicationMap(pageContext.getServletContext()), req,