diff --git a/core/src/main/java/org/apache/struts2/factory/PrefixBasedActionProxyFactory.java b/core/src/main/java/org/apache/struts2/factory/PrefixBasedActionProxyFactory.java index c522d1a6d3..cf196a9b20 100644 --- a/core/src/main/java/org/apache/struts2/factory/PrefixBasedActionProxyFactory.java +++ b/core/src/main/java/org/apache/struts2/factory/PrefixBasedActionProxyFactory.java @@ -22,13 +22,17 @@ import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.DefaultActionProxyFactory; import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Initializable; import com.opensymphony.xwork2.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.struts2.StrutsConstants; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * @@ -55,28 +59,22 @@ * * */ -public class PrefixBasedActionProxyFactory extends DefaultActionProxyFactory { +public class PrefixBasedActionProxyFactory extends StrutsActionProxyFactory { private static final Logger LOG = LogManager.getLogger(PrefixBasedActionProxyFactory.class); private Map actionProxyFactories = new HashMap<>(); - private ActionProxyFactory defaultFactory; @Inject public void setContainer(Container container) { this.container = container; } - @Inject(StrutsConstants.STRUTS_ACTIONPROXYFACTORY) - public void setActionProxyFactory(ActionProxyFactory factory) { - this.defaultFactory = factory; - } - @Inject(StrutsConstants.PREFIX_BASED_MAPPER_CONFIGURATION) public void setPrefixBasedActionProxyFactories(String list) { if (list != null) { - String[] factories = list.split(","); - for (String factory : factories) { + Set prefixes = new HashSet<>(Arrays.asList(list.split(","))); + for (String factory : prefixes) { String[] thisFactory = factory.split(":"); if (thisFactory.length == 2) { String factoryPrefix = thisFactory[0].trim(); @@ -106,8 +104,7 @@ public ActionProxy createActionProxy(String namespace, String actionName, String LOG.debug("No ActionProxyFactory defined for [{}]", key); } } - LOG.debug("Cannot find any matching ActionProxyFactory, falling back to [{}]", defaultFactory); - return defaultFactory.createActionProxy(namespace, actionName, methodName, extraContext, executeResult, cleanupContext); + LOG.debug("Cannot find any matching ActionProxyFactory, falling back to [{}]", super.getClass().getName()); + return super.createActionProxy(namespace, actionName, methodName, extraContext, executeResult, cleanupContext); } - } diff --git a/core/src/test/java/org/apache/struts2/factory/PrefixBasedActionProxyFactoryTest.java b/core/src/test/java/org/apache/struts2/factory/PrefixBasedActionProxyFactoryTest.java new file mode 100644 index 0000000000..27e9d019ca --- /dev/null +++ b/core/src/test/java/org/apache/struts2/factory/PrefixBasedActionProxyFactoryTest.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.struts2.factory; + +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.DefaultActionProxyFactory; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.inject.Context; +import com.opensymphony.xwork2.inject.Factory; +import com.opensymphony.xwork2.inject.Scope; +import com.opensymphony.xwork2.mock.MockActionProxy; +import com.opensymphony.xwork2.test.StubConfigurationProvider; +import com.opensymphony.xwork2.util.location.LocatableProperties; +import org.apache.struts2.StrutsInternalTestCase; + +import java.util.Collections; +import java.util.Map; + +public class PrefixBasedActionProxyFactoryTest extends StrutsInternalTestCase { + + private PrefixBasedActionProxyFactory factory; + + public void testDifferentPrefixes() throws Exception { + factory.setPrefixBasedActionProxyFactories("/ns1:prefix1,/ns2:prefix2"); + + ActionProxy proxy1 = factory.createActionProxy("/ns1", "", "", Collections.emptyMap(), false, true); + assertTrue(proxy1 instanceof Prefix1ActionProxy); + + ActionProxy proxy2 = factory.createActionProxy("/ns2", "", "", Collections.emptyMap(), false, true); + assertTrue(proxy2 instanceof Prefix2ActionProxy); + } + + public void testFallbackToDefault() throws Exception { + factory.setPrefixBasedActionProxyFactories("/ns1:prefix1"); + + ActionProxy proxy1 = factory.createActionProxy("/ns1", "", "", Collections.emptyMap(), false, true); + assertTrue(proxy1 instanceof Prefix1ActionProxy); + + ActionProxy proxy2 = factory.createActionProxy("", "Foo", "", Collections.emptyMap(), false, true); + assertTrue(proxy2 instanceof StrutsActionProxy); + } + + public void testEmptyPrefix() throws Exception { + factory.setPrefixBasedActionProxyFactories(":prefix1"); + + ActionProxy proxy1 = factory.createActionProxy("/ns1", "", "", Collections.emptyMap(), false, true); + assertTrue(proxy1 instanceof Prefix1ActionProxy); + + ActionProxy proxy2 = factory.createActionProxy("/ns2", "", "", Collections.emptyMap(), false, true); + assertTrue(proxy2 instanceof Prefix1ActionProxy); + } + + @Override + public void setUp() throws Exception { + ConfigurationProvider[] providers = new ConfigurationProvider[]{ + new XmlConfigurationProvider("xwork-sample.xml"), + new StubConfigurationProvider() { + @Override + public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { + builder.factory(ActionProxyFactory.class, "prefix1", new Factory() { + public Object create(Context context) throws Exception { + return new Prefix1Factory(); + } + + }, Scope.SINGLETON); + } + }, + new StubConfigurationProvider() { + @Override + public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { + builder.factory(ActionProxyFactory.class, "prefix2", new Factory() { + public Object create(Context context) throws Exception { + return new Prefix2Factory(); + } + + }, Scope.SINGLETON); + } + } + }; + + loadConfigurationProviders(providers); + + factory = new PrefixBasedActionProxyFactory(); + factory.setContainer(container); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + factory = null; + } + + public static class Prefix1Factory extends DefaultActionProxyFactory { + public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) { + return new Prefix1ActionProxy(); + } + + } + + public static class Prefix1ActionProxy extends MockActionProxy { + } + + public static class Prefix2Factory extends DefaultActionProxyFactory { + public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map extraContext, boolean executeResult, boolean cleanupContext) { + return new Prefix2ActionProxy(); + } + } + + public static class Prefix2ActionProxy extends MockActionProxy { + } + +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 672b126da8..644bf0d213 100644 --- a/pom.xml +++ b/pom.xml @@ -386,7 +386,7 @@ apache-rat-plugin - verify + prepare-package check