Author: lukaszlenart Date: Thu Jul 25 10:03:42 2013 New Revision: 1506872 URL: http://svn.apache.org/r1506872 Log: WW-4144 Defines ParamNameAwareResult interfaces and ResultBuilder to be used with
Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/ struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/StrutsResultBuilder.java struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/ struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/MyResultBuilder.java struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/StrutsResultBuilderTest.java struts/struts2/trunk/core/src/test/resources/struts-object-factory-result-builder.xml - copied, changed from r1506116, struts/struts2/trunk/core/src/test/resources/struts.xml struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ParamNameAwareResult.java Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java struts/struts2/trunk/core/src/main/resources/struts-default.xml struts/struts2/trunk/core/src/test/java/org/apache/struts2/StrutsTestCase.java Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java?rev=1506872&r1=1506871&r2=1506872&view=diff ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java Thu Jul 25 10:03:42 2013 @@ -64,6 +64,8 @@ public final class StrutsConstants { /** The com.opensymphony.xwork2.ObjectFactory implementation class */ public static final String STRUTS_OBJECTFACTORY = "struts.objectFactory"; + public static final String STRUTS_OBJECTFACTORY_RESULTBUILDER = "struts.objectFactory.resultBuilder"; + /** The com.opensymphony.xwork2.util.FileManager implementation class */ public static final String STRUTS_FILE_MANAGER_FACTORY = "struts.fileManagerFactory"; Modified: struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java?rev=1506872&r1=1506871&r2=1506872&view=diff ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java (original) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java Thu Jul 25 10:03:42 2013 @@ -61,6 +61,7 @@ import org.apache.struts2.components.Url import org.apache.struts2.dispatcher.StaticContentLoader; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.multipart.MultiPartRequest; +import com.opensymphony.xwork2.factory.ResultBuilder; import org.apache.struts2.views.freemarker.FreemarkerManager; import org.apache.struts2.views.util.UrlHelper; import org.apache.struts2.views.velocity.VelocityManager; @@ -92,6 +93,12 @@ import java.util.StringTokenizer; * <td>Creates actions, results, and interceptors</td> * </tr> * <tr> + * <td>com.opensymphony.xwork2.factory.ResultBuilder</td> + * <td>struts.objectFactory.resultBuilder</td> + * <td>singleton</td> + * <td>Dedicated builder to create Results, you can implement/extend existing one instead of defining new ObjectFactory</td> + * </tr> + * <tr> * <td>com.opensymphony.xwork2.ActionProxyFactory</td> * <td>struts.actionProxyFactory</td> * <td>singleton</td> @@ -325,6 +332,8 @@ public class BeanSelectionProvider imple public void register(ContainerBuilder builder, LocatableProperties props) { alias(ObjectFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY, builder, props); + alias(ResultBuilder.class, StrutsConstants.STRUTS_OBJECTFACTORY_RESULTBUILDER, builder, props); + alias(FileManagerFactory.class, StrutsConstants.STRUTS_FILE_MANAGER_FACTORY, builder, props, Scope.SINGLETON); alias(XWorkConverter.class, StrutsConstants.STRUTS_XWORKCONVERTER, builder, props); Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/StrutsResultBuilder.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/StrutsResultBuilder.java?rev=1506872&view=auto ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/StrutsResultBuilder.java (added) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/factory/StrutsResultBuilder.java Thu Jul 25 10:03:42 2013 @@ -0,0 +1,71 @@ +package org.apache.struts2.factory; + +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.factory.ResultBuilder; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.util.reflection.ReflectionException; +import com.opensymphony.xwork2.util.reflection.ReflectionExceptionHandler; +import com.opensymphony.xwork2.util.reflection.ReflectionProvider; +import com.opensymphony.xwork2.result.ParamNameAwareResult; + +import java.util.Map; + +/** + * Default implementation which uses {@link com.opensymphony.xwork2.result.ParamNameAwareResult} to accept or throwaway parameters + */ +public class StrutsResultBuilder implements ResultBuilder { + + protected ObjectFactory objectFactory; + protected ReflectionProvider reflectionProvider; + + @Inject + public void setObjectFactory(ObjectFactory objectFactory) { + this.objectFactory = objectFactory; + } + + @Inject + public void setReflectionProvider(ReflectionProvider provider) { + this.reflectionProvider = provider; + } + + public Result buildResult(ResultConfig resultConfig, Map<String, Object> extraContext) throws Exception { + String resultClassName = resultConfig.getClassName(); + Result result = null; + + if (resultClassName != null) { + result = (Result) objectFactory.buildBean(resultClassName, extraContext); + Map<String, String> params = resultConfig.getParams(); + if (params != null) { + setParameters(extraContext, result, params); + } + } + return result; + } + + protected void setParameters(Map<String, Object> extraContext, Result result, Map<String, String> params) { + for (Map.Entry<String, String> paramEntry : params.entrySet()) { + try { + String name = paramEntry.getKey(); + String value = paramEntry.getValue(); + setParameter(result, name, value, extraContext); + } catch (ReflectionException ex) { + if (result instanceof ReflectionExceptionHandler) { + ((ReflectionExceptionHandler) result).handle(ex); + } + } + } + } + + protected void setParameter(Result result, String name, String value, Map<String, Object> extraContext) { + if (result instanceof ParamNameAwareResult) { + if (((ParamNameAwareResult) result).acceptParamName(name, value)) { + reflectionProvider.setProperty(name, value, result, extraContext, true); + } + } else { + reflectionProvider.setProperty(name, value, result, extraContext, true); + } + } + +} Modified: struts/struts2/trunk/core/src/main/resources/struts-default.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/struts-default.xml?rev=1506872&r1=1506871&r2=1506872&view=diff ============================================================================== --- struts/struts2/trunk/core/src/main/resources/struts-default.xml (original) +++ struts/struts2/trunk/core/src/main/resources/struts-default.xml Thu Jul 25 10:03:42 2013 @@ -28,6 +28,8 @@ <struts> <bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" /> <bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" /> + <bean type="com.opensymphony.xwork2.factory.ResultBuilder" name="xwork" class="org.apache.struts2.factory.StrutsResultBuilder" /> + <bean type="com.opensymphony.xwork2.factory.ResultBuilder" name="struts" class="org.apache.struts2.factory.StrutsResultBuilder" /> <bean type="com.opensymphony.xwork2.FileManager" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" name="system" scope="singleton"/> Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/StrutsTestCase.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/StrutsTestCase.java?rev=1506872&r1=1506871&r2=1506872&view=diff ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/StrutsTestCase.java (original) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/StrutsTestCase.java Thu Jul 25 10:03:42 2013 @@ -21,23 +21,22 @@ package org.apache.struts2; +import com.opensymphony.xwork2.XWorkTestCase; +import com.opensymphony.xwork2.util.logging.LoggerFactory; +import com.opensymphony.xwork2.util.logging.jdk.JdkLoggerFactory; +import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.util.StrutsTestCaseHelper; +import org.springframework.mock.web.MockServletContext; + import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; -import java.util.logging.SimpleFormatter; - -import org.apache.struts2.dispatcher.Dispatcher; -import org.apache.struts2.util.StrutsTestCaseHelper; -import org.springframework.mock.web.MockServletContext; - -import com.opensymphony.xwork2.XWorkTestCase; -import com.opensymphony.xwork2.util.logging.LoggerFactory; -import com.opensymphony.xwork2.util.logging.jdk.JdkLoggerFactory; /** * Base test case for JUnit testing Struts. @@ -90,6 +89,19 @@ public abstract class StrutsTestCase ext return du; } + /** + * Init Dispatcher with provided comma delimited list of xml configs to use, ie: + * initDispatcherWithConfigs("struts-default.xml,test-struts-config.xml") + * + * @param configs comma delimited list of config files + * @return instance of {@see Dispatcher} + */ + protected Dispatcher initDispatcherWithConfigs(String configs) { + Map<String, String> params = new HashMap<String, String>(); + params.put("config", configs); + return initDispatcher(params); + } + protected void tearDown() throws Exception { super.tearDown(); StrutsTestCaseHelper.tearDown(); Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/MyResultBuilder.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/MyResultBuilder.java?rev=1506872&view=auto ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/MyResultBuilder.java (added) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/MyResultBuilder.java Thu Jul 25 10:03:42 2013 @@ -0,0 +1,4 @@ +package org.apache.struts2.factory; + +public class MyResultBuilder extends StrutsResultBuilder { +} Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/StrutsResultBuilderTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/StrutsResultBuilderTest.java?rev=1506872&view=auto ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/StrutsResultBuilderTest.java (added) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/factory/StrutsResultBuilderTest.java Thu Jul 25 10:03:42 2013 @@ -0,0 +1,75 @@ +package org.apache.struts2.factory; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.factory.ResultBuilder; +import org.apache.struts2.StrutsTestCase; +import com.opensymphony.xwork2.result.ParamNameAwareResult; + +import java.util.HashMap; +import java.util.Map; + +public class StrutsResultBuilderTest extends StrutsTestCase { + + public void testAcceptParams() throws Exception { + // given + initDispatcherWithConfigs("struts-default.xml"); + StrutsResultBuilder builder = (StrutsResultBuilder) container.getInstance(ResultBuilder.class); + + Map<String, String> params = new HashMap<String, String>(); + params.put("accept", "ok"); + params.put("reject", "bad"); + ResultConfig config = new ResultConfig.Builder("struts", MyResult.class.getName()).addParams(params).build(); + Map<String, Object> context = new HashMap<String, Object>(); + + // when + Result result = builder.buildResult(config, context); + + // then + assertEquals("ok", ((MyResult)result).getAccept()); + assertEquals("ok", ((MyResult)result).getReject()); + } + + public void testUseCustomResultBuilder() throws Exception { + // given + initDispatcherWithConfigs("struts-default.xml,struts-object-factory-result-builder.xml"); + + // when + ResultBuilder actual = container.getInstance(ResultBuilder.class); + + // then + assertTrue(actual instanceof MyResultBuilder); + } + + public static class MyResult implements Result, ParamNameAwareResult { + + private String accept; + private String reject = "ok"; + + public boolean acceptParamName(String name, String value) { + return "accept".equals(name); + } + + public void execute(ActionInvocation invocation) throws Exception { + + } + + public String getAccept() { + return accept; + } + + public void setAccept(String accept) { + this.accept = accept; + } + + public String getReject() { + return reject; + } + + public void setReject(String reject) { + this.reject = reject; + } + } + +} Copied: struts/struts2/trunk/core/src/test/resources/struts-object-factory-result-builder.xml (from r1506116, struts/struts2/trunk/core/src/test/resources/struts.xml) URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/struts-object-factory-result-builder.xml?p2=struts/struts2/trunk/core/src/test/resources/struts-object-factory-result-builder.xml&p1=struts/struts2/trunk/core/src/test/resources/struts.xml&r1=1506116&r2=1506872&rev=1506872&view=diff ============================================================================== --- struts/struts2/trunk/core/src/test/resources/struts.xml (original) +++ struts/struts2/trunk/core/src/test/resources/struts-object-factory-result-builder.xml Thu Jul 25 10:03:42 2013 @@ -21,78 +21,14 @@ */ --> <!DOCTYPE struts PUBLIC - "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" - "http://struts.apache.org/dtds/struts-2.0.dtd"> -<struts> - <package name="default" extends="struts-default"> - <action name="hello" class="com.opensymphony.xwork2.ActionSupport"> - <result name="success">hello.jsp</result> - <result name="tutorial" type="redirect">/tutorial/test.action</result> - </action> - </package> - - <package name="tutorial" namespace="/tutorial" extends="struts-default"> - <result-types> - <result-type name="freemarker" default="true" - class="org.apache.struts2.views.freemarker.FreemarkerResult"/> - </result-types> - - <action name="test" class="com.opensymphony.xwork2.ActionSupport"> - <result name="input">sitegraph/guess-input.ftl</result> - </action> - - <action name="test2" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/callActionFreeMarker.ftl</param> - </result> - </action> - - <action name="test3" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker">org/apache/struts2/views/freemarker/nested.ftl</result> - </action> + "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" + "http://struts.apache.org/dtds/struts-2.3.dtd"> - <action name="test4" class="org.apache.struts2.TestAction" method="executeThrowsException"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/nested.ftl</param> - </result> - </action> - - <action name="test5" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/callActionFreeMarker2.ftl</param> - </result> - </action> - - <action name="test6" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/dynaAttributes.ftl</param> - </result> - </action> - - <action name="test7" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/manual-list.ftl</param> - </result> - </action> - - <action name="test8" class="com.opensymphony.xwork2.ActionSupport"> - <result type="freemarker"> - <param name="location">org/apache/struts2/views/freemarker/customTextField.ftl</param> - </result> - </action> +<struts> - </package> + <bean type="com.opensymphony.xwork2.factory.ResultBuilder" + name="myResultBuilder" class="org.apache.struts2.factory.MyResultBuilder" /> - <package name="sitegraph" namespace="/tutorial/sitegraph" extends="struts-default"> - <result-types> - <result-type name="freemarker" default="true" - class="org.apache.struts2.views.freemarker.FreemarkerResult"/> - </result-types> + <constant name="struts.objectFactory.resultBuilder" value="myResultBuilder" /> - <action name="guess" class="com.opensymphony.xwork2.ActionSupport"> - <result name="success" type="redirect">guess-success.jsp</result> - <result name="input">guess-input.ftl</result> - <result name="error">guess-error.ftl</result> - </action> - </package> </struts> Added: struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ParamNameAwareResult.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ParamNameAwareResult.java?rev=1506872&view=auto ============================================================================== --- struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ParamNameAwareResult.java (added) +++ struts/struts2/trunk/xwork-core/src/main/java/com/opensymphony/xwork2/result/ParamNameAwareResult.java Thu Jul 25 10:03:42 2013 @@ -0,0 +1,10 @@ +package com.opensymphony.xwork2.result; + +/** + * Accept parameter name/value to be set on {@link com.opensymphony.xwork2.Result} + */ +public interface ParamNameAwareResult { + + boolean acceptParamName(String name, String value); + +}