From 2db660a3bbc91c6c53e692318c255f4ad12a6bf2 Mon Sep 17 00:00:00 2001 From: "Donald J. Brown" Date: Mon, 13 Nov 2006 08:30:40 +0000 Subject: [PATCH] Redesigning the Struts configuration to use the XWork DI container and its new configuration scheme. The DI container will allow us better wire the framework together while allowing self-defining plugins to extend/replace any component. This change also gets rid of the need for struts.properties, allowing settings/constants to be defined in the XML. In fact, even the XML isn't required when using the new zero configuration "actionPackages" filter init param. These changes should be fully backwards compatible for most applications. WW-1498 WW-1421 WW-1402 git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@474191 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/main/resources/struts.properties | 2 - apps/showcase/src/main/webapp/WEB-INF/web.xml | 4 + .../org/apache/struts2/StrutsConstants.java | 9 +- .../org/apache/struts2/StrutsTestCase.java | 29 +- .../struts2/components/ActionComponent.java | 29 +- .../apache/struts2/components/Component.java | 18 +- .../org/apache/struts2/components/Form.java | 28 +- .../org/apache/struts2/components/Head.java | 10 +- .../apache/struts2/components/Include.java | 10 +- .../org/apache/struts2/components/UIBean.java | 26 +- .../org/apache/struts2/components/URL.java | 13 +- .../template/FreemarkerTemplateEngine.java | 8 +- .../template/TemplateEngineManager.java | 56 +++- .../template/VelocityTemplateEngine.java | 10 +- .../struts2/config/BeanSelectionProvider.java | 128 ++++++++ .../ClasspathConfigurationProvider.java | 13 +- .../struts2/config/DelegatingSettings.java | 2 +- ...LegacyPropertiesConfigurationProvider.java | 84 +++++ .../struts2/config/PropertiesSettings.java | 8 +- .../org/apache/struts2/config/Settings.java | 2 +- .../StrutsXmlConfigurationProvider.java | 41 ++- .../struts2/dispatcher/AbstractFilter.java | 194 ----------- .../dispatcher/ActionContextCleanUp.java | 21 +- .../apache/struts2/dispatcher/Dispatcher.java | 279 ++++++++-------- .../struts2/dispatcher/FilterDispatcher.java | 152 ++++++++- .../ServletActionRedirectResult.java | 11 +- .../dispatcher/ServletRedirectResult.java | 12 +- .../struts2/dispatcher/VelocityResult.java | 20 +- .../mapper/ActionMapperFactory.java | 69 ---- .../mapper/CompositeActionMapper.java | 176 ++-------- .../mapper/DefaultActionMapper.java | 46 ++- .../multipart/JakartaMultiPartRequest.java | 21 +- .../multipart/MultiPartRequest.java | 37 +-- .../multipart/MultiPartRequestWrapper.java | 76 +---- .../struts2/impl/StrutsActionProxy.java | 5 +- .../impl/StrutsActionProxyFactory.java | 4 +- .../ProfilingActivationInterceptor.java | 11 +- .../debugging/DebuggingInterceptor.java | 10 +- .../portlet/dispatcher/Jsr168Dispatcher.java | 64 ++-- .../portlet/result/PortletVelocityResult.java | 23 +- .../spring/StrutsSpringObjectFactory.java | 28 +- ...xternalReferenceResolverSetupListener.java | 117 ------- .../util/ObjectFactoryInitializable.java | 33 -- .../struts2/util/ObjectFactoryLifecycle.java | 33 -- .../ResolverSetupServletContextListener.java | 90 ------ .../struts2/util/VelocityStrutsUtil.java | 7 +- .../struts2/validators/DWRValidator.java | 14 +- .../views/freemarker/FreemarkerManager.java | 55 +--- .../views/freemarker/FreemarkerResult.java | 11 +- .../freemarker/PortletFreemarkerResult.java | 11 +- .../views/freemarker/StrutsBeanWrapper.java | 9 +- .../views/freemarker/tags/ActionModel.java | 4 + .../views/freemarker/tags/TagModel.java | 5 + .../views/jsp/ComponentTagSupport.java | 7 + .../apache/struts2/views/jsp/TagUtils.java | 4 +- .../apache/struts2/views/jsp/ui/FormTag.java | 2 + .../struts2/views/util/ContextUtil.java | 10 +- .../apache/struts2/views/util/UrlHelper.java | 39 ++- .../views/velocity/StrutsVelocityServlet.java | 138 -------- .../views/velocity/VelocityManager.java | 90 +++--- .../components/AbstractDirective.java | 5 +- .../apache/struts2/views/xslt/XSLTResult.java | 9 +- .../org/apache/struts2/default.properties | 21 +- core/src/main/resources/struts-2.0.dtd | 18 +- core/src/main/resources/struts-default.xml | 35 ++ .../struts2/TestConfigurationProvider.java | 26 +- .../ClasspathConfigurationProviderTest.java | 1 + .../apache/struts2/config/SettingsTest.java | 2 +- .../dispatcher/ActionContextCleanUpTest.java | 31 +- .../struts2/dispatcher/DispatcherTest.java | 18 +- .../dispatcher/FilterDispatcherTest.java | 194 +++-------- .../apache/struts2/dispatcher/FilterTest.java | 35 +- .../ServletActionRedirectResultTest.java | 5 +- .../dispatcher/ServletRedirectResultTest.java | 8 +- .../mapper/CompositeActionMapperTest.java | 302 +++--------------- .../mapper/DefaultActionMapperTest.java | 91 ++---- .../mapper/Restful2ActionMapperTest.java | 10 +- .../ExecuteAndWaitInterceptorTest.java | 22 +- .../FileUploadInterceptorTest.java | 4 +- .../interceptor/TokenInterceptorTest.java | 6 +- .../dispatcher/Jsr168DispatcherTest.java | 2 + .../spring/StrutsSpringObjectFactoryTest.java | 7 +- .../views/TemplateEngineManagerTest.java | 51 +-- .../freemarker/FreemarkerManagerTest.java | 6 +- .../struts2/views/jsp/AbstractTagTest.java | 11 +- .../struts2/views/jsp/ActionTagTest.java | 6 +- .../struts2/views/jsp/ElseIfTagTest.java | 4 +- .../apache/struts2/views/jsp/ElseTagTest.java | 1 + .../apache/struts2/views/jsp/IfTagTest.java | 4 +- .../struts2/views/jsp/PortletUrlTagTest.java | 4 +- .../struts2/views/jsp/PropertyTagTest.java | 15 +- .../struts2/views/jsp/ui/FormTagTest.java | 74 +++-- .../struts2/views/jsp/ui/TooltipTest.java | 27 +- .../struts2/views/util/ContextUtilTest.java | 46 +-- .../struts2/views/util/UrlHelperTest.java | 37 +-- .../config_browser/ActionNamesAction.java | 14 +- .../multipart/PellMultiPartRequest.java | 32 +- .../src/main/resources/struts-plugin.xml | 9 + .../struts2/plexus/PlexusObjectFactory.java | 12 +- .../src/main/resources/struts-plugin.xml | 12 + .../sitegraph/StrutsConfigRetriever.java | 7 +- .../sitegraph/entities/FileBasedView.java | 5 +- .../sitegraph/renderers/DOTRenderer.java | 13 +- .../struts2/sitegraph/SiteGraphTest.java | 1 - .../sitemesh/FreeMarkerPageFilter.java | 13 +- .../struts2/sitemesh/TemplatePageFilter.java | 11 +- .../struts2/sitemesh/VelocityPageFilter.java | 16 +- .../src/main/resources/struts-plugin.xml | 10 + .../apache/struts2/s1/Struts1FactoryTest.java | 3 +- .../apache/struts2/s1/test-struts-factory.xml | 3 + 110 files changed, 1649 insertions(+), 2118 deletions(-) create mode 100644 core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java create mode 100644 core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java delete mode 100644 core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java delete mode 100644 core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapperFactory.java delete mode 100644 core/src/main/java/org/apache/struts2/spring/lifecycle/SpringExternalReferenceResolverSetupListener.java delete mode 100644 core/src/main/java/org/apache/struts2/util/ObjectFactoryInitializable.java delete mode 100644 core/src/main/java/org/apache/struts2/util/ObjectFactoryLifecycle.java delete mode 100644 core/src/main/java/org/apache/struts2/util/ResolverSetupServletContextListener.java delete mode 100644 core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityServlet.java create mode 100644 plugins/pell-multipart/src/main/resources/struts-plugin.xml create mode 100644 plugins/plexus/src/main/resources/struts-plugin.xml create mode 100644 plugins/sitemesh/src/main/resources/struts-plugin.xml diff --git a/apps/showcase/src/main/resources/struts.properties b/apps/showcase/src/main/resources/struts.properties index b3d7962cc..6352045a4 100644 --- a/apps/showcase/src/main/resources/struts.properties +++ b/apps/showcase/src/main/resources/struts.properties @@ -9,5 +9,3 @@ struts.url.http.port = 8080 struts.freemarker.manager.classname=customFreemarkerManager struts.serve.static=true struts.serve.static.browserCache=false - -struts.configuration.files=struts-default.xml,struts-plugin.xml,struts.xml,org.apache.struts2.showcase.person diff --git a/apps/showcase/src/main/webapp/WEB-INF/web.xml b/apps/showcase/src/main/webapp/WEB-INF/web.xml index 66d9a74eb..321fe0cd9 100644 --- a/apps/showcase/src/main/webapp/WEB-INF/web.xml +++ b/apps/showcase/src/main/webapp/WEB-INF/web.xml @@ -19,6 +19,10 @@ struts org.apache.struts2.dispatcher.FilterDispatcher + + actionPackages + org.apache.struts2.showcase.person + diff --git a/core/src/main/java/org/apache/struts2/StrutsConstants.java b/core/src/main/java/org/apache/struts2/StrutsConstants.java index 02a3a7084..259b3660b 100644 --- a/core/src/main/java/org/apache/struts2/StrutsConstants.java +++ b/core/src/main/java/org/apache/struts2/StrutsConstants.java @@ -133,12 +133,15 @@ public final class StrutsConstants { /** Allows one to disable dynamic method invocation from the URL */ public static final String STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION = "struts.enable.DynamicMethodInvocation"; - /** A list of configuration files automatically loaded by Struts */ - public static final String STRUTS_CONFIGURATION_FILES = "struts.configuration.files"; - /** Whether slashes in action names are allowed or not */ public static final String STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES = "struts.enable.SlashesInActionNames"; /** Prefix used by {@link CompositeActionMapper} to identified its containing {@link ActionMapper} class. */ public static final String STRUTS_MAPPER_COMPOSITE = "struts.mapper.composite."; + + public static final String STRUTS_ACTIONPROXYFACTORY = "struts.actionProxyFactory"; + + public static final String STRUTS_TEMPLATE_ENGINES = "struts.templateEngines"; + + public static final String STRUTS_FREEMARKER_WRAPPER_ALT_MAP = "struts.freemarker.wrapper.altMap"; } diff --git a/core/src/main/java/org/apache/struts2/StrutsTestCase.java b/core/src/main/java/org/apache/struts2/StrutsTestCase.java index 8e5c02d50..f7870c455 100644 --- a/core/src/main/java/org/apache/struts2/StrutsTestCase.java +++ b/core/src/main/java/org/apache/struts2/StrutsTestCase.java @@ -20,7 +20,9 @@ */ package org.apache.struts2; -import org.apache.struts2.config.Settings; +import java.util.HashMap; +import java.util.Map; + import org.apache.struts2.config.StrutsXmlConfigurationProvider; import org.apache.struts2.dispatcher.Dispatcher; import org.springframework.mock.web.MockServletContext; @@ -41,23 +43,26 @@ public abstract class StrutsTestCase extends XWorkTestCase { */ protected void setUp() throws Exception { super.setUp(); - Settings.reset(); LocalizedTextUtil.clearDefaultResourceBundles(); - Dispatcher du = new Dispatcher(new MockServletContext()); - Dispatcher.setInstance(du); - configurationManager = new ConfigurationManager(); - configurationManager.addConfigurationProvider( - new StrutsXmlConfigurationProvider("struts-default.xml", false)); - configurationManager.addConfigurationProvider( - new StrutsXmlConfigurationProvider("struts-plugin.xml", false)); - configurationManager.addConfigurationProvider( - new StrutsXmlConfigurationProvider("struts.xml", false)); - du.setConfigurationManager(configurationManager); + initDispatcher(null); } + + protected Dispatcher initDispatcher(Map params) { + if (params == null) { + params = new HashMap(); + } + Dispatcher du = new Dispatcher(new MockServletContext(), params); + Dispatcher.setInstance(du); + configurationManager = du.getConfigurationManager(); + configuration = configurationManager.getConfiguration(); + container = configuration.getContainer(); + return du; + } protected void tearDown() throws Exception { super.tearDown(); + Dispatcher.setInstance(null); } } diff --git a/core/src/main/java/org/apache/struts2/components/ActionComponent.java b/core/src/main/java/org/apache/struts2/components/ActionComponent.java index 791dffcac..a389c9d5e 100644 --- a/core/src/main/java/org/apache/struts2/components/ActionComponent.java +++ b/core/src/main/java/org/apache/struts2/components/ActionComponent.java @@ -42,6 +42,7 @@ import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; @@ -119,6 +120,8 @@ public class ActionComponent extends Component { protected HttpServletResponse res; protected HttpServletRequest req; + protected ActionProxyFactory actionProxyFactory; + protected Configuration configuration; protected ActionProxy proxy; protected String name; protected String namespace; @@ -131,6 +134,26 @@ public class ActionComponent extends Component { this.req = req; this.res = res; } + + /** + * @param actionProxyFactory the actionProxyFactory to set + */ + @Inject + public void setActionProxyFactory(ActionProxyFactory actionProxyFactory) { + this.actionProxyFactory = actionProxyFactory; + } + + + + /** + * @param configuration the configuration to set + */ + @Inject + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public boolean end(Writer writer, String body) { boolean end = super.end(writer, "", false); @@ -226,7 +249,7 @@ public class ActionComponent extends Component { String namespace; if (this.namespace == null) { - namespace = TagUtils.buildNamespace(getStack(), req); + namespace = TagUtils.buildNamespace(actionMapper, getStack(), req); } else { namespace = findString(this.namespace); } @@ -235,8 +258,8 @@ public class ActionComponent extends Component { ValueStack stack = getStack(); // execute at this point, after params have been set try { - Configuration config = Dispatcher.getInstance().getConfigurationManager().getConfiguration(); - proxy = ActionProxyFactory.getFactory().createActionProxy(config, namespace, actionName, createExtraContext(), executeResult, true); + + proxy = actionProxyFactory.createActionProxy(configuration, namespace, actionName, createExtraContext(), executeResult, true); if (null != methodName) { proxy.setMethod(methodName); } diff --git a/core/src/main/java/org/apache/struts2/components/Component.java b/core/src/main/java/org/apache/struts2/components/Component.java index 78f9b2cda..778e897d7 100644 --- a/core/src/main/java/org/apache/struts2/components/Component.java +++ b/core/src/main/java/org/apache/struts2/components/Component.java @@ -33,13 +33,16 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsException; import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.util.FastByteArrayOutputStream; import org.apache.struts2.views.jsp.TagUtils; import org.apache.struts2.views.util.ContextUtil; import org.apache.struts2.views.util.UrlHelper; +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.TextParseUtil; @@ -55,6 +58,7 @@ public class Component { protected ValueStack stack; protected Map parameters; protected String id; + protected ActionMapper actionMapper; /** * Constructor. @@ -78,7 +82,12 @@ public class Component { return name.substring(dot + 1).toLowerCase(); } - + + @Inject + public void setActionMapper(ActionMapper mapper) { + this.actionMapper = mapper; + } + /** * Get's the OGNL value stack assoicated with this component. * @return the OGNL value stack assoicated with this component. @@ -335,8 +344,7 @@ public class Component { String finalAction = findString(action); String finalNamespace = determineNamespace(namespace, getStack(), req); ActionMapping mapping = new ActionMapping(finalAction, finalNamespace, method, parameters); - ActionMapper mapper = ActionMapperFactory.getMapper(); - String uri = mapper.getUriFromActionMapping(mapping); + String uri = actionMapper.getUriFromActionMapping(mapping); return UrlHelper.buildUrl(uri, req, res, parameters, scheme, includeContext, encodeResult); } @@ -351,7 +359,7 @@ public class Component { String result; if (namespace == null) { - result = TagUtils.buildNamespace(stack, req); + result = TagUtils.buildNamespace(actionMapper, stack, req); } else { result = findString(namespace); } diff --git a/core/src/main/java/org/apache/struts2/components/Form.java b/core/src/main/java/org/apache/struts2/components/Form.java index 83fe28e3a..238b0b294 100644 --- a/core/src/main/java/org/apache/struts2/components/Form.java +++ b/core/src/main/java/org/apache/struts2/components/Form.java @@ -31,9 +31,8 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.Dispatcher; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; +import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.portlet.context.PortletActionContext; import org.apache.struts2.portlet.util.PortletUrlHelper; @@ -46,6 +45,7 @@ import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.RuntimeConfiguration; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptorUtil; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.validator.ActionValidatorManagerFactory; @@ -110,6 +110,9 @@ public class Form extends ClosingUIBean { protected String portletMode; protected String windowState; protected String acceptcharset; + + protected boolean enableDynamicMethodInvocation = true; + protected Configuration configuration; public Form(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { super(stack, request, response); @@ -126,6 +129,16 @@ public class Form extends ClosingUIBean { protected String getDefaultTemplate() { return TEMPLATE; } + + @Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION) + public void setEnableDynamicMethodInvocation(String enable) { + enableDynamicMethodInvocation = "true".equals(enable); + } + + @Inject + public void setConfiguration(Configuration configuration) { + this.configuration = configuration; + } /* @@ -233,10 +246,8 @@ public class Form extends ClosingUIBean { String actionMethod = ""; // FIXME: our implementation is flawed - the only concept of ! should be in DefaultActionMapper - boolean allowDynamicMethodCalls = "true".equals(Settings.get(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)); - // handle "name!method" convention. - if (allowDynamicMethodCalls) { + if (enableDynamicMethodInvocation) { if (action.indexOf("!") != -1) { int endIdx = action.lastIndexOf("!"); actionMethod = action.substring(endIdx + 1, action.length()); @@ -244,13 +255,12 @@ public class Form extends ClosingUIBean { } } - Configuration config = Dispatcher.getInstance().getConfigurationManager().getConfiguration(); - final ActionConfig actionConfig = config.getRuntimeConfiguration().getActionConfig(namespace, action); + final ActionConfig actionConfig = configuration.getRuntimeConfiguration().getActionConfig(namespace, action); String actionName = action; if (actionConfig != null) { ActionMapping mapping = new ActionMapping(action, namespace, actionMethod, parameters); - String result = UrlHelper.buildUrl(ActionMapperFactory.getMapper().getUriFromActionMapping(mapping), request, response, null); + String result = UrlHelper.buildUrl(actionMapper.getUriFromActionMapping(mapping), request, response, null); addParameter("action", result); // let's try to get the actual action class and name @@ -317,7 +327,7 @@ public class Form extends ClosingUIBean { addParameter("performValidation", Boolean.FALSE); - RuntimeConfiguration runtimeConfiguration = Dispatcher.getInstance().getConfigurationManager().getConfiguration().getRuntimeConfiguration(); + RuntimeConfiguration runtimeConfiguration = configuration.getRuntimeConfiguration(); ActionConfig actionConfig = runtimeConfiguration.getActionConfig(namespace, actionName); if (actionConfig != null) { diff --git a/core/src/main/java/org/apache/struts2/components/Head.java b/core/src/main/java/org/apache/struts2/components/Head.java index 210466e0f..03b49e3af 100644 --- a/core/src/main/java/org/apache/struts2/components/Head.java +++ b/core/src/main/java/org/apache/struts2/components/Head.java @@ -24,8 +24,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -82,6 +82,7 @@ public class Head extends UIBean { private String calendarcss = "calendar-blue.css"; private boolean debug; + private String encoding; public Head(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { super(stack, request, response); @@ -90,6 +91,11 @@ public class Head extends UIBean { protected String getDefaultTemplate() { return TEMPLATE; } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public void setEncoding(String encoding) { + this.encoding = encoding; + } public void evaluateParams() { super.evaluateParams(); @@ -105,7 +111,7 @@ public class Head extends UIBean { } } - addParameter("encoding", Settings.get(StrutsConstants.STRUTS_I18N_ENCODING)); + addParameter("encoding", encoding); addParameter("debug", Boolean.valueOf(debug).toString()); } diff --git a/core/src/main/java/org/apache/struts2/components/Include.java b/core/src/main/java/org/apache/struts2/components/Include.java index 8e6da344f..dd14b2c12 100644 --- a/core/src/main/java/org/apache/struts2/components/Include.java +++ b/core/src/main/java/org/apache/struts2/components/Include.java @@ -44,9 +44,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.RequestUtils; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.util.FastByteArrayOutputStream; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -103,12 +103,18 @@ public class Include extends Component { protected String value; private HttpServletRequest req; private HttpServletResponse res; + private static String defaultEncoding; public Include(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { super(stack); this.req = req; this.res = res; } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public static void setDefaultEncoding(String encoding) { + defaultEncoding = encoding; + } public boolean end(Writer writer, String body) { String page = findString(value, "value", "You must specify the URL to include. Example: /foo.jsp"); @@ -275,7 +281,7 @@ public class Include extends Component { private static String getEncoding() { if (encodingDefined) { try { - encoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + encoding = defaultEncoding; } catch (IllegalArgumentException e) { encoding = System.getProperty("file.encoding"); encodingDefined = false; diff --git a/core/src/main/java/org/apache/struts2/components/UIBean.java b/core/src/main/java/org/apache/struts2/components/UIBean.java index 91b425f47..0a1f8f868 100644 --- a/core/src/main/java/org/apache/struts2/components/UIBean.java +++ b/core/src/main/java/org/apache/struts2/components/UIBean.java @@ -36,10 +36,10 @@ import org.apache.struts2.components.template.Template; import org.apache.struts2.components.template.TemplateEngine; import org.apache.struts2.components.template.TemplateEngineManager; import org.apache.struts2.components.template.TemplateRenderingContext; -import org.apache.struts2.config.Settings; import org.apache.struts2.views.util.ContextUtil; import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -447,7 +447,25 @@ public abstract class UIBean extends Component { // javascript tooltip attribute protected String tooltip; protected String tooltipConfig; + + protected String defaultTemplateDir; + protected String defaultUITheme; + protected TemplateEngineManager templateEngineManager; + @Inject(StrutsConstants.STRUTS_UI_TEMPLATEDIR) + public void setDefaultTemplateDir(String dir) { + this.defaultTemplateDir = dir; + } + + @Inject(StrutsConstants.STRUTS_UI_THEME) + public void setDefaultUITheme(String theme) { + this.defaultUITheme = theme; + } + + @Inject + public void setTemplateEngineManager(TemplateEngineManager mgr) { + this.templateEngineManager = mgr; + } public boolean end(Writer writer, String body) { evaluateParams(); @@ -489,7 +507,7 @@ public abstract class UIBean extends Component { } protected void mergeTemplate(Writer writer, Template template) throws Exception { - final TemplateEngine engine = TemplateEngineManager.getTemplateEngine(template, templateSuffix); + final TemplateEngine engine = templateEngineManager.getTemplateEngine(template, templateSuffix); if (engine == null) { throw new ConfigurationException("Unable to find a TemplateEngine for template " + template); } @@ -517,7 +535,7 @@ public abstract class UIBean extends Component { // Default template set if ((templateDir == null) || (templateDir.equals(""))) { - templateDir = Settings.get(StrutsConstants.STRUTS_UI_TEMPLATEDIR); + templateDir = defaultTemplateDir; } // Defaults to 'template' @@ -550,7 +568,7 @@ public abstract class UIBean extends Component { // Default theme set if ((theme == null) || (theme.equals(""))) { - theme = Settings.get(StrutsConstants.STRUTS_UI_THEME); + theme = defaultUITheme; } return theme; diff --git a/core/src/main/java/org/apache/struts2/components/URL.java b/core/src/main/java/org/apache/struts2/components/URL.java index fc78f81ad..a79318f67 100644 --- a/core/src/main/java/org/apache/struts2/components/URL.java +++ b/core/src/main/java/org/apache/struts2/components/URL.java @@ -34,13 +34,13 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsException; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.portlet.context.PortletActionContext; import org.apache.struts2.portlet.util.PortletUrlHelper; import org.apache.struts2.views.util.UrlHelper; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.XWorkContinuationConfig; @@ -140,12 +140,18 @@ public class URL extends Component { protected String windowState; protected String portletUrlType; protected String anchor; + protected String urlIncludeParams; public URL(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { super(stack); this.req = req; this.res = res; } + + @Inject(StrutsConstants.STRUTS_URL_INCLUDEPARAMS) + public void setUrlIncludeParams(String urlIncludeParams) { + this.urlIncludeParams = urlIncludeParams; + } public boolean start(Writer writer) { boolean result = super.start(writer); @@ -158,10 +164,7 @@ public class URL extends Component { // this at start so body params can override any of these they wish. try { // ww-1266 - String includeParams = - Settings.isSet(StrutsConstants.STRUTS_URL_INCLUDEPARAMS) ? - Settings.get(StrutsConstants.STRUTS_URL_INCLUDEPARAMS).toLowerCase() : GET; - + String includeParams = (urlIncludeParams != null ? urlIncludeParams.toLowerCase() : GET); if (this.includeParams != null) { includeParams = findString(this.includeParams); diff --git a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java index fa4c73924..6a3554557 100644 --- a/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java +++ b/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java @@ -35,6 +35,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.views.freemarker.FreemarkerManager; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ClassLoaderUtil; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; @@ -48,6 +49,7 @@ import freemarker.template.SimpleHash; */ public class FreemarkerTemplateEngine extends BaseTemplateEngine { static Class bodyContent = null; + private FreemarkerManager freemarkerManager; static { try { @@ -63,6 +65,11 @@ public class FreemarkerTemplateEngine extends BaseTemplateEngine { private static final Log LOG = LogFactory.getLog(FreemarkerTemplateEngine.class); + @Inject + public void setFreemarkerManager(FreemarkerManager mgr) { + this.freemarkerManager = mgr; + } + public void renderTemplate(TemplateRenderingContext templateContext) throws Exception { // get the various items required from the stack ValueStack stack = templateContext.getStack(); @@ -72,7 +79,6 @@ public class FreemarkerTemplateEngine extends BaseTemplateEngine { HttpServletResponse res = (HttpServletResponse) context.get(ServletActionContext.HTTP_RESPONSE); // prepare freemarker - FreemarkerManager freemarkerManager = FreemarkerManager.getInstance(); Configuration config = freemarkerManager.getConfiguration(servletContext); // get the list of templates we can use diff --git a/core/src/main/java/org/apache/struts2/components/template/TemplateEngineManager.java b/core/src/main/java/org/apache/struts2/components/template/TemplateEngineManager.java index 9268ac06a..a7b318ef6 100644 --- a/core/src/main/java/org/apache/struts2/components/template/TemplateEngineManager.java +++ b/core/src/main/java/org/apache/struts2/components/template/TemplateEngineManager.java @@ -23,7 +23,11 @@ package org.apache.struts2.components.template; import java.util.HashMap; import java.util.Map; -import org.apache.struts2.config.Settings; +import org.apache.struts2.StrutsConstants; +import org.apache.struts2.dispatcher.Dispatcher; + +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; /** * The TemplateEngineManager will return a template engine for the template @@ -31,19 +35,38 @@ import org.apache.struts2.config.Settings; public class TemplateEngineManager { public static final String DEFAULT_TEMPLATE_TYPE_CONFIG_KEY = "struts.ui.templateSuffix"; - private static final TemplateEngineManager MANAGER = new TemplateEngineManager(); - /** The default template extenstion is ftl. */ public static final String DEFAULT_TEMPLATE_TYPE = "ftl"; Map templateEngines = new HashMap(); - - private TemplateEngineManager() { - templateEngines.put("ftl", new FreemarkerTemplateEngine()); - templateEngines.put("vm", new VelocityTemplateEngine()); - templateEngines.put("jsp", new JspTemplateEngine()); + Container container; + String defaultTemplateType; + + @Inject(DEFAULT_TEMPLATE_TYPE_CONFIG_KEY) + public void setDefaultTemplateType(String type) { + this.defaultTemplateType = type; } - + + @Inject + public void setContainer(Container container) { + this.container = container; + } + + @Inject(StrutsConstants.STRUTS_TEMPLATE_ENGINES) + public void setTemplateEngines(String engines) { + if (engines != null) { + String[] list = engines.split(","); + for (String name : list) { + TemplateEngine eng = container.getInstance(TemplateEngine.class, name); + if (eng != null) { + templateEngines.put(name, eng); + } else { + throw new IllegalArgumentException("Invalid template engine name: "+name); + } + } + } + } + /** * Registers the given template engine. *

@@ -51,8 +74,8 @@ public class TemplateEngineManager { * @param templateExtension filename extension (eg. .jsp, .ftl, .vm). * @param templateEngine the engine. */ - public static void registerTemplateEngine(String templateExtension, TemplateEngine templateEngine) { - MANAGER.templateEngines.put(templateExtension, templateEngine); + public void registerTemplateEngine(String templateExtension, TemplateEngine templateEngine) { + templateEngines.put(templateExtension, templateEngine); } /** @@ -65,17 +88,20 @@ public class TemplateEngineManager { * @param templateTypeOverride Overrides the default template type * @return the engine. */ - public static TemplateEngine getTemplateEngine(Template template, String templateTypeOverride) { + public TemplateEngine getTemplateEngine(Template template, String templateTypeOverride) { String templateType = DEFAULT_TEMPLATE_TYPE; String templateName = template.toString(); if (templateName.indexOf(".") > 0) { templateType = templateName.substring(templateName.indexOf(".") + 1); } else if (templateTypeOverride !=null && templateTypeOverride.length() > 0) { templateType = templateTypeOverride; - } else if (Settings.isSet(DEFAULT_TEMPLATE_TYPE_CONFIG_KEY)) { - templateType = (String) Settings.get(DEFAULT_TEMPLATE_TYPE_CONFIG_KEY); + } else { + String type = defaultTemplateType; + if (type != null) { + templateType = type; + } } - return (TemplateEngine) MANAGER.templateEngines.get(templateType); + return (TemplateEngine) templateEngines.get(templateType); } diff --git a/core/src/main/java/org/apache/struts2/components/template/VelocityTemplateEngine.java b/core/src/main/java/org/apache/struts2/components/template/VelocityTemplateEngine.java index 26f4a9cd3..1b251e2b5 100644 --- a/core/src/main/java/org/apache/struts2/components/template/VelocityTemplateEngine.java +++ b/core/src/main/java/org/apache/struts2/components/template/VelocityTemplateEngine.java @@ -37,11 +37,20 @@ import org.apache.struts2.views.velocity.VelocityManager; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; +import com.opensymphony.xwork2.inject.Inject; + /** * Velocity based template engine. */ public class VelocityTemplateEngine extends BaseTemplateEngine { private static final Log LOG = LogFactory.getLog(VelocityTemplateEngine.class); + + private VelocityManager velocityManager; + + @Inject + public void setVelocityManager(VelocityManager mgr) { + this.velocityManager = mgr; + } public void renderTemplate(TemplateRenderingContext templateContext) throws Exception { // get the various items required from the stack @@ -51,7 +60,6 @@ public class VelocityTemplateEngine extends BaseTemplateEngine { HttpServletResponse res = (HttpServletResponse) actionContext.get(ServletActionContext.HTTP_RESPONSE); // prepare velocity - VelocityManager velocityManager = VelocityManager.getInstance(); velocityManager.init(servletContext); VelocityEngine velocityEngine = velocityManager.getVelocityEngine(); diff --git a/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java b/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java new file mode 100644 index 000000000..98d3c64b6 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/config/BeanSelectionProvider.java @@ -0,0 +1,128 @@ +/* + * $Id: $ + * + * 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.config; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts2.StrutsConstants; +import org.apache.struts2.StrutsException; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import org.apache.struts2.dispatcher.multipart.MultiPartRequest; +import org.apache.struts2.views.freemarker.FreemarkerManager; +import org.apache.struts2.views.velocity.VelocityManager; + +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.inject.Context; +import com.opensymphony.xwork2.inject.Factory; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.inject.Scope; +import com.opensymphony.xwork2.util.ClassLoaderUtil; +import com.opensymphony.xwork2.util.ObjectTypeDeterminer; +import com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory; + +public class BeanSelectionProvider implements ConfigurationProvider { + public static final String DEFAULT_BEAN_NAME = "struts"; + private static final Log LOG = LogFactory.getLog(BeanSelectionProvider.class); + + public void destroy() { + // NO-OP + } + + public void loadPackages() throws ConfigurationException { + // NO-OP + } + + public void init(Configuration configuration) throws ConfigurationException { + // NO-OP + + } + + public boolean needsReload() { + return false; + } + + public void register(ContainerBuilder builder, Properties props) { + alias(ObjectFactory.class, StrutsConstants.STRUTS_OBJECTFACTORY, builder, props); + alias(ActionProxyFactory.class, StrutsConstants.STRUTS_ACTIONPROXYFACTORY, builder, props); + alias(ObjectTypeDeterminer.class, StrutsConstants.STRUTS_OBJECTTYPEDETERMINER, builder, props); + alias(ActionMapper.class, StrutsConstants.STRUTS_MAPPER_CLASS, builder, props); + alias(MultiPartRequest.class, StrutsConstants.STRUTS_MULTIPART_PARSER, builder, props, Scope.DEFAULT); + alias(FreemarkerManager.class, StrutsConstants.STRUTS_FREEMARKER_MANAGER_CLASSNAME, builder, props); + alias(VelocityManager.class, StrutsConstants.STRUTS_VELOCITY_MANAGER_CLASSNAME, builder, props); + + if ("true".equalsIgnoreCase(props.getProperty(StrutsConstants.STRUTS_DEVMODE))) { + props.setProperty(StrutsConstants.STRUTS_I18N_RELOAD, "true"); + props.setProperty(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true"); + } + } + + void alias(Class type, String key, ContainerBuilder builder, Properties props) { + alias(type, key, builder, props, Scope.SINGLETON); + } + + void alias(Class type, String key, ContainerBuilder builder, Properties props, Scope scope) { + if (!builder.contains(type)) { + String foundName = props.getProperty(key, DEFAULT_BEAN_NAME); + if (builder.contains(type, foundName)) { + if (LOG.isDebugEnabled()) { + LOG.info("Choosing bean ("+foundName+") for "+type); + } + builder.alias(type, foundName, Container.DEFAULT_NAME); + } else { + try { + Class cls = ClassLoaderUtil.loadClass(foundName, this.getClass()); + if (LOG.isDebugEnabled()) { + LOG.info("Choosing bean ("+cls+") for "+type); + } + builder.factory(type, cls, scope); + } catch (ClassNotFoundException ex) { + // Perhaps a spring bean id, so we'll delegate to the object factory at runtime + if (LOG.isDebugEnabled()) { + LOG.info("Choosing bean ("+foundName+") for "+type+" to be loaded from the ObjectFactory"); + } + builder.factory(type, new ObjectFactoryDelegateFactory(foundName), scope); + } + } + } else { + LOG.warn("Unable to alias bean type "+type+", default mapping already assigned."); + } + } + + class ObjectFactoryDelegateFactory implements Factory { + String name; + ObjectFactoryDelegateFactory(String name) { + this.name = name; + } + + public Object create(Context context) throws Exception { + ObjectFactory objFactory = context.getContainer().getInstance(ObjectFactory.class); + return objFactory.buildBean(name, null, false); + } + } +} diff --git a/core/src/main/java/org/apache/struts2/config/ClasspathConfigurationProvider.java b/core/src/main/java/org/apache/struts2/config/ClasspathConfigurationProvider.java index 8ed5ab93a..9cc3845d6 100644 --- a/core/src/main/java/org/apache/struts2/config/ClasspathConfigurationProvider.java +++ b/core/src/main/java/org/apache/struts2/config/ClasspathConfigurationProvider.java @@ -26,6 +26,7 @@ import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import java.util.Set; import org.apache.commons.logging.Log; @@ -40,6 +41,7 @@ import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.PackageConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.config.entities.ResultTypeConfig; +import com.opensymphony.xwork2.inject.ContainerBuilder; import com.opensymphony.xwork2.util.ClassLoaderUtil; import com.opensymphony.xwork2.util.ResolverUtil; import com.opensymphony.xwork2.util.TextUtils; @@ -237,9 +239,12 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider { public void destroy() { } + + public void init(Configuration config) { + this.configuration = config; + } - public void init(Configuration configuration) throws ConfigurationException { - this.configuration = configuration; + public void loadPackages() throws ConfigurationException { loadedPackageConfigs.clear(); loadPackages(packages); initialized = true; @@ -353,4 +358,8 @@ public class ClasspathConfigurationProvider implements ConfigurationProvider { return new ResultConfig((String) key, resultClass.getName(), params); } } + + public void register(ContainerBuilder builder, Properties props) throws ConfigurationException { + // Nothing + } } diff --git a/core/src/main/java/org/apache/struts2/config/DelegatingSettings.java b/core/src/main/java/org/apache/struts2/config/DelegatingSettings.java index 4ad086a71..cf0f28749 100644 --- a/core/src/main/java/org/apache/struts2/config/DelegatingSettings.java +++ b/core/src/main/java/org/apache/struts2/config/DelegatingSettings.java @@ -31,7 +31,7 @@ import java.util.Set; * and call the method until successful. * */ -public class DelegatingSettings extends Settings { +class DelegatingSettings extends Settings { Settings[] configList; diff --git a/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java b/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java new file mode 100644 index 000000000..ce7fb94f5 --- /dev/null +++ b/core/src/main/java/org/apache/struts2/config/LegacyPropertiesConfigurationProvider.java @@ -0,0 +1,84 @@ +/* + * $Id: $ + * + * 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.config; + +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Locale; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.apache.struts2.StrutsConstants; +import org.apache.struts2.StrutsException; +import org.apache.struts2.dispatcher.mapper.ActionMapper; + +import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.inject.Context; +import com.opensymphony.xwork2.inject.Factory; +import com.opensymphony.xwork2.util.LocalizedTextUtil; + +public class LegacyPropertiesConfigurationProvider implements ConfigurationProvider { + + public void destroy() { + Settings.reset(); + } + + public void init(Configuration configuration) + throws ConfigurationException { + Settings.reset(); + } + + public void loadPackages() + throws ConfigurationException { + } + + public boolean needsReload() { + return false; + } + + public void register(ContainerBuilder builder, Properties props) + throws ConfigurationException { + + final Settings settings = Settings.getInstance(); + + for (Iterator i = settings.list(); i.hasNext(); ) { + String name = (String) i.next(); + props.put(name, settings.get(name)); + if (StrutsConstants.STRUTS_DEVMODE.equals(name)) { + props.put("devMode", settings.get(name)); + } + } + + // Set default locale + final Locale locale = settings.getLocale(); + builder.factory(Locale.class, new Factory() { + public Object create(Context context) throws Exception { + return locale; + } + }); + } +} diff --git a/core/src/main/java/org/apache/struts2/config/PropertiesSettings.java b/core/src/main/java/org/apache/struts2/config/PropertiesSettings.java index a365de3e6..150c02789 100644 --- a/core/src/main/java/org/apache/struts2/config/PropertiesSettings.java +++ b/core/src/main/java/org/apache/struts2/config/PropertiesSettings.java @@ -25,15 +25,18 @@ import java.net.URL; import java.util.Iterator; import java.util.Properties; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsException; /** * A class to handle settings via a properties file. */ -public class PropertiesSettings extends Settings { +class PropertiesSettings extends Settings { Properties settings; + static Log LOG = LogFactory.getLog(PropertiesSettings.class); /** @@ -49,7 +52,8 @@ public class PropertiesSettings extends Settings { URL settingsUrl = Thread.currentThread().getContextClassLoader().getResource(name + ".properties"); if (settingsUrl == null) { - throw new IllegalStateException(name + ".properties missing"); + LOG.debug(name + ".properties missing"); + return; } // Load settings diff --git a/core/src/main/java/org/apache/struts2/config/Settings.java b/core/src/main/java/org/apache/struts2/config/Settings.java index 70f968a86..28b93bf6d 100644 --- a/core/src/main/java/org/apache/struts2/config/Settings.java +++ b/core/src/main/java/org/apache/struts2/config/Settings.java @@ -51,7 +51,7 @@ import com.opensymphony.xwork2.ObjectFactory; *

  • {@link #listImpl()}
  • *
  • {@link #isSetImpl(String)}
  • */ -public class Settings { +class Settings { static Settings settingsImpl; static Settings defaultImpl; diff --git a/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java b/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java index 2ea5ace64..8f2ed7d4b 100644 --- a/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java +++ b/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java @@ -29,13 +29,22 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; + +import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.impl.DefaultConfiguration; 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; /** * Override Xwork class so we can use an arbitrary config file @@ -46,6 +55,7 @@ public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider { private File baseDir = null; private String filename; private String reloadKey; + private Object servletContext; /** * Constructs the configuration provider @@ -53,7 +63,7 @@ public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider { * @param errorIfMissing If we should throw an exception if the file can't be found */ public StrutsXmlConfigurationProvider(boolean errorIfMissing) { - this("struts.xml", errorIfMissing); + this("struts.xml", errorIfMissing, null); } /** @@ -62,8 +72,9 @@ public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider { * @param filename The filename to look for * @param errorIfMissing If we should throw an exception if the file can't be found */ - public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing) { + public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) { super(filename, errorIfMissing); + this.servletContext = ctx; this.filename = filename; reloadKey = "configurationReload-"+filename; Map dtdMappings = new HashMap(getDtdMappings()); @@ -74,17 +85,31 @@ public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider { this.baseDir = file.getParentFile(); } } - - + + /* (non-Javadoc) + * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#register(com.opensymphony.xwork2.inject.ContainerBuilder, java.util.Properties) + */ + @Override + public void register(ContainerBuilder containerBuilder, Properties props) throws ConfigurationException { + if (servletContext != null && !containerBuilder.contains(ServletContext.class)) { + containerBuilder.factory(ServletContext.class, new Factory() { + public Object create(Context context) throws Exception { + return servletContext; + } + + }); + } + super.register(containerBuilder, props); + } /* (non-Javadoc) * @see com.opensymphony.xwork2.config.providers.XmlConfigurationProvider#init(com.opensymphony.xwork2.config.Configuration) */ @Override - public void init(Configuration configuration) { + public void loadPackages() { ActionContext ctx = ActionContext.getContext(); ctx.put(reloadKey, Boolean.TRUE); - super.init(configuration); + super.loadPackages(); } /** @@ -144,6 +169,10 @@ public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider { return false; } + + public String toString() { + return ("Struts XML configuration provider ("+filename+")"); + } } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java b/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java deleted file mode 100644 index 39c66b85b..000000000 --- a/core/src/main/java/org/apache/struts2/dispatcher/AbstractFilter.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * $Id: $ - * - * 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.dispatcher; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * An abstract for superclass for Struts2 filter, encapsulating common logics and - * helper methods usefull to subclass, to avoid duplication. - * - * Common logics encapsulated:- - *
      - *
    • - * Dispatcher instance creation through createDispatcher method that acts - * as a hook subclass could override. By default it creates an instance of Dispatcher. - *
    • - *
    • - * postInit(FilterConfig) is a hook subclass may use to add post initialization - * logics in {@link javax.servlet.Filter#init(FilterConfig)}. It is called before - * {@link javax.servlet.Filter#init(FilterConfig)} method ends. - *
    • - *
    • - * A default {@link javax.servlet.Filter#destroy()} that clean up Dispatcher by - * calling dispatcher.cleanup() - *
    • - *
    • - * prepareDispatcherAndWrapRequest(HttpServletRequest, HttpServletResponse) helper method - * that basically called dispatcher.prepare(), wrap the HttpServletRequest and return the - * wrapped version. - *
    • - *
    • - * Various other common helper methods like - *
        - *
      • getFilterConfig
      • - *
      • getServletContext
      • - *
      - *
    • - *
    - * - * - * @see Dispatcher - * @see FilterDispatcher - * @see ActionContextCleanUp - * - * @version $Date$ $Id$ - */ -public abstract class AbstractFilter implements Filter { - - private static final Log LOG = LogFactory.getLog(AbstractFilter.class); - - /** Internal copy of dispatcher, created when Filter instance gets initialized. */ - private Dispatcher _dispatcher; - - protected FilterConfig filterConfig; - - /** Dispatcher instance to be used by subclass. */ - protected Dispatcher dispatcher; - - - /** - * Initializes the filter - * - * @param filterConfig The filter configuration - */ - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - _dispatcher = createDispatcher(); - postInit(filterConfig); - } - - /** - * Cleans up the dispatcher - * - * @see javax.servlet.Filter#destroy() - */ - public void destroy() { - if (_dispatcher == null) { - LOG.warn("something is seriously wrong, Dispatcher is not initialized (null) "); - } else { - _dispatcher.cleanup(); - } - } - - /** - * Hook for subclass todo custom initialization, called after - * javax.servlet.Filter.init(FilterConfig). - * - * @param filterConfig - * @throws ServletException - */ - protected abstract void postInit(FilterConfig filterConfig) throws ServletException; - - /** - * Create a {@link Dispatcher}, this serves as a hook for subclass to overried - * such that a custom {@link Dispatcher} could be created. - * - * @return Dispatcher - */ - protected Dispatcher createDispatcher() { - return new Dispatcher(filterConfig.getServletContext()); - } - - /** - * Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of - * WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to - * retrieve the servlet context from other sources. - * - * @param session the HTTP session where, in Servlet 2.3, the servlet context can be retrieved - * @return the servlet context. - */ - protected ServletContext getServletContext() { - return filterConfig.getServletContext(); - } - - /** - * Gets this filter's configuration - * - * @return The filter config - */ - protected FilterConfig getFilterConfig() { - return filterConfig; - } - - /** - * Helper method that prepare Dispatcher - * (by calling Dispatcher.prepare(HttpServletRequest, HttpServletResponse)) - * following by wrapping and returning the wrapping HttpServletRequest [ through - * dispatcher.wrapRequest(HttpServletRequest, ServletContext) ] - * - * @param request - * @param response - * @return HttpServletRequest - * @throws ServletException - */ - protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException { - - Dispatcher du = Dispatcher.getInstance(); - - // Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be - // configured first before struts2 dispatcher filter, hence when its cleanup filter's turn, - // static instance of Dispatcher should be null. - if (du == null) { - dispatcher = _dispatcher; - - Dispatcher.setInstance(dispatcher); - - // prepare the request no matter what - this ensures that the proper character encoding - // is used before invoking the mapper (see WW-9127) - dispatcher.prepare(request, response); - - try { - // Wrap request first, just in case it is multipart/form-data - // parameters might not be accessible through before encoding (ww-1278) - request = dispatcher.wrapRequest(request, getServletContext()); - } catch (IOException e) { - String message = "Could not wrap servlet request with MultipartRequestWrapper!"; - LOG.error(message, e); - throw new ServletException(message, e); - } - } - else { - dispatcher = du; - } - return request; - } -} diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java b/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java index f1fd7527f..1f4de506e 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java @@ -22,6 +22,7 @@ package org.apache.struts2.dispatcher; import java.io.IOException; +import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; @@ -64,22 +65,12 @@ import com.opensymphony.xwork2.util.profiling.UtilTimerStack; * * @version $Date$ $Id$ */ -public class ActionContextCleanUp extends AbstractFilter { +public class ActionContextCleanUp implements Filter { private static final Log LOG = LogFactory.getLog(ActionContextCleanUp.class); private static final String COUNTER = "__cleanup_recursion_counter"; - protected FilterConfig filterConfig; - - - /** - * Empty implementation. - */ - protected void postInit(FilterConfig filterConfig) throws ServletException { - // does nothing. - } - /** * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @@ -92,8 +83,6 @@ public class ActionContextCleanUp extends AbstractFilter { try { UtilTimerStack.push(timerKey); - request = prepareDispatcherAndWrapRequest(request, response); - try { Integer count = (Integer)request.getAttribute(COUNTER); if (count == null) { @@ -144,4 +133,10 @@ public class ActionContextCleanUp extends AbstractFilter { LOG.debug("clean up "); } } + + public void destroy() { + } + + public void init(FilterConfig arg0) throws ServletException { + } } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java index be21e0403..bafec1837 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java @@ -26,9 +26,13 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.TreeSet; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -40,8 +44,9 @@ import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsStatics; +import org.apache.struts2.config.BeanSelectionProvider; import org.apache.struts2.config.ClasspathConfigurationProvider; -import org.apache.struts2.config.Settings; +import org.apache.struts2.config.LegacyPropertiesConfigurationProvider; import org.apache.struts2.config.StrutsXmlConfigurationProvider; import org.apache.struts2.config.ClasspathConfigurationProvider.ClasspathPageLocator; import org.apache.struts2.config.ClasspathConfigurationProvider.PageLocator; @@ -51,8 +56,8 @@ import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper; import org.apache.struts2.impl.StrutsActionProxyFactory; import org.apache.struts2.impl.StrutsObjectFactory; import org.apache.struts2.util.AttributeMap; +import org.apache.struts2.util.ClassLoaderUtils; import org.apache.struts2.util.ObjectFactoryDestroyable; -import org.apache.struts2.util.ObjectFactoryInitializable; import org.apache.struts2.views.freemarker.FreemarkerManager; import com.opensymphony.xwork2.util.ClassLoaderUtil; @@ -62,9 +67,14 @@ import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.config.ConfigurationProvider; import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.LocalizedTextUtil; import com.opensymphony.xwork2.util.ObjectTypeDeterminer; import com.opensymphony.xwork2.util.ObjectTypeDeterminerFactory; @@ -87,12 +97,6 @@ import freemarker.template.Template; */ public class Dispatcher { - // Set Struts-specific factories. - static { - ObjectFactory.setObjectFactory(new StrutsObjectFactory()); - ActionProxyFactory.setFactory(new StrutsActionProxyFactory()); - } - private static final Log LOG = LogFactory.getLog(Dispatcher.class); private static ThreadLocal instance = new ThreadLocal(); @@ -101,7 +105,12 @@ public class Dispatcher { private ConfigurationManager configurationManager; private static boolean portletSupportActive; - private boolean devMode = false; + private static boolean devMode; + private static String defaultEncoding; + private static String defaultLocale; + private static String multipartMaxSize; + private static String multipartSaveDir; + private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml"; // used to get WebLogic to play nice private boolean paramsWorkaroundEnabled = false; @@ -147,8 +156,33 @@ public class Dispatcher { * * @param servletContext The servlet context */ - public Dispatcher(ServletContext servletContext) { - init(servletContext); + public Dispatcher(ServletContext servletContext, Map initParams) { + init(servletContext, initParams); + } + + @Inject(StrutsConstants.STRUTS_DEVMODE) + public static void setDevMode(String mode) { + devMode = "true".equals(mode); + } + + @Inject(value=StrutsConstants.STRUTS_LOCALE, required=false) + public static void setDefaultLocale(String val) { + defaultLocale = val; + } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public static void setDefaultEncoding(String val) { + defaultEncoding = val; + } + + @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE) + public static void setMultipartMaxSize(String val) { + multipartMaxSize = val; + } + + @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR) + public static void setMultipartSaveDir(String val) { + multipartSaveDir = val; } /** @@ -183,69 +217,96 @@ public class Dispatcher { * * @param servletContext The servlet context */ - private void init(final ServletContext servletContext) { - boolean reloadi18n = Boolean.valueOf((String) Settings.get(StrutsConstants.STRUTS_I18N_RELOAD)).booleanValue(); + private void init(final ServletContext servletContext, final Map initParams) { + + + configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME); + + configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider()); + // Load traditional xml configuration + String configPaths = initParams.get("config"); + if (configPaths == null) { + configPaths = DEFAULT_CONFIGURATION_PATHS; + } + if (configPaths != null) { + String[] files = configPaths.split("\\s*[,]\\s*"); + for (String file : files) { + if (file.endsWith(".xml")) { + if ("xwork.xml".equals(file)) { + configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false)); + } else { + configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext)); + } + } else { + throw new IllegalArgumentException("Invalid configuration file name"); + } + } + } + + // Load configuration from a scan of the classloader + String packages = initParams.get("actionPackages"); + if (packages != null) { + String[] names = packages.split("\\s*[,]\\s*"); + // Initialize the classloader scanner with the configured packages + if (names.length > 0) { + ClasspathConfigurationProvider provider = new ClasspathConfigurationProvider(names); + provider.setPageLocator(new ServletContextPageLocator(servletContext)); + configurationManager.addConfigurationProvider(provider); + } + configurationManager.addConfigurationProvider(new BeanSelectionProvider()); + } + + String configProvs = initParams.get("configProviders"); + if (configProvs != null) { + String[] classes = configProvs.split("\\s*[,]\\s*"); + for (String cname : classes) { + try { + Class cls = ClassLoaderUtils.loadClass(cname, this.getClass()); + ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance(); + configurationManager.addConfigurationProvider(prov); + } catch (InstantiationException e) { + throw new ConfigurationException("Unable to instantiate provider: "+cname, e); + } catch (IllegalAccessException e) { + throw new ConfigurationException("Unable to access provider: "+cname, e); + } catch (ClassNotFoundException e) { + throw new ConfigurationException("Unable to locate provider class: "+cname, e); + } + } + } + + // Load filter init params as constants + configurationManager.addConfigurationProvider(new ConfigurationProvider() { + public void destroy() {} + public void init(Configuration configuration) throws ConfigurationException {} + public void loadPackages() throws ConfigurationException {} + public boolean needsReload() { return false; } + + public void register(ContainerBuilder builder, Properties props) throws ConfigurationException { + props.putAll(initParams); + } + }); + + configurationManager.addConfigurationProvider(new BeanSelectionProvider()); + // Preload the configuration + Configuration config = configurationManager.getConfiguration(); + Container container = config.getContainer(); + + + boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD)).booleanValue(); LocalizedTextUtil.setReloadBundles(reloadi18n); - if (Settings.isSet(StrutsConstants.STRUTS_OBJECTFACTORY)) { - String className = (String) Settings.get(StrutsConstants.STRUTS_OBJECTFACTORY); - if (className.equals("spring")) { - // note: this class name needs to be in string form so we don't put hard - // dependencies on spring, since it isn't technically required. - className = "org.apache.struts2.spring.StrutsSpringObjectFactory"; - } else if (className.equals("plexus")) { - className = "org.apache.struts2.plexus.PlexusObjectFactory"; - LOG.warn("The 'plexus' shorthand for the Plexus ObjectFactory is deprecated. Please " - +"use the full class name: "+className); - } + ObjectTypeDeterminer objectTypeDeterminer = container.getInstance(ObjectTypeDeterminer.class); + ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer); - try { - Class clazz = ClassLoaderUtil.loadClass(className, Dispatcher.class); - ObjectFactory objectFactory = (ObjectFactory) clazz.newInstance(); - if (servletContext != null) { - if (objectFactory instanceof ObjectFactoryInitializable) { - ((ObjectFactoryInitializable) objectFactory).init(servletContext); - } - } - ObjectFactory.setObjectFactory(objectFactory); - } catch (Exception e) { - LOG.error("Could not load ObjectFactory named " + className + ". Using default ObjectFactory.", e); - } - } - - if (Settings.isSet(StrutsConstants.STRUTS_OBJECTTYPEDETERMINER)) { - String className = (String) Settings.get(StrutsConstants.STRUTS_OBJECTTYPEDETERMINER); - if (className.equals("tiger")) { - // note: this class name needs to be in string form so we don't put hard - // dependencies on xwork-tiger, since it isn't technically required. - className = "com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer"; - } - else if (className.equals("notiger")) { - className = "com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"; - } - - try { - Class clazz = ClassLoaderUtil.loadClass(className, Dispatcher.class); - ObjectTypeDeterminer objectTypeDeterminer = (ObjectTypeDeterminer) clazz.newInstance(); - ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer); - } catch (Exception e) { - LOG.error("Could not load ObjectTypeDeterminer named " + className + ". Using default DefaultObjectTypeDeterminer.", e); - } - } - - if ("true".equals(Settings.get(StrutsConstants.STRUTS_DEVMODE))) { - devMode = true; - Settings.set(StrutsConstants.STRUTS_I18N_RELOAD, "true"); - Settings.set(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true"); - } +// devMode = "true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_DEVMODE)); +// Settings.set(StrutsConstants.STRUTS_I18N_RELOAD, "true"); +// Settings.set(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true"); //check for configuration reloading - if ("true".equalsIgnoreCase(Settings.get(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))) { - FileManager.setReloadingConfigs(true); - } + FileManager.setReloadingConfigs("true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))); - if (Settings.isSet(StrutsConstants.STRUTS_CONTINUATIONS_PACKAGE)) { - String pkg = Settings.get(StrutsConstants.STRUTS_CONTINUATIONS_PACKAGE); + String pkg = container.getInstance(String.class, StrutsConstants.STRUTS_CONTINUATIONS_PACKAGE); + if (pkg != null) { ObjectFactory.setContinuationPackage(pkg); } @@ -254,39 +315,9 @@ public class Dispatcher { && servletContext.getServerInfo().indexOf("WebLogic") >= 0) { LOG.info("WebLogic server detected. Enabling Struts parameter access work-around."); paramsWorkaroundEnabled = true; - } else if (Settings.isSet(StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)) { - paramsWorkaroundEnabled = "true".equals(Settings.get(StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)); } else { - LOG.debug("Parameter access work-around disabled."); - } - - configurationManager = new ConfigurationManager(); - String configFiles = null; - if (Settings.isSet(StrutsConstants.STRUTS_CONFIGURATION_FILES)) { - configFiles = Settings.get(StrutsConstants.STRUTS_CONFIGURATION_FILES); - } - if (configFiles != null) { - List packages = new ArrayList(); - String[] files = configFiles.split("\\s*[,]\\s*"); - for (String file : files) { - if (file.endsWith(".xml")) { - if ("xwork.xml".equals(file)) { - configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false)); - } else { - configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false)); - } - } else { - packages.add(file); - } - } - - // Initialize the classloader scanner with the configured paths - if (packages.size() > 0) { - ClasspathConfigurationProvider provider = new ClasspathConfigurationProvider((String[])packages.toArray(new String[]{})); - provider.setPageLocator(new ServletContextPageLocator(servletContext)); - configurationManager.addConfigurationProvider(provider); - } - } + paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class, StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND)); + } synchronized(Dispatcher.class) { if (dispatcherListeners.size() > 0) { @@ -337,8 +368,9 @@ public class Dispatcher { extraContext.put(XWorkContinuationConfig.CONTINUE_KEY, id); } - ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy( - configurationManager.getConfiguration(), namespace, name, extraContext, true, false); + Configuration config = configurationManager.getConfiguration(); + ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( + config, namespace, name, extraContext, true, false); proxy.setMethod(method); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack()); @@ -428,14 +460,14 @@ public class Dispatcher { extraContext.put(ActionContext.APPLICATION, applicationMap); Locale locale = null; - if (Settings.isSet(StrutsConstants.STRUTS_LOCALE)) { - locale = LocalizedTextUtil.localeFromString(Settings.get(StrutsConstants.STRUTS_LOCALE), request.getLocale()); + if (defaultLocale != null) { + locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale()); } else { locale = request.getLocale(); } extraContext.put(ActionContext.LOCALE, locale); - extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode)); + //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode)); extraContext.put(StrutsStatics.HTTP_REQUEST, request); extraContext.put(StrutsStatics.HTTP_RESPONSE, response); @@ -461,7 +493,7 @@ public class Dispatcher { private static int getMaxSize() { Integer maxSize = new Integer(Integer.MAX_VALUE); try { - String maxSizeStr = Settings.get(StrutsConstants.STRUTS_MULTIPART_MAXSIZE); + String maxSizeStr = multipartMaxSize; if (maxSizeStr != null) { try { @@ -489,7 +521,7 @@ public class Dispatcher { * @return the path to save uploaded files to */ private String getSaveDir(ServletContext servletContext) { - String saveDir = Settings.get(StrutsConstants.STRUTS_MULTIPART_SAVEDIR).trim(); + String saveDir = multipartSaveDir.trim(); if (saveDir.equals("")) { File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); @@ -521,13 +553,13 @@ public class Dispatcher { */ public void prepare(HttpServletRequest request, HttpServletResponse response) { String encoding = null; - if (Settings.isSet(StrutsConstants.STRUTS_I18N_ENCODING)) { - encoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + if (defaultEncoding != null) { + encoding = defaultEncoding; } Locale locale = null; - if (Settings.isSet(StrutsConstants.STRUTS_LOCALE)) { - locale = LocalizedTextUtil.localeFromString(Settings.get(StrutsConstants.STRUTS_LOCALE), request.getLocale()); + if (defaultLocale != null) { + locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale()); } if (encoding != null) { @@ -563,8 +595,10 @@ public class Dispatcher { return request; } - if (MultiPartRequest.isMultiPart(request)) { - request = new MultiPartRequestWrapper(request, getSaveDir(servletContext), getMaxSize()); + String content_type = request.getContentType(); + if (content_type != null && content_type.indexOf("multipart/form-data") != -1) { + MultiPartRequest multi = getContainer().getInstance(MultiPartRequest.class); + request = new MultiPartRequestWrapper(multi, request, getSaveDir(servletContext)); } else { request = new StrutsRequestWrapper(request); } @@ -586,7 +620,9 @@ public class Dispatcher { response.setContentType("text/html"); try { - freemarker.template.Configuration config = FreemarkerManager.getInstance().getConfiguration(ctx); + FreemarkerManager mgr = getContainer().getInstance(FreemarkerManager.class); + + freemarker.template.Configuration config = mgr.getConfiguration(ctx); Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl"); List chain = new ArrayList(); @@ -700,18 +736,7 @@ public class Dispatcher { this.configurationManager = mgr; } - /** - * @return the devMode - */ - public boolean isDevMode() { - return devMode; + public Container getContainer() { + return getConfigurationManager().getConfiguration().getContainer(); } - - /** - * @param devMode the devMode to set - */ - public void setDevMode(boolean devMode) { - this.devMode = devMode; - } - } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java index 5e89c9ea1..92db556e0 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java @@ -27,10 +27,14 @@ import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Enumeration; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.StringTokenizer; import java.util.TimeZone; +import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; @@ -45,14 +49,14 @@ import org.apache.commons.logging.LogFactory; import org.apache.struts2.RequestUtils; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsStatics; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; import org.apache.struts2.dispatcher.mapper.ActionMapping; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ClassLoaderUtil; import com.opensymphony.xwork2.util.profiling.UtilTimerStack; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ObjectFactory; /** * Master filter for Struts that handles four distinct @@ -119,7 +123,7 @@ import com.opensymphony.xwork2.ActionContext; * * @version $Date$ $Id$ */ -public class FilterDispatcher extends AbstractFilter implements StrutsStatics { +public class FilterDispatcher implements StrutsStatics, Filter { private static final Log LOG = LogFactory.getLog(FilterDispatcher.class); @@ -128,15 +132,25 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { private SimpleDateFormat df = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss"); private final Calendar lastModifiedCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); private final String lastModified = df.format(lastModifiedCal.getTime()); + + private static boolean serveStatic; + private static boolean serveStaticBrowserCache; + private static String encoding; + private static ActionMapper actionMapper; + private FilterConfig filterConfig; + + /** Dispatcher instance to be used by subclass. */ + protected Dispatcher dispatcher; /** - * Look for "packages" defined through filter-config's parameters. + * Initializes the filter * - * @param FilterConfig - * @throws ServletException + * @param filterConfig The filter configuration */ - protected void postInit(FilterConfig filterConfig) throws ServletException { + public void init(FilterConfig filterConfig) throws ServletException { + dispatcher = createDispatcher(filterConfig); + this.filterConfig = filterConfig; String param = filterConfig.getInitParameter("packages"); String packages = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging"; if (param != null) { @@ -144,6 +158,119 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { } this.pathPrefixes = parse(packages); } + + + /** + * Cleans up the dispatcher + * + * @see javax.servlet.Filter#destroy() + */ + public void destroy() { + if (dispatcher == null) { + LOG.warn("something is seriously wrong, Dispatcher is not initialized (null) "); + } else { + dispatcher.cleanup(); + } + } + + /** + * Create a {@link Dispatcher}, this serves as a hook for subclass to overried + * such that a custom {@link Dispatcher} could be created. + * + * @return Dispatcher + */ + protected Dispatcher createDispatcher(FilterConfig filterConfig) { + Map params = new HashMap(); + for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) { + String name = (String) e.nextElement(); + String value = filterConfig.getInitParameter(name); + params.put(name, value); + } + return new Dispatcher(filterConfig.getServletContext(), params); + } + + @Inject(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT) + public static void setServeStaticContent(String val) { + serveStatic = "true".equals(val); + } + + @Inject(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE) + public static void setServeStaticBrowserCache(String val) { + serveStaticBrowserCache = "true".equals(val); + } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public static void setEncoding(String val) { + encoding = val; + } + + @Inject + public static void setActionMapper(ActionMapper mapper) { + actionMapper = mapper; + } + + /** + * Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of + * WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to + * retrieve the servlet context from other sources. + * + * @param session the HTTP session where, in Servlet 2.3, the servlet context can be retrieved + * @return the servlet context. + */ + protected ServletContext getServletContext() { + return filterConfig.getServletContext(); + } + + /** + * Gets this filter's configuration + * + * @return The filter config + */ + protected FilterConfig getFilterConfig() { + return filterConfig; + } + + /** + * Helper method that prepare Dispatcher + * (by calling Dispatcher.prepare(HttpServletRequest, HttpServletResponse)) + * following by wrapping and returning the wrapping HttpServletRequest [ through + * dispatcher.wrapRequest(HttpServletRequest, ServletContext) ] + * + * @param request + * @param response + * @return HttpServletRequest + * @throws ServletException + */ + protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException { + + Dispatcher du = Dispatcher.getInstance(); + + // Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be + // configured first before struts2 dispatcher filter, hence when its cleanup filter's turn, + // static instance of Dispatcher should be null. + if (du == null) { + + Dispatcher.setInstance(dispatcher); + + // prepare the request no matter what - this ensures that the proper character encoding + // is used before invoking the mapper (see WW-9127) + dispatcher.prepare(request, response); + + try { + // Wrap request first, just in case it is multipart/form-data + // parameters might not be accessible through before encoding (ww-1278) + request = dispatcher.wrapRequest(request, getServletContext()); + } catch (IOException e) { + String message = "Could not wrap servlet request with MultipartRequestWrapper!"; + LOG.error(message, e); + throw new ServletException(message, e); + } + } + else { + dispatcher = du; + } + return request; + } /** * Parses the list of packages @@ -188,8 +315,7 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { ActionMapper mapper = null; ActionMapping mapping = null; try { - mapper = ActionMapperFactory.getMapper(); - mapping = mapper.getMapping(request, dispatcher.getConfigurationManager()); + mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager()); } catch (Exception ex) { LOG.error("error getting ActionMapping", ex); dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex); @@ -205,8 +331,7 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { resourcePath = request.getPathInfo(); } - if ("true".equals(Settings.get(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT)) - && resourcePath.startsWith("/struts")) { + if (serveStatic && resourcePath.startsWith("/struts")) { String name = resourcePath.substring("/struts".length()); findStaticResource(name, response); } else { @@ -247,7 +372,7 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { response.setContentType(contentType); } - if ("true".equals(Settings.get(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE))) { + if (serveStaticBrowserCache) { // set heading information for caching static content Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); response.setHeader("Date",df.format(cal.getTime())+" GMT"); @@ -335,8 +460,7 @@ public class FilterDispatcher extends AbstractFilter implements StrutsStatics { resourcePath = packagePrefix + name; } - String enc = (String) Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); - resourcePath = URLDecoder.decode(resourcePath, enc); + resourcePath = URLDecoder.decode(resourcePath, encoding); return ClassLoaderUtil.getResourceAsStream(resourcePath, getClass()); } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java b/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java index ba8823b0c..fba3cdc7b 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java @@ -27,12 +27,12 @@ import java.util.List; import java.util.Map; import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.views.util.UrlHelper; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.inject.Inject; /** * @@ -135,6 +135,7 @@ public class ServletActionRedirectResult extends ServletRedirectResult { protected String actionName; protected String namespace; protected String method; + protected ActionMapper actionMapper; private Map requestParameters = new HashMap(); @@ -156,6 +157,11 @@ public class ServletActionRedirectResult extends ServletRedirectResult { this.actionName = actionName; this.method = method; } + + @Inject + public void setActionMapper(ActionMapper mapper) { + this.actionMapper = mapper; + } protected List prohibitedResultParam = Arrays.asList(new String[] { DEFAULT_PARAM, "namespace", "method", "encode", "parse", "location", @@ -193,8 +199,7 @@ public class ServletActionRedirectResult extends ServletRedirectResult { } } - ActionMapper mapper = ActionMapperFactory.getMapper(); - StringBuffer tmpLocation = new StringBuffer(mapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null))); + StringBuffer tmpLocation = new StringBuffer(actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace, method, null))); UrlHelper.buildParametersString(requestParameters, tmpLocation, "&"); setLocation(tmpLocation.toString()); diff --git a/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java b/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java index 97d4a9dbc..abed1aa00 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java @@ -26,10 +26,11 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; +import org.apache.struts2.dispatcher.mapper.ActionMapper; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; /** @@ -83,6 +84,8 @@ public class ServletRedirectResult extends StrutsResultSupport { protected boolean prependServletContext = true; + private ActionMapper actionMapper; + public ServletRedirectResult() { super(); } @@ -90,6 +93,11 @@ public class ServletRedirectResult extends StrutsResultSupport { public ServletRedirectResult(String location) { super(location); } + + @Inject + public void setActionMapper(ActionMapper mapper) { + this.actionMapper = mapper; + } /** * Sets whether or not to prepend the servlet context path to the redirected URL. @@ -115,7 +123,7 @@ public class ServletRedirectResult extends StrutsResultSupport { if (isPathUrl(finalLocation)) { if (!finalLocation.startsWith("/")) { - String namespace = ActionMapperFactory.getMapper().getMapping( + String namespace = actionMapper.getMapping( request, Dispatcher.getInstance().getConfigurationManager()).getNamespace(); if ((namespace != null) && (namespace.length() > 0) && (!"/".equals(namespace))) { diff --git a/core/src/main/java/org/apache/struts2/dispatcher/VelocityResult.java b/core/src/main/java/org/apache/struts2/dispatcher/VelocityResult.java index 263b9090c..e29a05761 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/VelocityResult.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/VelocityResult.java @@ -34,7 +34,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.views.JspSupportServlet; import org.apache.struts2.views.velocity.VelocityManager; import org.apache.velocity.Template; @@ -43,6 +42,7 @@ import org.apache.velocity.context.Context; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; @@ -87,6 +87,9 @@ public class VelocityResult extends StrutsResultSupport { private static final long serialVersionUID = 7268830767762559424L; private static final Log log = LogFactory.getLog(VelocityResult.class); + + private String defaultEncoding; + private VelocityManager velocityManager; public VelocityResult() { super(); @@ -95,6 +98,16 @@ public class VelocityResult extends StrutsResultSupport { public VelocityResult(String location) { super(location); } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public void setDefaultEncoding(String val) { + defaultEncoding = val; + } + + @Inject + public void setVelocityManager(VelocityManager mgr) { + this.velocityManager = mgr; + } /** * Creates a Velocity context from the action, loads a Velocity template and executes the @@ -114,7 +127,7 @@ public class VelocityResult extends StrutsResultSupport { ServletContext servletContext = ServletActionContext.getServletContext(); Servlet servlet = JspSupportServlet.jspSupportServlet; - VelocityManager.getInstance().init(servletContext); + velocityManager.init(servletContext); boolean usedJspFactory = false; PageContext pageContext = (PageContext) ActionContext.getContext().get(ServletActionContext.PAGE_CONTEXT); @@ -134,7 +147,6 @@ public class VelocityResult extends StrutsResultSupport { contentType = contentType + ";charset=" + encoding; } - VelocityManager velocityManager = VelocityManager.getInstance(); Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding); Context context = createContext(velocityManager, stack, request, response, finalLocation); @@ -179,7 +191,7 @@ public class VelocityResult extends StrutsResultSupport { * @return The encoding associated with this template (defaults to the value of 'struts.i18n.encoding' property) */ protected String getEncoding(String templateLocation) { - String encoding = (String) Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + String encoding = defaultEncoding; if (encoding == null) { encoding = System.getProperty("file.encoding"); } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapperFactory.java b/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapperFactory.java deleted file mode 100644 index 46d87b172..000000000 --- a/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapperFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * $Id$ - * - * 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.dispatcher.mapper; - -import java.util.HashMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.struts2.StrutsConstants; -import org.apache.struts2.StrutsException; -import org.apache.struts2.config.Settings; - -import com.opensymphony.xwork2.ObjectFactory; - -/** - * - * - * Factory that creates {@link ActionMapper}s. This factory looks up the class name of the {@link ActionMapper} from - * Struts's configuration using the key struts.mapper.class. - * - * - * - */ -public class ActionMapperFactory { - protected static final Log LOG = LogFactory.getLog(ActionMapperFactory.class); - - private static final HashMap classMap = new HashMap(); - - /** - * Gets an instance of the ActionMapper - * - * @return The action mapper - */ - public static ActionMapper getMapper() { - synchronized (classMap) { - String clazz = (String) Settings.get(StrutsConstants.STRUTS_MAPPER_CLASS); - try { - ActionMapper mapper = (ActionMapper) classMap.get(clazz); - if (mapper == null) { - mapper = (ActionMapper) ObjectFactory.getObjectFactory().buildBean(clazz, null); - classMap.put(clazz, mapper); - } - - return mapper; - } catch (Exception e) { - String msg = "Could not create ActionMapper: Struts will *not* work!"; - throw new StrutsException(msg, e); - } - } - } -} diff --git a/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java b/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java index 0cc872225..e76199eb0 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapper.java @@ -31,10 +31,11 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.FileManager; /** @@ -90,19 +91,39 @@ public class CompositeActionMapper implements ActionMapper { private static final Log LOG = LogFactory.getLog(CompositeActionMapper.class); - protected List orderedActionMappers; + protected Container container; + + protected List actionMappers = new ArrayList(); + + @Inject + public void setContainer(Container container) { + this.container = container; + } + + @Inject(StrutsConstants.STRUTS_MAPPER_COMPOSITE) + public void setActionMappers(String list) { + if (list != null) { + String[] arr = list.split(","); + for (String name : arr) { + Object obj = container.getInstance(ActionMapper.class, name); + if (obj != null) { + actionMappers.add((ActionMapper) obj); + } + } + } + } public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) { - for (IndividualActionMapperEntry actionMapperEntry: getOrderedActionMapperEntries()) { - ActionMapping actionMapping = actionMapperEntry.actionMapper.getMapping(request, configManager); + for (ActionMapper actionMapper : actionMappers) { + ActionMapping actionMapping = actionMapper.getMapping(request, configManager); if (LOG.isDebugEnabled()) { - LOG.debug("Using ActionMapper from entry ["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"]"); + LOG.debug("Using ActionMapper "+actionMapper); } if (actionMapping == null) { if (LOG.isDebugEnabled()) { - LOG.debug("ActionMapper from entry ["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"] failed to return an ActionMapping (null)"); + LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)"); } } else { @@ -117,14 +138,14 @@ public class CompositeActionMapper implements ActionMapper { public String getUriFromActionMapping(ActionMapping mapping) { - for (IndividualActionMapperEntry actionMapperEntry: getOrderedActionMapperEntries()) { - String uri = actionMapperEntry.actionMapper.getUriFromActionMapping(mapping); + for (ActionMapper actionMapper : actionMappers) { + String uri = actionMapper.getUriFromActionMapping(mapping); if (LOG.isDebugEnabled()) { - LOG.debug("Using ActionMapper from entry ["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"]"); + LOG.debug("Using ActionMapper "+actionMapper); } if (uri == null) { if (LOG.isDebugEnabled()) { - LOG.debug("ActionMapper from entry ["+actionMapperEntry.propertyName+"="+actionMapperEntry.propertyValue+"] failed to return a uri (null)"); + LOG.debug("ActionMapper "+actionMapper+" failed to return an ActionMapping (null)"); } } else { @@ -136,139 +157,4 @@ public class CompositeActionMapper implements ActionMapper { } return null; } - - - protected List getOrderedActionMapperEntries() { - if (this.orderedActionMappers == null || FileManager.isReloadingConfigs()) { - - List actionMapperEntriesContainer = new ArrayList(); - Iterator settings = Settings.list(); - while(settings.hasNext()) { - String setting = settings.next().toString(); - if (setting.startsWith(StrutsConstants.STRUTS_MAPPER_COMPOSITE)) { - try { - int order = Integer.valueOf(setting.substring(StrutsConstants.STRUTS_MAPPER_COMPOSITE.length(), setting.length())); - String propertyValue = Settings.get(setting); - if (propertyValue != null && propertyValue.trim().length() > 0) { - actionMapperEntriesContainer.add( - new IndividualActionMapperEntry(order, setting, propertyValue)); - } - else { - LOG.warn("Ignoring property "+setting+" that contains no value"); - } - } - catch(NumberFormatException e) { - LOG.warn("Ignoring malformed property "+setting); - } - } - } - - Collections.sort(actionMapperEntriesContainer, new Comparator() { - public int compare(IndividualActionMapperEntry o1, IndividualActionMapperEntry o2) { - return o1.compareTo(o2); - } - }); - - - ObjectFactory objectFactory = ObjectFactory.getObjectFactory(); - List result = new ArrayList(); - for (IndividualActionMapperEntry entry: actionMapperEntriesContainer) { - String actionMapperClassName = entry.propertyValue; - try { - // Let us get ClassCastException if it does not implement ActionMapper - ActionMapper actionMapper = (ActionMapper) objectFactory.buildBean(actionMapperClassName, null); - result.add(new IndividualActionMapperEntry(entry.order, entry.propertyName, entry.propertyValue, actionMapper)); - } - catch(Exception e) { - LOG.warn("failed to create action mapper "+actionMapperClassName+", ignoring it", e); - } - } - - this.orderedActionMappers = result; - } - - return this.orderedActionMappers; - } - - - /** - * A value object (holder) that holds information regarding {@link ActionMapper} this {@link CompositeActionMapper} - * is capable of delegating to. - *

    - * The information stored are :- - *

      - *
    • order
    • - *
    • propertyValue
    • - *
    • propertyName
    • - *
    • actionMapper
    • - *
    - * - * eg. if we have the following entry in struts.properties - *
    -     * struts.mapper.composite.1=foo.bar.ActionMapper1
    -     * struts.mapper.composite.2=foo.bar.ActionMapper2
    -     * struts.mapper.composite.3=foo.bar.ActionMapper3
    -     * 
    - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
    orderpropertyNamepropertyValueactionMapper
    1struts.mapper.composite.1foo.bar.ActionMapper1instance of foo.bar.ActionMapper1
    2struts.mapper.composite.2foo.bar.ActionMapper2instance of foo.bar.ActionMapper2
    3struts.mapper.composite.3foo.bar.ActionMapper3instance of foo.bar.ActionMapper3
    - * - * @version $Date$ $Id$ - */ - public class IndividualActionMapperEntry implements Comparable { - - public Integer order; - public String propertyValue; - public String propertyName; - public ActionMapper actionMapper; - - - private IndividualActionMapperEntry(Integer order, String propertyName, String propertyValue) { - assert(order != null); - assert(propertyValue != null); - assert(propertyName != null); - this.order = order; - this.propertyValue = propertyValue; - this.propertyName = propertyName; - } - - public IndividualActionMapperEntry(Integer order, String propertyName, String propertyValue, ActionMapper actionMapper) { - assert(order != null); - assert(propertyValue != null); - assert(propertyName != null); - assert(actionMapper != null); - this.order = order; - this.propertyValue = propertyValue; - this.propertyName = propertyName; - this.actionMapper = actionMapper; - } - - public int compareTo(IndividualActionMapperEntry o) { - return order - o.order; - } - } } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java index e6c5c63d7..7ac1e6dc8 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java @@ -20,6 +20,7 @@ */ package org.apache.struts2.dispatcher.mapper; +import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; @@ -29,13 +30,13 @@ import javax.servlet.http.HttpServletRequest; import org.apache.struts2.RequestUtils; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.ServletRedirectResult; import org.apache.struts2.util.PrefixTrie; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.config.entities.PackageConfig; +import com.opensymphony.xwork2.inject.Inject; /** * @@ -171,18 +172,10 @@ public class DefaultActionMapper implements ActionMapper { private boolean allowSlashesInActionNames = false; private PrefixTrie prefixTrie = null; + + List extensions = new ArrayList() {{ add("action");}}; public DefaultActionMapper() { - if (Settings.isSet(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)) { - allowDynamicMethodCalls = "true".equals(Settings - .get(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION)); - } - - if (Settings.isSet(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES)) { - allowSlashesInActionNames = "true".equals(Settings - .get(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES)); - } - prefixTrie = new PrefixTrie() { { put(METHOD_PREFIX, new ParameterAction() { @@ -233,6 +226,16 @@ public class DefaultActionMapper implements ActionMapper { } }; } + + @Inject(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION) + public void setAllowDynamicMethodCalls(String allow) { + allowDynamicMethodCalls = "true".equals(allow); + } + + @Inject(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES) + public void setSlashesInActionNames(String allow) { + allowSlashesInActionNames = "true".equals(allow); + } /* * (non-Javadoc) @@ -352,7 +355,6 @@ public class DefaultActionMapper implements ActionMapper { * @return The action name without its extension */ String dropExtension(String name) { - List extensions = getExtensions(); if (extensions == null) { return name; } @@ -370,8 +372,7 @@ public class DefaultActionMapper implements ActionMapper { /** * Returns null if no extension is specified. */ - static String getDefaultExtension() { - List extensions = getExtensions(); + String getDefaultExtension() { if (extensions == null) { return null; } else { @@ -379,20 +380,15 @@ public class DefaultActionMapper implements ActionMapper { } } - /** - * Returns null if no extension is specified. - */ - static List getExtensions() { - String extensions = (String) org.apache.struts2.config.Settings - .get(StrutsConstants.STRUTS_ACTION_EXTENSION); - - if ("".equals(extensions)) { - return null; + @Inject(StrutsConstants.STRUTS_ACTION_EXTENSION) + public void setExtensions(String extensions) { + if (!"".equals(extensions)) { + this.extensions = Arrays.asList(extensions.split(",")); } else { - return Arrays.asList(extensions.split(",")); + this.extensions = null; } } - + /** * Gets the uri from the request * diff --git a/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java b/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java index 176d0c8eb..b62446f52 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java @@ -38,18 +38,33 @@ import org.apache.commons.fileupload.RequestContext; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts2.StrutsConstants; + +import com.opensymphony.xwork2.inject.Inject; /** * Multipart form data request adapter for Jakarta Commons Fileupload package. * */ -public class JakartaMultiPartRequest extends MultiPartRequest { +public class JakartaMultiPartRequest implements MultiPartRequest { + + static final Log log = LogFactory.getLog(MultiPartRequest.class); + // maps parameter name -> List of FileItem objects private Map> files = new HashMap>(); // maps parameter name -> List of param values private Map> params = new HashMap>(); // any errors while processing this request private List errors = new ArrayList(); + + private long maxSize; + + @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE) + public void setMaxSize(String maxSize) { + this.maxSize = Long.parseLong(maxSize); + } /** * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's @@ -60,10 +75,10 @@ public class JakartaMultiPartRequest extends MultiPartRequest { * @param servletRequest the request containing the multipart * @throws java.io.IOException is thrown if encoding fails. */ - public JakartaMultiPartRequest(HttpServletRequest servletRequest, String saveDir, int maxSize) + public void parse(HttpServletRequest servletRequest, String saveDir) throws IOException { DiskFileItemFactory fac = new DiskFileItemFactory(); - fac.setSizeThreshold(0); + fac.setSizeThreshold((int)maxSize); if (saveDir != null) { fac.setRepository(new File(saveDir)); } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequest.java b/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequest.java index 68b3036c7..398f272e5 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequest.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequest.java @@ -21,6 +21,7 @@ package org.apache.struts2.dispatcher.multipart; import java.io.File; +import java.io.IOException; import java.util.Enumeration; import java.util.List; @@ -34,28 +35,16 @@ import org.apache.commons.logging.LogFactory; * Abstract wrapper class HTTP requests to handle multi-part data.

    * */ -public abstract class MultiPartRequest { - - protected static Log log = LogFactory.getLog(MultiPartRequest.class); - - - /** - * Returns true if the request is multipart form data, false otherwise. - * - * @param request the http servlet request. - * @return true if the request is multipart form data, false otherwise. - */ - public static boolean isMultiPart(HttpServletRequest request) { - String content_type = request.getContentType(); - return content_type != null && content_type.indexOf("multipart/form-data") != -1; - } +public interface MultiPartRequest { + public void parse(HttpServletRequest request, String saveDir) throws IOException; + /** * Returns an enumeration of the parameter names for uploaded files * * @return an enumeration of the parameter names for uploaded files */ - public abstract Enumeration getFileParameterNames(); + public Enumeration getFileParameterNames(); /** * Returns the content type(s) of the file(s) associated with the specified field name @@ -66,7 +55,7 @@ public abstract class MultiPartRequest { * @return an array of content encoding for the specified input field name or null if * no content type was specified. */ - public abstract String[] getContentType(String fieldName); + public String[] getContentType(String fieldName); /** * Returns a {@link java.io.File} object for the filename specified or null if no files @@ -75,7 +64,7 @@ public abstract class MultiPartRequest { * @param fieldName input field name * @return a File[] object for files associated with the specified input field name */ - public abstract File[] getFile(String fieldName); + public File[] getFile(String fieldName); /** * Returns a String[] of file names for files associated with the specified input field name @@ -83,7 +72,7 @@ public abstract class MultiPartRequest { * @param fieldName input field name * @return a String[] of file names for files associated with the specified input field name */ - public abstract String[] getFileNames(String fieldName); + public String[] getFileNames(String fieldName); /** * Returns the file system name(s) of files associated with the given field name or @@ -92,7 +81,7 @@ public abstract class MultiPartRequest { * @param fieldName input field name * @return the file system name(s) of files associated with the given field name */ - public abstract String[] getFilesystemName(String fieldName); + public String[] getFilesystemName(String fieldName); /** * Returns the specified request parameter. @@ -100,14 +89,14 @@ public abstract class MultiPartRequest { * @param name the name of the parameter to get * @return the parameter or null if it was not found. */ - public abstract String getParameter(String name); + public String getParameter(String name); /** * Returns an enumeration of String parameter names. * * @return an enumeration of String parameter names. */ - public abstract Enumeration getParameterNames(); + public Enumeration getParameterNames(); /** * Returns a list of all parameter values associated with a parameter name. If there is only @@ -116,7 +105,7 @@ public abstract class MultiPartRequest { * @param name the name of the parameter. * @return an array of all values associated with the parameter name. */ - public abstract String[] getParameterValues(String name); + public String[] getParameterValues(String name); /** * Returns a list of error messages that may have occurred while processing the request. @@ -127,5 +116,5 @@ public abstract class MultiPartRequest { * * @return a list of Strings that represent various errors during parsing */ - public abstract List getErrors(); + public List getErrors(); } diff --git a/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequestWrapper.java b/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequestWrapper.java index 35ce509a0..9eead01f3 100644 --- a/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequestWrapper.java +++ b/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequestWrapper.java @@ -21,6 +21,7 @@ package org.apache.struts2.dispatcher.multipart; import java.io.File; +import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -36,7 +37,6 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.StrutsRequestWrapper; import org.apache.struts2.util.ClassLoaderUtils; @@ -72,71 +72,19 @@ public class MultiPartRequestWrapper extends StrutsRequestWrapper { * @param saveDir directory to save the file(s) to * @param maxSize maximum file size allowed */ - public MultiPartRequestWrapper(HttpServletRequest request, String saveDir, int maxSize) { + public MultiPartRequestWrapper(MultiPartRequest multiPartRequest, HttpServletRequest request, String saveDir) { super(request); - - if (request instanceof MultiPartRequest) { - multi = (MultiPartRequest) request; - } else { - String parser = Settings.get(StrutsConstants.STRUTS_MULTIPART_PARSER); - - // If it's not set, use Jakarta - if (parser.equals("")) { - log.warn("Property struts.multipart.parser not set." + - " Using org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest"); - parser = "org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest"; + + multi = multiPartRequest; + try { + multi.parse(request, saveDir); + for (Iterator iter = multi.getErrors().iterator(); iter.hasNext();) { + String error = (String) iter.next(); + addError(error); } - // legacy support for old style property values - else if (parser.equals("pell")) { - parser = "org.apache.struts2.dispatcher.multipart.PellMultiPartRequest"; - } else if (parser.equals("cos")) { - parser = "org.apache.struts2.dispatcher.multipart.CosMultiPartRequest"; - } else if (parser.equals("jakarta")) { - parser = "org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest"; - } - - try { - Class baseClazz = org.apache.struts2.dispatcher.multipart.MultiPartRequest.class; - - Class clazz = ClassLoaderUtils.loadClass(parser, MultiPartRequestWrapper.class); - - // make sure it extends MultiPartRequest - if (!baseClazz.isAssignableFrom(clazz)) { - addError("Class '" + parser + "' does not extend MultiPartRequest"); - - return; - } - - // get the constructor - Constructor ctor = clazz.getDeclaredConstructor(new Class[]{ - ClassLoaderUtils.loadClass("javax.servlet.http.HttpServletRequest", MultiPartRequestWrapper.class), - java.lang.String.class, int.class - }); - - // build the parameter list - Object[] parms = new Object[]{ - request, saveDir, new Integer(maxSize) - }; - - // instantiate it - multi = (MultiPartRequest) ctor.newInstance(parms); - for (Iterator iter = multi.getErrors().iterator(); iter.hasNext();) { - String error = (String) iter.next(); - addError(error); - } - } catch (ClassNotFoundException e) { - addError("Class: " + parser + " not found."); - } catch (NoSuchMethodException e) { - addError("Constructor error for " + parser + ": " + e); - } catch (InstantiationException e) { - addError("Error instantiating " + parser + ": " + e); - } catch (IllegalAccessException e) { - addError("Access errror for " + parser + ": " + e); - } catch (InvocationTargetException e) { - // This is a wrapper for any exceptions thrown by the constructor called from newInstance - addError(e.getTargetException().toString()); - } - } + } catch (IOException e) { + addError("Cannot parse request: "+e.toString()); + } } /** diff --git a/core/src/main/java/org/apache/struts2/impl/StrutsActionProxy.java b/core/src/main/java/org/apache/struts2/impl/StrutsActionProxy.java index 1bed10810..6c294f76b 100644 --- a/core/src/main/java/org/apache/struts2/impl/StrutsActionProxy.java +++ b/core/src/main/java/org/apache/struts2/impl/StrutsActionProxy.java @@ -27,15 +27,16 @@ import java.util.concurrent.Callable; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.DefaultActionProxy; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; public class StrutsActionProxy extends DefaultActionProxy { private static final long serialVersionUID = -2434901249671934080L; - public StrutsActionProxy(Configuration cfg, String namespace, String actionName, Map extraContext, + public StrutsActionProxy(ObjectFactory objectFactory, Configuration cfg, String namespace, String actionName, Map extraContext, boolean executeResult, boolean cleanupContext) throws Exception { - super(cfg, namespace, actionName, extraContext, executeResult, cleanupContext); + super(objectFactory, cfg, namespace, actionName, extraContext, executeResult, cleanupContext); } public String execute() throws Exception { diff --git a/core/src/main/java/org/apache/struts2/impl/StrutsActionProxyFactory.java b/core/src/main/java/org/apache/struts2/impl/StrutsActionProxyFactory.java index 9630d7306..fb81ec849 100644 --- a/core/src/main/java/org/apache/struts2/impl/StrutsActionProxyFactory.java +++ b/core/src/main/java/org/apache/struts2/impl/StrutsActionProxyFactory.java @@ -32,11 +32,11 @@ public class StrutsActionProxyFactory extends DefaultActionProxyFactory { public ActionProxy createActionProxy(Configuration config, String namespace, String actionName, Map extraContext) throws Exception { - return new StrutsActionProxy(config, namespace, actionName, extraContext, true, true); + return new StrutsActionProxy(objectFactory, config, namespace, actionName, extraContext, true, true); } public ActionProxy createActionProxy(Configuration config, String namespace, String actionName, Map extraContext, boolean executeResult, boolean cleanupContext) throws Exception { - return new StrutsActionProxy(config, namespace, actionName, extraContext, executeResult, cleanupContext); + return new StrutsActionProxy(objectFactory, config, namespace, actionName, extraContext, executeResult, cleanupContext); } } diff --git a/core/src/main/java/org/apache/struts2/interceptor/ProfilingActivationInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/ProfilingActivationInterceptor.java index 1e091d6e6..1f5c3a10d 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/ProfilingActivationInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/ProfilingActivationInterceptor.java @@ -23,9 +23,12 @@ package org.apache.struts2.interceptor; import org.apache.struts2.dispatcher.Dispatcher; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.util.profiling.UtilTimerStack; +import org.apache.struts2.StrutsConstants; + /** * * @@ -69,6 +72,7 @@ import com.opensymphony.xwork2.util.profiling.UtilTimerStack; public class ProfilingActivationInterceptor extends AbstractInterceptor { private String profilingKey = "profiling"; + private boolean devMode; /** * @return the profilingKey @@ -83,10 +87,15 @@ public class ProfilingActivationInterceptor extends AbstractInterceptor { public void setProfilingKey(String profilingKey) { this.profilingKey = profilingKey; } + + @Inject(StrutsConstants.STRUTS_DEVMODE) + public void setDevMode(String mode) { + this.devMode = "true".equals(mode); + } @Override public String intercept(ActionInvocation invocation) throws Exception { - if (Dispatcher.getInstance().isDevMode()) { + if (devMode) { Object val = invocation.getInvocationContext().getParameters().get(profilingKey); if (val != null) { String sval = (val instanceof String ? (String)val : ((String[])val)[0]); diff --git a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java index df6390256..a1562d78e 100644 --- a/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java +++ b/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java @@ -41,9 +41,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.views.freemarker.FreemarkerResult; +import org.apache.struts2.StrutsConstants; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.Interceptor; import com.opensymphony.xwork2.interceptor.PreResultListener; import com.opensymphony.xwork2.util.ValueStack; @@ -101,7 +103,13 @@ public class DebuggingInterceptor implements Interceptor { private final static String EXPRESSION_PARAM = "expression"; private boolean enableXmlWithConsole = false; + + private boolean devMode; + @Inject(StrutsConstants.STRUTS_DEVMODE) + public void setDevMode(String mode) { + this.devMode = "true".equals(mode); + } /** * Unused. @@ -124,8 +132,6 @@ public class DebuggingInterceptor implements Interceptor { */ public String intercept(ActionInvocation inv) throws Exception { - Boolean devMode = (Boolean) ActionContext.getContext().get( - ActionContext.DEV_MODE); boolean cont = true; if (devMode) { final ActionContext ctx = ActionContext.getContext(); diff --git a/core/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java b/core/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java index 27c075ef7..9eec0d2d0 100644 --- a/core/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java +++ b/core/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java @@ -21,6 +21,7 @@ package org.apache.struts2.portlet.dispatcher; import java.io.IOException; +import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -41,7 +42,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsStatics; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.ApplicationMap; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.RequestMap; @@ -54,7 +54,6 @@ import org.apache.struts2.portlet.PortletSessionMap; import org.apache.struts2.portlet.context.PortletActionContext; import org.apache.struts2.portlet.context.ServletContextHolderListener; import org.apache.struts2.util.AttributeMap; -import org.apache.struts2.util.ObjectFactoryInitializable; import com.opensymphony.xwork2.util.ClassLoaderUtil; import com.opensymphony.xwork2.util.FileManager; @@ -64,6 +63,7 @@ import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.LocalizedTextUtil; /** @@ -177,9 +177,20 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics, public void init(PortletConfig cfg) throws PortletException { super.init(cfg); LOG.debug("Initializing portlet " + getPortletName()); + + Map params = new HashMap(); + for (Enumeration e = cfg.getInitParameterNames(); e.hasMoreElements(); ) { + String name = (String) e.nextElement(); + String value = cfg.getInitParameter(name); + params.put(name, value); + } + + Dispatcher.setPortletSupportActive(true); + dispatcherUtils = new Dispatcher(ServletContextHolderListener.getServletContext(), params); + // For testability if (factory == null) { - factory = ActionProxyFactory.getFactory(); + factory = dispatcherUtils.getConfigurationManager().getConfiguration().getContainer().getInstance(ActionProxyFactory.class); } portletNamespace = cfg.getInitParameter("portletNamespace"); LOG.debug("PortletNamespace: " + portletNamespace); @@ -205,48 +216,11 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics, LocalizedTextUtil .addDefaultResourceBundle("org/apache/struts2/struts-messages"); + Container container = dispatcherUtils.getContainer(); //check for configuration reloading - if ("true".equalsIgnoreCase(Settings - .get(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))) { + if ("true".equalsIgnoreCase(container.getInstance(String.class, StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD))) { FileManager.setReloadingConfigs(true); } - - if ("true".equalsIgnoreCase(Settings.get(StrutsConstants.STRUTS_DEVMODE))) { - Settings.set(StrutsConstants.STRUTS_I18N_RELOAD, "true"); - Settings.set(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "true"); - } - - if (Settings.isSet(StrutsConstants.STRUTS_OBJECTFACTORY)) { - String className = (String) Settings - .get(StrutsConstants.STRUTS_OBJECTFACTORY); - if (className.equals("spring")) { - // note: this class name needs to be in string form so we don't put hard - // dependencies on spring, since it isn't technically required. - className = "org.apache.struts2.spring.StrutsSpringObjectFactory"; - } else if (className.equals("plexus")) { - // note: this class name needs to be in string form so we don't put hard - // dependencies on spring, since it isn't technically required. - className = "org.apache.struts2.plexus.PlexusObjectFactory"; - } - - try { - Class clazz = ClassLoaderUtil.loadClass(className, - Jsr168Dispatcher.class); - ObjectFactory objectFactory = (ObjectFactory) clazz - .newInstance(); - if (objectFactory instanceof ObjectFactoryInitializable) { - ((ObjectFactoryInitializable) objectFactory) - .init(ServletContextHolderListener - .getServletContext()); - } - ObjectFactory.setObjectFactory(objectFactory); - } catch (Exception e) { - LOG.error("Could not load ObjectFactory named " + className - + ". Using default ObjectFactory.", e); - } - } - Dispatcher.setPortletSupportActive(true); - dispatcherUtils = new Dispatcher(ServletContextHolderListener.getServletContext()); } /** @@ -363,16 +337,16 @@ public class Jsr168Dispatcher extends GenericPortlet implements StrutsStatics, extraContext.put(ActionContext.SESSION, sessionMap); extraContext.put(ActionContext.APPLICATION, applicationMap); + String defaultLocale = dispatcherUtils.getContainer().getInstance(String.class, StrutsConstants.STRUTS_LOCALE); Locale locale = null; - if (Settings.isSet(StrutsConstants.STRUTS_LOCALE)) { - locale = LocalizedTextUtil.localeFromString(Settings.get(StrutsConstants.STRUTS_LOCALE), request.getLocale()); + if (defaultLocale != null) { + locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale()); } else { locale = request.getLocale(); } extraContext.put(ActionContext.LOCALE, locale); extraContext.put(StrutsStatics.STRUTS_PORTLET_CONTEXT, getPortletContext()); - extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(Settings.get(StrutsConstants.STRUTS_DEVMODE))); extraContext.put(REQUEST, request); extraContext.put(RESPONSE, response); extraContext.put(PORTLET_CONFIG, portletConfig); diff --git a/core/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java b/core/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java index 957a3d028..899f02fe8 100644 --- a/core/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java +++ b/core/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java @@ -38,7 +38,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.StrutsResultSupport; import org.apache.struts2.portlet.PortletActionConstants; import org.apache.struts2.portlet.context.PortletActionContext; @@ -50,6 +49,7 @@ import org.apache.velocity.context.Context; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -96,7 +96,10 @@ public class PortletVelocityResult extends StrutsResultSupport { private static final Log log = LogFactory .getLog(PortletVelocityResult.class); - + + private String defaultEncoding; + private VelocityManager velocityManager; + public PortletVelocityResult() { super(); } @@ -104,6 +107,16 @@ public class PortletVelocityResult extends StrutsResultSupport { public PortletVelocityResult(String location) { super(location); } + + @Inject + public void setVelocityManager(VelocityManager mgr) { + this.velocityManager = mgr; + } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public void setDefaultEncoding(String encoding) { + this.defaultEncoding = encoding; + } /* (non-Javadoc) * @see org.apache.struts2.dispatcher.StrutsResultSupport#doExecute(java.lang.String, com.opensymphony.xwork2.ActionInvocation) @@ -157,7 +170,7 @@ public class PortletVelocityResult extends StrutsResultSupport { .getServletContext(); Servlet servlet = JspSupportServlet.jspSupportServlet; - VelocityManager.getInstance().init(servletContext); + velocityManager.init(servletContext); boolean usedJspFactory = false; PageContext pageContext = (PageContext) ActionContext.getContext().get( @@ -180,7 +193,6 @@ public class PortletVelocityResult extends StrutsResultSupport { contentType = contentType + ";charset=" + encoding; } - VelocityManager velocityManager = VelocityManager.getInstance(); Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding); @@ -232,8 +244,7 @@ public class PortletVelocityResult extends StrutsResultSupport { * of 'struts.i18n.encoding' property) */ protected String getEncoding(String templateLocation) { - String encoding = (String) Settings - .get(StrutsConstants.STRUTS_I18N_ENCODING); + String encoding = defaultEncoding; if (encoding == null) { encoding = System.getProperty("file.encoding"); } diff --git a/core/src/main/java/org/apache/struts2/spring/StrutsSpringObjectFactory.java b/core/src/main/java/org/apache/struts2/spring/StrutsSpringObjectFactory.java index 54cd0bc8b..9b547c629 100644 --- a/core/src/main/java/org/apache/struts2/spring/StrutsSpringObjectFactory.java +++ b/core/src/main/java/org/apache/struts2/spring/StrutsSpringObjectFactory.java @@ -25,12 +25,11 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; -import org.apache.struts2.util.ObjectFactoryInitializable; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.spring.SpringObjectFactory; @@ -42,13 +41,24 @@ import com.opensymphony.xwork2.spring.SpringObjectFactory; * org.springframework.web.context.ContextLoaderListener defined in web.xml. * */ -public class StrutsSpringObjectFactory extends SpringObjectFactory implements ObjectFactoryInitializable { +public class StrutsSpringObjectFactory extends SpringObjectFactory { private static final Log log = LogFactory.getLog(StrutsSpringObjectFactory.class); - - /* (non-Javadoc) - * @see org.apache.struts2.util.ObjectFactoryInitializable#init(javax.servlet.ServletContext) - */ - public void init(ServletContext servletContext) { + + private String autoWire; + private boolean useClassCache = true; + + @Inject(value=StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE,required=false) + public void setAutoWire(String val) { + autoWire = val; + } + + @Inject(value=StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_USE_CLASS_CACHE,required=false) + public void setUseClassCache(String val) { + useClassCache = "true".equals(val); + } + + @Inject + public void setServletContext(ServletContext servletContext) { log.info("Initializing Struts-Spring integration..."); ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); @@ -67,7 +77,6 @@ public class StrutsSpringObjectFactory extends SpringObjectFactory implements Ob this.setApplicationContext(appContext); - String autoWire = Settings.get(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE); int type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; // default if ("name".equals(autoWire)) { type = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; @@ -80,7 +89,6 @@ public class StrutsSpringObjectFactory extends SpringObjectFactory implements Ob } this.setAutowireStrategy(type); - boolean useClassCache = "true".equals(Settings.get(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_USE_CLASS_CACHE)); this.setUseClassCache(useClassCache); log.info("... initialized Struts-Spring integration successfully"); diff --git a/core/src/main/java/org/apache/struts2/spring/lifecycle/SpringExternalReferenceResolverSetupListener.java b/core/src/main/java/org/apache/struts2/spring/lifecycle/SpringExternalReferenceResolverSetupListener.java deleted file mode 100644 index e32af7ab9..000000000 --- a/core/src/main/java/org/apache/struts2/spring/lifecycle/SpringExternalReferenceResolverSetupListener.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * $Id$ - * - * 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.spring.lifecycle; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.struts2.dispatcher.Dispatcher; -import org.apache.struts2.dispatcher.DispatcherListener; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.web.context.support.WebApplicationContextUtils; - -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.config.ExternalReferenceResolver; -import com.opensymphony.xwork2.config.entities.PackageConfig; - -/** - * Setup any {@link com.opensymphony.xwork2.config.ExternalReferenceResolver}s - * that implement the ApplicationContextAware interface from the Spring - * framework. Relies on Spring's - * {@link org.springframework.web.context.ContextLoaderListener}having been - * called first. - */ -public class SpringExternalReferenceResolverSetupListener implements - ServletContextListener { - - private Map listeners = new HashMap(); - - /* (non-Javadoc) - * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) - */ - public synchronized void contextDestroyed(ServletContextEvent event) { - Listener l = listeners.get(event.getServletContext()); - Dispatcher.removeDispatcherListener(l); - listeners.remove(event.getServletContext()); - } - - /* (non-Javadoc) - * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) - */ - public synchronized void contextInitialized(ServletContextEvent event) { - Listener l = new Listener(event.getServletContext()); - Dispatcher.addDispatcherListener(l); - listeners.put(event.getServletContext(), l); - } - - /** - * Handles initializing and cleaning up the dispatcher - * @author brownd - * - */ - private class Listener implements DispatcherListener { - - private ServletContext servletContext; - - /** - * Constructs the listener - * - * @param ctx The servlet context - */ - public Listener(ServletContext ctx) { - this.servletContext = ctx; - } - - /* (non-Javadoc) - * @see org.apache.struts2.dispatcher.DispatcherListener#dispatcherInitialized(org.apache.struts2.dispatcher.Dispatcher) - */ - public void dispatcherInitialized(Dispatcher du) { - ApplicationContext appContext = WebApplicationContextUtils - .getWebApplicationContext(servletContext); - - Configuration xworkConfig = du.getConfigurationManager().getConfiguration(); - Map packageConfigs = xworkConfig.getPackageConfigs(); - Iterator i = packageConfigs.values().iterator(); - - while (i.hasNext()) { - PackageConfig packageConfig = (PackageConfig) i.next(); - ExternalReferenceResolver resolver = packageConfig.getExternalRefResolver(); - if (resolver == null || !(resolver instanceof ApplicationContextAware)) - continue; - ApplicationContextAware contextAware = (ApplicationContextAware) resolver; - contextAware.setApplicationContext(appContext); - } - - } - - /* (non-Javadoc) - * @see org.apache.struts2.dispatcher.DispatcherListener#dispatcherDestroyed(org.apache.struts2.dispatcher.Dispatcher) - */ - public void dispatcherDestroyed(Dispatcher du) { - } - } -} diff --git a/core/src/main/java/org/apache/struts2/util/ObjectFactoryInitializable.java b/core/src/main/java/org/apache/struts2/util/ObjectFactoryInitializable.java deleted file mode 100644 index 1b19efa90..000000000 --- a/core/src/main/java/org/apache/struts2/util/ObjectFactoryInitializable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * $Id$ - * - * 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.util; - -import javax.servlet.ServletContext; - -/** - * Used to pass ServletContext init parameters to various - * frameworks such as Spring, Plexus and Portlet. - */ -public interface ObjectFactoryInitializable { - - void init(ServletContext servletContext); - -} diff --git a/core/src/main/java/org/apache/struts2/util/ObjectFactoryLifecycle.java b/core/src/main/java/org/apache/struts2/util/ObjectFactoryLifecycle.java deleted file mode 100644 index c03e37205..000000000 --- a/core/src/main/java/org/apache/struts2/util/ObjectFactoryLifecycle.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * $Id$ - * - * 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.util; - -/** - * An interface indicating the lifecycle of an ObjectFactory implementation. - * - * @see ObjectFactoryLifecycle - * @see com.opensymphony.xwork2.ObjectFactory - * @see org.apache.struts2.util.ObjectFactoryInitializable - * @see org.apache.struts2.util.ObjectFactoryDestroyable - */ -public interface ObjectFactoryLifecycle extends ObjectFactoryInitializable, ObjectFactoryDestroyable { - -} diff --git a/core/src/main/java/org/apache/struts2/util/ResolverSetupServletContextListener.java b/core/src/main/java/org/apache/struts2/util/ResolverSetupServletContextListener.java deleted file mode 100644 index 1627d8191..000000000 --- a/core/src/main/java/org/apache/struts2/util/ResolverSetupServletContextListener.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * $Id$ - * - * 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.util; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.struts2.dispatcher.Dispatcher; -import org.apache.struts2.dispatcher.DispatcherListener; - -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.config.entities.PackageConfig; - - -/** - * A Servlet Context Listener that will loop through all Reference Resolvers available in - * the xwork Configuration and set the ServletContext on those that are ServletContextAware. - * The Servlet Context can be used by the External Reference Resolver to initialise it's state. i.e. the - * Spring framework uses a ContextServletListener to initialise it's IoC container, storing it's - * container context (ApplicationContext in Spring terms) in the Servlet context, the External - * Reference Resolver can get a reference to the container context from the servlet context. - */ -public class ResolverSetupServletContextListener implements ServletContextListener { - - Map listeners = new HashMap(); - - public synchronized void contextDestroyed(ServletContextEvent event) { - Listener l = listeners.get(event.getServletContext()); - Dispatcher.removeDispatcherListener(l); - listeners.remove(event.getServletContext()); - } - - public synchronized void contextInitialized(ServletContextEvent event) { - Listener l = new Listener(event.getServletContext()); - Dispatcher.addDispatcherListener(l); - listeners.put(event.getServletContext(), l); - } - - private class Listener implements DispatcherListener { - - private ServletContext servletContext; - - public Listener(ServletContext ctx) { - this.servletContext = ctx; - } - - public void dispatcherInitialized(Dispatcher du) { - Configuration config = du.getConfigurationManager().getConfiguration(); - String key; - PackageConfig packageConfig; - - for (Iterator iter = config.getPackageConfigNames().iterator(); - iter.hasNext();) { - key = (String) iter.next(); - packageConfig = config.getPackageConfig(key); - - if (packageConfig.getExternalRefResolver()instanceof ServletContextAware) { - ((ServletContextAware) packageConfig.getExternalRefResolver()).setServletContext(servletContext); - } - } - - } - - public void dispatcherDestroyed(Dispatcher du) { - } - } -} diff --git a/core/src/main/java/org/apache/struts2/util/VelocityStrutsUtil.java b/core/src/main/java/org/apache/struts2/util/VelocityStrutsUtil.java index cee874065..1c7b674bc 100644 --- a/core/src/main/java/org/apache/struts2/util/VelocityStrutsUtil.java +++ b/core/src/main/java/org/apache/struts2/util/VelocityStrutsUtil.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.views.velocity.VelocityManager; +import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.context.Context; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; @@ -42,15 +43,17 @@ import com.opensymphony.xwork2.util.ValueStack; public class VelocityStrutsUtil extends StrutsUtil { private Context ctx; + private VelocityEngine velocityEngine; - public VelocityStrutsUtil(Context ctx, ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + public VelocityStrutsUtil(VelocityEngine engine, Context ctx, ValueStack stack, HttpServletRequest request, HttpServletResponse response) { super(stack, request, response); this.ctx = ctx; + this.velocityEngine = engine; } public String evaluate(String expression) throws IOException, ResourceNotFoundException, MethodInvocationException, ParseErrorException { CharArrayWriter writer = new CharArrayWriter(); - VelocityManager.getInstance().getVelocityEngine().evaluate(ctx, writer, "Error parsing " + expression, expression); + velocityEngine.evaluate(ctx, writer, "Error parsing " + expression, expression); return writer.toString(); } diff --git a/core/src/main/java/org/apache/struts2/validators/DWRValidator.java b/core/src/main/java/org/apache/struts2/validators/DWRValidator.java index 78eae1dfb..7703e22f1 100644 --- a/core/src/main/java/org/apache/struts2/validators/DWRValidator.java +++ b/core/src/main/java/org/apache/struts2/validators/DWRValidator.java @@ -40,6 +40,7 @@ import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.DefaultActionInvocation; import com.opensymphony.xwork2.DefaultActionProxy; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.ValidationAware; import com.opensymphony.xwork2.ValidationAwareSupport; import com.opensymphony.xwork2.config.Configuration; @@ -90,7 +91,8 @@ public class DWRValidator { try { Configuration cfg = du.getConfigurationManager().getConfiguration(); - ValidatorActionProxy proxy = new ValidatorActionProxy(cfg, namespace, action, ctx); + ObjectFactory of = cfg.getContainer().getInstance(ObjectFactory.class); + ValidatorActionProxy proxy = new ValidatorActionProxy(of, cfg, namespace, action, ctx); proxy.execute(); Object a = proxy.getAction(); @@ -114,8 +116,8 @@ public class DWRValidator { public static class ValidatorActionInvocation extends DefaultActionInvocation { private static final long serialVersionUID = -7645433725470191275L; - protected ValidatorActionInvocation(ActionProxy proxy, Map extraContext) throws Exception { - super(proxy, extraContext, true); + protected ValidatorActionInvocation(ObjectFactory objectFactory, ActionProxy proxy, Map extraContext) throws Exception { + super(objectFactory, proxy, extraContext, true); } protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception { @@ -126,12 +128,12 @@ public class DWRValidator { public static class ValidatorActionProxy extends DefaultActionProxy { private static final long serialVersionUID = 5754781916414047963L; - protected ValidatorActionProxy(Configuration config, String namespace, String actionName, Map extraContext) throws Exception { - super(config, namespace, actionName, extraContext, false, true); + protected ValidatorActionProxy(ObjectFactory objectFactory, Configuration config, String namespace, String actionName, Map extraContext) throws Exception { + super(objectFactory, config, namespace, actionName, extraContext, false, true); } protected void prepare() throws Exception { - invocation = new ValidatorActionInvocation(this, extraContext); + invocation = new ValidatorActionInvocation(objectFactory, this, extraContext); } } } diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java index e6f3585dc..2d6c92ab2 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java @@ -35,11 +35,11 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.views.JspSupportServlet; import org.apache.struts2.views.freemarker.tags.StrutsModels; import org.apache.struts2.views.util.ContextUtil; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.FileManager; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.ObjectFactory; @@ -114,40 +114,19 @@ public class FreemarkerManager { public static final String KEY_SESSION_MODEL = "Session"; public static final String KEY_JSP_TAGLIBS = "JspTaglibs"; public static final String KEY_REQUEST_PARAMETER_MODEL = "Parameters"; - private static FreemarkerManager instance = null; - - - /** - * To allow for custom configuration of freemarker, sublcass this class "ConfigManager" and - * set the Struts configuration property - * struts.freemarker.configmanager.classname to the fully qualified classname. - *

    - * This allows you to override the protected methods in the ConfigMangaer - * to programatically create your own Configuration instance - */ - public final static synchronized FreemarkerManager getInstance() { - if (instance == null) { - String classname = FreemarkerManager.class.getName(); - - if (Settings.isSet(StrutsConstants.STRUTS_FREEMARKER_MANAGER_CLASSNAME)) { - classname = Settings.get(StrutsConstants.STRUTS_FREEMARKER_MANAGER_CLASSNAME).trim(); - } - - try { - log.info("Instantiating Freemarker ConfigManager!, " + classname); - // singleton instances shouldn't be built accessing request or session-specific context data - instance = (FreemarkerManager) ObjectFactory.getObjectFactory().buildBean(classname, null); - } catch (Exception e) { - log.fatal("Fatal exception occurred while trying to instantiate a Freemarker ConfigManager instance, " + classname, e); - } - } - - // if the instance creation failed, make sure there is a default instance - if (instance == null) { - instance = new FreemarkerManager(); - } - - return instance; + + private String encoding; + private boolean altMapWrapper; + + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + @Inject(StrutsConstants.STRUTS_FREEMARKER_WRAPPER_ALT_MAP) + public void setWrapperAltMap(String val) { + altMapWrapper = "true".equals(val); } public final synchronized freemarker.template.Configuration getConfiguration(ServletContext servletContext) throws TemplateException { @@ -240,7 +219,7 @@ public class FreemarkerManager { } protected BeansWrapper getObjectWrapper() { - return new StrutsBeanWrapper(); + return new StrutsBeanWrapper(altMapWrapper); } /** @@ -306,8 +285,8 @@ public class FreemarkerManager { configuration.setObjectWrapper(getObjectWrapper()); - if (Settings.isSet(StrutsConstants.STRUTS_I18N_ENCODING)) { - configuration.setDefaultEncoding(Settings.get(StrutsConstants.STRUTS_I18N_ENCODING)); + if (encoding != null) { + configuration.setDefaultEncoding(encoding); } loadSettings(servletContext, configuration); diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java index 25bacc63c..5f62988a7 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java @@ -35,6 +35,7 @@ import org.apache.struts2.views.util.ResourceUtil; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.LocaleProvider; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import freemarker.template.Configuration; @@ -99,6 +100,7 @@ public class FreemarkerResult extends StrutsResultSupport { protected ActionInvocation invocation; protected Configuration configuration; protected ObjectWrapper wrapper; + protected FreemarkerManager freemarkerManager; /* * Struts results are constructed for each result execution @@ -115,6 +117,11 @@ public class FreemarkerResult extends StrutsResultSupport { public FreemarkerResult(String location) { super(location); } + + @Inject + public void setFreemarkerManager(FreemarkerManager mgr) { + this.freemarkerManager = mgr; + } public void setContentType(String aContentType) { pContentType = aContentType; @@ -176,7 +183,7 @@ public class FreemarkerResult extends StrutsResultSupport { * */ protected Configuration getConfiguration() throws TemplateException { - return FreemarkerManager.getInstance().getConfiguration(ServletActionContext.getServletContext()); + return freemarkerManager.getConfiguration(ServletActionContext.getServletContext()); } /** @@ -226,7 +233,7 @@ public class FreemarkerResult extends StrutsResultSupport { Object action = null; if(invocation!= null ) action = invocation.getAction(); //Added for NullPointException - return FreemarkerManager.getInstance().buildTemplateModel(stack, action, servletContext, request, response, wrapper); + return freemarkerManager.buildTemplateModel(stack, action, servletContext, request, response, wrapper); } /** diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/PortletFreemarkerResult.java b/core/src/main/java/org/apache/struts2/views/freemarker/PortletFreemarkerResult.java index e0a6d9583..5063126b8 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/PortletFreemarkerResult.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/PortletFreemarkerResult.java @@ -38,6 +38,7 @@ import org.apache.struts2.portlet.context.PortletActionContext; import org.apache.struts2.views.util.ResourceUtil; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; import freemarker.template.Configuration; @@ -58,6 +59,7 @@ public class PortletFreemarkerResult extends StrutsResultSupport { protected Configuration configuration; protected ObjectWrapper wrapper; + protected FreemarkerManager freemarkerManager; /* * Struts results are constructed for each result execeution @@ -75,6 +77,11 @@ public class PortletFreemarkerResult extends StrutsResultSupport { public PortletFreemarkerResult(String location) { super(location); } + + @Inject + public void setFreemarkerManager(FreemarkerManager mgr) { + this.freemarkerManager = mgr; + } public void setContentType(String aContentType) { pContentType = aContentType; @@ -177,7 +184,7 @@ public class PortletFreemarkerResult extends StrutsResultSupport { * from the ConfigurationManager instance. */ protected Configuration getConfiguration() throws TemplateException { - return FreemarkerManager.getInstance().getConfiguration( + return freemarkerManager.getConfiguration( ServletActionContext.getServletContext()); } @@ -224,7 +231,7 @@ public class PortletFreemarkerResult extends StrutsResultSupport { HttpServletResponse response = ServletActionContext.getResponse(); ValueStack stack = ServletActionContext.getContext() .getValueStack(); - return FreemarkerManager.getInstance().buildTemplateModel(stack, + return freemarkerManager.buildTemplateModel(stack, invocation.getAction(), servletContext, request, response, wrapper); } diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/StrutsBeanWrapper.java b/core/src/main/java/org/apache/struts2/views/freemarker/StrutsBeanWrapper.java index 92e051502..f63fc9ee3 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/StrutsBeanWrapper.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/StrutsBeanWrapper.java @@ -23,6 +23,8 @@ package org.apache.struts2.views.freemarker; import java.util.Map; import java.util.Set; +import org.apache.struts2.StrutsConstants; + import freemarker.core.CollectionAndSequence; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.MapModel; @@ -51,8 +53,11 @@ import freemarker.template.TemplateModelException; * */ public class StrutsBeanWrapper extends BeansWrapper { - private static final boolean altMapWrapper - = "true".equals(org.apache.struts2.config.Settings.get("struts.freemarker.wrapper.altMap")); + private boolean altMapWrapper; + + StrutsBeanWrapper(boolean altMapWrapper) { + this.altMapWrapper = altMapWrapper; + } public TemplateModel wrap(Object object) throws TemplateModelException { if (object instanceof TemplateBooleanModel) { diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionModel.java b/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionModel.java index b935c107c..c85aa3953 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionModel.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionModel.java @@ -25,7 +25,11 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.ActionComponent; import org.apache.struts2.components.Component; +import org.apache.struts2.dispatcher.Dispatcher; +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; /** diff --git a/core/src/main/java/org/apache/struts2/views/freemarker/tags/TagModel.java b/core/src/main/java/org/apache/struts2/views/freemarker/tags/TagModel.java index 008de0ed7..4d132e073 100644 --- a/core/src/main/java/org/apache/struts2/views/freemarker/tags/TagModel.java +++ b/core/src/main/java/org/apache/struts2/views/freemarker/tags/TagModel.java @@ -31,8 +31,11 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.struts2.components.ActionComponent; import org.apache.struts2.components.Component; +import org.apache.struts2.dispatcher.Dispatcher; +import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; import freemarker.template.SimpleNumber; @@ -55,6 +58,8 @@ public abstract class TagModel implements TemplateTransformModel { public Writer getWriter(Writer writer, Map params) throws TemplateModelException, IOException { Component bean = getBean(); + Container container = Dispatcher.getInstance().getConfigurationManager().getConfiguration().getContainer(); + container.inject(bean); Map basicParams = convertParams(params); bean.copyParams(basicParams); bean.addAllParameters(getComplexParams(params)); diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java index b27ea80ab..a4aa3ff07 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java @@ -25,7 +25,11 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import org.apache.struts2.components.Component; +import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -43,6 +47,9 @@ public abstract class ComponentTagSupport extends StrutsBodyTagSupport { public int doStartTag() throws JspException { component = getBean(getStack(), (HttpServletRequest) pageContext.getRequest(), (HttpServletResponse) pageContext.getResponse()); + Container container = Dispatcher.getInstance().getContainer(); + container.inject(component); + populateParams(); boolean evalBody = component.start(pageContext.getOut()); diff --git a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java index 58f2aa3dd..4aeb91ec5 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java @@ -33,7 +33,6 @@ import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.RequestMap; import org.apache.struts2.dispatcher.SessionMap; import org.apache.struts2.dispatcher.mapper.ActionMapper; -import org.apache.struts2.dispatcher.mapper.ActionMapperFactory; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.util.AttributeMap; @@ -81,12 +80,11 @@ public class TagUtils { return stack; } - public static String buildNamespace(ValueStack stack, HttpServletRequest request) { + public static String buildNamespace(ActionMapper mapper, ValueStack stack, HttpServletRequest request) { ActionContext context = new ActionContext(stack.getContext()); ActionInvocation invocation = context.getActionInvocation(); if (invocation == null) { - ActionMapper mapper = ActionMapperFactory.getMapper(); ActionMapping mapping = mapper.getMapping(request, Dispatcher.getInstance().getConfigurationManager()); diff --git a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java index 435261b96..72c2350d6 100644 --- a/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java +++ b/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java @@ -25,7 +25,9 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.Component; import org.apache.struts2.components.Form; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; diff --git a/core/src/main/java/org/apache/struts2/views/util/ContextUtil.java b/core/src/main/java/org/apache/struts2/views/util/ContextUtil.java index 35a236a73..3ad854d43 100644 --- a/core/src/main/java/org/apache/struts2/views/util/ContextUtil.java +++ b/core/src/main/java/org/apache/struts2/views/util/ContextUtil.java @@ -27,12 +27,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.util.StrutsUtil; import org.apache.struts2.views.jsp.ui.OgnlTool; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; /** @@ -50,6 +50,13 @@ public class ContextUtil { public static final String OGNL = "ognl"; public static final String STRUTS = "struts"; public static final String ACTION = "action"; + + public static boolean altSyntax; + + @Inject(StrutsConstants.STRUTS_TAG_ALTSYNTAX) + public static void setAltSyntax(String val) { + altSyntax = "true".equals(val); + } public static Map getStandardContext(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { HashMap map = new HashMap(); @@ -79,7 +86,6 @@ public class ContextUtil { // We didn't make altSyntax static cause, if so, struts.configuration.xml.reload will not work // plus the Configuration implementation should cache the properties, which the framework's // configuration implementation does - boolean altSyntax = "true".equals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX)); return altSyntax ||( (context.containsKey("useAltSyntax") && context.get("useAltSyntax") != null && diff --git a/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java b/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java index e0e40a5aa..17dbbe625 100644 --- a/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java +++ b/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java @@ -36,9 +36,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.XWorkContinuationConfig; @@ -62,6 +62,25 @@ public class UrlHelper { private static final int DEFAULT_HTTPS_PORT = 443; private static final String AMP = "&"; + + private static int httpPort = DEFAULT_HTTP_PORT; + private static int httpsPort = DEFAULT_HTTPS_PORT; + private static String customEncoding; + + @Inject(StrutsConstants.STRUTS_URL_HTTP_PORT) + public static void setHttpPort(String val) { + httpPort = Integer.parseInt(val); + } + + @Inject(StrutsConstants.STRUTS_URL_HTTPS_PORT) + public static void setHttpsPort(String val) { + httpsPort = Integer.parseInt(val); + } + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public static void setCustomEncoding(String val) { + customEncoding = val; + } public static String buildUrl(String action, HttpServletRequest request, HttpServletResponse response, Map params) { return buildUrl(action, request, response, params, null, true, true); @@ -76,20 +95,6 @@ public class UrlHelper { boolean changedScheme = false; - int httpPort = DEFAULT_HTTP_PORT; - - try { - httpPort = Integer.parseInt((String) Settings.get(StrutsConstants.STRUTS_URL_HTTP_PORT)); - } catch (Exception ex) { - } - - int httpsPort = DEFAULT_HTTPS_PORT; - - try { - httpsPort = Integer.parseInt((String) Settings.get(StrutsConstants.STRUTS_URL_HTTPS_PORT)); - } catch (Exception ex) { - } - // only append scheme if it is different to the current scheme *OR* // if we explicity want it to be appended by having forceAddSchemeHostAndPort = true if (forceAddSchemeHostAndPort) { @@ -276,8 +281,8 @@ public class UrlHelper { private static String getEncodingFromConfiguration() { final String encoding; - if (Settings.isSet(StrutsConstants.STRUTS_I18N_ENCODING)) { - encoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + if (customEncoding != null) { + encoding = customEncoding; } else { encoding = "UTF-8"; } diff --git a/core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityServlet.java b/core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityServlet.java deleted file mode 100644 index 979c1acb5..000000000 --- a/core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityServlet.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * $Id$ - * - * 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.views.velocity; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.io.Writer; -import java.util.Properties; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.jsp.JspFactory; -import javax.servlet.jsp.PageContext; - -import org.apache.struts2.RequestUtils; -import org.apache.struts2.ServletActionContext; -import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; -import org.apache.struts2.views.util.ContextUtil; -import org.apache.velocity.Template; -import org.apache.velocity.context.Context; -import org.apache.velocity.exception.MethodInvocationException; -import org.apache.velocity.exception.ParseErrorException; -import org.apache.velocity.exception.ResourceNotFoundException; -import org.apache.velocity.runtime.RuntimeSingleton; -import org.apache.velocity.servlet.VelocityServlet; - -import com.opensymphony.xwork2.ActionContext; - - -/** - * @deprecated please use {@link org.apache.struts2.dispatcher.VelocityResult} instead of direct access - */ -public class StrutsVelocityServlet extends VelocityServlet { - private static final long serialVersionUID = -2078492831396251182L; - private VelocityManager velocityManager; - - public StrutsVelocityServlet() { - velocityManager = VelocityManager.getInstance(); - } - - public void init(ServletConfig servletConfig) throws ServletException { - super.init(servletConfig); - - // initialize our VelocityManager - velocityManager.init(servletConfig.getServletContext()); - } - - protected Context createContext(HttpServletRequest request, HttpServletResponse response) { - return velocityManager.createContext(ActionContext.getContext().getValueStack(), request, response); - } - - protected Template handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Context context) throws Exception { - String servletPath = (String) httpServletRequest.getAttribute("javax.servlet.include.servlet_path"); - - if (servletPath == null) { - servletPath = RequestUtils.getServletPath(httpServletRequest); - } - - return getTemplate(servletPath, getEncoding()); - } - - /** - * This method extends the VelocityServlet's loadConfiguration method by performing the following actions: - *

      - *
    • invokes VelocityServlet.loadConfiguration to create a properties object
    • - *
    • alters the RESOURCE_LOADER to include a class loader
    • - *
    • configures the class loader using the StrutsResourceLoader
    • - *
    - * - * @param servletConfig - * @throws IOException - * @throws FileNotFoundException - * @see org.apache.velocity.servlet.VelocityServlet#loadConfiguration - */ - protected Properties loadConfiguration(ServletConfig servletConfig) throws IOException, FileNotFoundException { - return velocityManager.loadConfiguration(servletConfig.getServletContext()); - } - - /** - * create a PageContext and render the template to PageContext.getOut() - * - * @see VelocityServlet#mergeTemplate(Template, Context, HttpServletResponse) for additional documentation - */ - protected void mergeTemplate(Template template, Context context, HttpServletResponse response) throws ResourceNotFoundException, ParseErrorException, MethodInvocationException, IOException, UnsupportedEncodingException, Exception { - // save the old PageContext - PageContext oldPageContext = ServletActionContext.getPageContext(); - - // create a new PageContext - JspFactory jspFactory = JspFactory.getDefaultFactory(); - HttpServletRequest request = (HttpServletRequest) context.get(ContextUtil.REQUEST); - PageContext pageContext = jspFactory.getPageContext(this, request, response, null, true, 8192, true); - - // put the new PageContext into ActionContext - ActionContext actionContext = ActionContext.getContext(); - actionContext.put(ServletActionContext.PAGE_CONTEXT, pageContext); - - try { - Writer writer = pageContext.getOut(); - template.merge(context, writer); - writer.flush(); - } finally { - // perform cleanup - jspFactory.releasePageContext(pageContext); - actionContext.put(ServletActionContext.PAGE_CONTEXT, oldPageContext); - } - } - - private String getEncoding() { - // todo look into converting this to using XWork/Struts encoding rules - try { - return Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); - } catch (IllegalArgumentException e) { - return RuntimeSingleton.getString(RuntimeSingleton.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING); - } - } -} diff --git a/core/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java b/core/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java index 690052691..a013e4c41 100644 --- a/core/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java +++ b/core/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java @@ -40,7 +40,6 @@ import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsException; -import org.apache.struts2.config.Settings; import org.apache.struts2.util.VelocityStrutsUtil; import org.apache.struts2.views.jsp.ui.OgnlTool; import org.apache.struts2.views.util.ContextUtil; @@ -95,6 +94,7 @@ import org.apache.velocity.tools.view.context.ChainedContext; import org.apache.velocity.tools.view.servlet.ServletToolboxManager; import com.opensymphony.xwork2.ObjectFactory; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.ValueStack; @@ -133,14 +133,15 @@ public class VelocityManager { private Properties velocityProperties; - protected VelocityManager() { - init(); + private String customConfigFile; + + public VelocityManager() { } /** * retrieve an instance to the current VelocityManager */ - public synchronized static VelocityManager getInstance() { + /*public synchronized static VelocityManager getInstance() { if (instance == null) { String classname = VelocityManager.class.getName(); @@ -164,6 +165,7 @@ public class VelocityManager { return instance; } + */ /** * @return a reference to the VelocityEngine used by all struts velocity thingies with the exception of @@ -196,7 +198,7 @@ public class VelocityManager { Map.Entry entry = (Map.Entry) iterator.next(); context.put((String) entry.getKey(), entry.getValue()); } - context.put(STRUTS, new VelocityStrutsUtil(context, stack, req, res)); + context.put(STRUTS, new VelocityStrutsUtil(velocityEngine, context, stack, req, res)); ServletContext ctx = null; @@ -299,8 +301,8 @@ public class VelocityManager { */ String configfile; - if (Settings.isSet(StrutsConstants.STRUTS_VELOCITY_CONFIGFILE)) { - configfile = Settings.get(StrutsConstants.STRUTS_VELOCITY_CONFIGFILE); + if (customConfigFile != null) { + configfile = customConfigFile; } else { configfile = "velocity.properties"; } @@ -396,22 +398,39 @@ public class VelocityManager { return properties; } - - /** - * performs one-time initializations - */ - protected void init() { - - // read in the names of contexts to add to each request - initChainedContexts(); - - - if (Settings.isSet(StrutsConstants.STRUTS_VELOCITY_TOOLBOXLOCATION)) { - toolBoxLocation = Settings.get(StrutsConstants.STRUTS_VELOCITY_TOOLBOXLOCATION).toString(); - } - + + @Inject(StrutsConstants.STRUTS_VELOCITY_CONFIGFILE) + public void setCustomConfigFile(String val) { + this.customConfigFile = val; } + + @Inject(StrutsConstants.STRUTS_VELOCITY_TOOLBOXLOCATION) + public void setToolBoxLocation(String toolboxLocation) { + this.toolBoxLocation = toolboxLocation; + } + + /** + * allow users to specify via the struts.properties file a set of additional VelocityContexts to chain to the + * the StrutsVelocityContext. The intent is to allow these contexts to store helper objects that the ui + * developer may want access to. Examples of reasonable VelocityContexts would be an IoCVelocityContext, a + * SpringReferenceVelocityContext, and a ToolboxVelocityContext + */ + @Inject(StrutsConstants.STRUTS_VELOCITY_CONTEXTS) + public void setChainedContexts(String contexts) { + // we expect contexts to be a comma separated list of classnames + StringTokenizer st = new StringTokenizer(contexts, ","); + List contextList = new ArrayList(); + while (st.hasMoreTokens()) { + String classname = st.nextToken(); + contextList.add(classname); + } + if (contextList.size() > 0) { + String[] chainedContexts = new String[contextList.size()]; + contextList.toArray(chainedContexts); + this.chainedContextNames = chainedContexts; + } + } /** * Initializes the ServletToolboxManager for this servlet's @@ -427,34 +446,7 @@ public class VelocityManager { } - /** - * allow users to specify via the struts.properties file a set of additional VelocityContexts to chain to the - * the StrutsVelocityContext. The intent is to allow these contexts to store helper objects that the ui - * developer may want access to. Examples of reasonable VelocityContexts would be an IoCVelocityContext, a - * SpringReferenceVelocityContext, and a ToolboxVelocityContext - */ - protected void initChainedContexts() { - - if (Settings.isSet(StrutsConstants.STRUTS_VELOCITY_CONTEXTS)) { - // we expect contexts to be a comma separated list of classnames - String contexts = Settings.get(StrutsConstants.STRUTS_VELOCITY_CONTEXTS).toString(); - StringTokenizer st = new StringTokenizer(contexts, ","); - List contextList = new ArrayList(); - - while (st.hasMoreTokens()) { - String classname = st.nextToken(); - contextList.add(classname); - } - if (contextList.size() > 0) { - String[] chainedContexts = new String[contextList.size()]; - contextList.toArray(chainedContexts); - this.chainedContextNames = chainedContexts; - } - - - } - - } + /** *

    diff --git a/core/src/main/java/org/apache/struts2/views/velocity/components/AbstractDirective.java b/core/src/main/java/org/apache/struts2/views/velocity/components/AbstractDirective.java index 327c43139..fe9f1ff98 100644 --- a/core/src/main/java/org/apache/struts2/views/velocity/components/AbstractDirective.java +++ b/core/src/main/java/org/apache/struts2/views/velocity/components/AbstractDirective.java @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.components.Component; +import org.apache.struts2.dispatcher.Dispatcher; import org.apache.velocity.context.InternalContextAdapter; import org.apache.velocity.exception.MethodInvocationException; import org.apache.velocity.exception.ParseErrorException; @@ -37,6 +38,7 @@ import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.runtime.directive.Directive; import org.apache.velocity.runtime.parser.node.Node; +import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; public abstract class AbstractDirective extends Directive { @@ -61,7 +63,8 @@ public abstract class AbstractDirective extends Directive { HttpServletRequest req = (HttpServletRequest) stack.getContext().get(ServletActionContext.HTTP_REQUEST); HttpServletResponse res = (HttpServletResponse) stack.getContext().get(ServletActionContext.HTTP_RESPONSE); Component bean = getBean(stack, req, res); - + Container container = Dispatcher.getInstance().getConfigurationManager().getConfiguration().getContainer(); + container.inject(bean); // get the parameters Map params = createPropertyMap(ctx, node); bean.copyParams(params); diff --git a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java index be0cb241f..ee5d2bf5e 100644 --- a/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java +++ b/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java @@ -42,11 +42,12 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.ServletActionContext; -import org.apache.struts2.config.Settings; +import org.apache.struts2.StrutsConstants; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.TextParseUtil; import com.opensymphony.xwork2.util.ValueStack; @@ -202,13 +203,17 @@ public class XSLTResult implements Result { public XSLTResult() { templatesCache = new HashMap(); - noCache = Settings.get("struts.xslt.nocache").trim().equalsIgnoreCase("true"); } public XSLTResult(String stylesheetLocation) { this(); setStylesheetLocation(stylesheetLocation); } + + @Inject(StrutsConstants.STRUTS_XSLT_NOCACHE) + public void setNoCache(String val) { + noCache = "true".equals(val); + } /** * @deprecated Use #setStylesheetLocation(String) diff --git a/core/src/main/resources/org/apache/struts2/default.properties b/core/src/main/resources/org/apache/struts2/default.properties index 927800379..88835d3cf 100644 --- a/core/src/main/resources/org/apache/struts2/default.properties +++ b/core/src/main/resources/org/apache/struts2/default.properties @@ -48,16 +48,7 @@ struts.multipart.maxSize=2097152 # struts.custom.properties=application,org/apache/struts2/extension/custom ### How request URLs are mapped to and from actions -struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper -### The above line is to be commented and following are to be uncommented to -### enable CompositeActionMapper -### - With CompositeActionMapper one could specified many ActionMapper instance, where -### each of them will be chosen according to the order. Lower order number has -### higher precedence -#struts.mapper.class=org.apache.struts2.dispatcher.mapper.CompositeActionMapper -#struts.mapper.composite.1=org.apache.struts2.dispatcher.mapper.DefaultActionMapper -#struts.mapper.composite.2=foo.bar.MyActionMapper -#struts.mapper.composite.3=foo.bar.MyAnotherActionMapper +#struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper ### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do @@ -128,10 +119,13 @@ struts.ui.templateSuffix=ftl struts.configuration.xml.reload=false ### Location of velocity.properties file. defaults to velocity.properties -# struts.velocity.configfile = velocity.properties +struts.velocity.configfile = velocity.properties ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext -# struts.velocity.contexts = +struts.velocity.contexts = + +### Location of the velocity toolbox +struts.velocity.toolboxlocation= ### used to build URLs, such as the UrlTag struts.url.http.port = 80 @@ -161,4 +155,7 @@ struts.xslt.nocache=false ### A list of configuration files automatically loaded by Struts struts.configuration.files=struts-default.xml,struts-plugin.xml,struts.xml +### A list of template engines available +struts.templateEngines=ftl,jsp,vm + ### END SNIPPET: complete_file diff --git a/core/src/main/resources/struts-2.0.dtd b/core/src/main/resources/struts-2.0.dtd index 5612042ef..6a1dcdec3 100644 --- a/core/src/main/resources/struts-2.0.dtd +++ b/core/src/main/resources/struts-2.0.dtd @@ -11,7 +11,7 @@ "http://struts.apache.org/dtds/struts-2.0.dtd"> --> - + + + + + + + diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index ad3244c99..334101125 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -5,6 +5,41 @@ "http://struts.apache.org/dtds/struts-2.0.dtd"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/src/test/java/org/apache/struts2/TestConfigurationProvider.java b/core/src/test/java/org/apache/struts2/TestConfigurationProvider.java index a641711f2..ac58f4c32 100644 --- a/core/src/test/java/org/apache/struts2/TestConfigurationProvider.java +++ b/core/src/test/java/org/apache/struts2/TestConfigurationProvider.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import org.apache.struts2.dispatcher.ServletDispatcherResult; import org.apache.struts2.interceptor.TokenInterceptor; @@ -31,12 +32,17 @@ import org.apache.struts2.interceptor.TokenSessionStoreInterceptor; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionChainResult; +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.DefaultActionProxyFactory; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.ConfigurationProvider; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; import com.opensymphony.xwork2.config.entities.PackageConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.inject.ContainerBuilder; import com.opensymphony.xwork2.interceptor.ParametersInterceptor; import com.opensymphony.xwork2.mock.MockResult; @@ -53,6 +59,7 @@ public class TestConfigurationProvider implements ConfigurationProvider { public static final String TOKEN_SESSION_ACTION_NAME = "tokenSessionAction"; public static final String TEST_NAMESPACE = "/testNamespace"; public static final String TEST_NAMESPACE_ACTION = "testNamespaceAction"; + private Configuration configuration; /** @@ -60,11 +67,15 @@ public class TestConfigurationProvider implements ConfigurationProvider { */ public void destroy() { } + + public void init(Configuration config) { + this.configuration = config; + } /** * Initializes the configuration object. */ - public void init(Configuration configurationManager) { + public void loadPackages() { PackageConfig defaultPackageConfig = new PackageConfig(""); HashMap results = new HashMap(); @@ -125,7 +136,7 @@ public class TestConfigurationProvider implements ConfigurationProvider { tokenSessionActionConfig.addResultConfig(new ResultConfig("success", MockResult.class.getName())); defaultPackageConfig.addActionConfig(TOKEN_SESSION_ACTION_NAME, tokenSessionActionConfig); - configurationManager.addPackageConfig("", defaultPackageConfig); + configuration.addPackageConfig("", defaultPackageConfig); Map testActionTagResults = new HashMap(); testActionTagResults.put(Action.SUCCESS, new ResultConfig(Action.SUCCESS, TestActionTagResult.class.getName(), new HashMap())); @@ -140,7 +151,7 @@ public class TestConfigurationProvider implements ConfigurationProvider { ActionConfig namespaceAction = new ActionConfig(null, TestAction.class, null, null, null); namespacePackageConfig.addActionConfig(TEST_NAMESPACE_ACTION, namespaceAction); - configurationManager.addPackageConfig("namespacePackage", namespacePackageConfig); + configuration.addPackageConfig("namespacePackage", namespacePackageConfig); } /** @@ -151,4 +162,13 @@ public class TestConfigurationProvider implements ConfigurationProvider { public boolean needsReload() { return false; } + + public void register(ContainerBuilder builder, Properties props) throws ConfigurationException { + if (!builder.contains(ObjectFactory.class)) { + builder.factory(ObjectFactory.class); + } + if (!builder.contains(ActionProxyFactory.class)) { + builder.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class); + } + } } diff --git a/core/src/test/java/org/apache/struts2/config/ClasspathConfigurationProviderTest.java b/core/src/test/java/org/apache/struts2/config/ClasspathConfigurationProviderTest.java index c9ee50e76..0003c00b4 100644 --- a/core/src/test/java/org/apache/struts2/config/ClasspathConfigurationProviderTest.java +++ b/core/src/test/java/org/apache/struts2/config/ClasspathConfigurationProviderTest.java @@ -49,6 +49,7 @@ public class ClasspathConfigurationProviderTest extends TestCase { customPackage.setNamespace("/custom"); config.addPackageConfig("custom-package", customPackage); provider.init(config); + provider.loadPackages(); } public void testFoundRootPackages() { diff --git a/core/src/test/java/org/apache/struts2/config/SettingsTest.java b/core/src/test/java/org/apache/struts2/config/SettingsTest.java index 7d19dd6c6..65b08f2be 100644 --- a/core/src/test/java/org/apache/struts2/config/SettingsTest.java +++ b/core/src/test/java/org/apache/struts2/config/SettingsTest.java @@ -48,7 +48,7 @@ public class SettingsTest extends StrutsTestCase { assertEquals("de", locale.getLanguage()); int count = getKeyCount(); - assertEquals(32, count); + assertEquals(35, count); } public void testDefaultResourceBundlesLoaded() { diff --git a/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java b/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java index 0bf5ade72..012015b53 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/ActionContextCleanUpTest.java @@ -21,6 +21,7 @@ package org.apache.struts2.dispatcher; import java.io.IOException; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -110,20 +111,8 @@ public class ActionContextCleanUpTest extends TestCase { } }; - cleanUp = new ActionContextCleanUp() { - @Override - protected Dispatcher createDispatcher() { - return _dispatcher; - } - }; - - cleanUp2 = new ActionContextCleanUp() { - @Override - protected Dispatcher createDispatcher() { - return _dispatcher2; - } - }; - + cleanUp = new ActionContextCleanUp(); + cleanUp2 = new ActionContextCleanUp(); filterChain2 = new MockFilterChain() { @Override public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { @@ -135,8 +124,6 @@ public class ActionContextCleanUpTest extends TestCase { public void testSingle() throws Exception { - assertFalse(_dispatcher.prepare); - assertFalse(_dispatcher.wrapRequest); assertNull(request.getAttribute("__cleanup_recursion_counter")); cleanUp.init(filterConfig); @@ -146,16 +133,10 @@ public class ActionContextCleanUpTest extends TestCase { assertEquals(_tmpStore.size(), 1); assertEquals(_tmpStore.get("counter0"), new Integer(1)); - assertTrue(_dispatcher.prepare); - assertTrue(_dispatcher.wrapRequest); assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0")); } public void testMultiple() throws Exception { - assertFalse(_dispatcher.prepare); - assertFalse(_dispatcher.wrapRequest); - assertFalse(_dispatcher2.prepare); - assertFalse(_dispatcher2.wrapRequest); assertNull(request.getAttribute("__cleanup_recursion_counter")); cleanUp.init(filterConfig); @@ -168,10 +149,6 @@ public class ActionContextCleanUpTest extends TestCase { assertEquals(_tmpStore.get("counter0"), new Integer(1)); assertEquals(_tmpStore.get("counter1"), new Integer(2)); - assertFalse(_dispatcher2.prepare); - assertFalse(_dispatcher2.wrapRequest); - assertTrue(_dispatcher.prepare); - assertTrue(_dispatcher.wrapRequest); assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0")); } @@ -182,7 +159,7 @@ public class ActionContextCleanUpTest extends TestCase { public boolean service = false; public InnerDispatcher(ServletContext servletContext) { - super(servletContext); + super(servletContext, new HashMap()); } @Override diff --git a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java index 5e1540ac6..9f6d02cd2 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java @@ -20,6 +20,7 @@ */ package org.apache.struts2.dispatcher; +import java.util.HashMap; import java.util.Locale; import javax.servlet.http.HttpServletRequest; @@ -27,7 +28,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -58,10 +58,9 @@ public class DispatcherTest extends StrutsTestCase { HttpServletRequest req = new MockHttpServletRequest(); HttpServletResponse res = new MockHttpServletResponse(); - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8"); - - - Dispatcher du = Dispatcher.getInstance(); + Dispatcher du = initDispatcher(new HashMap() {{ + put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8"); + }}); du.prepare(req, res); assertEquals(req.getCharacterEncoding(), "utf-8"); @@ -72,12 +71,11 @@ public class DispatcherTest extends StrutsTestCase { MockHttpServletResponse res = new MockHttpServletResponse(); req.setContentType("multipart/form-data"); - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8"); - - - Dispatcher du = Dispatcher.getInstance(); + Dispatcher du = initDispatcher(new HashMap() {{ + put(StrutsConstants.STRUTS_I18N_ENCODING, "utf-8"); + }}); du.prepare(req, res); - assertEquals(req.getCharacterEncoding(), "utf-8"); + assertEquals("utf-8", req.getCharacterEncoding()); } } diff --git a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java index 1c51d7ec6..1b06bbed8 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -31,12 +32,9 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.util.ObjectFactoryDestroyable; -import org.apache.struts2.util.ObjectFactoryInitializable; -import org.apache.struts2.util.ObjectFactoryLifecycle; import org.springframework.mock.web.MockFilterConfig; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; @@ -93,119 +91,63 @@ public class FilterDispatcherTest extends StrutsTestCase { assertTrue(destroyedObjectFactory.destroyed); } - - public void testObjectFactoryInitializable() throws Exception { - - Map configMap = new HashMap(); - configMap.put(StrutsConstants.STRUTS_OBJECTFACTORY, "org.apache.struts2.dispatcher.FilterDispatcherTest$InnerInitializableObjectFactory"); - configMap.put(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "false"); - Settings.setInstance(new InnerConfiguration(configMap)); - - MockServletContext servletContext = new MockServletContext(); - MockFilterConfig filterConfig = new MockFilterConfig(servletContext); - - - FilterDispatcher filterDispatcher = new FilterDispatcher(); - filterDispatcher.init(filterConfig); - - assertTrue(ObjectFactory.getObjectFactory() instanceof InnerInitializableObjectFactory); - assertTrue(((InnerInitializableObjectFactory) ObjectFactory.getObjectFactory()).initializable); - } - - public void testObjectFactoryLifecycle() throws Exception { - - Map configMap = new HashMap(); - configMap.put(StrutsConstants.STRUTS_OBJECTFACTORY, "org.apache.struts2.dispatcher.FilterDispatcherTest$InnerInitailizableDestroyableObjectFactory"); - configMap.put(StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD, "false"); - Settings.setInstance(new InnerConfiguration(configMap)); - - MockServletContext servletContext = new MockServletContext(); - MockFilterConfig filterConfig = new MockFilterConfig(servletContext); - - - FilterDispatcher filterDispatcher = new FilterDispatcher(); - filterDispatcher.init(filterConfig); - - assertTrue(ObjectFactory.getObjectFactory() instanceof InnerInitailizableDestroyableObjectFactory); - assertTrue(((InnerInitailizableDestroyableObjectFactory) ObjectFactory.getObjectFactory()).initializable); - - assertFalse(((InnerInitailizableDestroyableObjectFactory) ObjectFactory.getObjectFactory()).destroyable); - filterDispatcher.destroy(); - assertTrue(((InnerInitailizableDestroyableObjectFactory) ObjectFactory.getObjectFactory()).destroyable); - } - public void testIfActionMapperIsNullDontServiceAction() throws Exception { - try { - MockServletContext servletContext = new MockServletContext(); - MockFilterConfig filterConfig = new MockFilterConfig(servletContext); - MockHttpServletRequest req = new MockHttpServletRequest(servletContext); - MockHttpServletResponse res = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - final NoOpDispatcher _dispatcher = new NoOpDispatcher(servletContext); - Dispatcher.setInstance(null); + MockServletContext servletContext = new MockServletContext(); + MockFilterConfig filterConfig = new MockFilterConfig(servletContext); + MockHttpServletRequest req = new MockHttpServletRequest(servletContext); + MockHttpServletResponse res = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + final NoOpDispatcher _dispatcher = new NoOpDispatcher(servletContext); + Dispatcher.setInstance(_dispatcher); - ConfigurationManager confManager = new ConfigurationManager(); - confManager.setConfiguration(new DefaultConfiguration()); - _dispatcher.setConfigurationManager(confManager); + ConfigurationManager confManager = new ConfigurationManager(); + confManager.setConfiguration(new DefaultConfiguration()); + _dispatcher.setConfigurationManager(confManager); - ObjectFactory.setObjectFactory(new InnerObjectFactory()); + ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Map settings = new HashMap(); - settings.put(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterDispatcherTest$NullActionMapper"); - Settings.setInstance(new InnerConfiguration(settings)); + FilterDispatcher filter = new FilterDispatcher() { + protected Dispatcher createDispatcher() { + return _dispatcher; + } + }; + filter.setActionMapper(null); + filter.init(filterConfig); + filter.doFilter(req, res, chain); - FilterDispatcher filter = new FilterDispatcher() { - protected Dispatcher createDispatcher() { - return _dispatcher; - } - }; - filter.init(filterConfig); - filter.doFilter(req, res, chain); - - assertFalse(_dispatcher.serviceRequest); - } - finally { - Settings.reset(); - } + assertFalse(_dispatcher.serviceRequest); } public void testCharacterEncodingSetBeforeRequestWrappingAndActionService() throws Exception { - try { - MockServletContext servletContext = new MockServletContext(); - MockFilterConfig filterConfig = new MockFilterConfig(servletContext); - MockHttpServletRequest req = new MockHttpServletRequest(servletContext); - MockHttpServletResponse res = new MockHttpServletResponse(); - MockFilterChain chain = new MockFilterChain(); - final InnerDispatcher _dispatcher = new InnerDispatcher(servletContext); - Dispatcher.setInstance(null); + MockServletContext servletContext = new MockServletContext(); + MockFilterConfig filterConfig = new MockFilterConfig(servletContext); + MockHttpServletRequest req = new MockHttpServletRequest(servletContext); + MockHttpServletResponse res = new MockHttpServletResponse(); + MockFilterChain chain = new MockFilterChain(); + final InnerDispatcher _dispatcher = new InnerDispatcher(servletContext); + Dispatcher.setInstance(null); - ConfigurationManager confManager = new ConfigurationManager(); - confManager.setConfiguration(new DefaultConfiguration()); - _dispatcher.setConfigurationManager(confManager); + ConfigurationManager confManager = new ConfigurationManager(); + confManager.setConfiguration(new DefaultConfiguration()); + _dispatcher.setConfigurationManager(confManager); - ObjectFactory.setObjectFactory(new InnerObjectFactory()); + ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Map settings = new HashMap(); - settings.put(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-16_DUMMY"); - settings.put(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterDispatcherTest$InnerActionMapper"); - Settings.setInstance(new InnerConfiguration(settings)); + _dispatcher.setDefaultEncoding("UTF-16_DUMMY"); - FilterDispatcher filter = new FilterDispatcher() { - protected Dispatcher createDispatcher() { - return _dispatcher; - } - }; - filter.init(filterConfig); - filter.doFilter(req, res, chain); + FilterDispatcher filter = new FilterDispatcher() { + protected Dispatcher createDispatcher(FilterConfig filterConfig) { + return _dispatcher; + } + }; + filter.init(filterConfig); + filter.setActionMapper(new InnerActionMapper()); + filter.doFilter(req, res, chain); - assertTrue(_dispatcher.wrappedRequest); - assertTrue(_dispatcher.serviceRequest); - } - finally { - Settings.reset(); - } + assertTrue(_dispatcher.wrappedRequest); + assertTrue(_dispatcher.serviceRequest); } @@ -219,9 +161,10 @@ public class FilterDispatcherTest extends StrutsTestCase { protected boolean serviceRequest = false; public NoOpDispatcher(ServletContext servletContext) { - super(servletContext); + super(servletContext, new HashMap()); } + @Override public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException { wrappedRequest = true; return request; @@ -238,9 +181,10 @@ public class FilterDispatcherTest extends StrutsTestCase { protected boolean serviceRequest = false; public InnerDispatcher(ServletContext servletContext) { - super(servletContext); + super(servletContext, new HashMap()); } + @Override public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException { wrappedRequest = true; // if we set the chracter encoding AFTER we do wrap request, we will get @@ -282,28 +226,6 @@ public class FilterDispatcherTest extends StrutsTestCase { } - public static class InnerConfiguration extends Settings { - Map m; - - public InnerConfiguration(Map configMap) { - m = configMap; - } - - public boolean isSetImpl(String name) { - if (!m.containsKey(name)) - return super.isSetImpl(name); - else - return true; - } - - public String getImpl(String aName) throws IllegalArgumentException { - if (!m.containsKey(aName)) - return super.getImpl(aName); - else - return m.get(aName); - } - } - public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable { public boolean destroyed = false; @@ -312,26 +234,4 @@ public class FilterDispatcherTest extends StrutsTestCase { } } - public static class InnerInitializableObjectFactory extends ObjectFactory implements ObjectFactoryInitializable { - public boolean initializable = false; - - public void init(ServletContext servletContext) { - initializable = true; - } - } - - public static class InnerInitailizableDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryLifecycle { - public boolean initializable = false; - public boolean destroyable = false; - - public void init(ServletContext servletContext) { - initializable = true; - } - - public void destroy() { - destroyable = true; - } - } - - } diff --git a/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java b/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java index 1d27e5062..6a21f4688 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/FilterTest.java @@ -21,7 +21,9 @@ package org.apache.struts2.dispatcher; import java.io.IOException; +import java.util.HashMap; +import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -32,7 +34,6 @@ import javax.servlet.http.HttpServletResponse; import junit.framework.TestCase; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.springframework.mock.web.MockFilterConfig; @@ -115,22 +116,11 @@ public class FilterTest extends TestCase { }; - cleanUp = new ActionContextCleanUp() { - @Override - protected Dispatcher createDispatcher() { - cleanUpFilterCreateDispatcherCount++; - return _dispatcher1; - } - - @Override - public String toString() { - return "cleanUp"; - } - }; + cleanUp = new ActionContextCleanUp(); filterDispatcher = new FilterDispatcher() { @Override - protected Dispatcher createDispatcher() { + protected Dispatcher createDispatcher(FilterConfig filterConfig) { filterDispatcherCreateDispatcherCount++; return _dispatcher2; } @@ -147,7 +137,7 @@ public class FilterTest extends TestCase { ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory(); try { ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper"); + filterDispatcher.setActionMapper(new FilterTest.InnerMapper()); assertEquals(cleanUpFilterCreateDispatcherCount, 0); assertEquals(filterDispatcherCreateDispatcherCount, 0); @@ -182,7 +172,7 @@ public class FilterTest extends TestCase { ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory(); try { ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper"); + filterDispatcher.setActionMapper(new FilterTest.InnerMapper()); assertEquals(cleanUpFilterCreateDispatcherCount, 0); assertEquals(filterDispatcherCreateDispatcherCount, 0); @@ -214,11 +204,11 @@ public class FilterTest extends TestCase { } } - public void testUsingCleanUpAndFilterDispatcher() throws Exception { + /*public void testUsingCleanUpAndFilterDispatcher() throws Exception { ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory(); try { ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper"); + filterDispatcher.setActionMapper(new FilterTest.InnerMapper()); assertEquals(cleanUpFilterCreateDispatcherCount, 0); assertEquals(filterDispatcherCreateDispatcherCount, 0); @@ -235,8 +225,8 @@ public class FilterTest extends TestCase { filterDispatcher.destroy(); cleanUp.destroy(); - assertEquals(cleanUpFilterCreateDispatcherCount, 1); - assertEquals(filterDispatcherCreateDispatcherCount, 1); + assertEquals(1, cleanUpFilterCreateDispatcherCount); + assertEquals(1, filterDispatcherCreateDispatcherCount); assertTrue(_dispatcher1.prepare); assertTrue(_dispatcher1.wrapRequest); assertTrue(_dispatcher1.service); @@ -255,7 +245,7 @@ public class FilterTest extends TestCase { ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory(); try { ObjectFactory.setObjectFactory(new InnerObjectFactory()); - Settings.set(StrutsConstants.STRUTS_MAPPER_CLASS, "org.apache.struts2.dispatcher.FilterTest$InnerMapper"); + filterDispatcher.setActionMapper(new FilterTest.InnerMapper()); assertEquals(cleanUpFilterCreateDispatcherCount, 0); assertEquals(filterDispatcherCreateDispatcherCount, 0); @@ -287,6 +277,7 @@ public class FilterTest extends TestCase { ObjectFactory.setObjectFactory(oldObjecFactory); } } + */ class InnerDispatcher extends Dispatcher { @@ -295,7 +286,7 @@ public class FilterTest extends TestCase { public boolean service = false; public InnerDispatcher(ServletContext servletContext) { - super(servletContext); + super(servletContext, new HashMap()); } @Override diff --git a/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java b/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java index e0d69e2ae..9fea59787 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsTestCase; +import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.easymock.EasyMock; import org.easymock.IMocksControl; import org.springframework.mock.web.MockHttpServletRequest; @@ -99,7 +100,7 @@ public class ServletActionRedirectResultTest extends StrutsTestCase { control.anyTimes(); control.replay(); - + result.setActionMapper(container.getInstance(ActionMapper.class)); result.execute(mockInvocation); assertEquals("/myNamespace/myAction.action?param2=value+2¶m1=value+1¶m3=value+3", res.getRedirectedUrl()); @@ -153,7 +154,7 @@ public class ServletActionRedirectResultTest extends StrutsTestCase { control.andReturn(context); control.replay(); - + result.setActionMapper(container.getInstance(ActionMapper.class)); result.execute(mockInvocation); assertEquals("/myNamespace/myAction.action?param2=value+2¶m1=value+1¶m3=value+3", res.getRedirectedUrl()); diff --git a/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java b/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java index 4a30a77ff..0c9af62e7 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java @@ -100,16 +100,12 @@ public class ServletRedirectResultTest extends StrutsTestCase implements StrutsS protected void setUp() throws Exception { super.setUp(); - Dispatcher du = new Dispatcher(new MockServletContext()); - Dispatcher.setInstance(du); - ConfigurationManager cm = new ConfigurationManager(); - cm.addConfigurationProvider(new StrutsXmlConfigurationProvider("struts.xml", false)); - du.setConfigurationManager(cm); - du.getConfigurationManager().getConfiguration(). + configurationManager.getConfiguration(). addPackageConfig("foo", new PackageConfig("foo", "/namespace", false, null)); view = new ServletRedirectResult(); + container.inject(view); responseMock = new Mock(HttpServletResponse.class); diff --git a/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java b/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java index 6a6f7e282..a684cd1da 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/mapper/CompositeActionMapperTest.java @@ -28,11 +28,13 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; -import org.apache.struts2.dispatcher.mapper.CompositeActionMapper.IndividualActionMapperEntry; import org.springframework.mock.web.MockHttpServletRequest; +import com.mockobjects.dynamic.C; +import com.mockobjects.dynamic.Mock; import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Scope.Strategy; import junit.framework.TestCase; @@ -42,253 +44,49 @@ import junit.framework.TestCase; */ public class CompositeActionMapperTest extends TestCase { - /** - * Test with empty settings (settings with no entries of interest) - * - * @throws Exception - */ - public void testGetOrderActionMapperEntries1() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - List result = - compositeActionMapper.getOrderedActionMapperEntries(); - - assertEquals(result.size(), 0); + CompositeActionMapper compositeActionMapper; + Mock mockContainer; + + public void setUp() throws Exception { + compositeActionMapper = new CompositeActionMapper(); + mockContainer = new Mock(Container.class); + compositeActionMapper.setContainer((Container)mockContainer.proxy()); } - - /** - * Test with a normal settings. - * - * @throws Exception - */ - public void testGetOrderActionMapperEntries2() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", InnerActionMapper2.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", InnerActionMapper3.class.getName()); - - List result = - compositeActionMapper.getOrderedActionMapperEntries(); - - assertEquals(result.size(), 3); - - IndividualActionMapperEntry e = null; - Iterator i = result.iterator(); - - // 1 - e = i.next(); - - assertEquals(e.order, new Integer(1)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1"); - assertEquals(e.propertyValue, InnerActionMapper1.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper1.class); - - // 2 - e = i.next(); - - assertEquals(e.order, new Integer(2)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2"); - assertEquals(e.propertyValue, InnerActionMapper2.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper2.class); - - // 3 - e = i.next(); - assertEquals(e.order, new Integer(3)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3"); - assertEquals(e.propertyValue, InnerActionMapper3.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper3.class); - } - finally { - Settings.setInstance(old); - } - } - - /** - * Test with settings where entries are out-of-order, it needs to be able to retrieve them - * back in proper order. - * - * @throws Exception - */ - public void testGetOrderActionMapperEntries3() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", InnerActionMapper3.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", InnerActionMapper2.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - - List result = - compositeActionMapper.getOrderedActionMapperEntries(); - - assertEquals(result.size(), 3); - - IndividualActionMapperEntry e = null; - Iterator i = result.iterator(); - - // 1 - e = i.next(); - - assertEquals(e.order, new Integer(1)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1"); - assertEquals(e.propertyValue, InnerActionMapper1.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper1.class); - - // 2 - e = i.next(); - - assertEquals(e.order, new Integer(2)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2"); - assertEquals(e.propertyValue, InnerActionMapper2.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper2.class); - - // 3 - e = i.next(); - assertEquals(e.order, new Integer(3)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3"); - assertEquals(e.propertyValue, InnerActionMapper3.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper3.class); - } - finally { - Settings.setInstance(old); - } - } - - /** - * Test with a bad entry - * - * @throws Exception - */ - public void testGetOrderActionMapperEntries4() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"NotANumber", InnerActionMapper2.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", InnerActionMapper3.class.getName()); - - List result = - compositeActionMapper.getOrderedActionMapperEntries(); - - assertEquals(result.size(), 2); - - IndividualActionMapperEntry e = null; - Iterator i = result.iterator(); - - // 1 - e = i.next(); - - assertEquals(e.order, new Integer(1)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1"); - assertEquals(e.propertyValue, InnerActionMapper1.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper1.class); - - // 2 - e = i.next(); - assertEquals(e.order, new Integer(3)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3"); - assertEquals(e.propertyValue, InnerActionMapper3.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper3.class); - } - finally { - Settings.setInstance(old); - } - } - - /** - * Test with an entry where the action mapper class is bogus. - * @throws Exception - */ - public void testGetOrderActionMapperEntries5() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", "bogus.class.name"); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", InnerActionMapper3.class.getName()); - - List result = - compositeActionMapper.getOrderedActionMapperEntries(); - - assertEquals(result.size(), 2); - - IndividualActionMapperEntry e = null; - Iterator i = result.iterator(); - - // 1 - e = i.next(); - - assertEquals(e.order, new Integer(1)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1"); - assertEquals(e.propertyValue, InnerActionMapper1.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper1.class); - - - // 2 - e = i.next(); - assertEquals(e.order, new Integer(3)); - assertEquals(e.propertyName, StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3"); - assertEquals(e.propertyValue, InnerActionMapper3.class.getName()); - assertEquals(e.actionMapper.getClass(), InnerActionMapper3.class); - } - finally { - Settings.setInstance(old); - } - } - - + public void testGetActionMappingAndUri1() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); - - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", InnerActionMapper2.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"3", InnerActionMapper3.class.getName()); - - - ActionMapping actionMapping = compositeActionMapper.getMapping(new MockHttpServletRequest(), new ConfigurationManager()); - String uri = compositeActionMapper.getUriFromActionMapping(new ActionMapping()); - - assertNotNull(actionMapping); - assertNotNull(uri); - assertTrue(actionMapping == InnerActionMapper3.actionMapping); - assertTrue(uri == InnerActionMapper3.uri); - } - finally { - Settings.setInstance(old); - } + ActionMapper mapper1 = new InnerActionMapper1(); + ActionMapper mapper2 = new InnerActionMapper2(); + ActionMapper mapper3 = new InnerActionMapper3(); + mockContainer.expectAndReturn("getInstance", C.args(C.eq(ActionMapper.class), C.eq("mapper1")), mapper1); + mockContainer.expectAndReturn("getInstance", C.args(C.eq(ActionMapper.class), C.eq("mapper2")), mapper3); + mockContainer.expectAndReturn("getInstance", C.args(C.eq(ActionMapper.class), C.eq("mapper3")), mapper2); + compositeActionMapper.setActionMappers("mapper1,mapper2,mapper3"); + + ActionMapping actionMapping = compositeActionMapper.getMapping(new MockHttpServletRequest(), new ConfigurationManager()); + String uri = compositeActionMapper.getUriFromActionMapping(new ActionMapping()); + mockContainer.verify(); + + assertNotNull(actionMapping); + assertNotNull(uri); + assertTrue(actionMapping == InnerActionMapper3.actionMapping); + assertTrue(uri == InnerActionMapper3.uri); + } public void testGetActionMappingAndUri2() throws Exception { - CompositeActionMapper compositeActionMapper = new CompositeActionMapper(); + ActionMapper mapper1 = new InnerActionMapper1(); + ActionMapper mapper2 = new InnerActionMapper2(); + mockContainer.expectAndReturn("getInstance", C.args(C.eq(ActionMapper.class), C.eq("mapper1")), mapper1); + mockContainer.expectAndReturn("getInstance", C.args(C.eq(ActionMapper.class), C.eq("mapper2")), mapper2); + compositeActionMapper.setActionMappers("mapper1,mapper2"); - Settings old = Settings.getInstance(); - try { - Settings.setInstance(new InnerSettings()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"1", InnerActionMapper1.class.getName()); - Settings.set(StrutsConstants.STRUTS_MAPPER_COMPOSITE+"2", InnerActionMapper2.class.getName()); + ActionMapping actionMapping = compositeActionMapper.getMapping(new MockHttpServletRequest(), new ConfigurationManager()); + String uri = compositeActionMapper.getUriFromActionMapping(new ActionMapping()); + mockContainer.verify(); - - ActionMapping actionMapping = compositeActionMapper.getMapping(new MockHttpServletRequest(), new ConfigurationManager()); - String uri = compositeActionMapper.getUriFromActionMapping(new ActionMapping()); - - assertNull(actionMapping); - assertNull(uri); - } - finally { - Settings.setInstance(old); - } + assertNull(actionMapping); + assertNull(uri); } @@ -325,26 +123,4 @@ public class CompositeActionMapperTest extends TestCase { return uri; } } - - class InnerSettings extends Settings { - private Map _impl = new LinkedHashMap(); - - @Override - public boolean isSetImpl(String name) { - return _impl.containsKey(name); - } - @Override - public void setImpl(String name, String value) throws IllegalArgumentException, UnsupportedOperationException { - _impl.put(name, value); - } - @Override - public String getImpl(String name) throws IllegalArgumentException { - return (String) _impl.get(name); - } - @Override - public Iterator listImpl() { - return _impl.keySet().iterator(); - } - } - } diff --git a/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java b/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java index f49218891..8382138fe 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java @@ -25,7 +25,6 @@ import java.util.Map; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.ServletRedirectResult; import org.apache.struts2.views.jsp.StrutsMockHttpServletRequest; @@ -96,24 +95,18 @@ public class DefaultActionMapperTest extends StrutsTestCase { public void testGetMappingWithSlashedName() throws Exception { - String old = Settings.get(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES); - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, "true"); - try { - req.setupGetRequestURI("/my/foo/actionName.action"); - req.setupGetServletPath("/my/foo/actionName.action"); - req.setupGetAttribute(null); - req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); + req.setupGetRequestURI("/my/foo/actionName.action"); + req.setupGetServletPath("/my/foo/actionName.action"); + req.setupGetAttribute(null); + req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); - DefaultActionMapper mapper = new DefaultActionMapper(); - ActionMapping mapping = mapper.getMapping(req, configManager); - - assertEquals("/my", mapping.getNamespace()); - assertEquals("foo/actionName", mapping.getName()); - assertNull(mapping.getMethod()); } - finally { - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, old); - } + DefaultActionMapper mapper = new DefaultActionMapper(); + mapper.setSlashesInActionNames("true"); + ActionMapping mapping = mapper.getMapping(req, configManager); + assertEquals("/my", mapping.getNamespace()); + assertEquals("foo/actionName", mapping.getName()); + assertNull(mapping.getMethod()); } public void testGetMappingWithUnknownNamespace() throws Exception { @@ -157,25 +150,19 @@ public class DefaultActionMapperTest extends StrutsTestCase { } public void testGetMappingWithNoExtension() throws Exception { - String old = org.apache.struts2.config.Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); - org.apache.struts2.config.Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, ""); - try { - req.setupGetParameterMap(new HashMap()); - req.setupGetRequestURI("/my/namespace/actionName"); - req.setupGetServletPath("/my/namespace/actionName"); - req.setupGetAttribute(null); - req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); + req.setupGetParameterMap(new HashMap()); + req.setupGetRequestURI("/my/namespace/actionName"); + req.setupGetServletPath("/my/namespace/actionName"); + req.setupGetAttribute(null); + req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); - DefaultActionMapper mapper = new DefaultActionMapper(); - ActionMapping mapping = mapper.getMapping(req, configManager); + DefaultActionMapper mapper = new DefaultActionMapper(); + mapper.setExtensions(""); + ActionMapping mapping = mapper.getMapping(req, configManager); - assertEquals("/my/namespace", mapping.getNamespace()); - assertEquals("actionName", mapping.getName()); - assertNull(mapping.getMethod()); - } - finally { - org.apache.struts2.config.Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, old); - } + assertEquals("/my/namespace", mapping.getNamespace()); + assertEquals("actionName", mapping.getName()); + assertNull(mapping.getMethod()); } // ============================= @@ -213,37 +200,25 @@ public class DefaultActionMapperTest extends StrutsTestCase { } public void testParseNameAndNamespace_NoSlashes() throws Exception { - String old = Settings.get(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES); - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, "false"); - try { - ActionMapping actionMapping = new ActionMapping(); + ActionMapping actionMapping = new ActionMapping(); - DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); - defaultActionMapper.parseNameAndNamespace("/foo/someAction", actionMapping, config); + DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); + defaultActionMapper.setSlashesInActionNames("false"); + defaultActionMapper.parseNameAndNamespace("/foo/someAction", actionMapping, config); - assertEquals(actionMapping.getName(), "someAction"); - assertEquals(actionMapping.getNamespace(), ""); - } - finally { - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, old); - } + assertEquals(actionMapping.getName(), "someAction"); + assertEquals(actionMapping.getNamespace(), ""); } public void testParseNameAndNamespace_AllowSlashes() throws Exception { - String old = Settings.get(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES); - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, "true"); - try { - ActionMapping actionMapping = new ActionMapping(); + ActionMapping actionMapping = new ActionMapping(); - DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); - defaultActionMapper.parseNameAndNamespace("/foo/someAction", actionMapping, config); + DefaultActionMapper defaultActionMapper = new DefaultActionMapper(); + defaultActionMapper.setSlashesInActionNames("true"); + defaultActionMapper.parseNameAndNamespace("/foo/someAction", actionMapping, config); - assertEquals(actionMapping.getName(), "foo/someAction"); - assertEquals(actionMapping.getNamespace(), ""); - } - finally { - Settings.set(StrutsConstants.STRUTS_ENABLE_SLASHES_IN_ACTION_NAMES, old); - } + assertEquals(actionMapping.getName(), "foo/someAction"); + assertEquals(actionMapping.getNamespace(), ""); } diff --git a/core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java b/core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java index 2fa6587e9..7b505ea6c 100644 --- a/core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java +++ b/core/src/test/java/org/apache/struts2/dispatcher/mapper/Restful2ActionMapperTest.java @@ -22,7 +22,6 @@ package org.apache.struts2.dispatcher.mapper; import org.apache.struts2.StrutsTestCase; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import com.mockobjects.servlet.MockHttpServletRequest; import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.config.Configuration; @@ -33,6 +32,7 @@ import java.util.HashMap; public class Restful2ActionMapperTest extends StrutsTestCase { + private Restful2ActionMapper mapper; private MockHttpServletRequest req; private ConfigurationManager configManager; private Configuration config; @@ -40,7 +40,8 @@ public class Restful2ActionMapperTest extends StrutsTestCase { @Override protected void setUp() throws Exception { super.setUp(); - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, ""); + mapper = new Restful2ActionMapper(); + mapper.setExtensions(""); req = new MockHttpServletRequest(); req.setupGetParameterMap(new HashMap()); req.setupGetContextPath("/my/namespace"); @@ -56,7 +57,7 @@ public class Restful2ActionMapperTest extends StrutsTestCase { } }; } - + public void testGetIndex() throws Exception { req.setupGetRequestURI("/my/namespace/foo/"); req.setupGetServletPath("/my/namespace/foo/"); @@ -64,7 +65,6 @@ public class Restful2ActionMapperTest extends StrutsTestCase { req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); req.setupGetMethod("GET"); - Restful2ActionMapper mapper = new Restful2ActionMapper(); ActionMapping mapping = mapper.getMapping(req, configManager); assertEquals("/my/namespace", mapping.getNamespace()); @@ -79,7 +79,6 @@ public class Restful2ActionMapperTest extends StrutsTestCase { req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); req.setupGetMethod("GET"); - Restful2ActionMapper mapper = new Restful2ActionMapper(); ActionMapping mapping = mapper.getMapping(req, configManager); assertEquals("/my/namespace", mapping.getNamespace()); @@ -96,7 +95,6 @@ public class Restful2ActionMapperTest extends StrutsTestCase { req.addExpectedGetAttributeName("javax.servlet.include.servlet_path"); req.setupGetMethod("POST"); - Restful2ActionMapper mapper = new Restful2ActionMapper(); ActionMapping mapping = mapper.getMapping(req, configManager); assertEquals("/my/namespace", mapping.getNamespace()); diff --git a/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java index af40001dd..4fb1bfc5e 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import javax.servlet.http.HttpSession; @@ -36,13 +37,17 @@ import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.DefaultActionProxyFactory; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.config.ConfigurationProvider; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; import com.opensymphony.xwork2.config.entities.PackageConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.inject.ContainerBuilder; import com.opensymphony.xwork2.interceptor.ParametersInterceptor; import com.opensymphony.xwork2.mock.MockResult; @@ -164,14 +169,15 @@ public class ExecuteAndWaitInterceptorTest extends StrutsTestCase { } protected ActionProxy buildProxy(String actionName) throws Exception { - return ActionProxyFactory.getFactory().createActionProxy( + return container.getInstance(ActionProxyFactory.class).createActionProxy( configurationManager.getConfiguration(), "", actionName, context); } protected void setUp() throws Exception { - configurationManager.clearConfigurationProviders(); + configurationManager = new ConfigurationManager(); configurationManager.addConfigurationProvider(new WaitConfigurationProvider()); configurationManager.reload(); + container = configurationManager.getConfiguration().getContainer(); session = new HashMap(); params = new HashMap(); @@ -194,6 +200,7 @@ public class ExecuteAndWaitInterceptorTest extends StrutsTestCase { private class WaitConfigurationProvider implements ConfigurationProvider { + Configuration configuration; public void destroy() { waitInterceptor.destroy(); } @@ -201,8 +208,12 @@ public class ExecuteAndWaitInterceptorTest extends StrutsTestCase { public boolean needsReload() { return false; } - + public void init(Configuration configuration) throws ConfigurationException { + this.configuration = configuration; + } + + public void loadPackages() throws ConfigurationException { PackageConfig wait = new PackageConfig(""); Map results = new HashMap(); @@ -221,6 +232,11 @@ public class ExecuteAndWaitInterceptorTest extends StrutsTestCase { configuration.addPackageConfig("", wait); } + public void register(ContainerBuilder builder, Properties props) throws ConfigurationException { + builder.factory(ObjectFactory.class); + builder.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class); + } + } } diff --git a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java index 61f81c03c..42e86619a 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java @@ -33,6 +33,8 @@ import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsTestCase; +import org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest; +import org.apache.struts2.dispatcher.multipart.MultiPartRequest; import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper; import org.springframework.mock.web.MockHttpServletRequest; @@ -226,7 +228,7 @@ public class FileUploadInterceptorTest extends StrutsTestCase { } private MultiPartRequestWrapper createMultipartRequest(HttpServletRequest req, int maxsize) throws IOException { - return new MultiPartRequestWrapper(req, tempDir.getAbsolutePath(), maxsize); + return new MultiPartRequestWrapper(new JakartaMultiPartRequest(), req, tempDir.getAbsolutePath()); } protected void setUp() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java index 9003ea0a1..d1ebb6f3d 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java @@ -37,6 +37,7 @@ import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; @@ -106,9 +107,10 @@ public class TokenInterceptorTest extends StrutsTestCase { } protected void setUp() throws Exception { - configurationManager.clearConfigurationProviders(); + configurationManager = new ConfigurationManager(); configurationManager.addConfigurationProvider(new TestConfigurationProvider()); configurationManager.reload(); + container = configurationManager.getConfiguration().getContainer(); session = new HashMap(); params = new HashMap(); @@ -129,7 +131,7 @@ public class TokenInterceptorTest extends StrutsTestCase { } protected ActionProxy buildProxy(String actionName) throws Exception { - return ActionProxyFactory.getFactory().createActionProxy( + return container.getInstance(ActionProxyFactory.class).createActionProxy( configurationManager.getConfiguration(), "", actionName, extraContext, true, true); } diff --git a/core/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java b/core/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java index b9647a871..46b3191f8 100644 --- a/core/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java +++ b/core/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java @@ -85,6 +85,8 @@ public class Jsr168DispatcherTest extends MockObjectTestCase implements PortletA mockConfig.stubs().method("getPortletContext").will(returnValue(mockCtx.proxy())); mockCtx.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet()))); setupStub(initParams, mockCtx, "getInitParameter"); + mockConfig.stubs().method("getInitParameterNames").will(returnValue(Collections.enumeration(initParams.keySet()))); + setupStub(initParams, mockConfig, "getInitParameter"); mockConfig.stubs().method("getResourceBundle").will(returnValue(new ListResourceBundle() { protected Object[][] getContents() { diff --git a/core/src/test/java/org/apache/struts2/spring/StrutsSpringObjectFactoryTest.java b/core/src/test/java/org/apache/struts2/spring/StrutsSpringObjectFactoryTest.java index 807b3e57d..b5e825068 100644 --- a/core/src/test/java/org/apache/struts2/spring/StrutsSpringObjectFactoryTest.java +++ b/core/src/test/java/org/apache/struts2/spring/StrutsSpringObjectFactoryTest.java @@ -24,7 +24,6 @@ import javax.servlet.ServletContext; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.mock.web.MockServletContext; import org.springframework.web.context.ConfigurableWebApplicationContext; @@ -41,7 +40,7 @@ public class StrutsSpringObjectFactoryTest extends StrutsTestCase { // to cover situations where there will be logged an error StrutsSpringObjectFactory fac = new StrutsSpringObjectFactory(); ServletContext msc = (ServletContext) new MockServletContext(); - fac.init(msc); + fac.setServletContext(msc); assertEquals(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, fac.getAutowireStrategy()); } @@ -50,7 +49,7 @@ public class StrutsSpringObjectFactoryTest extends StrutsTestCase { StrutsSpringObjectFactory fac = new StrutsSpringObjectFactory(); // autowire by constructure, we try a non default setting in this unit test - Settings.set(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE, "constructor"); + fac.setAutoWire("constructor"); ConfigurableWebApplicationContext ac = new XmlWebApplicationContext(); ServletContext msc = (ServletContext) new MockServletContext(); @@ -59,7 +58,7 @@ public class StrutsSpringObjectFactoryTest extends StrutsTestCase { ac.setConfigLocations(new String[] {"org/apache/struts2/spring/StrutsSpringObjectFactoryTest-applicationContext.xml"}); ac.refresh(); - fac.init(msc); + fac.setServletContext(msc); assertEquals(AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, fac.getAutowireStrategy()); } diff --git a/core/src/test/java/org/apache/struts2/views/TemplateEngineManagerTest.java b/core/src/test/java/org/apache/struts2/views/TemplateEngineManagerTest.java index 12417b8db..31f4771d2 100644 --- a/core/src/test/java/org/apache/struts2/views/TemplateEngineManagerTest.java +++ b/core/src/test/java/org/apache/struts2/views/TemplateEngineManagerTest.java @@ -28,50 +28,59 @@ import org.apache.struts2.components.template.Template; import org.apache.struts2.components.template.TemplateEngine; import org.apache.struts2.components.template.TemplateEngineManager; import org.apache.struts2.components.template.VelocityTemplateEngine; -import org.apache.struts2.config.Settings; +import org.apache.struts2.dispatcher.mapper.CompositeActionMapper; + +import com.mockobjects.dynamic.C; +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.inject.Container; /** * TemplateEngineManagerTest * */ public class TemplateEngineManagerTest extends TestCase { + + TemplateEngineManager mgr; + Mock mockContainer; + + public void setUp() throws Exception { + mgr = new TemplateEngineManager(); + mockContainer = new Mock(Container.class); + mockContainer.matchAndReturn("getInstance", C.args(C.eq(TemplateEngine.class), C.eq("jsp")), new JspTemplateEngine()); + mockContainer.matchAndReturn("getInstance", C.args(C.eq(TemplateEngine.class), C.eq("vm")), new VelocityTemplateEngine()); + mockContainer.matchAndReturn("getInstance", C.args(C.eq(TemplateEngine.class), C.eq("ftl")), new FreemarkerTemplateEngine()); + + mgr.setContainer((Container)mockContainer.proxy()); + mgr.setTemplateEngines("jsp,vm,ftl"); + mgr.setDefaultTemplateType("jsp"); + } + public void testTemplateTypeFromTemplateNameAndDefaults() { - Settings.setInstance(new Settings() { - public boolean isSetImpl(String name) { - return name.equals(TemplateEngineManager.DEFAULT_TEMPLATE_TYPE_CONFIG_KEY); - } - - public String getImpl(String aName) throws IllegalArgumentException { - if (aName.equals(TemplateEngineManager.DEFAULT_TEMPLATE_TYPE_CONFIG_KEY)) { - return "jsp"; - } - return null; - } - }); - TemplateEngine engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo"), null); + + TemplateEngine engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo"), null); assertTrue(engine instanceof JspTemplateEngine); - engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo.vm"), null); + engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo.vm"), null); assertTrue(engine instanceof VelocityTemplateEngine); } public void testTemplateTypeOverrides() { - TemplateEngine engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo"), "ftl"); + TemplateEngine engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo"), "ftl"); assertTrue(engine instanceof FreemarkerTemplateEngine); - engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo.vm"), "ftl"); + engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo.vm"), "ftl"); assertTrue(engine instanceof VelocityTemplateEngine); - engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo.ftl"), ""); + engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo.ftl"), ""); assertTrue(engine instanceof FreemarkerTemplateEngine); } public void testTemplateTypeUsesDefaultWhenNotSetInConfiguration() { - TemplateEngine engine = TemplateEngineManager.getTemplateEngine(new Template("/template", "simple", "foo"), null); + mgr.setDefaultTemplateType(null); + TemplateEngine engine = mgr.getTemplateEngine(new Template("/template", "simple", "foo"), null); Template template = new Template("/template", "simple", "foo." + TemplateEngineManager.DEFAULT_TEMPLATE_TYPE); - TemplateEngine defaultTemplateEngine = TemplateEngineManager.getTemplateEngine(template, null); + TemplateEngine defaultTemplateEngine = mgr.getTemplateEngine(template, null); assertTrue(engine.getClass().equals(defaultTemplateEngine.getClass())); } protected void tearDown() throws Exception { super.tearDown(); - Settings.setInstance(null); } } diff --git a/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerManagerTest.java b/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerManagerTest.java index cefcb9b1c..3aa2ec4c5 100644 --- a/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerManagerTest.java +++ b/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerManagerTest.java @@ -22,7 +22,6 @@ package org.apache.struts2.views.freemarker; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import org.apache.struts2.views.jsp.StrutsMockServletContext; /** @@ -32,10 +31,11 @@ import org.apache.struts2.views.jsp.StrutsMockServletContext; public class FreemarkerManagerTest extends StrutsTestCase { public void testIfStrutsEncodingIsSetProperty() throws Exception { - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8"); + FreemarkerManager mgr = new FreemarkerManager(); + mgr.setEncoding("UTF-8"); StrutsMockServletContext servletContext = new StrutsMockServletContext(); servletContext.setAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY, null); - freemarker.template.Configuration conf = FreemarkerManager.getInstance().getConfiguration(servletContext); + freemarker.template.Configuration conf = mgr.getConfiguration(servletContext); assertEquals(conf.getDefaultEncoding(), "UTF-8"); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java index 5efeb09a9..8d63e722a 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java @@ -22,6 +22,7 @@ package org.apache.struts2.views.jsp; import java.io.File; import java.io.StringWriter; +import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletResponse; @@ -30,14 +31,15 @@ import javax.servlet.jsp.JspWriter; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsTestCase; import org.apache.struts2.TestAction; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.ApplicationMap; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.RequestMap; import org.apache.struts2.dispatcher.SessionMap; +import com.mockobjects.dynamic.Mock; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.inject.Container; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; @@ -60,6 +62,8 @@ public abstract class AbstractTagTest extends StrutsTestCase { protected StrutsMockPageContext pageContext; protected HttpServletResponse response; protected StrutsMockServletContext servletContext; + + protected Mock mockContainer; /** * Constructs the action that we're going to test against. For most UI tests, this default action should be enough. @@ -102,7 +106,8 @@ public abstract class AbstractTagTest extends StrutsTestCase { pageContext.setJspWriter(jspWriter); pageContext.setServletContext(servletContext); - Dispatcher du = new Dispatcher(pageContext.getServletContext()); + mockContainer = new Mock(Container.class); + Dispatcher du = new Dispatcher(pageContext.getServletContext(), new HashMap()); Dispatcher.setInstance(du); du.setConfigurationManager(configurationManager); session = new SessionMap(request); @@ -123,8 +128,6 @@ public abstract class AbstractTagTest extends StrutsTestCase { context.put(ServletActionContext.SERVLET_CONTEXT, servletContext); ActionContext.setContext(new ActionContext(context)); - - Settings.setInstance(null); } protected void tearDown() throws Exception { diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java index 64d79b993..e80416362 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java @@ -20,6 +20,8 @@ */ package org.apache.struts2.views.jsp; +import java.util.HashMap; + import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; @@ -241,9 +243,7 @@ public class ActionTagTest extends AbstractTagTest { protected void setUp() throws Exception { super.setUp(); - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); - configurationManager.reload(); + initDispatcher(new HashMap() {{ put("configProviders", TestConfigurationProvider.class.getName()); }}); ActionContext actionContext = new ActionContext(context); actionContext.setValueStack(stack); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java index 1b9848aa6..cfd3a0087 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java @@ -25,6 +25,7 @@ import javax.servlet.jsp.tagext.TagSupport; import junit.framework.TestCase; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsTestCase; import org.apache.struts2.components.If; import com.mockobjects.servlet.MockJspWriter; @@ -35,7 +36,7 @@ import com.opensymphony.xwork2.util.ValueStackFactory; /** * */ -public class ElseIfTagTest extends TestCase { +public class ElseIfTagTest extends StrutsTestCase { protected MockPageContext pageContext; protected MockJspWriter jspWriter; @@ -96,6 +97,7 @@ public class ElseIfTagTest extends TestCase { protected void setUp() throws Exception { + super.setUp(); stack = ValueStackFactory.getFactory().createValueStack(); jspWriter = new MockJspWriter(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java index 5d63dc38b..78477e18c 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java @@ -90,6 +90,7 @@ public class ElseTagTest extends StrutsTestCase { } protected void setUp() throws Exception { + super.setUp(); // create the needed objects elseTag = new ElseTag(); stack = ValueStackFactory.getFactory().createValueStack(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java index bbb3aa6a8..4562e47cd 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java @@ -26,6 +26,7 @@ import javax.servlet.jsp.tagext.TagSupport; import junit.framework.TestCase; import org.apache.struts2.ServletActionContext; +import org.apache.struts2.StrutsTestCase; import com.mockobjects.servlet.MockJspWriter; import com.mockobjects.servlet.MockPageContext; @@ -36,7 +37,7 @@ import com.opensymphony.xwork2.util.ValueStackFactory; /** */ -public class IfTagTest extends TestCase { +public class IfTagTest extends StrutsTestCase { IfTag tag; MockPageContext pageContext; @@ -320,6 +321,7 @@ public class IfTagTest extends TestCase { protected void setUp() throws Exception { + super.setUp(); // create the needed objects tag = new IfTag(); stack = ValueStackFactory.getFactory().createValueStack(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java index 780078dfc..ce0edf523 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java @@ -39,7 +39,6 @@ import javax.servlet.jsp.PageContext; import junit.textui.TestRunner; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.portlet.PortletActionConstants; import org.apache.struts2.portlet.util.PortletUrlHelper; @@ -81,8 +80,7 @@ public class PortletUrlTagTest extends MockObjectTestCase { public void setUp() throws Exception { super.setUp(); - Settings.reset(); - Dispatcher.setInstance(new Dispatcher(null)); + Dispatcher.setInstance(new Dispatcher(null, new HashMap())); mockPortletApiAvailable(); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java index d577ec650..5d177c035 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java @@ -20,12 +20,13 @@ */ package org.apache.struts2.views.jsp; +import java.util.HashMap; + import javax.servlet.jsp.JspException; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import com.mockobjects.servlet.MockJspWriter; import com.mockobjects.servlet.MockPageContext; @@ -165,8 +166,7 @@ public class PropertyTagTest extends StrutsTestCase { public void testWithAltSyntax1() throws Exception { // setups - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); Foo foo = new Foo(); foo.setTitle("tm_jee"); @@ -194,8 +194,7 @@ public class PropertyTagTest extends StrutsTestCase { public void testWithAltSyntax2() throws Exception { // setups - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true");}}); Foo foo = new Foo(); foo.setTitle("tm_jee"); @@ -223,8 +222,7 @@ public class PropertyTagTest extends StrutsTestCase { public void testWithoutAltSyntax1() throws Exception { // setups - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); Foo foo = new Foo(); foo.setTitle("tm_jee"); @@ -253,8 +251,7 @@ public class PropertyTagTest extends StrutsTestCase { public void testWithoutAltSyntax2() throws Exception { // setups - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + initDispatcher(new HashMap() {{ put(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false");}}); Foo foo = new Foo(); foo.setTitle("tm_jee"); diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java index b080aaf92..97ad69efc 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java @@ -21,23 +21,32 @@ package org.apache.struts2.views.jsp.ui; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.struts2.StrutsConstants; import org.apache.struts2.TestAction; import org.apache.struts2.TestConfigurationProvider; -import org.apache.struts2.config.Settings; +import org.apache.struts2.components.Component; +import org.apache.struts2.components.Form; +import org.apache.struts2.components.template.TemplateEngineManager; +import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.DefaultActionMapper; import org.apache.struts2.views.jsp.AbstractUITagTest; import org.apache.struts2.views.jsp.ActionTag; +import com.mockobjects.dynamic.Mock; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.RuntimeConfiguration; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; +import com.opensymphony.xwork2.config.impl.DefaultConfiguration; +import com.opensymphony.xwork2.inject.Container; +import com.opensymphony.xwork2.inject.Inject; +import com.opensymphony.xwork2.inject.Scope.Strategy; import com.opensymphony.xwork2.validator.ValidationInterceptor; @@ -117,8 +126,26 @@ public class FormTagTest extends AbstractUITagTest { ObjectFactory originalObjectFactory = ObjectFactory.getObjectFactory(); try { + final Container cont = container; // used to determined if the form action needs js validation configurationManager.setConfiguration(new com.opensymphony.xwork2.config.impl.DefaultConfiguration() { + private DefaultConfiguration self = this; + public Container getContainer() { + return new Container() { + public T inject(Class implementation) {return null;} + public void removeScopeStrategy() {} + public void setScopeStrategy(Strategy scopeStrategy) {} + public T getInstance(Class type, String name) {return null;} + public T getInstance(Class type) {return null;} + + public void inject(Object o) { + cont.inject(o); + if (o instanceof Form) { + ((Form)o).setConfiguration(self); + } + } + }; + } public RuntimeConfiguration getRuntimeConfiguration() { return new RuntimeConfiguration() { public ActionConfig getActionConfig(String namespace, String name) { @@ -199,9 +226,27 @@ public class FormTagTest extends AbstractUITagTest { com.opensymphony.xwork2.config.Configuration originalConfiguration = configurationManager.getConfiguration(); ObjectFactory originalObjectFactory = ObjectFactory.getObjectFactory(); + final Container cont = container; try { // used to determined if the form action needs js validation - configurationManager.setConfiguration(new com.opensymphony.xwork2.config.impl.DefaultConfiguration() { + configurationManager.setConfiguration(new DefaultConfiguration() { + private DefaultConfiguration self = this; + public Container getContainer() { + return new Container() { + public T inject(Class implementation) {return null;} + public void removeScopeStrategy() {} + public void setScopeStrategy(Strategy scopeStrategy) {} + public T getInstance(Class type, String name) {return null;} + public T getInstance(Class type) {return null;} + + public void inject(Object o) { + cont.inject(o); + if (o instanceof Form) { + ((Form)o).setConfiguration(self); + } + } + }; + } public RuntimeConfiguration getRuntimeConfiguration() { return new RuntimeConfiguration() { public ActionConfig getActionConfig(String namespace, String name) { @@ -307,9 +352,11 @@ public class FormTagTest extends AbstractUITagTest { * config property is set to "jspa". */ public void testFormTagWithDifferentActionExtension() throws Exception { + initDispatcher(new HashMap(){{ + put(StrutsConstants.STRUTS_ACTION_EXTENSION, "jspa"); + put("configProviders", TestConfigurationProvider.class.getName()); + }}); request.setupGetServletPath("/testNamespace/testNamespaceAction"); - String oldConfiguration = (String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, "jspa"); FormTag tag = new FormTag(); tag.setPageContext(pageContext); @@ -321,12 +368,7 @@ public class FormTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, oldConfiguration); - verify(FormTag.class.getResource("Formtag-5.txt")); - - // set it back to the default - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, "action"); } /** @@ -519,9 +561,7 @@ public class FormTagTest extends AbstractUITagTest { public void testFormWithActionAndExtension() throws Exception { request.setupGetServletPath("/BLA"); - String oldConfiguration = (String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, "jspa"); - + FormTag tag = new FormTag(); tag.setPageContext(pageContext); tag.setAction("/testNamespace/testNamespaceAction.jspa"); @@ -530,19 +570,17 @@ public class FormTagTest extends AbstractUITagTest { tag.doStartTag(); tag.doEndTag(); - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, oldConfiguration); verify(FormTag.class.getResource("Formtag-8.txt")); - // set it back to the default - Settings.set(StrutsConstants.STRUTS_ACTION_EXTENSION, "action"); - } + @Override protected void setUp() throws Exception { super.setUp(); - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); + initDispatcher(new HashMap(){{ + put("configProviders", TestConfigurationProvider.class.getName()); + }}); ActionContext.getContext().setValueStack(stack); } } diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java index f51496bf5..6a0568ea2 100644 --- a/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java +++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java @@ -20,6 +20,8 @@ */ package org.apache.struts2.views.jsp.ui; +import java.util.HashMap; + import org.apache.struts2.TestConfigurationProvider; import org.apache.struts2.views.jsp.AbstractUITagTest; import org.apache.struts2.views.jsp.ParamTag; @@ -34,9 +36,6 @@ public class TooltipTest extends AbstractUITagTest { public void testWithoutFormOverriding() throws Exception { - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); - // we test it on textfield component, but since the tooltip are common to // all components, it will be the same for other components as well. FormTag formTag = new FormTag(); @@ -71,9 +70,6 @@ public class TooltipTest extends AbstractUITagTest { public void testWithFormOverriding() throws Exception { - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); - FormTag formTag = new FormTag(); formTag.setPageContext(pageContext); formTag.setName("myForm"); @@ -106,9 +102,6 @@ public class TooltipTest extends AbstractUITagTest { public void testWithPartialFormOverriding() throws Exception { - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); - FormTag formTag = new FormTag(); formTag.setName("myForm"); formTag.setPageContext(pageContext); @@ -147,9 +140,6 @@ public class TooltipTest extends AbstractUITagTest { public void testUsingParamValueToSetConfigurations() throws Exception { - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); - FormTag formTag = new FormTag(); formTag.setName("myForm"); formTag.setPageContext(pageContext); @@ -199,8 +189,6 @@ public class TooltipTest extends AbstractUITagTest { public void testUsingParamBodyValueToSetConfigurations() throws Exception { - configurationManager.clearConfigurationProviders(); - configurationManager.addConfigurationProvider(new TestConfigurationProvider()); FormTag formTag = new FormTag(); formTag.setName("myForm"); @@ -250,4 +238,15 @@ public class TooltipTest extends AbstractUITagTest { verify(TooltipTest.class.getResource("tooltip-3.txt")); } + + /** + * @throws Exception + * + */ + public void setUp() throws Exception { + super.setUp(); + initDispatcher(new HashMap(){{ + put("configProviders", TestConfigurationProvider.class.getName()); + }}); + } } diff --git a/core/src/test/java/org/apache/struts2/views/util/ContextUtilTest.java b/core/src/test/java/org/apache/struts2/views/util/ContextUtilTest.java index 8a4a84033..dd7b05c3b 100755 --- a/core/src/test/java/org/apache/struts2/views/util/ContextUtilTest.java +++ b/core/src/test/java/org/apache/struts2/views/util/ContextUtilTest.java @@ -23,7 +23,6 @@ package org.apache.struts2.views.util; import junit.framework.TestCase; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import com.opensymphony.xwork2.util.ValueStack; import com.opensymphony.xwork2.util.ValueStackFactory; @@ -38,10 +37,7 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", "true"); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + ContextUtil.setAltSyntax("true"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } @@ -49,10 +45,7 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", "false"); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + ContextUtil.setAltSyntax("true"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } @@ -60,10 +53,7 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", "true"); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + ContextUtil.setAltSyntax("false"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } @@ -71,10 +61,7 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", "false"); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + ContextUtil.setAltSyntax("false"); assertFalse(ContextUtil.isUseAltSyntax(stack.getContext())); } @@ -84,40 +71,28 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", Boolean.TRUE); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + ContextUtil.setAltSyntax("true"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } public void testAltSyntaxMethod6() throws Exception { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", Boolean.FALSE); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + ContextUtil.setAltSyntax("true"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } public void testAltSyntaxMethod7() throws Exception { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", Boolean.TRUE); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + ContextUtil.setAltSyntax("false"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } public void testAltSyntaxMethod8() throws Exception { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", Boolean.FALSE); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "false"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "false"); + ContextUtil.setAltSyntax("false"); assertFalse(ContextUtil.isUseAltSyntax(stack.getContext())); } @@ -126,10 +101,7 @@ public class ContextUtilTest extends TestCase { ValueStack stack = ValueStackFactory.getFactory().createValueStack(); stack.getContext().put("useAltSyntax", null); - Settings.reset(); - Settings.set(StrutsConstants.STRUTS_TAG_ALTSYNTAX, "true"); - - assertEquals(Settings.get(StrutsConstants.STRUTS_TAG_ALTSYNTAX), "true"); + ContextUtil.setAltSyntax("true"); assertTrue(ContextUtil.isUseAltSyntax(stack.getContext())); } } diff --git a/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java b/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java index 366632247..98dc39a3b 100644 --- a/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java +++ b/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.StrutsConstants; import org.apache.struts2.StrutsTestCase; -import org.apache.struts2.config.Settings; import com.mockobjects.dynamic.Mock; @@ -201,8 +200,8 @@ public class UrlHelperTest extends StrutsTestCase { String expectedString = "https://www.mydomain.com:7002/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars"; - Settings.set(StrutsConstants.STRUTS_URL_HTTP_PORT, "7001"); - Settings.set(StrutsConstants.STRUTS_URL_HTTPS_PORT, "7002"); + UrlHelper.setHttpPort("7001"); + UrlHelper.setHttpsPort("7002"); Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com"); @@ -230,8 +229,8 @@ public class UrlHelperTest extends StrutsTestCase { String expectedString = "http://www.mydomain.com:7001/mywebapp/MyAction.action?foo=bar&hello=earth&hello=mars"; - Settings.set(StrutsConstants.STRUTS_URL_HTTP_PORT, "7001"); - Settings.set(StrutsConstants.STRUTS_URL_HTTPS_PORT, "7002"); + UrlHelper.setHttpPort("7001"); + UrlHelper.setHttpsPort("7002"); Mock mockHttpServletRequest = new Mock(HttpServletRequest.class); mockHttpServletRequest.expectAndReturn("getServerName", "www.mydomain.com"); @@ -303,30 +302,18 @@ public class UrlHelperTest extends StrutsTestCase { public void testTranslateAndEncode() throws Exception { - String defaultI18nEncoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); - try { - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8"); - String result = UrlHelper.translateAndEncode("\u65b0\u805e"); - String expectedResult = "%E6%96%B0%E8%81%9E"; + UrlHelper.setCustomEncoding("UTF-8"); + String result = UrlHelper.translateAndEncode("\u65b0\u805e"); + String expectedResult = "%E6%96%B0%E8%81%9E"; - assertEquals(result, expectedResult); - } - finally { - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, defaultI18nEncoding); - } + assertEquals(result, expectedResult); } public void testTranslateAndDecode() throws Exception { - String defaultI18nEncoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); - try { - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8"); - String result = UrlHelper.translateAndDecode("%E6%96%B0%E8%81%9E"); - String expectedResult = "\u65b0\u805e"; + UrlHelper.setCustomEncoding("UTF-8"); + String result = UrlHelper.translateAndDecode("%E6%96%B0%E8%81%9E"); + String expectedResult = "\u65b0\u805e"; - assertEquals(result, expectedResult); - } - finally { - Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, defaultI18nEncoding); - } + assertEquals(result, expectedResult); } } diff --git a/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ActionNamesAction.java b/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ActionNamesAction.java index e3cb5de5a..4ce0bd120 100644 --- a/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ActionNamesAction.java +++ b/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ActionNamesAction.java @@ -24,10 +24,10 @@ import java.util.Set; import java.util.TreeSet; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.inject.Inject; /** * ActionNamesAction @@ -53,6 +53,11 @@ public class ActionNamesAction extends ActionSupport { public void setNamespace(String namespace) { this.namespace = namespace; } + + @Inject(StrutsConstants.STRUTS_ACTION_EXTENSION) + public void setExtension(String ext) { + this.extension = ext; + } public ActionConfig getConfig(String actionName) { return ConfigurationHelper.getActionConfig(namespace, actionName); @@ -64,12 +69,7 @@ public class ActionNamesAction extends ActionSupport { public String getExtension() { if ( extension == null) { - String ext = (String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); - if ( ext == null || ext.equals("")) { - extension = "action"; - } else { - extension = ext; - } + extension = "action"; } return extension; } diff --git a/plugins/pell-multipart/src/main/java/org/apache/struts2/dispatcher/multipart/PellMultiPartRequest.java b/plugins/pell-multipart/src/main/java/org/apache/struts2/dispatcher/multipart/PellMultiPartRequest.java index f89c469b2..234340d3b 100644 --- a/plugins/pell-multipart/src/main/java/org/apache/struts2/dispatcher/multipart/PellMultiPartRequest.java +++ b/plugins/pell-multipart/src/main/java/org/apache/struts2/dispatcher/multipart/PellMultiPartRequest.java @@ -20,8 +20,12 @@ */ package org.apache.struts2.dispatcher.multipart; -import org.apache.struts2.config.Settings; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; + +import com.opensymphony.xwork2.inject.Inject; + import http.utils.multipartrequest.ServletMultipartRequest; import javax.servlet.http.HttpServletRequest; @@ -38,11 +42,18 @@ import java.util.List; * Multipart form data request adapter for Jason Pell's multipart utils package. * */ -public class PellMultiPartRequest extends MultiPartRequest { +public class PellMultiPartRequest implements MultiPartRequest { + private static final Log LOG = LogFactory.getLog(PellMultiPartRequest.class); private ServletMultipartRequest multi; - + private String defaultEncoding; + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public void setDefaultEncoding(String enc) { + this.defaultEncoding = enc; + } + /** * Creates a new request wrapper to handle multi-part data using methods adapted from Jason Pell's * multipart classes (see class description). @@ -51,16 +62,15 @@ public class PellMultiPartRequest extends MultiPartRequest { * @param saveDir the directory to save off the file * @param servletRequest the request containing the multipart */ - public PellMultiPartRequest(HttpServletRequest servletRequest, String saveDir, int maxSize) throws IOException { + public void parse(HttpServletRequest servletRequest, String saveDir) throws IOException { //this needs to be synchronised, as we should not change the encoding at the same time as //calling the constructor. See javadoc for MultipartRequest.setEncoding(). synchronized (this) { setEncoding(); - multi = new ServletMultipartRequest(servletRequest, saveDir, maxSize); + multi = new ServletMultipartRequest(servletRequest, saveDir); } } - - + public Enumeration getFileParameterNames() { return multi.getFileParameterNames(); } @@ -120,11 +130,11 @@ public class PellMultiPartRequest extends MultiPartRequest { * The encoding is looked up from the configuration setting 'struts.i18n.encoding'. This is usually set in * default.properties & struts.properties. */ - private static void setEncoding() { + private void setEncoding() { String encoding = null; try { - encoding = Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + encoding = defaultEncoding; if (encoding != null) { //NB: This should never be called at the same time as the constructor for @@ -135,9 +145,9 @@ public class PellMultiPartRequest extends MultiPartRequest { http.utils.multipartrequest.MultipartRequest.setEncoding("UTF-8"); } } catch (IllegalArgumentException e) { - log.info("Could not get encoding property 'struts.i18n.encoding' for file upload. Using system default"); + LOG.info("Could not get encoding property 'struts.i18n.encoding' for file upload. Using system default"); } catch (UnsupportedEncodingException e) { - log.error("Encoding " + encoding + " is not a valid encoding. Please check your struts.properties file."); + LOG.error("Encoding " + encoding + " is not a valid encoding. Please check your struts.properties file."); } } } diff --git a/plugins/pell-multipart/src/main/resources/struts-plugin.xml b/plugins/pell-multipart/src/main/resources/struts-plugin.xml new file mode 100644 index 000000000..45fed82da --- /dev/null +++ b/plugins/pell-multipart/src/main/resources/struts-plugin.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusObjectFactory.java b/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusObjectFactory.java index 5de63dde6..78f0d105f 100644 --- a/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusObjectFactory.java +++ b/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusObjectFactory.java @@ -27,7 +27,6 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.struts2.util.ObjectFactoryInitializable; import org.codehaus.plexus.PlexusContainer; import com.opensymphony.xwork2.Action; @@ -37,6 +36,7 @@ import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorConfig; import com.opensymphony.xwork2.config.entities.ResultConfig; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.Interceptor; import com.opensymphony.xwork2.util.OgnlUtil; import com.opensymphony.xwork2.validator.Validator; @@ -70,17 +70,17 @@ import com.opensymphony.xwork2.validator.Validator; * * @author Emmanuel Venisse */ -public class PlexusObjectFactory extends ObjectFactory implements ObjectFactoryInitializable { +public class PlexusObjectFactory extends ObjectFactory { private static final Log log = LogFactory.getLog(PlexusObjectFactory.class); private static final String PLEXUS_COMPONENT_TYPE = "plexus.component.type"; private PlexusContainer base; + + - /* (non-Javadoc) - * @see org.apache.struts2.util.ObjectFactoryInitializable#init(javax.servlet.ServletContext) - */ - public void init(ServletContext servletContext) { + @Inject + public void setServletConfig(ServletContext servletContext) { if (!PlexusLifecycleListener.isLoaded() || !PlexusFilter.isLoaded()) { // uh oh! looks like the lifecycle listener wasn't installed. Let's inform the user String message = "********** FATAL ERROR STARTING UP PLEXUS-STRUTS INTEGRATION **********\n" + diff --git a/plugins/plexus/src/main/resources/struts-plugin.xml b/plugins/plexus/src/main/resources/struts-plugin.xml new file mode 100644 index 000000000..dc55670a1 --- /dev/null +++ b/plugins/plexus/src/main/resources/struts-plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/StrutsConfigRetriever.java b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/StrutsConfigRetriever.java index 4700f7119..b0794ed18 100644 --- a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/StrutsConfigRetriever.java +++ b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/StrutsConfigRetriever.java @@ -12,6 +12,8 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.struts2.config.BeanSelectionProvider; +import org.apache.struts2.config.LegacyPropertiesConfigurationProvider; import org.apache.struts2.config.StrutsXmlConfigurationProvider; import org.apache.struts2.sitegraph.entities.FreeMarkerView; import org.apache.struts2.sitegraph.entities.JspView; @@ -50,9 +52,12 @@ public class StrutsConfigRetriever { String configFilePath = configDir + "/struts.xml"; File configFile = new File(configFilePath); try { - ConfigurationProvider configProvider = new StrutsXmlConfigurationProvider(configFile.getCanonicalPath(), true); + ConfigurationProvider configProvider = new StrutsXmlConfigurationProvider(configFile.getCanonicalPath(), true, null); cm = new ConfigurationManager(); + cm.addConfigurationProvider(new StrutsXmlConfigurationProvider("struts-default.xml", false, null)); cm.addConfigurationProvider(configProvider); + cm.addConfigurationProvider(new LegacyPropertiesConfigurationProvider()); + cm.addConfigurationProvider(new BeanSelectionProvider()); isXWorkStarted = true; } catch (IOException e) { LOG.error("IOException", e); diff --git a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FileBasedView.java b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FileBasedView.java index 743cc9917..c344a45eb 100644 --- a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FileBasedView.java +++ b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FileBasedView.java @@ -33,7 +33,6 @@ import java.util.regex.Pattern; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.sitegraph.model.Link; /** @@ -70,7 +69,9 @@ public abstract class FileBasedView implements View { } protected Pattern getLinkPattern() { - Object ext = Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); + // FIXME: work with new configuration style + //Object ext = Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION); + String ext = "action"; String actionRegex = "([A-Za-z0-9\\._\\-\\!]+\\." + ext + ")"; return Pattern.compile(actionRegex); } diff --git a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/renderers/DOTRenderer.java b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/renderers/DOTRenderer.java index 7ac69fa62..4d38e139f 100644 --- a/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/renderers/DOTRenderer.java +++ b/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/renderers/DOTRenderer.java @@ -31,7 +31,6 @@ import java.util.Set; import java.util.TreeMap; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.sitegraph.StrutsConfigRetriever; import org.apache.struts2.sitegraph.entities.Target; import org.apache.struts2.sitegraph.entities.View; @@ -106,7 +105,8 @@ public class DOTRenderer { } String location = getViewLocation((String) resultConfig.getParams().get("location"), namespace); - if (location.endsWith((String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION))) { + // FIXME: work with new configuration style + if (location.endsWith("action")) { addTempLink(action, location, Link.TYPE_RESULT, resultConfig.getName()); } else { ViewNode view = new ViewNode(stripLocation(location)); @@ -126,7 +126,8 @@ public class DOTRenderer { } else if (resultClassName.indexOf("Redirect") != -1) { // check if the redirect is to an action -- if so, link it String location = getViewLocation((String) resultConfig.getParams().get("location"), namespace); - if (location.endsWith((String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION))) { + // FIXME: work with new configuration style + if (location.endsWith("action")) { addTempLink(action, location, Link.TYPE_REDIRECT, resultConfig.getName()); } else { ViewNode view = new ViewNode(stripLocation(location)); @@ -161,8 +162,10 @@ public class DOTRenderer { for (Iterator iterator = links.iterator(); iterator.hasNext();) { TempLink temp = (TempLink) iterator.next(); String location = temp.location; - if (location.endsWith((String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION))) { - location = location.substring(0, location.indexOf((String) Settings.get(StrutsConstants.STRUTS_ACTION_EXTENSION)) - 1); + + // FIXME: work with new configuration style + if (location.endsWith("action")) { + location = location.substring(0, location.indexOf("action") - 1); if (location.indexOf('!') != -1) { temp.label = temp.label + "\\n(" + location.substring(location.indexOf('!')) + ")"; diff --git a/plugins/sitegraph/src/test/java/org/apache/struts2/sitegraph/SiteGraphTest.java b/plugins/sitegraph/src/test/java/org/apache/struts2/sitegraph/SiteGraphTest.java index e5393c4d0..9a9de8557 100644 --- a/plugins/sitegraph/src/test/java/org/apache/struts2/sitegraph/SiteGraphTest.java +++ b/plugins/sitegraph/src/test/java/org/apache/struts2/sitegraph/SiteGraphTest.java @@ -34,7 +34,6 @@ import com.opensymphony.xwork2.util.ClassLoaderUtil; */ public class SiteGraphTest extends StrutsTestCase { public void testWebFlow() throws Exception { - Dispatcher.getInstance().getConfigurationManager().clearConfigurationProviders(); // use the classloader rather than relying on the // working directory being an assumed value when // running the test: so let's get this class's parent dir diff --git a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreeMarkerPageFilter.java b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreeMarkerPageFilter.java index 66b81e958..5b5196ff3 100644 --- a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreeMarkerPageFilter.java +++ b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreeMarkerPageFilter.java @@ -38,6 +38,7 @@ import com.opensymphony.module.sitemesh.Page; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.LocaleProvider; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.util.profiling.UtilTimerStack; import freemarker.template.Configuration; @@ -106,6 +107,13 @@ import freemarker.template.Template; */ public class FreeMarkerPageFilter extends TemplatePageFilter { private static final Log LOG = LogFactory.getLog(FreeMarkerPageFilter.class); + + private static FreemarkerManager freemarkerManager; + + @Inject + public void setFreemarkerManager(FreemarkerManager mgr) { + freemarkerManager = mgr; + } /** * Applies the decorator, using the relevent contexts @@ -126,14 +134,13 @@ public class FreeMarkerPageFilter extends TemplatePageFilter { try { UtilTimerStack.push(timerKey); - FreemarkerManager fmm = FreemarkerManager.getInstance(); // get the configuration and template - Configuration config = fmm.getConfiguration(servletContext); + Configuration config = freemarkerManager.getConfiguration(servletContext); Template template = config.getTemplate(decorator.getPage(), getLocale(ctx.getActionInvocation(), config)); // WW-1181 // get the main hash - SimpleHash model = fmm.buildTemplateModel(ctx.getValueStack(), null, servletContext, req, res, config.getObjectWrapper()); + SimpleHash model = freemarkerManager.buildTemplateModel(ctx.getValueStack(), null, servletContext, req, res, config.getObjectWrapper()); // populate the hash with the page model.put("page", page); diff --git a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java index cfc98e1c9..8f4ccafc9 100644 --- a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java +++ b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java @@ -30,7 +30,6 @@ import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import org.apache.struts2.StrutsConstants; -import org.apache.struts2.config.Settings; import org.apache.struts2.dispatcher.Dispatcher; import com.opensymphony.module.sitemesh.Decorator; @@ -41,6 +40,7 @@ import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionProxy; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.Result; +import com.opensymphony.xwork2.inject.Inject; import com.opensymphony.xwork2.interceptor.PreResultListener; import com.opensymphony.xwork2.util.OgnlValueStack; @@ -52,6 +52,13 @@ import com.opensymphony.xwork2.util.OgnlValueStack; public abstract class TemplatePageFilter extends PageFilter { private FilterConfig filterConfig; + + private static String customEncoding; + + @Inject(StrutsConstants.STRUTS_I18N_ENCODING) + public static void setCustomEncoding(String enc) { + customEncoding = enc; + } public void init(FilterConfig filterConfig) { super.init(filterConfig); @@ -110,7 +117,7 @@ public abstract class TemplatePageFilter extends PageFilter { * Gets the L18N encoding of the system. The default is UTF-8. */ protected String getEncoding() { - String encoding = (String) Settings.get(StrutsConstants.STRUTS_I18N_ENCODING); + String encoding = customEncoding; if (encoding == null) { encoding = System.getProperty("file.encoding"); } diff --git a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java index 4226ce00b..8cf0ef59d 100644 --- a/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java +++ b/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.struts2.views.freemarker.FreemarkerManager; import org.apache.struts2.views.velocity.VelocityManager; import org.apache.velocity.Template; import org.apache.velocity.context.Context; @@ -38,6 +39,7 @@ import com.opensymphony.module.sitemesh.Decorator; import com.opensymphony.module.sitemesh.HTMLPage; import com.opensymphony.module.sitemesh.Page; import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.inject.Inject; /** @@ -47,6 +49,13 @@ import com.opensymphony.xwork2.ActionContext; public class VelocityPageFilter extends TemplatePageFilter { private static final Log LOG = LogFactory.getLog(VelocityPageFilter.class); + private static VelocityManager velocityManager; + + @Inject + public void setVelocityManager(VelocityManager mgr) { + velocityManager = mgr; + } + /** * Applies the decorator, using the relevent contexts * @@ -62,17 +71,16 @@ public class VelocityPageFilter extends TemplatePageFilter { ServletContext servletContext, ActionContext ctx) throws ServletException, IOException { try { - VelocityManager vm = VelocityManager.getInstance(); // init (if needed) - vm.init(servletContext); + velocityManager.init(servletContext); // get encoding String encoding = getEncoding(); // get the template and context - Template template = vm.getVelocityEngine().getTemplate(decorator.getPage(), encoding); - Context context = vm.createContext(ctx.getValueStack(), req, res); + Template template = velocityManager.getVelocityEngine().getTemplate(decorator.getPage(), encoding); + Context context = velocityManager.createContext(ctx.getValueStack(), req, res); // put the page in the context context.put("page", page); diff --git a/plugins/sitemesh/src/main/resources/struts-plugin.xml b/plugins/sitemesh/src/main/resources/struts-plugin.xml new file mode 100644 index 000000000..bcce06337 --- /dev/null +++ b/plugins/sitemesh/src/main/resources/struts-plugin.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/plugins/struts1/src/test/java/org/apache/struts2/s1/Struts1FactoryTest.java b/plugins/struts1/src/test/java/org/apache/struts2/s1/Struts1FactoryTest.java index e1441b53d..d39831808 100644 --- a/plugins/struts1/src/test/java/org/apache/struts2/s1/Struts1FactoryTest.java +++ b/plugins/struts1/src/test/java/org/apache/struts2/s1/Struts1FactoryTest.java @@ -15,6 +15,7 @@ import org.apache.struts.config.ModuleConfig; import org.apache.struts2.config.StrutsXmlConfigurationProvider; import com.opensymphony.xwork2.ActionSupport; +import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.config.ConfigurationManager; import com.opensymphony.xwork2.config.ConfigurationProvider; @@ -46,7 +47,7 @@ public class Struts1FactoryTest extends TestCase { */ public void setUp() { ConfigurationManager manager = new ConfigurationManager(); - ConfigurationProvider provider = new StrutsXmlConfigurationProvider(PACKAGE_NAME + "/test-struts-factory.xml", true); + StrutsXmlConfigurationProvider provider = new StrutsXmlConfigurationProvider(PACKAGE_NAME + "/test-struts-factory.xml", true, null); manager.addConfigurationProvider(provider); config = manager.getConfiguration(); factory = new Struts1Factory(config); diff --git a/plugins/struts1/src/test/resources/org/apache/struts2/s1/test-struts-factory.xml b/plugins/struts1/src/test/resources/org/apache/struts2/s1/test-struts-factory.xml index 5d1886006..ee38d95d1 100644 --- a/plugins/struts1/src/test/resources/org/apache/struts2/s1/test-struts-factory.xml +++ b/plugins/struts1/src/test/resources/org/apache/struts2/s1/test-struts-factory.xml @@ -6,6 +6,9 @@ + + +