Adds support to parse collection of parameters
Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/a4a7edd5 Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/a4a7edd5 Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/a4a7edd5 Branch: refs/heads/feature/use-js-to-support-multiple-buttons Commit: a4a7edd56a3c930e18b275aeefe6fd161c73d66e Parents: c03962c Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Sat Mar 22 09:42:54 2014 +0100 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Sat Mar 22 09:42:54 2014 +0100 ---------------------------------------------------------------------- .../struts2/dispatcher/StrutsResultSupport.java | 75 ++++++++++++++------ .../dispatcher/StrutsResultSupportTest.java | 31 ++++++++ 2 files changed, 86 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/a4a7edd5/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java b/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java index 676b0b9..269ed87 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java @@ -23,6 +23,8 @@ package org.apache.struts2.dispatcher; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; import org.apache.struts2.StrutsStatics; @@ -195,32 +197,65 @@ public abstract class StrutsResultSupport implements Result, StrutsStatics { */ protected String conditionalParse(String param, ActionInvocation invocation) { if (parse && param != null && invocation != null) { - return TextParseUtil.translateVariables(param, invocation.getStack(), - new TextParseUtil.ParsedValueEvaluator() { - public Object evaluate(String parsedValue) { - if (encode) { - if (parsedValue != null) { - try { - // use UTF-8 as this is the recommended encoding by W3C to - // avoid incompatibilities. - return URLEncoder.encode(parsedValue, "UTF-8"); - } - catch(UnsupportedEncodingException e) { - if (LOG.isWarnEnabled()) { - LOG.warn("error while trying to encode ["+parsedValue+"]", e); - } - } - } - } - return parsedValue; - } - }); + return TextParseUtil.translateVariables( + param, + invocation.getStack(), + new EncodingParsedValueEvaluator()); } else { return param; } } /** + * As {@link #conditionalParse(String, ActionInvocation)} but does not + * convert found object into String. If found object is a collection it is + * returned if found object is not a collection it is wrapped in one. + * + * @param param + * @param invocation + * @param excludeEmptyElements + * @return + */ + protected Collection<String> conditionalParseCollection(String param, ActionInvocation invocation, boolean excludeEmptyElements) { + if (parse && param != null && invocation != null) { + return TextParseUtil.translateVariablesCollection( + param, + invocation.getStack(), + excludeEmptyElements, + new EncodingParsedValueEvaluator()); + } else { + Collection<String> collection = new ArrayList<String>(1); + collection.add(param); + return collection; + } + } + + /** + * {@link com.opensymphony.xwork2.util.TextParseUtil.ParsedValueEvaluator} to do URL encoding for found values. To be + * used for single strings or collections. + * + */ + private final class EncodingParsedValueEvaluator implements TextParseUtil.ParsedValueEvaluator { + public Object evaluate(String parsedValue) { + if (encode) { + if (parsedValue != null) { + try { + // use UTF-8 as this is the recommended encoding by W3C to + // avoid incompatibilities. + return URLEncoder.encode(parsedValue, "UTF-8"); + } + catch(UnsupportedEncodingException e) { + if (LOG.isWarnEnabled()) { + LOG.warn("error while trying to encode ["+parsedValue+"]", e); + } + } + } + } + return parsedValue; + } + } + + /** * Executes the result given a final location (jsp page, action, etc) and the action invocation * (the state in which the action was executed). Subclasses must implement this class to handle * custom logic for result handling. http://git-wip-us.apache.org/repos/asf/struts/blob/a4a7edd5/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java b/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java index 1d3556e..cc4bf6c 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java @@ -21,6 +21,9 @@ package org.apache.struts2.dispatcher; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import org.apache.struts2.StrutsInternalTestCase; import org.easymock.EasyMock; @@ -109,6 +112,34 @@ public class StrutsResultSupportTest extends StrutsInternalTestCase { EasyMock.verify(mockActionInvocation); } + public void testConditionalParseCollection() throws Exception { + ValueStack stack = ActionContext.getContext().getValueStack(); + stack.push(new ActionSupport() { + public List<String> getList() { + return new ArrayList<String>(){{ + add("val 1"); + add("val 2"); + }}; + } + }); + + ActionInvocation mockActionInvocation = EasyMock.createNiceMock(ActionInvocation.class); + mockActionInvocation.getStack(); + EasyMock.expectLastCall().andReturn(stack); + EasyMock.replay(mockActionInvocation); + + InternalStrutsResultSupport result = new InternalStrutsResultSupport(); + result.setParse(true); + result.setEncode(true); + + Collection<String> collection = result.conditionalParseCollection("${list}", mockActionInvocation, true); + + assertNotNull(collection); + assertEquals(2, collection.size()); + assertTrue(collection.contains("val+1")); + assertTrue(collection.contains("val+2")); + EasyMock.verify(mockActionInvocation); + } public static class InternalStrutsResultSupport extends StrutsResultSupport { private String _internalLocation = null;