WW-4160 Adds UnknownHandlerFactory to allow override

This can be used to implement different factories with different
backing DI container ie. Spring
This commit is contained in:
Lukasz Lenart
2014-07-20 10:43:30 +02:00
parent 351263a679
commit de5edd875f
9 changed files with 91 additions and 20 deletions
@@ -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";
@@ -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);
@@ -60,6 +60,7 @@
<bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" />
<bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" />
<bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" />
<bean type="com.opensymphony.xwork2.factory.UnknownHandlerFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultUnknownHandlerFactory" />
<bean type="com.opensymphony.xwork2.FileManager" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" name="system" scope="singleton"/>
<bean type="com.opensymphony.xwork2.FileManagerFactory" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" name="struts" scope="singleton"/>
@@ -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<UnknownHandler> unknownHandlers;
private Configuration configuration;
private Container container;
@Inject
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
build();
}
protected ArrayList<UnknownHandler> 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<UnknownHandlerConfig> unkownHandlerStack = configuration.getUnknownHandlerStack();
unknownHandlers = new ArrayList<UnknownHandler>();
@@ -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<String, Object>());
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) {
@@ -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<String, Object> extraContext) throws Exception {
return unknownHandlerFactory.buildUnknownHandler(unknownHandlerName, extraContext);
}
}
@@ -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) {
@@ -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)
@@ -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<String, Object> extraContext) throws Exception {
return container.getInstance(UnknownHandler.class, unknownHandlerName);
}
}
@@ -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<String, Object> extraContext) throws Exception;
}