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
This commit is contained in:
Donald J. Brown
2006-11-13 08:30:40 +00:00
parent c78a362b7d
commit 2db660a3bb
110 changed files with 1649 additions and 2118 deletions
@@ -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
@@ -19,6 +19,10 @@
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>org.apache.struts2.showcase.person</param-value>
</init-param>
</filter>
<filter>
@@ -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";
}
@@ -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<String,String> params) {
if (params == null) {
params = new HashMap<String,String>();
}
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);
}
}
@@ -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);
}
@@ -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);
}
@@ -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) {
@@ -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());
}
@@ -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;
@@ -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;
@@ -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);
@@ -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
@@ -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 <code>ftl</code>. */
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.
* <p/>
@@ -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);
}
@@ -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();
@@ -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);
}
}
}
@@ -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
}
}
@@ -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;
@@ -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;
}
});
}
}
@@ -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
@@ -51,7 +51,7 @@ import com.opensymphony.xwork2.ObjectFactory;
* <li>{@link #listImpl()}</li>
* <li>{@link #isSetImpl(String)}</li></ul>
*/
public class Settings {
class Settings {
static Settings settingsImpl;
static Settings defaultImpl;
@@ -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<String,String> dtdMappings = new HashMap<String,String>(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+")");
}
}
@@ -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:-
* <ul>
* <li>
* Dispatcher instance creation through <code>createDispatcher</code> method that acts
* as a hook subclass could override. By default it creates an instance of Dispatcher.
* </li>
* <li>
* <code>postInit(FilterConfig)</code> is a hook subclass may use to add post initialization
* logics in <code>{@link javax.servlet.Filter#init(FilterConfig)}</code>. It is called before
* {@link javax.servlet.Filter#init(FilterConfig)} method ends.
* </li>
* <li>
* A default <code>{@link javax.servlet.Filter#destroy()}</code> that clean up Dispatcher by
* calling <code>dispatcher.cleanup()</code>
* </li>
* <li>
* <code>prepareDispatcherAndWrapRequest(HttpServletRequest, HttpServletResponse)</code> helper method
* that basically called <code>dispatcher.prepare()</code>, wrap the HttpServletRequest and return the
* wrapped version.
* </li>
* <li>
* Various other common helper methods like
* <ul>
* <li>getFilterConfig</li>
* <li>getServletContext</li>
* </ul>
* </li>
* </ul>
*
*
* @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
* <code>javax.servlet.Filter.init(FilterConfig)</code>.
*
* @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 <code>Dispatcher</code>
* (by calling <code>Dispatcher.prepare(HttpServletRequest, HttpServletResponse)</code>)
* following by wrapping and returning the wrapping <code>HttpServletRequest</code> [ through
* <code>dispatcher.wrapRequest(HttpServletRequest, ServletContext)</code> ]
*
* @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;
}
}
@@ -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 {
}
}
@@ -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<Dispatcher> instance = new ThreadLocal<Dispatcher>();
@@ -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<String,String> 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<String> packages = new ArrayList<String>();
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<Throwable> chain = new ArrayList<Throwable>();
@@ -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;
}
}
@@ -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<String,String> params = new HashMap<String,String>();
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 <code>Dispatcher</code>
* (by calling <code>Dispatcher.prepare(HttpServletRequest, HttpServletResponse)</code>)
* following by wrapping and returning the wrapping <code>HttpServletRequest</code> [ through
* <code>dispatcher.wrapRequest(HttpServletRequest, ServletContext)</code> ]
*
* @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());
}
@@ -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;
/**
* <!-- START SNIPPET: description -->
@@ -135,6 +135,7 @@ public class ServletActionRedirectResult extends ServletRedirectResult {
protected String actionName;
protected String namespace;
protected String method;
protected ActionMapper actionMapper;
private Map<String, String> requestParameters = new HashMap<String, String>();
@@ -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<String> 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());
@@ -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))) {
@@ -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");
}
@@ -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;
/**
* <!-- START SNIPPET: javadoc -->
*
* Factory that creates {@link ActionMapper}s. This factory looks up the class name of the {@link ActionMapper} from
* Struts's configuration using the key <b>struts.mapper.class</b>.
*
* <!-- END SNIPPET: javadoc -->
*
*/
public class ActionMapperFactory {
protected static final Log LOG = LogFactory.getLog(ActionMapperFactory.class);
private static final HashMap<String,ActionMapper> classMap = new HashMap<String,ActionMapper>();
/**
* 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);
}
}
}
}
@@ -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<IndividualActionMapperEntry> orderedActionMappers;
protected Container container;
protected List<ActionMapper> actionMappers = new ArrayList<ActionMapper>();
@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<IndividualActionMapperEntry> getOrderedActionMapperEntries() {
if (this.orderedActionMappers == null || FileManager.isReloadingConfigs()) {
List<IndividualActionMapperEntry> actionMapperEntriesContainer = new ArrayList<IndividualActionMapperEntry>();
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<IndividualActionMapperEntry>() {
public int compare(IndividualActionMapperEntry o1, IndividualActionMapperEntry o2) {
return o1.compareTo(o2);
}
});
ObjectFactory objectFactory = ObjectFactory.getObjectFactory();
List<IndividualActionMapperEntry> result = new ArrayList<IndividualActionMapperEntry>();
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.
* <p/>
* The information stored are :-
* <ul>
* <li> order</li>
* <li> propertyValue</li>
* <li> propertyName</li>
* <li> actionMapper</li>
* </ul>
*
* eg. if we have the following entry in struts.properties
* <pre>
* struts.mapper.composite.1=foo.bar.ActionMapper1
* struts.mapper.composite.2=foo.bar.ActionMapper2
* struts.mapper.composite.3=foo.bar.ActionMapper3
* </pre>
*
* <table border="1">
* <tr>
* <td>order</td>
* <td>propertyName</td>
* <td>propertyValue</td>
* <td>actionMapper</td>
* </tr>
* <tr>
* <td>1</td>
* <td>struts.mapper.composite.1</td>
* <td>foo.bar.ActionMapper1</td>
* <td>instance of foo.bar.ActionMapper1</td>
* </tr>
* <tr>
* <td>2</td>
* <td>struts.mapper.composite.2</td>
* <td>foo.bar.ActionMapper2</td>
* <td>instance of foo.bar.ActionMapper2</td>
* </tr>
* <tr>
* <td>3</td>
* <td>struts.mapper.composite.3</td>
* <td>foo.bar.ActionMapper3</td>
* <td>instance of foo.bar.ActionMapper3</td>
* </tr>
* </table>
*
* @version $Date$ $Id$
*/
public class IndividualActionMapperEntry implements Comparable<IndividualActionMapperEntry> {
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;
}
}
}
@@ -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;
/**
* <!-- START SNIPPET: javadoc -->
@@ -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
*
@@ -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<String,List<FileItem>> files = new HashMap<String,List<FileItem>>();
// maps parameter name -> List of param values
private Map<String,List<String>> params = new HashMap<String,List<String>>();
// any errors while processing this request
private List<String> errors = new ArrayList<String>();
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));
}
@@ -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. <p>
*
*/
public abstract class MultiPartRequest {
protected static Log log = LogFactory.getLog(MultiPartRequest.class);
/**
* Returns <tt>true</tt> if the request is multipart form data, <tt>false</tt> otherwise.
*
* @param request the http servlet request.
* @return <tt>true</tt> if the request is multipart form data, <tt>false</tt> 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<String> getFileParameterNames();
public Enumeration<String> 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 <tt>null</tt> 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 <tt>null</tt> 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 <tt>null</tt> 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<String> getParameterNames();
public Enumeration<String> 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();
}
@@ -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());
}
}
/**
@@ -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 {
@@ -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);
}
}
@@ -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;
/**
* <!-- START SNIPPET: description -->
*
@@ -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]);
@@ -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();
@@ -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<String,String> params = new HashMap<String,String>();
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);
@@ -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");
}
@@ -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;
* <code>org.springframework.web.context.ContextLoaderListener</code> defined in <code>web.xml</code>.
*
*/
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");
@@ -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<ServletContext,Listener> listeners = new HashMap<ServletContext,Listener>();
/* (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) {
}
}
}
@@ -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);
}
@@ -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 {
}
@@ -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<ServletContext,Listener> listeners = new HashMap<ServletContext,Listener>();
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) {
}
}
}
@@ -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();
}
@@ -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);
}
}
}
@@ -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
* <b>struts.freemarker.configmanager.classname</b> to the fully qualified classname.
* <p/>
* 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);
@@ -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 {
* </b>
*/
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);
}
/**
@@ -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. </b>
*/
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);
}
@@ -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;
* <!-- END SNIPPET: javadoc -->
*/
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) {
@@ -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;
/**
@@ -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));
@@ -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());
@@ -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());
@@ -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;
@@ -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 &&
@@ -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 = "&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";
}
@@ -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:
* <ul>
* <li>invokes VelocityServlet.loadConfiguration to create a properties object</li>
* <li>alters the RESOURCE_LOADER to include a class loader</li>
* <li>configures the class loader using the StrutsResourceLoader</li>
* </ul>
*
* @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);
}
}
}
@@ -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 <b>all</b> 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;
}
}
}
/**
* <p/>
@@ -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);
@@ -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<String, Templates>();
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)
@@ -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
+17 -1
View File
@@ -11,7 +11,7 @@
"http://struts.apache.org/dtds/struts-2.0.dtd">
-->
<!ELEMENT struts (package|include)*>
<!ELEMENT struts (package|include|bean|constant)*>
<!ELEMENT package (result-types?, interceptors?, default-interceptor-ref?, default-action-ref?, global-results?, global-exception-mappings?, action*)>
<!ATTLIST package
@@ -100,5 +100,21 @@
file CDATA #REQUIRED
>
<!ELEMENT bean (#PCDATA)>
<!ATTLIST bean
type CDATA #IMPLIED
name CDATA #IMPLIED
class CDATA #REQUIRED
scope CDATA #IMPLIED
static CDATA #IMPLIED
optional CDATA #IMPLIED
>
<!ELEMENT constant (#PCDATA)>
<!ATTLIST constant
name CDATA #REQUIRED
value CDATA #REQUIRED
>
<!-- END SNIPPET: strutsDtd -->
@@ -5,6 +5,41 @@
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
<bean type="com.opensymphony.xwork2.ObjectFactory" name="struts" class="org.apache.struts2.impl.StrutsObjectFactory" />
<bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" optional="true"/>
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="xwork" class="com.opensymphony.xwork2.DefaultActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.ActionProxyFactory" name="struts" class="org.apache.struts2.impl.StrutsActionProxyFactory"/>
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="tiger" class="com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="notiger" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
<bean type="com.opensymphony.xwork2.util.ObjectTypeDeterminer" name="struts" class="com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer"/>
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" />
<bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful2" class="org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" />
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="struts" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default"/>
<bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default"/>
<bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="struts" optional="true"/>
<bean class="org.apache.struts2.views.velocity.VelocityManager" name="struts" optional="true" />
<bean class="org.apache.struts2.components.template.TemplateEngineManager" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="ftl" class="org.apache.struts2.components.template.FreemarkerTemplateEngine" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="vm" class="org.apache.struts2.components.template.VelocityTemplateEngine" />
<bean type="org.apache.struts2.components.template.TemplateEngine" name="jsp" class="org.apache.struts2.components.template.JspTemplateEngine" />
<!-- Only have static constant injections -->
<bean class="com.opensymphony.xwork2.util.OgnlValueStack" static="true" />
<bean class="org.apache.struts2.dispatcher.Dispatcher" static="true" />
<bean class="org.apache.struts2.components.Include" static="true" />
<bean class="org.apache.struts2.dispatcher.FilterDispatcher" static="true" />
<bean class="org.apache.struts2.views.util.ContextUtil" static="true" />
<bean class="org.apache.struts2.views.util.UrlHelper" static="true" />
<package name="struts-default">
<result-types>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
@@ -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);
}
}
}
@@ -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() {
@@ -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() {
@@ -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<String,String>());
}
@Override
@@ -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());
}
}
@@ -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<String,String> 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;
}
}
}
@@ -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
@@ -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&param1=value+1&param3=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&param1=value+1&param3=value+3", res.getRedirectedUrl());
@@ -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);
@@ -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<IndividualActionMapperEntry> 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<IndividualActionMapperEntry> result =
compositeActionMapper.getOrderedActionMapperEntries();
assertEquals(result.size(), 3);
IndividualActionMapperEntry e = null;
Iterator<IndividualActionMapperEntry> 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<IndividualActionMapperEntry> result =
compositeActionMapper.getOrderedActionMapperEntries();
assertEquals(result.size(), 3);
IndividualActionMapperEntry e = null;
Iterator<IndividualActionMapperEntry> 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<IndividualActionMapperEntry> result =
compositeActionMapper.getOrderedActionMapperEntries();
assertEquals(result.size(), 2);
IndividualActionMapperEntry e = null;
Iterator<IndividualActionMapperEntry> 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<IndividualActionMapperEntry> result =
compositeActionMapper.getOrderedActionMapperEntries();
assertEquals(result.size(), 2);
IndividualActionMapperEntry e = null;
Iterator<IndividualActionMapperEntry> 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<String, String> _impl = new LinkedHashMap<String, String>();
@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();
}
}
}
@@ -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(), "");
}
@@ -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());
@@ -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);
}
}
}
@@ -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 {
@@ -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);
}
@@ -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() {
@@ -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());
}
@@ -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);
}
}
@@ -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");
}
}
@@ -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 {
@@ -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);
@@ -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();
@@ -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();
@@ -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();
@@ -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();
@@ -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");
@@ -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> T inject(Class<T> implementation) {return null;}
public void removeScopeStrategy() {}
public void setScopeStrategy(Strategy scopeStrategy) {}
public <T> T getInstance(Class<T> type, String name) {return null;}
public <T> T getInstance(Class<T> 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> T inject(Class<T> implementation) {return null;}
public void removeScopeStrategy() {}
public void setScopeStrategy(Strategy scopeStrategy) {}
public <T> T getInstance(Class<T> type, String name) {return null;}
public <T> T getInstance(Class<T> 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 &quot;jspa&quot;.
*/
public void testFormTagWithDifferentActionExtension() throws Exception {
initDispatcher(new HashMap<String,String>(){{
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<String,String>(){{
put("configProviders", TestConfigurationProvider.class.getName());
}});
ActionContext.getContext().setValueStack(stack);
}
}
@@ -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<String,String>(){{
put("configProviders", TestConfigurationProvider.class.getName());
}});
}
}
@@ -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()));
}
}
@@ -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&amp;hello=earth&amp;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&amp;hello=earth&amp;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);
}
}
@@ -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;
}
@@ -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.");
}
}
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<bean type="org.apache.struts2.dispatcher.MultiPartRequest" name="pell" class="org.apache.struts2.dispatcher.PellMultiPartRequest" />
</struts>
@@ -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 <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
*/
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" +
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<bean type="com.opensymphony.xwork.ObjectFactory" name="plexus" class="org.apache.struts2.plexus.PlexusObjectFactory" />
<!-- Make the Plexus object factory the automatic default -->
<constant name="struts.objectFactory" value="plexus" />
</struts>

Some files were not shown because too many files have changed in this diff Show More