From de5edd875fa766ad6214b7b4aef8daf369d360ea Mon Sep 17 00:00:00 2001 From: Lukasz Lenart Date: Sun, 20 Jul 2014 10:43:30 +0200 Subject: [PATCH] WW-4160 Adds UnknownHandlerFactory to allow override This can be used to implement different factories with different backing DI container ie. Spring --- .../org/apache/struts2/StrutsConstants.java | 6 +--- .../config/DefaultBeanSelectionProvider.java | 2 ++ core/src/main/resources/struts-default.xml | 1 + .../xwork2/DefaultUnknownHandlerManager.java | 30 ++++++++++--------- .../opensymphony/xwork2/ObjectFactory.java | 19 ++++++++++++ .../config/impl/DefaultConfiguration.java | 4 ++- .../providers/XWorkConfigurationProvider.java | 3 ++ .../factory/DefaultUnknownHandlerFactory.java | 25 ++++++++++++++++ .../xwork2/factory/UnknownHandlerFactory.java | 21 +++++++++++++ 9 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 xwork-core/src/main/java/com/opensymphony/xwork2/factory/DefaultUnknownHandlerFactory.java create mode 100644 xwork-core/src/main/java/com/opensymphony/xwork2/factory/UnknownHandlerFactory.java diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java index 918f91bc1..10deced71 100644 --- a/core/src/main/java/org/apache/struts2/StrutsConstants.java +++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java @@ -63,16 +63,12 @@ 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_ACTIONFACTORY = "struts.objectFactory.actionFactory"; - public static final String STRUTS_OBJECTFACTORY_RESULTFACTORY = "struts.objectFactory.resultFactory"; - public static final String STRUTS_OBJECTFACTORY_CONVERTERFACTORY = "struts.objectFactory.converterFactory"; - public static final String STRUTS_OBJECTFACTORY_INTERCEPTORFACTORY = "struts.objectFactory.interceptorFactory"; - public static final String STRUTS_OBJECTFACTORY_VALIDATORFACTORY = "struts.objectFactory.validatorFactory"; + public static final String STRUTS_OBJECTFACTORY_UNKNOWNHANDLERFACTORY = "struts.objectFactory.unknownHandlerFactory"; /** The com.opensymphony.xwork2.util.FileManager implementation class */ public static final String STRUTS_FILE_MANAGER_FACTORY = "struts.fileManagerFactory"; diff --git a/core/src/main/java/org/apache/struts2/config/DefaultBeanSelectionProvider.java b/core/src/main/java/org/apache/struts2/config/DefaultBeanSelectionProvider.java index 06b730290..8999a31e1 100644 --- a/core/src/main/java/org/apache/struts2/config/DefaultBeanSelectionProvider.java +++ b/core/src/main/java/org/apache/struts2/config/DefaultBeanSelectionProvider.java @@ -22,6 +22,7 @@ package org.apache.struts2.config; import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.factory.UnknownHandlerFactory; import com.opensymphony.xwork2.security.AcceptedPatternsChecker; import com.opensymphony.xwork2.security.ExcludedPatternsChecker; import com.opensymphony.xwork2.FileManager; @@ -352,6 +353,7 @@ public class DefaultBeanSelectionProvider extends AbstractBeanSelectionProvider alias(ConverterFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY_CONVERTERFACTORY, builder, props); alias(InterceptorFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY_INTERCEPTORFACTORY, builder, props); alias(ValidatorFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY_VALIDATORFACTORY, builder, props); + alias(UnknownHandlerFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY_UNKNOWNHANDLERFACTORY, builder, props); alias(FileManagerFactory.class, StrutsConstants.STRUTS_FILE_MANAGER_FACTORY, builder, props, Scope.SINGLETON); diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index ea2a631c5..6628c5370 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -60,6 +60,7 @@ + diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java index b1e36d582..b0fffd5c3 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/DefaultUnknownHandlerManager.java @@ -16,12 +16,14 @@ package com.opensymphony.xwork2; import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.UnknownHandlerConfig; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Set; @@ -31,27 +33,29 @@ import java.util.Set; * @see com.opensymphony.xwork2.UnknownHandlerManager */ public class DefaultUnknownHandlerManager implements UnknownHandlerManager { - protected ArrayList unknownHandlers; - private Configuration configuration; + private Container container; - @Inject - public void setConfiguration(Configuration configuration) { - this.configuration = configuration; - build(); - } + protected ArrayList unknownHandlers; @Inject public void setContainer(Container container) { this.container = container; - build(); + try { + build(); + } catch (Exception e) { + throw new ConfigurationException(e); + } } /** - * Builds a list of UnknowHandlers in the order specified by the configured "unknown-handler-stack". - * If "unknown-handler-stack" was not configured, all UnknowHandlers will be returned, in no specific order + * Builds a list of UnknownHandlers in the order specified by the configured "unknown-handler-stack". + * If "unknown-handler-stack" was not configured, all UnknownHandlers will be returned, in no specific order */ - protected void build() { + protected void build() throws Exception { + Configuration configuration = container.getInstance(Configuration.class); + ObjectFactory factory = container.getInstance(ObjectFactory.class); + if (configuration != null && container != null) { List unkownHandlerStack = configuration.getUnknownHandlerStack(); unknownHandlers = new ArrayList(); @@ -59,7 +63,7 @@ public class DefaultUnknownHandlerManager implements UnknownHandlerManager { if (unkownHandlerStack != null && !unkownHandlerStack.isEmpty()) { //get UnknownHandlers in the specified order for (UnknownHandlerConfig unknownHandlerConfig : unkownHandlerStack) { - UnknownHandler uh = container.getInstance(UnknownHandler.class, unknownHandlerConfig.getName()); + UnknownHandler uh = factory.buildUnknownHandler(unknownHandlerConfig.getName(), new HashMap()); unknownHandlers.add(uh); } } else { @@ -103,8 +107,6 @@ public class DefaultUnknownHandlerManager implements UnknownHandlerManager { /** * Iterate over UnknownHandlers and return the result of the first one that can handle it - * - * @throws NoSuchMethodException */ public ActionConfig handleUnknownAction(String namespace, String actionName) { for (UnknownHandler unknownHandler : unknownHandlers) { diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/ObjectFactory.java b/xwork-core/src/main/java/com/opensymphony/xwork2/ObjectFactory.java index dd51adf24..bdee9613b 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/ObjectFactory.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/ObjectFactory.java @@ -24,6 +24,7 @@ import com.opensymphony.xwork2.factory.ActionFactory; import com.opensymphony.xwork2.factory.ConverterFactory; import com.opensymphony.xwork2.factory.InterceptorFactory; import com.opensymphony.xwork2.factory.ResultFactory; +import com.opensymphony.xwork2.factory.UnknownHandlerFactory; import com.opensymphony.xwork2.factory.ValidatorFactory; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.Inject; @@ -59,6 +60,7 @@ public class ObjectFactory implements Serializable { private InterceptorFactory interceptorFactory; private ValidatorFactory validatorFactory; private ConverterFactory converterFactory; + private UnknownHandlerFactory unknownHandlerFactory; @Inject(value="objectFactory.classloader", required=false) public void setClassLoader(ClassLoader cl) { @@ -95,6 +97,11 @@ public class ObjectFactory implements Serializable { this.converterFactory = converterFactory; } + @Inject + public void setUnknownHandlerFactory(UnknownHandlerFactory unknownHandlerFactory) { + this.unknownHandlerFactory = unknownHandlerFactory; + } + /** * @deprecated Since 2.1 */ @@ -234,4 +241,16 @@ public class ObjectFactory implements Serializable { return converterFactory.buildConverter(converterClass, extraContext); } + /** + * Builds unknown handler + * + * @param unknownHandlerName + * @param extraContext + * @return + * @throws Exception + */ + public UnknownHandler buildUnknownHandler(String unknownHandlerName, Map extraContext) throws Exception { + return unknownHandlerFactory.buildUnknownHandler(unknownHandlerName, extraContext); + } + } diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java b/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java index 8fea5d201..0192729f4 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/config/impl/DefaultConfiguration.java @@ -63,8 +63,10 @@ import com.opensymphony.xwork2.factory.DefaultActionFactory; import com.opensymphony.xwork2.factory.DefaultConverterFactory; import com.opensymphony.xwork2.factory.DefaultInterceptorFactory; import com.opensymphony.xwork2.factory.DefaultResultFactory; +import com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory; import com.opensymphony.xwork2.factory.InterceptorFactory; import com.opensymphony.xwork2.factory.ResultFactory; +import com.opensymphony.xwork2.factory.UnknownHandlerFactory; import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.inject.ContainerBuilder; import com.opensymphony.xwork2.inject.Context; @@ -308,7 +310,7 @@ public class DefaultConfiguration implements Configuration { builder.factory(InterceptorFactory.class, DefaultInterceptorFactory.class, Scope.SINGLETON); builder.factory(com.opensymphony.xwork2.factory.ValidatorFactory.class, com.opensymphony.xwork2.factory.DefaultValidatorFactory.class, Scope.SINGLETON); builder.factory(ConverterFactory.class, DefaultConverterFactory.class, Scope.SINGLETON); - + builder.factory(UnknownHandlerFactory.class, DefaultUnknownHandlerFactory.class, Scope.SINGLETON); builder.factory(FileManager.class, "system", DefaultFileManager.class, Scope.SINGLETON); if (!fmFactoryRegistered) { diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java b/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java index 19e8e76a8..4ade520ba 100644 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java @@ -2,6 +2,8 @@ package com.opensymphony.xwork2.config.providers; import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.DefaultActionProxyFactory; +import com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory; +import com.opensymphony.xwork2.factory.UnknownHandlerFactory; import com.opensymphony.xwork2.security.AcceptedPatternsChecker; import com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker; import com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker; @@ -121,6 +123,7 @@ public class XWorkConfigurationProvider implements ConfigurationProvider { .factory(InterceptorFactory.class, DefaultInterceptorFactory.class) .factory(com.opensymphony.xwork2.factory.ValidatorFactory.class, com.opensymphony.xwork2.factory.DefaultValidatorFactory.class) .factory(ConverterFactory.class, DefaultConverterFactory.class) + .factory(UnknownHandlerFactory.class, DefaultUnknownHandlerFactory.class) .factory(ActionProxyFactory.class, DefaultActionProxyFactory.class, Scope.SINGLETON) .factory(ObjectTypeDeterminer.class, DefaultObjectTypeDeterminer.class, Scope.SINGLETON) diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/factory/DefaultUnknownHandlerFactory.java b/xwork-core/src/main/java/com/opensymphony/xwork2/factory/DefaultUnknownHandlerFactory.java new file mode 100644 index 000000000..58fb339ac --- /dev/null +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/factory/DefaultUnknownHandlerFactory.java @@ -0,0 +1,25 @@ +package com.opensymphony.xwork2.factory; + +import com.opensymphony.xwork2.UnknownHandler; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; + +import java.util.Map; + +/** + * Default implementation + */ +public class DefaultUnknownHandlerFactory implements UnknownHandlerFactory { + + private Container container; + + @Inject + public void setContainer(Container container) { + this.container = container; + } + + public UnknownHandler buildUnknownHandler(String unknownHandlerName, Map extraContext) throws Exception { + return container.getInstance(UnknownHandler.class, unknownHandlerName); + } + +} diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/factory/UnknownHandlerFactory.java b/xwork-core/src/main/java/com/opensymphony/xwork2/factory/UnknownHandlerFactory.java new file mode 100644 index 000000000..244f3abe2 --- /dev/null +++ b/xwork-core/src/main/java/com/opensymphony/xwork2/factory/UnknownHandlerFactory.java @@ -0,0 +1,21 @@ +package com.opensymphony.xwork2.factory; + +import com.opensymphony.xwork2.UnknownHandler; + +import java.util.Map; + +/** + * Dedicated interface used by {@link com.opensymphony.xwork2.ObjectFactory} to build {@link com.opensymphony.xwork2.UnknownHandler} + */ +public interface UnknownHandlerFactory { + + /** + * Builds unknown handler of given name + * + * @param unknownHandlerName name of unknown handler defined in struts.xml + * @param extraContext extra params + * @return instance of {@link com.opensymphony.xwork2.UnknownHandler} with injected dependencies + */ + UnknownHandler buildUnknownHandler(String unknownHandlerName, Map extraContext) throws Exception; + +}