SPR-6236: Reintroduce Struts support
This commit is contained in:
parent
e24e768054
commit
7fa9105096
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="org.springframework.web.struts">
|
||||
<property file="${basedir}/../build.properties"/>
|
||||
<import file="${basedir}/../build-spring-framework/package-bundle.xml"/>
|
||||
<import file="${basedir}/../spring-build/standard/default.xml"/>
|
||||
</project>
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml-stylesheet type="text/xsl" href="http://ivyrep.jayasoft.org/ivy-doc.xsl"?>
|
||||
<ivy-module
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://incubator.apache.org/ivy/schemas/ivy.xsd"
|
||||
version="1.3">
|
||||
|
||||
<info organisation="org.springframework" module="${ant.project.name}">
|
||||
<license name="Apache 2.0" url="http://www.apache.org/licenses/LICENSE-2.0"/>
|
||||
</info>
|
||||
|
||||
<configurations>
|
||||
<include file="${spring.build.dir}/common/default-ivy-configurations.xml"/>
|
||||
<conf name="tiles" extends="runtime" description="JARs neeeded to create beans for Tiles"/>
|
||||
</configurations>
|
||||
|
||||
<publications>
|
||||
<artifact name="${ant.project.name}"/>
|
||||
<artifact name="${ant.project.name}-sources" type="src" ext="jar"/>
|
||||
</publications>
|
||||
|
||||
<dependencies>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet" rev="2.5.0" conf="provided->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.beanutils" rev="1.7.0"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.apache.struts" name="com.springsource.org.apache.struts" rev="1.2.9" />
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.web" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.web.servlet" rev="latest.integration"
|
||||
conf="optional, tiles->compile"/>
|
||||
<!--
|
||||
<dependency org="com.sun.syndication" name="com.springsource.com.sun.syndication" rev="1.0.0"
|
||||
conf="optional, feed->compile"/>
|
||||
<dependency org="com.lowagie.text" name="com.springsource.com.lowagie.text" rev="2.0.8"
|
||||
conf="optional, itext->compile"/>
|
||||
<dependency org="org.freemarker" name="com.springsource.freemarker" rev="2.3.15"
|
||||
conf="optional, freemarker->compile"/>
|
||||
<dependency org="javax.el" name="com.springsource.javax.el" rev="1.0.0" conf="provided->compile"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp" rev="2.1.0" conf="provided->compile"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp.jstl" rev="1.1.2"
|
||||
conf="provided->compile"/>
|
||||
<dependency org="net.sourceforge.jexcelapi" name="com.springsource.jxl" rev="2.6.6"
|
||||
conf="optional, jexcelapi->compile"/>
|
||||
<dependency org="net.sourceforge.jasperreports" name="com.springsource.net.sf.jasperreports" rev="2.0.5"
|
||||
conf="optional, jasper-reports->compile"/>
|
||||
<dependency org="org.apache.commons" name="com.springsource.org.apache.commons.logging" rev="1.1.1"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.apache.poi" name="com.springsource.org.apache.poi" rev="3.0.2.FINAL"
|
||||
conf="optional, poi->compile"/>
|
||||
<dependency org="org.apache.tiles" name="com.springsource.org.apache.tiles" rev="2.1.2.osgi"
|
||||
conf="optional, tiles->compile"/>
|
||||
<dependency org="org.apache.tiles" name="com.springsource.org.apache.tiles.core" rev="2.1.2.osgi"
|
||||
conf="optional, tiles->compile"/>
|
||||
<dependency org="org.apache.tiles" name="com.springsource.org.apache.tiles.jsp" rev="2.1.2"
|
||||
conf="optional, tiles->compile"/>
|
||||
<dependency org="org.apache.tiles" name="com.springsource.org.apache.tiles.servlet" rev="2.1.2"
|
||||
conf="optional, tiles->compile"/>
|
||||
<dependency org="org.apache.velocity" name="com.springsource.org.apache.velocity" rev="1.5.0"
|
||||
conf="optional, velocity->compile"/>
|
||||
<dependency org="org.apache.velocity" name="com.springsource.org.apache.velocity.tools.view" rev="1.4.0"
|
||||
conf="optional, velocity->compile"/>
|
||||
<dependency org="org.codehaus.jackson" name="com.springsource.org.codehaus.jackson.mapper" rev="1.0.0"
|
||||
conf="optional, jackson->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.beans" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.context.support" rev="latest.integration"
|
||||
conf="optional, velocity, freemarker, jasper-reports->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.core" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.oxm" rev="latest.integration"
|
||||
conf="optional, oxm->compile"/>
|
||||
-->
|
||||
<!-- test dependencies -->
|
||||
<dependency org="org.junit" name="com.springsource.org.junit" rev="4.7.0" conf="test->runtime"/>
|
||||
<dependency org="org.easymock" name="com.springsource.org.easymock" rev="2.5.1" conf="test->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.test" rev="latest.integration"
|
||||
conf="test->compile"/>
|
||||
<dependency org="javax.servlet" name="com.springsource.javax.servlet.jsp.jstl" rev="1.1.2"
|
||||
conf="test->compile"/>
|
||||
</dependencies>
|
||||
|
||||
</ivy-module>
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.tiles.ComponentContext;
|
||||
import org.apache.struts.tiles.ControllerSupport;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware Tiles component controllers.
|
||||
* Provides a reference to the current Spring application context,
|
||||
* e.g. for bean lookup or resource loading.
|
||||
*
|
||||
* <p>Derives from the Tiles {@link ControllerSupport} class rather than
|
||||
* implementing the Tiles {@link org.apache.struts.tiles.Controller} interface
|
||||
* in order to be compatible with Struts 1.1 and 1.2. Implements both Struts 1.1's
|
||||
* <code>perform</code> and Struts 1.2's <code>execute</code> method accordingly.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Alef Arendsen
|
||||
* @since 22.08.2003
|
||||
* @see org.springframework.web.context.support.WebApplicationObjectSupport
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ComponentControllerSupport extends ControllerSupport {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
|
||||
/**
|
||||
* This implementation delegates to <code>execute</code>,
|
||||
* converting non-Servlet/IO Exceptions to ServletException.
|
||||
* <p>This is the only execution method available in Struts 1.1.
|
||||
* @see #execute
|
||||
*/
|
||||
@Override
|
||||
public final void perform(
|
||||
ComponentContext componentContext, HttpServletRequest request,
|
||||
HttpServletResponse response, ServletContext servletContext)
|
||||
throws ServletException, IOException {
|
||||
|
||||
try {
|
||||
execute(componentContext, request, response, servletContext);
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new NestedServletException("Execution of component controller failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation delegates to <code>doPerform</code>,
|
||||
* lazy-initializing the application context reference if necessary.
|
||||
* <p>This is the preferred execution method in Struts 1.2.
|
||||
* When running with Struts 1.1, it will be called by <code>perform</code>.
|
||||
* @see #perform
|
||||
* @see #doPerform
|
||||
*/
|
||||
@Override
|
||||
public final void execute(
|
||||
ComponentContext componentContext, HttpServletRequest request,
|
||||
HttpServletResponse response, ServletContext servletContext)
|
||||
throws Exception {
|
||||
|
||||
synchronized (this) {
|
||||
if (this.webApplicationContext == null) {
|
||||
this.webApplicationContext = RequestContextUtils.getWebApplicationContext(request, servletContext);
|
||||
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
|
||||
}
|
||||
}
|
||||
doPerform(componentContext, request, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subclasses can override this for custom initialization behavior.
|
||||
* Gets called on initialization of the context for this controller.
|
||||
* @throws org.springframework.context.ApplicationContextException in case of initialization errors
|
||||
* @throws org.springframework.beans.BeansException if thrown by application context methods
|
||||
*/
|
||||
protected void initApplicationContext() throws BeansException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current Spring ApplicationContext.
|
||||
*/
|
||||
protected final ApplicationContext getApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MessageSourceAccessor for the application context
|
||||
* used by this object, for easy message access.
|
||||
*/
|
||||
protected final MessageSourceAccessor getMessageSourceAccessor() {
|
||||
return this.messageSourceAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ServletContext.
|
||||
*/
|
||||
protected final ServletContext getServletContext() {
|
||||
return this.webApplicationContext.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temporary directory for the current web application,
|
||||
* as provided by the servlet container.
|
||||
* @return the File representing the temporary directory
|
||||
*/
|
||||
protected final File getTempDir() {
|
||||
return WebUtils.getTempDir(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform the preparation for the component, allowing for any Exception to be thrown.
|
||||
* The ServletContext can be retrieved via getServletContext, if necessary.
|
||||
* The Spring WebApplicationContext can be accessed via getWebApplicationContext.
|
||||
* <p>This method will be called both in the Struts 1.1 and Struts 1.2 case,
|
||||
* by <code>perform</code> or <code>execute</code>, respectively.
|
||||
* @param componentContext current Tiles component context
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @throws Exception in case of errors
|
||||
* @see org.apache.struts.tiles.Controller#perform
|
||||
* @see #getServletContext
|
||||
* @see #getWebApplicationContext
|
||||
* @see #perform
|
||||
* @see #execute
|
||||
*/
|
||||
protected abstract void doPerform(
|
||||
ComponentContext componentContext, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import org.apache.struts.tiles.DefinitionsFactory;
|
||||
import org.apache.struts.tiles.DefinitionsFactoryConfig;
|
||||
import org.apache.struts.tiles.DefinitionsFactoryException;
|
||||
import org.apache.struts.tiles.TilesUtil;
|
||||
import org.apache.struts.tiles.xmlDefinition.I18nFactorySet;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||
|
||||
/**
|
||||
* Helper class to configure Tiles 1.x for the Spring Framework. See
|
||||
* <a href="http://struts.apache.org">http://struts.apache.org</a>
|
||||
* for more information about Struts Tiles, which basically is a templating
|
||||
* mechanism for JSP-based web applications.
|
||||
*
|
||||
* <p><b>NOTE:</b> This TilesConfigurer class supports Tiles 1.x,
|
||||
* a.k.a. "Struts Tiles", which comes as part of Struts 1.x.
|
||||
* For Tiles 2.x support, check out
|
||||
* {@link org.springframework.web.servlet.view.tiles2.TilesConfigurer}.
|
||||
*
|
||||
* <p>The TilesConfigurer simply configures a Tiles DefinitionsFactory using
|
||||
* a set of files containing definitions, to be accessed by {@link TilesView}
|
||||
* instances.
|
||||
*
|
||||
* <p>TilesViews can be managed by any {@link org.springframework.web.servlet.ViewResolver}.
|
||||
* For simple convention-based view resolution, consider using
|
||||
* {@link org.springframework.web.servlet.view.UrlBasedViewResolver} with the
|
||||
* "viewClass" property set to "org.springframework.web.servlet.view.tiles.TilesView".
|
||||
*
|
||||
* <p>A typical TilesConfigurer bean definition looks as follows:
|
||||
*
|
||||
* <pre>
|
||||
* <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles.TilesConfigurer">
|
||||
* <property name="definitions">
|
||||
* <list>
|
||||
* <value>/WEB-INF/defs/general.xml</value>
|
||||
* <value>/WEB-INF/defs/widgets.xml</value>
|
||||
* <value>/WEB-INF/defs/administrator.xml</value>
|
||||
* <value>/WEB-INF/defs/customer.xml</value>
|
||||
* <value>/WEB-INF/defs/templates.xml</value>
|
||||
* </list>
|
||||
* </property>
|
||||
* </bean></pre>
|
||||
*
|
||||
* The values in the list are the actual files containing the definitions.
|
||||
*
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
* @see TilesView
|
||||
* @see org.springframework.web.servlet.view.UrlBasedViewResolver
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class TilesConfigurer extends WebApplicationObjectSupport implements InitializingBean {
|
||||
|
||||
/** Definition URLs mapped to descriptions */
|
||||
private String[] definitions;
|
||||
|
||||
/** Validate the Tiles definitions? */
|
||||
private boolean validateDefinitions = true;
|
||||
|
||||
/** Factory class for Tiles */
|
||||
private Class factoryClass = I18nFactorySet.class;
|
||||
|
||||
|
||||
/**
|
||||
* Set the Tiles definitions, i.e. the list of files containing the definitions.
|
||||
*/
|
||||
public void setDefinitions(String[] definitions) {
|
||||
this.definitions = definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to validate the Tiles XML definitions. Default is "true".
|
||||
*/
|
||||
public void setValidateDefinitions(boolean validateDefinitions) {
|
||||
this.validateDefinitions = validateDefinitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the factory class for Tiles. Default is I18nFactorySet.
|
||||
* @see org.apache.struts.tiles.xmlDefinition.I18nFactorySet
|
||||
*/
|
||||
public void setFactoryClass(Class factoryClass) {
|
||||
this.factoryClass = factoryClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the Tiles definition factory.
|
||||
* Delegates to createDefinitionsFactory for the actual creation.
|
||||
* @throws DefinitionsFactoryException if an error occurs
|
||||
* @see #createDefinitionsFactory
|
||||
*/
|
||||
public void afterPropertiesSet() throws DefinitionsFactoryException {
|
||||
logger.debug("TilesConfigurer: initializion started");
|
||||
|
||||
// initialize the configuration for the definitions factory
|
||||
DefinitionsFactoryConfig factoryConfig = new DefinitionsFactoryConfig();
|
||||
factoryConfig.setFactoryName("");
|
||||
factoryConfig.setFactoryClassname(this.factoryClass.getName());
|
||||
factoryConfig.setParserValidate(this.validateDefinitions);
|
||||
|
||||
if (this.definitions != null) {
|
||||
String defs = StringUtils.arrayToCommaDelimitedString(this.definitions);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("TilesConfigurer: adding definitions [" + defs + "]");
|
||||
}
|
||||
factoryConfig.setDefinitionConfigFiles(defs);
|
||||
}
|
||||
|
||||
// initialize the definitions factory
|
||||
createDefinitionsFactory(factoryConfig);
|
||||
|
||||
logger.debug("TilesConfigurer: initialization completed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Tiles DefinitionsFactory and expose it to the ServletContext.
|
||||
* @param factoryConfig the configuration for the DefinitionsFactory
|
||||
* @return the DefinitionsFactory
|
||||
* @throws DefinitionsFactoryException if an error occurs
|
||||
*/
|
||||
protected DefinitionsFactory createDefinitionsFactory(DefinitionsFactoryConfig factoryConfig)
|
||||
throws DefinitionsFactoryException {
|
||||
|
||||
return TilesUtil.createDefinitionsFactory(getServletContext(), factoryConfig);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.servlet.support.JstlUtils;
|
||||
import org.springframework.web.servlet.support.RequestContext;
|
||||
|
||||
/**
|
||||
* Specialization of {@link TilesView} for JSTL pages,
|
||||
* i.e. Tiles pages that use the JSP Standard Tag Library.
|
||||
*
|
||||
* <p><b>NOTE:</b> This TilesJstlView class supports Tiles 1.x,
|
||||
* a.k.a. "Struts Tiles", which comes as part of Struts 1.x.
|
||||
* For Tiles 2.x support, check out
|
||||
* {@link org.springframework.web.servlet.view.tiles2.TilesView}.
|
||||
*
|
||||
* <p>Exposes JSTL-specific request attributes specifying locale
|
||||
* and resource bundle for JSTL's formatting and message tags,
|
||||
* using Spring's locale and message source.
|
||||
*
|
||||
* <p>This is a separate class mainly to avoid JSTL dependencies
|
||||
* in TilesView itself.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 20.08.2003
|
||||
* @see org.springframework.web.servlet.support.JstlUtils#exposeLocalizationContext
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class TilesJstlView extends TilesView {
|
||||
|
||||
@Override
|
||||
protected void exposeHelpers(HttpServletRequest request) throws Exception {
|
||||
JstlUtils.exposeLocalizationContext(new RequestContext(request, getServletContext()));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.tiles.ComponentContext;
|
||||
import org.apache.struts.tiles.ComponentDefinition;
|
||||
import org.apache.struts.tiles.Controller;
|
||||
import org.apache.struts.tiles.DefinitionsFactory;
|
||||
import org.apache.struts.tiles.TilesUtilImpl;
|
||||
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.web.servlet.view.InternalResourceView;
|
||||
|
||||
/**
|
||||
* View implementation that retrieves a Tiles definition.
|
||||
* The "url" property is interpreted as name of a Tiles definition.
|
||||
*
|
||||
* <p>{@link TilesJstlView} with JSTL support is a separate class,
|
||||
* mainly to avoid JSTL dependencies in this class.
|
||||
*
|
||||
* <p><b>NOTE:</b> This TilesView class supports Tiles 1.x,
|
||||
* a.k.a. "Struts Tiles", which comes as part of Struts 1.x.
|
||||
* For Tiles 2.x support, check out
|
||||
* {@link org.springframework.web.servlet.view.tiles2.TilesView}.
|
||||
*
|
||||
* <p>Depends on a Tiles DefinitionsFactory which must be available
|
||||
* in the ServletContext. This factory is typically set up via a
|
||||
* {@link TilesConfigurer} bean definition in the application context.
|
||||
*
|
||||
* <p>Check out {@link ComponentControllerSupport} which provides
|
||||
* a convenient base class for Spring-aware component controllers,
|
||||
* allowing convenient access to the Spring ApplicationContext.
|
||||
*
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
* @see #setUrl
|
||||
* @see TilesJstlView
|
||||
* @see TilesConfigurer
|
||||
* @see ComponentControllerSupport
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class TilesView extends InternalResourceView {
|
||||
|
||||
/**
|
||||
* Name of the attribute that will override the path of the layout page
|
||||
* to render. A Tiles component controller can set such an attribute
|
||||
* to dynamically switch the look and feel of a Tiles page.
|
||||
* @see #setPath
|
||||
*/
|
||||
public static final String PATH_ATTRIBUTE = TilesView.class.getName() + ".PATH";
|
||||
|
||||
/**
|
||||
* Set the path of the layout page to render.
|
||||
* @param request current HTTP request
|
||||
* @param path the path of the layout page
|
||||
* @see #PATH_ATTRIBUTE
|
||||
*/
|
||||
public static void setPath(HttpServletRequest request, String path) {
|
||||
request.setAttribute(PATH_ATTRIBUTE, path);
|
||||
}
|
||||
|
||||
|
||||
private DefinitionsFactory definitionsFactory;
|
||||
|
||||
|
||||
@Override
|
||||
protected void initApplicationContext() throws ApplicationContextException {
|
||||
super.initApplicationContext();
|
||||
|
||||
// get definitions factory
|
||||
this.definitionsFactory =
|
||||
(DefinitionsFactory) getServletContext().getAttribute(TilesUtilImpl.DEFINITIONS_FACTORY);
|
||||
if (this.definitionsFactory == null) {
|
||||
throw new ApplicationContextException("Tiles definitions factory not found: TilesConfigurer not defined?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare for rendering the Tiles definition: Execute the associated
|
||||
* component controller if any, and determine the request dispatcher path.
|
||||
*/
|
||||
@Override
|
||||
protected String prepareForRendering(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
// get component definition
|
||||
ComponentDefinition definition = getComponentDefinition(this.definitionsFactory, request);
|
||||
if (definition == null) {
|
||||
throw new ServletException("No Tiles definition found for name '" + getUrl() + "'");
|
||||
}
|
||||
|
||||
// get current component context
|
||||
ComponentContext context = getComponentContext(definition, request);
|
||||
|
||||
// execute component controller associated with definition, if any
|
||||
Controller controller = getController(definition, request);
|
||||
if (controller != null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Executing Tiles controller [" + controller + "]");
|
||||
}
|
||||
executeController(controller, context, request, response);
|
||||
}
|
||||
|
||||
// determine the path of the definition
|
||||
String path = getDispatcherPath(definition, request);
|
||||
if (path == null) {
|
||||
throw new ServletException(
|
||||
"Could not determine a path for Tiles definition '" + definition.getName() + "'");
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the Tiles component definition for the given Tiles
|
||||
* definitions factory.
|
||||
* @param factory the Tiles definitions factory
|
||||
* @param request current HTTP request
|
||||
* @return the component definition
|
||||
*/
|
||||
protected ComponentDefinition getComponentDefinition(DefinitionsFactory factory, HttpServletRequest request)
|
||||
throws Exception {
|
||||
return factory.getDefinition(getUrl(), request, getServletContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the Tiles component context for the given Tiles definition.
|
||||
* @param definition the Tiles definition to render
|
||||
* @param request current HTTP request
|
||||
* @return the component context
|
||||
* @throws Exception if preparations failed
|
||||
*/
|
||||
protected ComponentContext getComponentContext(ComponentDefinition definition, HttpServletRequest request)
|
||||
throws Exception {
|
||||
ComponentContext context = ComponentContext.getContext(request);
|
||||
if (context == null) {
|
||||
context = new ComponentContext(definition.getAttributes());
|
||||
ComponentContext.setContext(context, request);
|
||||
}
|
||||
else {
|
||||
context.addMissing(definition.getAttributes());
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine and initialize the Tiles component controller for the
|
||||
* given Tiles definition, if any.
|
||||
* @param definition the Tiles definition to render
|
||||
* @param request current HTTP request
|
||||
* @return the component controller to execute, or <code>null</code> if none
|
||||
* @throws Exception if preparations failed
|
||||
*/
|
||||
protected Controller getController(ComponentDefinition definition, HttpServletRequest request)
|
||||
throws Exception {
|
||||
|
||||
return definition.getOrCreateController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given Tiles controller.
|
||||
* @param controller the component controller to execute
|
||||
* @param context the component context
|
||||
* @param request current HTTP request
|
||||
* @param response current HTTP response
|
||||
* @throws Exception if controller execution failed
|
||||
*/
|
||||
protected void executeController(
|
||||
Controller controller, ComponentContext context, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
controller.perform(context, request, response, getServletContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the dispatcher path for the given Tiles definition,
|
||||
* i.e. the request dispatcher path of the layout page.
|
||||
* @param definition the Tiles definition to render
|
||||
* @param request current HTTP request
|
||||
* @return the path of the layout page to render
|
||||
* @throws Exception if preparations failed
|
||||
*/
|
||||
protected String getDispatcherPath(ComponentDefinition definition, HttpServletRequest request)
|
||||
throws Exception {
|
||||
|
||||
Object pathAttr = request.getAttribute(PATH_ATTRIBUTE);
|
||||
return (pathAttr != null ? pathAttr.toString() : definition.getPath());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
Support classes for the integration of
|
||||
<a href="http://www.lifl.fr/~dumoulin/tiles">Tiles</a>
|
||||
(included in Struts) as Spring web view technology.
|
||||
Contains a View implementation for Tiles definitions.
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
|
||||
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
|
||||
* implementation that passes the ActionServlet to beans that extend
|
||||
* the Struts {@link org.apache.struts.action.Action} class.
|
||||
* Invokes <code>Action.setServlet</code> with <code>null</dode> on
|
||||
* bean destruction, providing the same lifecycle handling as the
|
||||
* native Struts ActionServlet.
|
||||
*
|
||||
* <p>ContextLoaderPlugIn automatically registers this processor
|
||||
* with the underlying bean factory of its WebApplicationContext.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.1
|
||||
* @see ContextLoaderPlugIn
|
||||
* @see org.apache.struts.action.Action#setServlet
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
class ActionServletAwareProcessor implements DestructionAwareBeanPostProcessor {
|
||||
|
||||
private final ActionServlet actionServlet;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ActionServletAwareProcessor for the given servlet.
|
||||
*/
|
||||
public ActionServletAwareProcessor(ActionServlet actionServlet) {
|
||||
this.actionServlet = actionServlet;
|
||||
}
|
||||
|
||||
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof Action) {
|
||||
((Action) bean).setServlet(this.actionServlet);
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
public void postProcessBeforeDestruction(Object bean, String beanName) {
|
||||
if (bean instanceof Action) {
|
||||
((Action) bean).setServlet(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware Struts 1.1+ Actions.
|
||||
*
|
||||
* <p>Provides a reference to the current Spring application context, e.g.
|
||||
* for bean lookup or resource loading. Auto-detects a ContextLoaderPlugIn
|
||||
* context, falling back to the root WebApplicationContext. For typical
|
||||
* usage, i.e. accessing middle tier beans, use a root WebApplicationContext.
|
||||
*
|
||||
* <p>For Struts DispatchActions or Lookup/MappingDispatchActions, use the
|
||||
* analogous {@link DispatchActionSupport DispatchActionSupport} or
|
||||
* {@link LookupDispatchActionSupport LookupDispatchActionSupport} /
|
||||
* {@link MappingDispatchActionSupport MappingDispatchActionSupport} class,
|
||||
* respectively.
|
||||
*
|
||||
* <p>As an alternative approach, you can wire your Struts Actions themselves
|
||||
* as Spring beans, passing references to them via IoC rather than looking
|
||||
* up references in a programmatic fashion. Check out
|
||||
* {@link DelegatingActionProxy DelegatingActionProxy} and
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.1
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
* @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see org.springframework.web.context.ContextLoaderServlet
|
||||
* @see DispatchActionSupport
|
||||
* @see LookupDispatchActionSupport
|
||||
* @see MappingDispatchActionSupport
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class ActionSupport extends Action {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the WebApplicationContext for this Action.
|
||||
* Invokes onInit after successful initialization of the context.
|
||||
* @see #initWebApplicationContext
|
||||
* @see #onInit
|
||||
*/
|
||||
@Override
|
||||
public void setServlet(ActionServlet actionServlet) {
|
||||
super.setServlet(actionServlet);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet);
|
||||
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
|
||||
onInit();
|
||||
}
|
||||
else {
|
||||
onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext (the usual case).
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet)
|
||||
throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MessageSourceAccessor for the application context
|
||||
* used by this object, for easy message access.
|
||||
*/
|
||||
protected final MessageSourceAccessor getMessageSourceAccessor() {
|
||||
return this.messageSourceAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ServletContext.
|
||||
*/
|
||||
protected final ServletContext getServletContext() {
|
||||
return this.webApplicationContext.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temporary directory for the current web application,
|
||||
* as provided by the servlet container.
|
||||
* @return the File representing the temporary directory
|
||||
*/
|
||||
protected final File getTempDir() {
|
||||
return WebUtils.getTempDir(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for custom initialization after the context has been set up.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for custom destruction when the ActionServlet shuts down.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onDestroy() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.action.RequestProcessor;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Subclass of Struts's default RequestProcessor that autowires Struts Actions
|
||||
* with Spring beans defined in ContextLoaderPlugIn's WebApplicationContext
|
||||
* or - in case of general service layer beans - in the root WebApplicationContext.
|
||||
*
|
||||
* <p>In the Struts config file, you simply continue to specify the original
|
||||
* Action class. The instance created for that class will automatically get
|
||||
* wired with matching service layer beans, that is, bean property setters
|
||||
* will automatically be called if a service layer bean matches the property.
|
||||
*
|
||||
* <pre>
|
||||
* <action path="/login" type="myapp.MyAction"/></pre>
|
||||
*
|
||||
* There are two autowire modes available: "byType" and "byName". The default
|
||||
* is "byType", matching service layer beans with the Action's bean property
|
||||
* argument types. This behavior can be changed through specifying an "autowire"
|
||||
* init-param for the Struts ActionServlet with the value "byName", which will
|
||||
* match service layer bean names with the Action's bean property <i>names</i>.
|
||||
*
|
||||
* <p>Dependency checking is turned off by default: If no matching service
|
||||
* layer bean can be found, the setter in question will simply not get invoked.
|
||||
* To enforce matching service layer beans, consider specify the "dependencyCheck"
|
||||
* init-param for the Struts ActionServlet with the value "true".
|
||||
*
|
||||
* <p>If you also need the Tiles setup functionality of the original
|
||||
* TilesRequestProcessor, use AutowiringTilesRequestProcessor. As there's just
|
||||
* a single central class to customize in Struts, we have to provide another
|
||||
* subclass here, covering both the Tiles and the Spring delegation aspect.
|
||||
*
|
||||
* <p>The default implementation delegates to the DelegatingActionUtils
|
||||
* class as fas as possible, to reuse as much code as possible despite
|
||||
* the need to provide two RequestProcessor subclasses. If you need to
|
||||
* subclass yet another RequestProcessor, take this class as a template,
|
||||
* delegating to DelegatingActionUtils just like it.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @see AutowiringTilesRequestProcessor
|
||||
* @see ContextLoaderPlugIn
|
||||
* @see DelegatingActionUtils
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class AutowiringRequestProcessor extends RequestProcessor {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_NO;
|
||||
|
||||
private boolean dependencyCheck = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
|
||||
super.init(actionServlet, moduleConfig);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
|
||||
this.autowireMode = initAutowireMode(actionServlet, moduleConfig);
|
||||
this.dependencyCheck = initDependencyCheck(actionServlet, moduleConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext. This context is supposed
|
||||
* to contain the service layer beans to wire the Struts Actions with.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
WebApplicationContext wac =
|
||||
DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
|
||||
if (wac instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) wac).getBeanFactory().ignoreDependencyType(ActionServlet.class);
|
||||
}
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the autowire mode to use for wiring Struts Actions.
|
||||
* <p>The default implementation checks the "autowire" init-param of the
|
||||
* Struts ActionServlet, falling back to "AUTOWIRE_BY_TYPE" as default.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return the autowire mode to use
|
||||
* @see DelegatingActionUtils#getAutowireMode
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
|
||||
*/
|
||||
protected int initAutowireMode(ActionServlet actionServlet, ModuleConfig moduleConfig) {
|
||||
return DelegatingActionUtils.getAutowireMode(actionServlet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to apply a dependency check after wiring Struts Actions.
|
||||
* <p>The default implementation checks the "dependencyCheck" init-param of the
|
||||
* Struts ActionServlet, falling back to no dependency check as default.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return whether to enforce a dependency check or not
|
||||
* @see DelegatingActionUtils#getDependencyCheck
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
*/
|
||||
protected boolean initDependencyCheck(ActionServlet actionServlet, ModuleConfig moduleConfig) {
|
||||
return DelegatingActionUtils.getDependencyCheck(actionServlet);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the autowire mode to use for wiring Struts Actions.
|
||||
*/
|
||||
protected final int getAutowireMode() {
|
||||
return autowireMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to apply a dependency check after wiring Struts Actions.
|
||||
*/
|
||||
protected final boolean getDependencyCheck() {
|
||||
return dependencyCheck;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend the base class method to autowire each created Action instance.
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
*/
|
||||
@Override
|
||||
protected Action processActionCreate(
|
||||
HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
|
||||
throws IOException {
|
||||
|
||||
Action action = super.processActionCreate(request, response, mapping);
|
||||
getWebApplicationContext().getAutowireCapableBeanFactory().autowireBeanProperties(
|
||||
action, getAutowireMode(), getDependencyCheck());
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
import org.apache.struts.tiles.TilesRequestProcessor;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Subclass of Struts's TilesRequestProcessor that autowires Struts Actions
|
||||
* with Spring beans defined in ContextLoaderPlugIn's WebApplicationContext
|
||||
* or - in case of general service layer beans - in the root WebApplicationContext.
|
||||
*
|
||||
* <p>Behaves like
|
||||
* {@link AutowiringRequestProcessor AutowiringRequestProcessor},
|
||||
* but also provides the Tiles functionality of the original TilesRequestProcessor.
|
||||
* As there's just a single central class to customize in Struts, we have to provide
|
||||
* another subclass here, covering both the Tiles and the Spring delegation aspect.
|
||||
*
|
||||
* <p>The default implementation delegates to the DelegatingActionUtils
|
||||
* class as fas as possible, to reuse as much code as possible despite
|
||||
* the need to provide two RequestProcessor subclasses. If you need to
|
||||
* subclass yet another RequestProcessor, take this class as a template,
|
||||
* delegating to DelegatingActionUtils just like it.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
* @see AutowiringRequestProcessor
|
||||
* @see ContextLoaderPlugIn
|
||||
* @see DelegatingActionUtils
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class AutowiringTilesRequestProcessor extends TilesRequestProcessor {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_NO;
|
||||
|
||||
private boolean dependencyCheck = false;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
|
||||
super.init(actionServlet, moduleConfig);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
|
||||
this.autowireMode = initAutowireMode(actionServlet, moduleConfig);
|
||||
this.dependencyCheck = initDependencyCheck(actionServlet, moduleConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext. This context is supposed
|
||||
* to contain the service layer beans to wire the Struts Actions with.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
WebApplicationContext wac =
|
||||
DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
|
||||
if (wac instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) wac).getBeanFactory().ignoreDependencyType(ActionServlet.class);
|
||||
}
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the autowire mode to use for wiring Struts Actions.
|
||||
* <p>The default implementation checks the "autowire" init-param of the
|
||||
* Struts ActionServlet, falling back to "AUTOWIRE_BY_TYPE" as default.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return the autowire mode to use
|
||||
* @see DelegatingActionUtils#getAutowireMode
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
|
||||
*/
|
||||
protected int initAutowireMode(ActionServlet actionServlet, ModuleConfig moduleConfig) {
|
||||
return DelegatingActionUtils.getAutowireMode(actionServlet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether to apply a dependency check after wiring Struts Actions.
|
||||
* <p>The default implementation checks the "dependencyCheck" init-param of the
|
||||
* Struts ActionServlet, falling back to no dependency check as default.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return whether to enforce a dependency check or not
|
||||
* @see DelegatingActionUtils#getDependencyCheck
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
*/
|
||||
protected boolean initDependencyCheck(ActionServlet actionServlet, ModuleConfig moduleConfig) {
|
||||
return DelegatingActionUtils.getDependencyCheck(actionServlet);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the autowire mode to use for wiring Struts Actions.
|
||||
*/
|
||||
protected final int getAutowireMode() {
|
||||
return autowireMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to apply a dependency check after wiring Struts Actions.
|
||||
*/
|
||||
protected final boolean getDependencyCheck() {
|
||||
return dependencyCheck;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend the base class method to autowire each created Action instance.
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
*/
|
||||
@Override
|
||||
protected Action processActionCreate(
|
||||
HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
|
||||
throws IOException {
|
||||
|
||||
Action action = super.processActionCreate(request, response, mapping);
|
||||
getWebApplicationContext().getAutowireCapableBeanFactory().autowireBeanProperties(
|
||||
action, getAutowireMode(), getDependencyCheck());
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.action.PlugIn;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.context.support.XmlWebApplicationContext;
|
||||
|
||||
/**
|
||||
* Struts 1.1+ PlugIn that loads a Spring application context for the Struts
|
||||
* ActionServlet. This context will automatically refer to the root
|
||||
* WebApplicationContext (loaded by ContextLoaderListener/Servlet) as parent.
|
||||
*
|
||||
* <p>The default namespace of the WebApplicationContext is the name of the
|
||||
* Struts ActionServlet, suffixed with "-servlet" (e.g. "action-servlet").
|
||||
* The default location of the XmlWebApplicationContext configuration file
|
||||
* is therefore "/WEB-INF/action-servlet.xml".
|
||||
*
|
||||
* <pre>
|
||||
* <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn"/></pre>
|
||||
*
|
||||
* The location of the context configuration files can be customized
|
||||
* through the "contextConfigLocation" setting, analogous to the root
|
||||
* WebApplicationContext and FrameworkServlet contexts.
|
||||
*
|
||||
* <pre>
|
||||
* <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
|
||||
* <set-property property="contextConfigLocation" value="/WEB-INF/action-servlet.xml /WEB-INF/myContext.xml"/>
|
||||
* </plug-in></pre>
|
||||
*
|
||||
* Beans defined in the ContextLoaderPlugIn context can be accessed
|
||||
* from conventional Struts Actions, via fetching the WebApplicationContext
|
||||
* reference from the ServletContext. ActionSupport and DispatchActionSupport
|
||||
* are pre-built convenience classes that provide easy access to the context.
|
||||
*
|
||||
* <p>It is normally preferable to access Spring's root WebApplicationContext
|
||||
* in such scenarios, though: A shared middle tier should be defined there
|
||||
* rather than in a ContextLoaderPlugin context, for access by any web component.
|
||||
* ActionSupport and DispatchActionSupport autodetect the root context too.
|
||||
*
|
||||
* <p>A special usage of this PlugIn is to define Struts Actions themselves
|
||||
* as beans, typically wiring them with middle tier components defined in the
|
||||
* root context. Such Actions will then be delegated to by proxy definitions
|
||||
* in the Struts configuration, using the DelegatingActionProxy class or
|
||||
* the DelegatingRequestProcessor.
|
||||
*
|
||||
* <p>Note that you can use a single ContextLoaderPlugIn for all Struts modules.
|
||||
* That context can in turn be loaded from multiple XML files, for example split
|
||||
* according to Struts modules. Alternatively, define one ContextLoaderPlugIn per
|
||||
* Struts module, specifying appropriate "contextConfigLocation" parameters.
|
||||
*
|
||||
* <p>Note: The idea of delegating to Spring-managed Struts Actions originated in
|
||||
* Don Brown's <a href="http://struts.sourceforge.net/struts-spring">Spring Struts Plugin</a>.
|
||||
* ContextLoaderPlugIn and DelegatingActionProxy constitute a clean-room
|
||||
* implementation of the same idea, essentially superseding the original plugin.
|
||||
* Many thanks to Don Brown and Matt Raible for the original work and for the
|
||||
* agreement to reimplement the idea in Spring proper!
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.1
|
||||
* @see #SERVLET_CONTEXT_PREFIX
|
||||
* @see ActionSupport
|
||||
* @see DispatchActionSupport
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @see DelegatingTilesRequestProcessor
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see org.springframework.web.context.ContextLoaderServlet
|
||||
* @see org.springframework.web.servlet.FrameworkServlet
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class ContextLoaderPlugIn implements PlugIn {
|
||||
|
||||
/**
|
||||
* Suffix for WebApplicationContext namespaces. If a Struts ActionServlet is
|
||||
* given the name "action" in a context, the namespace used by this PlugIn will
|
||||
* resolve to "action-servlet".
|
||||
*/
|
||||
public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
|
||||
|
||||
/**
|
||||
* Default context class for ContextLoaderPlugIn.
|
||||
* @see org.springframework.web.context.support.XmlWebApplicationContext
|
||||
*/
|
||||
public static final Class DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
|
||||
|
||||
/**
|
||||
* Prefix for the ServletContext attribute for the WebApplicationContext.
|
||||
* The completion is the Struts module name.
|
||||
*/
|
||||
public static final String SERVLET_CONTEXT_PREFIX = ContextLoaderPlugIn.class.getName() + ".CONTEXT.";
|
||||
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/** Custom WebApplicationContext class */
|
||||
private Class contextClass = DEFAULT_CONTEXT_CLASS;
|
||||
|
||||
/** Namespace for this servlet */
|
||||
private String namespace;
|
||||
|
||||
/** Explicit context config location */
|
||||
private String contextConfigLocation;
|
||||
|
||||
/** The Struts ActionServlet that this PlugIn is registered with */
|
||||
private ActionServlet actionServlet;
|
||||
|
||||
/** The Struts ModuleConfig that this PlugIn is registered with */
|
||||
private ModuleConfig moduleConfig;
|
||||
|
||||
/** WebApplicationContext for the ActionServlet */
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* Set a custom context class by name. This class must be of type WebApplicationContext,
|
||||
* when using the default ContextLoaderPlugIn implementation, the context class
|
||||
* must also implement ConfigurableWebApplicationContext.
|
||||
* @see #createWebApplicationContext
|
||||
*/
|
||||
public void setContextClassName(String contextClassName) throws ClassNotFoundException {
|
||||
this.contextClass = ClassUtils.forName(contextClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom context class. This class must be of type WebApplicationContext,
|
||||
* when using the default ContextLoaderPlugIn implementation, the context class
|
||||
* must also implement ConfigurableWebApplicationContext.
|
||||
* @see #createWebApplicationContext
|
||||
*/
|
||||
public void setContextClass(Class contextClass) {
|
||||
this.contextClass = contextClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the custom context class.
|
||||
*/
|
||||
public Class getContextClass() {
|
||||
return this.contextClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a custom namespace for the ActionServlet,
|
||||
* to be used for building a default context config location.
|
||||
*/
|
||||
public void setNamespace(String namespace) {
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the namespace for the ActionServlet, falling back to default scheme if
|
||||
* no custom namespace was set: e.g. "test-servlet" for a servlet named "test".
|
||||
*/
|
||||
public String getNamespace() {
|
||||
if (this.namespace != null) {
|
||||
return this.namespace;
|
||||
}
|
||||
if (this.actionServlet != null) {
|
||||
return this.actionServlet.getServletName() + DEFAULT_NAMESPACE_SUFFIX;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the context config location explicitly, instead of relying on the default
|
||||
* location built from the namespace. This location string can consist of
|
||||
* multiple locations separated by any number of commas and spaces.
|
||||
*/
|
||||
public void setContextConfigLocation(String contextConfigLocation) {
|
||||
this.contextConfigLocation = contextConfigLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the explicit context config location, if any.
|
||||
*/
|
||||
public String getContextConfigLocation() {
|
||||
return this.contextConfigLocation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the ActionServlet's WebApplicationContext.
|
||||
*/
|
||||
public final void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
|
||||
long startTime = System.currentTimeMillis();
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("ContextLoaderPlugIn for Struts ActionServlet '" + actionServlet.getServletName() +
|
||||
", module '" + moduleConfig.getPrefix() + "': initialization started");
|
||||
}
|
||||
|
||||
this.actionServlet = actionServlet;
|
||||
this.moduleConfig = moduleConfig;
|
||||
try {
|
||||
this.webApplicationContext = initWebApplicationContext();
|
||||
onInit();
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
logger.error("Context initialization failed", ex);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
if (logger.isInfoEnabled()) {
|
||||
long elapsedTime = System.currentTimeMillis() - startTime;
|
||||
logger.info("ContextLoaderPlugIn for Struts ActionServlet '" + actionServlet.getServletName() +
|
||||
"', module '" + moduleConfig.getPrefix() + "': initialization completed in " + elapsedTime + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Struts ActionServlet that this PlugIn is associated with.
|
||||
*/
|
||||
public final ActionServlet getActionServlet() {
|
||||
return actionServlet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the ActionServlet that this PlugIn is associated with.
|
||||
*/
|
||||
public final String getServletName() {
|
||||
return this.actionServlet.getServletName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ServletContext that this PlugIn is associated with.
|
||||
*/
|
||||
public final ServletContext getServletContext() {
|
||||
return this.actionServlet.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Struts ModuleConfig that this PlugIn is associated with.
|
||||
*/
|
||||
public final ModuleConfig getModuleConfig() {
|
||||
return this.moduleConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix of the ModuleConfig that this PlugIn is associated with.
|
||||
* @see org.apache.struts.config.ModuleConfig#getPrefix
|
||||
*/
|
||||
public final String getModulePrefix() {
|
||||
return this.moduleConfig.getPrefix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and publish the WebApplicationContext for the ActionServlet.
|
||||
* <p>Delegates to {@link #createWebApplicationContext} for actual creation.
|
||||
* <p>Can be overridden in subclasses. Call <code>getActionServlet()</code>
|
||||
* and/or <code>getModuleConfig()</code> to access the Struts configuration
|
||||
* that this PlugIn is associated with.
|
||||
* @throws org.springframework.beans.BeansException if the context couldn't be initialized
|
||||
* @throws IllegalStateException if there is already a context for the Struts ActionServlet
|
||||
* @see #getActionServlet()
|
||||
* @see #getServletName()
|
||||
* @see #getServletContext()
|
||||
* @see #getModuleConfig()
|
||||
* @see #getModulePrefix()
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext() throws BeansException, IllegalStateException {
|
||||
getServletContext().log("Initializing WebApplicationContext for Struts ActionServlet '" +
|
||||
getServletName() + "', module '" + getModulePrefix() + "'");
|
||||
WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
|
||||
|
||||
WebApplicationContext wac = createWebApplicationContext(parent);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Using context class '" + wac.getClass().getName() + "' for servlet '" + getServletName() + "'");
|
||||
}
|
||||
|
||||
// Publish the context as a servlet context attribute.
|
||||
String attrName = getServletContextAttributeName();
|
||||
getServletContext().setAttribute(attrName, wac);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Published WebApplicationContext of Struts ActionServlet '" + getServletName() +
|
||||
"', module '" + getModulePrefix() + "' as ServletContext attribute with name [" + attrName + "]");
|
||||
}
|
||||
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the WebApplicationContext for the ActionServlet, either a default
|
||||
* XmlWebApplicationContext or a custom context class if set.
|
||||
* <p>This implementation expects custom contexts to implement ConfigurableWebApplicationContext.
|
||||
* Can be overridden in subclasses.
|
||||
* @throws org.springframework.beans.BeansException if the context couldn't be initialized
|
||||
* @see #setContextClass
|
||||
* @see org.springframework.web.context.support.XmlWebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
|
||||
throws BeansException {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("ContextLoaderPlugIn for Struts ActionServlet '" + getServletName() +
|
||||
"', module '" + getModulePrefix() + "' will try to create custom WebApplicationContext " +
|
||||
"context of class '" + getContextClass().getName() + "', using parent context [" + parent + "]");
|
||||
}
|
||||
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(getContextClass())) {
|
||||
throw new ApplicationContextException(
|
||||
"Fatal initialization error in ContextLoaderPlugIn for Struts ActionServlet '" + getServletName() +
|
||||
"', module '" + getModulePrefix() + "': custom WebApplicationContext class [" +
|
||||
getContextClass().getName() + "] is not of type ConfigurableWebApplicationContext");
|
||||
}
|
||||
|
||||
ConfigurableWebApplicationContext wac =
|
||||
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
|
||||
wac.setParent(parent);
|
||||
wac.setServletContext(getServletContext());
|
||||
wac.setNamespace(getNamespace());
|
||||
if (getContextConfigLocation() != null) {
|
||||
wac.setConfigLocations(
|
||||
StringUtils.tokenizeToStringArray(
|
||||
getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
|
||||
}
|
||||
wac.addBeanFactoryPostProcessor(
|
||||
new BeanFactoryPostProcessor() {
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
|
||||
beanFactory.addBeanPostProcessor(new ActionServletAwareProcessor(getActionServlet()));
|
||||
beanFactory.ignoreDependencyType(ActionServlet.class);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
wac.refresh();
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ServletContext attribute name for this PlugIn's WebApplicationContext.
|
||||
* <p>The default implementation returns SERVLET_CONTEXT_PREFIX + module prefix.
|
||||
* @see #SERVLET_CONTEXT_PREFIX
|
||||
* @see #getModulePrefix()
|
||||
*/
|
||||
public String getServletContextAttributeName() {
|
||||
return SERVLET_CONTEXT_PREFIX + getModulePrefix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this PlugIn's WebApplicationContext.
|
||||
*/
|
||||
public final WebApplicationContext getWebApplicationContext() {
|
||||
return webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for custom initialization after the context has been set up.
|
||||
* @throws ServletException if initialization failed
|
||||
*/
|
||||
protected void onInit() throws ServletException {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close the WebApplicationContext of the ActionServlet.
|
||||
* @see org.springframework.context.ConfigurableApplicationContext#close()
|
||||
*/
|
||||
public void destroy() {
|
||||
getServletContext().log("Closing WebApplicationContext of Struts ActionServlet '" +
|
||||
getServletName() + "', module '" + getModulePrefix() + "'");
|
||||
if (getWebApplicationContext() instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) getWebApplicationContext()).close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionForm;
|
||||
import org.apache.struts.action.ActionForward;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Proxy for a Spring-managed Struts <code>Action</code> that is defined in
|
||||
* {@link ContextLoaderPlugIn ContextLoaderPlugIn's}
|
||||
* {@link WebApplicationContext}.
|
||||
*
|
||||
* <p>The proxy is defined in the Struts config file, specifying this
|
||||
* class as the action class. This class will delegate to a Struts
|
||||
* <code>Action</code> bean in the <code>ContextLoaderPlugIn</code> context.
|
||||
*
|
||||
* <pre class="code"><action path="/login" type="org.springframework.web.struts.DelegatingActionProxy"/></pre>
|
||||
*
|
||||
* The name of the <code>Action</code> bean in the
|
||||
* <code>WebApplicationContext</code> will be determined from the mapping
|
||||
* path and module prefix. This can be customized by overriding the
|
||||
* <code>determineActionBeanName</code> method.
|
||||
*
|
||||
* <p>Example:
|
||||
* <ul>
|
||||
* <li>mapping path "/login" -> bean name "/login"<br>
|
||||
* <li>mapping path "/login", module prefix "/mymodule" ->
|
||||
* bean name "/mymodule/login"
|
||||
* </ul>
|
||||
*
|
||||
* <p>A corresponding bean definition in the <code>ContextLoaderPlugin</code>
|
||||
* context would look as follows; notice that the <code>Action</code> is now
|
||||
* able to leverage fully Spring's configuration facilities:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean name="/login" class="myapp.MyAction">
|
||||
* <property name="...">...</property>
|
||||
* </bean></pre>
|
||||
*
|
||||
* Note that you can use a single <code>ContextLoaderPlugIn</code> for all
|
||||
* Struts modules. That context can in turn be loaded from multiple XML files,
|
||||
* for example split according to Struts modules. Alternatively, define one
|
||||
* <code>ContextLoaderPlugIn</code> per Struts module, specifying appropriate
|
||||
* "contextConfigLocation" parameters. In both cases, the Spring bean name
|
||||
* has to include the module prefix.
|
||||
*
|
||||
* <p>If you want to avoid having to specify <code>DelegatingActionProxy</code>
|
||||
* as the <code>Action</code> type in your struts-config file (for example to
|
||||
* be able to generate your Struts config file with XDoclet) consider using the
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor}.
|
||||
* The latter's disadvantage is that it might conflict with the need
|
||||
* for a different <code>RequestProcessor</code> subclass.
|
||||
*
|
||||
* <p>The default implementation delegates to the {@link DelegatingActionUtils}
|
||||
* class as much as possible, to reuse as much code as possible with
|
||||
* <code>DelegatingRequestProcessor</code> and
|
||||
* {@link DelegatingTilesRequestProcessor}.
|
||||
*
|
||||
* <p>Note: The idea of delegating to Spring-managed Struts Actions originated in
|
||||
* Don Brown's <a href="http://struts.sourceforge.net/struts-spring">Spring Struts Plugin</a>.
|
||||
* <code>ContextLoaderPlugIn</code> and <code>DelegatingActionProxy</code>
|
||||
* constitute a clean-room implementation of the same idea, essentially
|
||||
* superseding the original plugin. Many thanks to Don Brown and Matt Raible
|
||||
* for the original work and for the agreement to reimplement the idea in
|
||||
* Spring proper!
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.1
|
||||
* @see #determineActionBeanName
|
||||
* @see DelegatingRequestProcessor
|
||||
* @see DelegatingTilesRequestProcessor
|
||||
* @see DelegatingActionUtils
|
||||
* @see ContextLoaderPlugIn
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DelegatingActionProxy extends Action {
|
||||
|
||||
/**
|
||||
* Pass the execute call on to the Spring-managed delegate <code>Action</code>.
|
||||
* @see #getDelegateAction
|
||||
*/
|
||||
@Override
|
||||
public ActionForward execute(
|
||||
ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
|
||||
Action delegateAction = getDelegateAction(mapping);
|
||||
return delegateAction.execute(mapping, form, request, response);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the delegate <code>Action</code> for the given <code>mapping</code>.
|
||||
* <p>The default implementation determines a bean name from the
|
||||
* given <code>ActionMapping</code> and looks up the corresponding bean in
|
||||
* the {@link WebApplicationContext}.
|
||||
* @param mapping the Struts <code>ActionMapping</code>
|
||||
* @return the delegate <code>Action</code>
|
||||
* @throws BeansException if thrown by <code>WebApplicationContext</code> methods
|
||||
* @see #determineActionBeanName
|
||||
*/
|
||||
protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
|
||||
WebApplicationContext wac = getWebApplicationContext(getServlet(), mapping.getModuleConfig());
|
||||
String beanName = determineActionBeanName(mapping);
|
||||
return (Action) wac.getBean(beanName, Action.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's {@link WebApplicationContext} from the
|
||||
* <code>ServletContext</code>, falling back to the root
|
||||
* <code>WebApplicationContext</code>.
|
||||
* <p>This context is supposed to contain the Struts <code>Action</code>
|
||||
* beans to delegate to.
|
||||
* @param actionServlet the associated <code>ActionServlet</code>
|
||||
* @param moduleConfig the associated <code>ModuleConfig</code>
|
||||
* @return the <code>WebApplicationContext</code>
|
||||
* @throws IllegalStateException if no <code>WebApplicationContext</code> could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
protected WebApplicationContext getWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the name of the <code>Action</code> bean, to be looked up in
|
||||
* the <code>WebApplicationContext</code>.
|
||||
* <p>The default implementation takes the
|
||||
* {@link org.apache.struts.action.ActionMapping#getPath mapping path} and
|
||||
* prepends the
|
||||
* {@link org.apache.struts.config.ModuleConfig#getPrefix module prefix},
|
||||
* if any.
|
||||
* @param mapping the Struts <code>ActionMapping</code>
|
||||
* @return the name of the Action bean
|
||||
* @see DelegatingActionUtils#determineActionBeanName
|
||||
* @see org.apache.struts.action.ActionMapping#getPath
|
||||
* @see org.apache.struts.config.ModuleConfig#getPrefix
|
||||
*/
|
||||
protected String determineActionBeanName(ActionMapping mapping) {
|
||||
return DelegatingActionUtils.determineActionBeanName(mapping);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Common methods for letting Struts Actions work with a
|
||||
* Spring WebApplicationContext.
|
||||
*
|
||||
* <p>As everything in Struts is based on concrete inheritance,
|
||||
* we have to provide an Action subclass (DelegatingActionProxy) and
|
||||
* two RequestProcessor subclasses (DelegatingRequestProcessor and
|
||||
* DelegatingTilesRequestProcessor). The only way to share common
|
||||
* functionality is a utility class like this one.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.2
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @see DelegatingTilesRequestProcessor
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class DelegatingActionUtils {
|
||||
|
||||
/**
|
||||
* The name of the autowire init-param specified on the Struts ActionServlet:
|
||||
* "spring.autowire"
|
||||
*/
|
||||
public static final String PARAM_AUTOWIRE = "spring.autowire";
|
||||
|
||||
/**
|
||||
* The name of the dependency check init-param specified on the Struts ActionServlet:
|
||||
* "spring.dependencyCheck"
|
||||
*/
|
||||
public static final String PARAM_DEPENDENCY_CHECK = "spring.dependencyCheck";
|
||||
|
||||
/**
|
||||
* Value of the autowire init-param that indicates autowiring by name:
|
||||
* "byName"
|
||||
*/
|
||||
public static final String AUTOWIRE_BY_NAME = "byName";
|
||||
|
||||
/**
|
||||
* Value of the autowire init-param that indicates autowiring by type:
|
||||
* "byType"
|
||||
*/
|
||||
public static final String AUTOWIRE_BY_TYPE = "byType";
|
||||
|
||||
|
||||
private static final Log logger = LogFactory.getLog(DelegatingActionUtils.class);
|
||||
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext.
|
||||
* <p>Checks for a module-specific context first, falling back to the
|
||||
* context for the default module else.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig (can be <code>null</code>)
|
||||
* @return the WebApplicationContext, or <code>null</code> if none
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
public static WebApplicationContext getWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) {
|
||||
|
||||
WebApplicationContext wac = null;
|
||||
String modulePrefix = null;
|
||||
|
||||
// Try module-specific attribute.
|
||||
if (moduleConfig != null) {
|
||||
modulePrefix = moduleConfig.getPrefix();
|
||||
wac = (WebApplicationContext) actionServlet.getServletContext().getAttribute(
|
||||
ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + modulePrefix);
|
||||
}
|
||||
|
||||
// If not found, try attribute for default module.
|
||||
if (wac == null && !"".equals(modulePrefix)) {
|
||||
wac = (WebApplicationContext) actionServlet.getServletContext().getAttribute(
|
||||
ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX);
|
||||
}
|
||||
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext.
|
||||
* <p>Checks for a module-specific context first, falling back to the
|
||||
* context for the default module else.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig (can be <code>null</code>)
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
public static WebApplicationContext getRequiredWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
WebApplicationContext wac = getWebApplicationContext(actionServlet, moduleConfig);
|
||||
// If no Struts-specific context found, throw an exception.
|
||||
if (wac == null) {
|
||||
throw new IllegalStateException(
|
||||
"Could not find ContextLoaderPlugIn's WebApplicationContext as ServletContext attribute [" +
|
||||
ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + "]: Did you register [" +
|
||||
ContextLoaderPlugIn.class.getName() + "]?");
|
||||
}
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find most specific context available: check ContextLoaderPlugIn's
|
||||
* WebApplicationContext first, fall back to root WebApplicationContext else.
|
||||
* <p>When checking the ContextLoaderPlugIn context: checks for a module-specific
|
||||
* context first, falling back to the context for the default module else.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig (can be <code>null</code>)
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see #getWebApplicationContext
|
||||
* @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
|
||||
*/
|
||||
public static WebApplicationContext findRequiredWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
WebApplicationContext wac = getWebApplicationContext(actionServlet, moduleConfig);
|
||||
// If no Struts-specific context found, fall back to root context.
|
||||
if (wac == null) {
|
||||
wac = WebApplicationContextUtils.getRequiredWebApplicationContext(actionServlet.getServletContext());
|
||||
}
|
||||
return wac;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of Action bean determination, taking
|
||||
* the mapping path and prepending the module prefix, if any.
|
||||
* @param mapping the Struts ActionMapping
|
||||
* @return the name of the Action bean
|
||||
* @see org.apache.struts.action.ActionMapping#getPath
|
||||
* @see org.apache.struts.config.ModuleConfig#getPrefix
|
||||
*/
|
||||
public static String determineActionBeanName(ActionMapping mapping) {
|
||||
String prefix = mapping.getModuleConfig().getPrefix();
|
||||
String path = mapping.getPath();
|
||||
String beanName = prefix + path;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("DelegatingActionProxy with mapping path '" + path + "' and module prefix '" +
|
||||
prefix + "' delegating to Spring bean with name [" + beanName + "]");
|
||||
}
|
||||
return beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the autowire mode from the "autowire" init-param of the
|
||||
* Struts ActionServlet, falling back to "AUTOWIRE_BY_TYPE" as default.
|
||||
* @param actionServlet the Struts ActionServlet
|
||||
* @return the autowire mode to use
|
||||
* @see #PARAM_AUTOWIRE
|
||||
* @see #AUTOWIRE_BY_NAME
|
||||
* @see #AUTOWIRE_BY_TYPE
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
|
||||
*/
|
||||
public static int getAutowireMode(ActionServlet actionServlet) {
|
||||
String autowire = actionServlet.getInitParameter(PARAM_AUTOWIRE);
|
||||
if (autowire != null) {
|
||||
if (AUTOWIRE_BY_NAME.equals(autowire)) {
|
||||
return AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
|
||||
}
|
||||
else if (!AUTOWIRE_BY_TYPE.equals(autowire)) {
|
||||
throw new IllegalArgumentException("ActionServlet 'autowire' parameter must be 'byName' or 'byType'");
|
||||
}
|
||||
}
|
||||
return AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the dependency check to use from the "dependencyCheck" init-param
|
||||
* of the Struts ActionServlet, falling back to no dependency check as default.
|
||||
* @param actionServlet the Struts ActionServlet
|
||||
* @return whether to enforce a dependency check or not
|
||||
* @see #PARAM_DEPENDENCY_CHECK
|
||||
* @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBeanProperties
|
||||
*/
|
||||
public static boolean getDependencyCheck(ActionServlet actionServlet) {
|
||||
String dependencyCheck = actionServlet.getInitParameter(PARAM_DEPENDENCY_CHECK);
|
||||
return Boolean.valueOf(dependencyCheck).booleanValue();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.action.RequestProcessor;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Subclass of Struts's default {@link RequestProcessor} that looks up
|
||||
* Spring-managed Struts {@link Action Actions} defined in
|
||||
* {@link ContextLoaderPlugIn ContextLoaderPlugIn's} {@link WebApplicationContext}
|
||||
* (or, as a fallback, in the root <code>WebApplicationContext</code>).
|
||||
*
|
||||
* <p>In the Struts config file, you can either specify the original
|
||||
* <code>Action</code> class (as when generated by XDoclet), or no
|
||||
* <code>Action</code> class at all. In any case, Struts will delegate to an
|
||||
* <code>Action</code> bean in the <code>ContextLoaderPlugIn</code> context.
|
||||
*
|
||||
* <pre class="code"><action path="/login" type="myapp.MyAction"/></pre>
|
||||
*
|
||||
* or
|
||||
*
|
||||
* <pre class="code"><action path="/login"/></pre>
|
||||
*
|
||||
* The name of the <code>Action</code> bean in the
|
||||
* <code>WebApplicationContext</code> will be determined from the mapping path
|
||||
* and module prefix. This can be customized by overriding the
|
||||
* {@link #determineActionBeanName} method.
|
||||
*
|
||||
* <p>Example:
|
||||
* <ul>
|
||||
* <li>mapping path "/login" -> bean name "/login"<br>
|
||||
* <li>mapping path "/login", module prefix "/mymodule" ->
|
||||
* bean name "/mymodule/login"
|
||||
* </ul>
|
||||
*
|
||||
* <p>A corresponding bean definition in the <code>ContextLoaderPlugin</code>
|
||||
* context would look as follows; notice that the <code>Action</code> is now
|
||||
* able to leverage fully Spring's configuration facilities:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean name="/login" class="myapp.MyAction">
|
||||
* <property name="...">...</property>
|
||||
* </bean></pre>
|
||||
*
|
||||
* Note that you can use a single <code>ContextLoaderPlugIn</code> for all
|
||||
* Struts modules. That context can in turn be loaded from multiple XML files,
|
||||
* for example split according to Struts modules. Alternatively, define one
|
||||
* <code>ContextLoaderPlugIn</code> per Struts module, specifying appropriate
|
||||
* "contextConfigLocation" parameters. In both cases, the Spring bean name has
|
||||
* to include the module prefix.
|
||||
*
|
||||
* <p>If you also need the Tiles setup functionality of the original
|
||||
* <code>TilesRequestProcessor</code>, use
|
||||
* <code>DelegatingTilesRequestProcessor</code>. As there is just a
|
||||
* single central class to customize in Struts, we have to provide another
|
||||
* subclass here, covering both the Tiles and the Spring delegation aspect.
|
||||
*
|
||||
* <p>If this <code>RequestProcessor</code> conflicts with the need for a
|
||||
* different <code>RequestProcessor</code> subclass (other than
|
||||
* <code>TilesRequestProcessor</code>), consider using
|
||||
* {@link DelegatingActionProxy} as the Struts <code>Action</code> type in
|
||||
* your struts-config file.
|
||||
*
|
||||
* <p>The default implementation delegates to the
|
||||
* <code>DelegatingActionUtils</code> class as much as possible, to reuse as
|
||||
* much code as possible despite the need to provide two
|
||||
* <code>RequestProcessor</code> subclasses. If you need to subclass yet
|
||||
* another <code>RequestProcessor</code>, take this class as a template,
|
||||
* delegating to <code>DelegatingActionUtils</code> just like it.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.2
|
||||
* @see #determineActionBeanName
|
||||
* @see DelegatingTilesRequestProcessor
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingActionUtils
|
||||
* @see ContextLoaderPlugIn
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DelegatingRequestProcessor extends RequestProcessor {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
|
||||
super.init(actionServlet, moduleConfig);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's {@link WebApplicationContext} from the
|
||||
* <code>ServletContext</code>, falling back to the root
|
||||
* <code>WebApplicationContext</code>.
|
||||
* <p>This context is supposed to contain the Struts <code>Action</code>
|
||||
* beans to delegate to.
|
||||
* @param actionServlet the associated <code>ActionServlet</code>
|
||||
* @param moduleConfig the associated <code>ModuleConfig</code>
|
||||
* @return the <code>WebApplicationContext</code>
|
||||
* @throws IllegalStateException if no <code>WebApplicationContext</code> could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the <code>WebApplicationContext</code> that this processor
|
||||
* delegates to.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Override the base class method to return the delegate action.
|
||||
* @see #getDelegateAction
|
||||
*/
|
||||
@Override
|
||||
protected Action processActionCreate(
|
||||
HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
|
||||
throws IOException {
|
||||
|
||||
Action action = getDelegateAction(mapping);
|
||||
if (action != null) {
|
||||
return action;
|
||||
}
|
||||
return super.processActionCreate(request, response, mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the delegate <code>Action</code> for the given mapping.
|
||||
* <p>The default implementation determines a bean name from the
|
||||
* given <code>ActionMapping</code> and looks up the corresponding
|
||||
* bean in the <code>WebApplicationContext</code>.
|
||||
* @param mapping the Struts <code>ActionMapping</code>
|
||||
* @return the delegate <code>Action</code>, or <code>null</code> if none found
|
||||
* @throws BeansException if thrown by <code>WebApplicationContext</code> methods
|
||||
* @see #determineActionBeanName
|
||||
*/
|
||||
protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
|
||||
String beanName = determineActionBeanName(mapping);
|
||||
if (!getWebApplicationContext().containsBean(beanName)) {
|
||||
return null;
|
||||
}
|
||||
return (Action) getWebApplicationContext().getBean(beanName, Action.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the name of the <code>Action</code> bean, to be looked up in
|
||||
* the <code>WebApplicationContext</code>.
|
||||
* <p>The default implementation takes the
|
||||
* {@link org.apache.struts.action.ActionMapping#getPath mapping path} and
|
||||
* prepends the
|
||||
* {@link org.apache.struts.config.ModuleConfig#getPrefix module prefix},
|
||||
* if any.
|
||||
* @param mapping the Struts <code>ActionMapping</code>
|
||||
* @return the name of the Action bean
|
||||
* @see DelegatingActionUtils#determineActionBeanName
|
||||
* @see org.apache.struts.action.ActionMapping#getPath
|
||||
* @see org.apache.struts.config.ModuleConfig#getPrefix
|
||||
*/
|
||||
protected String determineActionBeanName(ActionMapping mapping) {
|
||||
return DelegatingActionUtils.determineActionBeanName(mapping);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
import org.apache.struts.tiles.TilesRequestProcessor;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
/**
|
||||
* Subclass of Struts's TilesRequestProcessor that autowires
|
||||
* Struts Actions defined in ContextLoaderPlugIn's WebApplicationContext
|
||||
* (or, as a fallback, in the root WebApplicationContext).
|
||||
*
|
||||
* <p>Behaves like
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor},
|
||||
* but also provides the Tiles functionality of the original TilesRequestProcessor.
|
||||
* As there's just a single central class to customize in Struts, we have to provide
|
||||
* another subclass here, covering both the Tiles and the Spring delegation aspect.
|
||||
*
|
||||
* <p>The default implementation delegates to the DelegatingActionUtils
|
||||
* class as fas as possible, to reuse as much code as possible despite
|
||||
* the need to provide two RequestProcessor subclasses. If you need to
|
||||
* subclass yet another RequestProcessor, take this class as a template,
|
||||
* delegating to DelegatingActionUtils just like it.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.2
|
||||
* @see DelegatingRequestProcessor
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingActionUtils
|
||||
* @see ContextLoaderPlugIn
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class DelegatingTilesRequestProcessor extends TilesRequestProcessor {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
|
||||
@Override
|
||||
public void init(ActionServlet actionServlet, ModuleConfig moduleConfig) throws ServletException {
|
||||
super.init(actionServlet, moduleConfig);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet, moduleConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext. This context is supposed
|
||||
* to contain the Struts Action beans to delegate to.
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @param moduleConfig the associated ModuleConfig
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(
|
||||
ActionServlet actionServlet, ModuleConfig moduleConfig) throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, moduleConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the WebApplicationContext that this processor delegates to.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return webApplicationContext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Override the base class method to return the delegate action.
|
||||
* @see #getDelegateAction
|
||||
*/
|
||||
@Override
|
||||
protected Action processActionCreate(
|
||||
HttpServletRequest request, HttpServletResponse response, ActionMapping mapping)
|
||||
throws IOException {
|
||||
|
||||
Action action = getDelegateAction(mapping);
|
||||
if (action != null) {
|
||||
return action;
|
||||
}
|
||||
return super.processActionCreate(request, response, mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the delegate Action for the given mapping.
|
||||
* <p>The default implementation determines a bean name from the
|
||||
* given ActionMapping and looks up the corresponding bean in the
|
||||
* WebApplicationContext.
|
||||
* @param mapping the Struts ActionMapping
|
||||
* @return the delegate Action, or <code>null</code> if none found
|
||||
* @throws BeansException if thrown by WebApplicationContext methods
|
||||
* @see #determineActionBeanName
|
||||
*/
|
||||
protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
|
||||
String beanName = determineActionBeanName(mapping);
|
||||
if (!getWebApplicationContext().containsBean(beanName)) {
|
||||
return null;
|
||||
}
|
||||
return (Action) getWebApplicationContext().getBean(beanName, Action.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the name of the Action bean, to be looked up in
|
||||
* the WebApplicationContext.
|
||||
* <p>The default implementation takes the mapping path and
|
||||
* prepends the module prefix, if any.
|
||||
* @param mapping the Struts ActionMapping
|
||||
* @return the name of the Action bean
|
||||
* @see DelegatingActionUtils#determineActionBeanName
|
||||
* @see ActionMapping#getPath
|
||||
* @see ModuleConfig#getPrefix
|
||||
*/
|
||||
protected String determineActionBeanName(ActionMapping mapping) {
|
||||
return DelegatingActionUtils.determineActionBeanName(mapping);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.actions.DispatchAction;
|
||||
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware Struts 1.1+ DispatchActions.
|
||||
*
|
||||
* <p>Provides a reference to the current Spring application context, e.g.
|
||||
* for bean lookup or resource loading. Auto-detects a ContextLoaderPlugIn
|
||||
* context, falling back to the root WebApplicationContext. For typical
|
||||
* usage, i.e. accessing middle tier beans, use a root WebApplicationContext.
|
||||
*
|
||||
* <p>For classic Struts Actions or Lookup/MappingDispatchActions, use the
|
||||
* analogous {@link ActionSupport ActionSupport} or
|
||||
* {@link LookupDispatchActionSupport LookupDispatchActionSupport} /
|
||||
* {@link MappingDispatchActionSupport MappingDispatchActionSupport} class,
|
||||
* respectively.
|
||||
*
|
||||
* <p>As an alternative approach, you can wire your Struts Actions themselves
|
||||
* as Spring beans, passing references to them via IoC rather than looking
|
||||
* up references in a programmatic fashion. Check out
|
||||
* {@link DelegatingActionProxy DelegatingActionProxy} and
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.0.1
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
* @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see org.springframework.web.context.ContextLoaderServlet
|
||||
* @see ActionSupport
|
||||
* @see LookupDispatchActionSupport
|
||||
* @see MappingDispatchActionSupport
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class DispatchActionSupport extends DispatchAction {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the WebApplicationContext for this Action.
|
||||
* Invokes onInit after successful initialization of the context.
|
||||
* @see #initWebApplicationContext
|
||||
* @see #onInit
|
||||
*/
|
||||
@Override
|
||||
public void setServlet(ActionServlet actionServlet) {
|
||||
super.setServlet(actionServlet);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet);
|
||||
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
|
||||
onInit();
|
||||
}
|
||||
else {
|
||||
onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext (the usual case).
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet)
|
||||
throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MessageSourceAccessor for the application context
|
||||
* used by this object, for easy message access.
|
||||
*/
|
||||
protected final MessageSourceAccessor getMessageSourceAccessor() {
|
||||
return this.messageSourceAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ServletContext.
|
||||
*/
|
||||
protected final ServletContext getServletContext() {
|
||||
return this.webApplicationContext.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temporary directory for the current web application,
|
||||
* as provided by the servlet container.
|
||||
* @return the File representing the temporary directory
|
||||
*/
|
||||
protected final File getTempDir() {
|
||||
return WebUtils.getTempDir(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for custom initialization after the context has been set up.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for custom destruction when the ActionServlet shuts down.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onDestroy() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.actions.LookupDispatchAction;
|
||||
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware Struts 1.1+ LookupDispatchActions.
|
||||
*
|
||||
* <p>Provides a reference to the current Spring application context, e.g.
|
||||
* for bean lookup or resource loading. Auto-detects a ContextLoaderPlugIn
|
||||
* context, falling back to the root WebApplicationContext. For typical
|
||||
* usage, i.e. accessing middle tier beans, use a root WebApplicationContext.
|
||||
*
|
||||
* <p>For classic Struts Actions, DispatchActions or MappingDispatchActions,
|
||||
* use the analogous {@link ActionSupport ActionSupport} or
|
||||
* {@link DispatchActionSupport DispatchActionSupport} /
|
||||
* {@link MappingDispatchActionSupport MappingDispatchActionSupport} class.
|
||||
*
|
||||
* <p>As an alternative approach, you can wire your Struts Actions themselves
|
||||
* as Spring beans, passing references to them via IoC rather than looking
|
||||
* up references in a programmatic fashion. Check out
|
||||
* {@link DelegatingActionProxy DelegatingActionProxy} and
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
* @see WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see org.springframework.web.context.ContextLoaderServlet
|
||||
* @see ActionSupport
|
||||
* @see DispatchActionSupport
|
||||
* @see MappingDispatchActionSupport
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class LookupDispatchActionSupport extends LookupDispatchAction {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the WebApplicationContext for this Action.
|
||||
* Invokes onInit after successful initialization of the context.
|
||||
* @see #initWebApplicationContext
|
||||
* @see #onInit
|
||||
*/
|
||||
@Override
|
||||
public void setServlet(ActionServlet actionServlet) {
|
||||
super.setServlet(actionServlet);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet);
|
||||
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
|
||||
onInit();
|
||||
}
|
||||
else {
|
||||
onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext (the usual case).
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet)
|
||||
throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MessageSourceAccessor for the application context
|
||||
* used by this object, for easy message access.
|
||||
*/
|
||||
protected final MessageSourceAccessor getMessageSourceAccessor() {
|
||||
return this.messageSourceAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ServletContext.
|
||||
*/
|
||||
protected final ServletContext getServletContext() {
|
||||
return this.webApplicationContext.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temporary directory for the current web application,
|
||||
* as provided by the servlet container.
|
||||
* @return the File representing the temporary directory
|
||||
*/
|
||||
protected final File getTempDir() {
|
||||
return WebUtils.getTempDir(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for custom initialization after the context has been set up.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for custom destruction when the ActionServlet shuts down.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onDestroy() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.actions.MappingDispatchAction;
|
||||
|
||||
import org.springframework.context.support.MessageSourceAccessor;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Convenience class for Spring-aware Struts 1.2 MappingDispatchActions.
|
||||
*
|
||||
* <p>Provides a reference to the current Spring application context, e.g.
|
||||
* for bean lookup or resource loading. Auto-detects a ContextLoaderPlugIn
|
||||
* context, falling back to the root WebApplicationContext. For typical
|
||||
* usage, i.e. accessing middle tier beans, use a root WebApplicationContext.
|
||||
*
|
||||
* <p>For classic Struts Actions, DispatchActions or LookupDispatchActions,
|
||||
* use the analogous {@link ActionSupport ActionSupport} or
|
||||
* {@link DispatchActionSupport DispatchActionSupport} /
|
||||
* {@link LookupDispatchActionSupport LookupDispatchActionSupport} class.
|
||||
*
|
||||
* <p>As an alternative approach, you can wire your Struts Actions themselves
|
||||
* as Spring beans, passing references to them via IoC rather than looking
|
||||
* up references in a programmatic fashion. Check out
|
||||
* {@link DelegatingActionProxy DelegatingActionProxy} and
|
||||
* {@link DelegatingRequestProcessor DelegatingRequestProcessor}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1.3
|
||||
* @see ContextLoaderPlugIn#SERVLET_CONTEXT_PREFIX
|
||||
* @see WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see org.springframework.web.context.ContextLoaderServlet
|
||||
* @see ActionSupport
|
||||
* @see DispatchActionSupport
|
||||
* @see LookupDispatchActionSupport
|
||||
* @see DelegatingActionProxy
|
||||
* @see DelegatingRequestProcessor
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class MappingDispatchActionSupport extends MappingDispatchAction {
|
||||
|
||||
private WebApplicationContext webApplicationContext;
|
||||
|
||||
private MessageSourceAccessor messageSourceAccessor;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the WebApplicationContext for this Action.
|
||||
* Invokes onInit after successful initialization of the context.
|
||||
* @see #initWebApplicationContext
|
||||
* @see #onInit
|
||||
*/
|
||||
@Override
|
||||
public void setServlet(ActionServlet actionServlet) {
|
||||
super.setServlet(actionServlet);
|
||||
if (actionServlet != null) {
|
||||
this.webApplicationContext = initWebApplicationContext(actionServlet);
|
||||
this.messageSourceAccessor = new MessageSourceAccessor(this.webApplicationContext);
|
||||
onInit();
|
||||
}
|
||||
else {
|
||||
onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch ContextLoaderPlugIn's WebApplicationContext from the ServletContext,
|
||||
* falling back to the root WebApplicationContext (the usual case).
|
||||
* @param actionServlet the associated ActionServlet
|
||||
* @return the WebApplicationContext
|
||||
* @throws IllegalStateException if no WebApplicationContext could be found
|
||||
* @see DelegatingActionUtils#findRequiredWebApplicationContext
|
||||
*/
|
||||
protected WebApplicationContext initWebApplicationContext(ActionServlet actionServlet)
|
||||
throws IllegalStateException {
|
||||
|
||||
return DelegatingActionUtils.findRequiredWebApplicationContext(actionServlet, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current Spring WebApplicationContext.
|
||||
*/
|
||||
protected final WebApplicationContext getWebApplicationContext() {
|
||||
return this.webApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a MessageSourceAccessor for the application context
|
||||
* used by this object, for easy message access.
|
||||
*/
|
||||
protected final MessageSourceAccessor getMessageSourceAccessor() {
|
||||
return this.messageSourceAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current ServletContext.
|
||||
*/
|
||||
protected final ServletContext getServletContext() {
|
||||
return this.webApplicationContext.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the temporary directory for the current web application,
|
||||
* as provided by the servlet container.
|
||||
* @return the File representing the temporary directory
|
||||
*/
|
||||
protected final File getTempDir() {
|
||||
return WebUtils.getTempDir(getServletContext());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for custom initialization after the context has been set up.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onInit() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for custom destruction when the ActionServlet shuts down.
|
||||
* @see #setServlet
|
||||
*/
|
||||
protected void onDestroy() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.beanutils.BeanUtilsBean;
|
||||
import org.apache.commons.beanutils.ConvertUtilsBean;
|
||||
import org.apache.commons.beanutils.PropertyUtilsBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.struts.Globals;
|
||||
import org.apache.struts.action.ActionForm;
|
||||
import org.apache.struts.action.ActionMessage;
|
||||
import org.apache.struts.action.ActionMessages;
|
||||
import org.apache.struts.util.MessageResources;
|
||||
|
||||
import org.springframework.context.MessageSourceResolvable;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.validation.ObjectError;
|
||||
|
||||
/**
|
||||
* A thin Struts ActionForm adapter that delegates to Spring's more complete
|
||||
* and advanced data binder and Errors object underneath the covers to bind
|
||||
* to POJOs and manage rejected values.
|
||||
*
|
||||
* <p>Exposes Spring-managed errors to the standard Struts view tags, through
|
||||
* exposing a corresponding Struts ActionMessages object as request attribute.
|
||||
* Also exposes current field values in a Struts-compliant fashion, including
|
||||
* rejected values (which Spring's binding keeps even for non-String fields).
|
||||
*
|
||||
* <p>Consequently, Struts views can be written in a completely traditional
|
||||
* fashion (with standard <code>html:form</code>, <code>html:errors</code>, etc),
|
||||
* seamlessly accessing a Spring-bound POJO form object underneath.
|
||||
*
|
||||
* <p>Note this ActionForm is designed explicitly for use in <i>request scope</i>.
|
||||
* It expects to receive an <code>expose</code> call from the Action, passing
|
||||
* in the Errors object to expose plus the current HttpServletRequest.
|
||||
*
|
||||
* <p>Example definition in <code>struts-config.xml</code>:
|
||||
*
|
||||
* <pre>
|
||||
* <form-beans>
|
||||
* <form-bean name="actionForm" type="org.springframework.web.struts.SpringBindingActionForm"/>
|
||||
* </form-beans></pre>
|
||||
*
|
||||
* Example code in a custom Struts <code>Action</code>:
|
||||
*
|
||||
* <pre>
|
||||
* public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
* SpringBindingActionForm form = (SpringBindingActionForm) actionForm;
|
||||
* MyPojoBean bean = ...;
|
||||
* ServletRequestDataBinder binder = new ServletRequestDataBinder(bean, "myPojo");
|
||||
* binder.bind(request);
|
||||
* form.expose(binder.getBindingResult(), request);
|
||||
* return actionMapping.findForward("success");
|
||||
* }</pre>
|
||||
*
|
||||
* This class is compatible with both Struts 1.2.x and Struts 1.1.
|
||||
* On Struts 1.2, default messages registered with Spring binding errors
|
||||
* are exposed when none of the error codes could be resolved.
|
||||
* On Struts 1.1, this is not possible due to a limitation in the Struts
|
||||
* message facility; hence, we expose the plain default error code there.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.2
|
||||
* @see #expose(org.springframework.validation.Errors, javax.servlet.http.HttpServletRequest)
|
||||
* @deprecated as of Spring 3.0
|
||||
*/
|
||||
@Deprecated
|
||||
public class SpringBindingActionForm extends ActionForm {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SpringBindingActionForm.class);
|
||||
|
||||
private static boolean defaultActionMessageAvailable = true;
|
||||
|
||||
|
||||
static {
|
||||
// Register special PropertyUtilsBean subclass that knows how to
|
||||
// extract field values from a SpringBindingActionForm.
|
||||
// As a consequence of the static nature of Commons BeanUtils,
|
||||
// we have to resort to this initialization hack here.
|
||||
ConvertUtilsBean convUtils = new ConvertUtilsBean();
|
||||
PropertyUtilsBean propUtils = new SpringBindingAwarePropertyUtilsBean();
|
||||
BeanUtilsBean beanUtils = new BeanUtilsBean(convUtils, propUtils);
|
||||
BeanUtilsBean.setInstance(beanUtils);
|
||||
|
||||
// Determine whether the Struts 1.2 support for default messages
|
||||
// is available on ActionMessage: ActionMessage(String, boolean)
|
||||
// with "false" to be passed into the boolean flag.
|
||||
try {
|
||||
ActionMessage.class.getConstructor(new Class[] {String.class, boolean.class});
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
defaultActionMessageAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Errors errors;
|
||||
|
||||
private Locale locale;
|
||||
|
||||
private MessageResources messageResources;
|
||||
|
||||
|
||||
/**
|
||||
* Set the Errors object that this SpringBindingActionForm is supposed
|
||||
* to wrap. The contained field values and errors will be exposed
|
||||
* to the view, accessible through Struts standard tags.
|
||||
* @param errors the Spring Errors object to wrap, usually taken from
|
||||
* a DataBinder that has been used for populating a POJO form object
|
||||
* @param request the HttpServletRequest to retrieve the attributes from
|
||||
* @see org.springframework.validation.DataBinder#getBindingResult()
|
||||
*/
|
||||
public void expose(Errors errors, HttpServletRequest request) {
|
||||
this.errors = errors;
|
||||
|
||||
// Obtain the locale from Struts well-known location.
|
||||
this.locale = (Locale) request.getSession().getAttribute(Globals.LOCALE_KEY);
|
||||
|
||||
// Obtain the MessageResources from Struts' well-known location.
|
||||
this.messageResources = (MessageResources) request.getAttribute(Globals.MESSAGES_KEY);
|
||||
|
||||
if (errors != null && errors.hasErrors()) {
|
||||
// Add global ActionError instances from the Spring Errors object.
|
||||
ActionMessages actionMessages = (ActionMessages) request.getAttribute(Globals.ERROR_KEY);
|
||||
if (actionMessages == null) {
|
||||
request.setAttribute(Globals.ERROR_KEY, getActionMessages());
|
||||
}
|
||||
else {
|
||||
actionMessages.add(getActionMessages());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return an ActionMessages representation of this SpringBindingActionForm,
|
||||
* exposing all errors contained in the underlying Spring Errors object.
|
||||
* @see org.springframework.validation.Errors#getAllErrors()
|
||||
*/
|
||||
private ActionMessages getActionMessages() {
|
||||
ActionMessages actionMessages = new ActionMessages();
|
||||
Iterator it = this.errors.getAllErrors().iterator();
|
||||
while (it.hasNext()) {
|
||||
ObjectError objectError = (ObjectError) it.next();
|
||||
String effectiveMessageKey = findEffectiveMessageKey(objectError);
|
||||
if (effectiveMessageKey == null && !defaultActionMessageAvailable) {
|
||||
// Need to specify default code despite it not being resolvable:
|
||||
// Struts 1.1 ActionMessage doesn't support default messages.
|
||||
effectiveMessageKey = objectError.getCode();
|
||||
}
|
||||
ActionMessage message = (effectiveMessageKey != null) ?
|
||||
new ActionMessage(effectiveMessageKey, resolveArguments(objectError.getArguments())) :
|
||||
new ActionMessage(objectError.getDefaultMessage(), false);
|
||||
if (objectError instanceof FieldError) {
|
||||
FieldError fieldError = (FieldError) objectError;
|
||||
actionMessages.add(fieldError.getField(), message);
|
||||
}
|
||||
else {
|
||||
actionMessages.add(ActionMessages.GLOBAL_MESSAGE, message);
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Final ActionMessages used for binding: " + actionMessages);
|
||||
}
|
||||
return actionMessages;
|
||||
}
|
||||
|
||||
private Object[] resolveArguments(Object[] arguments) {
|
||||
if (arguments == null || arguments.length == 0) {
|
||||
return arguments;
|
||||
}
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
Object arg = arguments[i];
|
||||
if (arg instanceof MessageSourceResolvable) {
|
||||
MessageSourceResolvable resolvable = (MessageSourceResolvable)arg;
|
||||
String[] codes = resolvable.getCodes();
|
||||
boolean resolved = false;
|
||||
if (this.messageResources != null) {
|
||||
for (int j = 0; j < codes.length; j++) {
|
||||
String code = codes[j];
|
||||
if (this.messageResources.isPresent(this.locale, code)) {
|
||||
arguments[i] = this.messageResources.getMessage(
|
||||
this.locale, code, resolveArguments(resolvable.getArguments()));
|
||||
resolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!resolved) {
|
||||
arguments[i] = resolvable.getDefaultMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the most specific message key for the given error.
|
||||
* @param error the ObjectError to find a message key for
|
||||
* @return the most specific message key found
|
||||
*/
|
||||
private String findEffectiveMessageKey(ObjectError error) {
|
||||
if (this.messageResources != null) {
|
||||
String[] possibleMatches = error.getCodes();
|
||||
for (int i = 0; i < possibleMatches.length; i++) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Looking for error code '" + possibleMatches[i] + "'");
|
||||
}
|
||||
if (this.messageResources.isPresent(this.locale, possibleMatches[i])) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found error code '" + possibleMatches[i] + "' in resource bundle");
|
||||
}
|
||||
return possibleMatches[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Could not find a suitable message error code, returning default message");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the formatted value for the property at the provided path.
|
||||
* The formatted value is a string value for display, converted
|
||||
* via a registered property editor.
|
||||
* @param propertyPath the property path
|
||||
* @return the formatted property value
|
||||
* @throws NoSuchMethodException if called during Struts binding
|
||||
* (without Spring Errors object being exposed), to indicate no
|
||||
* available property to Struts
|
||||
*/
|
||||
private Object getFieldValue(String propertyPath) throws NoSuchMethodException {
|
||||
if (this.errors == null) {
|
||||
throw new NoSuchMethodException(
|
||||
"No bean properties exposed to Struts binding - performing Spring binding later on");
|
||||
}
|
||||
return this.errors.getFieldValue(propertyPath);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special subclass of PropertyUtilsBean that it is aware of SpringBindingActionForm
|
||||
* and uses it for retrieving field values. The field values will be taken from
|
||||
* the underlying POJO form object that the Spring Errors object was created for.
|
||||
*/
|
||||
private static class SpringBindingAwarePropertyUtilsBean extends PropertyUtilsBean {
|
||||
|
||||
@Override
|
||||
public Object getNestedProperty(Object bean, String propertyPath)
|
||||
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
|
||||
// Extract Spring-managed field value in case of SpringBindingActionForm.
|
||||
if (bean instanceof SpringBindingActionForm) {
|
||||
SpringBindingActionForm form = (SpringBindingActionForm) bean;
|
||||
return form.getFieldValue(propertyPath);
|
||||
}
|
||||
|
||||
// Else fall back to default PropertyUtils behavior.
|
||||
return super.getNestedProperty(bean, propertyPath);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Support classes for integrating a Struts web tier with a Spring middle
|
||||
* tier which is typically hosted in a Spring root WebApplicationContext.
|
||||
*
|
||||
* <p>Supports easy access to the Spring root WebApplicationContext
|
||||
* from Struts Actions via the ActionSupport and DispatchActionSupport
|
||||
* classes. Actions have full access to Spring's WebApplicationContext
|
||||
* facilities in this case, and explicitly look up Spring-managed beans.
|
||||
*
|
||||
* <p>Also supports wiring Struts Actions as Spring-managed beans in
|
||||
* a ContextLoaderPlugIn context, passing middle tier references to them
|
||||
* via bean references, using the Action path as bean name. There are two
|
||||
* ways to make Struts delegate Action lookup to the ContextLoaderPlugIn:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Use DelegationActionProxy as Action "type" in struts-config.
|
||||
* There's no further setup necessary; you can choose any RequestProcessor.
|
||||
* Each such proxy will automatically delegate to the corresponding
|
||||
* Spring-managed Action bean in the ContextLoaderPlugIn context.
|
||||
*
|
||||
* <li>Configure DelegatingRequestProcessor as "processorClass" in
|
||||
* struts-config, using the original Action "type" (possibly generated
|
||||
* by XDoclet) or no "type" at all. To also use Tiles, configure
|
||||
* DelegatingTilesRequestProcessor instead.
|
||||
* </ul>
|
||||
*/
|
||||
@Deprecated
|
||||
package org.springframework.web.struts;
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.tiles.ComponentContext;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 22.08.2003
|
||||
*/
|
||||
public class TestComponentController extends ComponentControllerSupport {
|
||||
|
||||
@Override
|
||||
protected void doPerform(ComponentContext componentContext, HttpServletRequest request, HttpServletResponse response) {
|
||||
request.setAttribute("testAttr", "testVal");
|
||||
TilesView.setPath(request, "/WEB-INF/jsp/layout.jsp");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.servlet.view.tiles;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import javax.servlet.jsp.jstl.core.Config;
|
||||
import javax.servlet.jsp.jstl.fmt.LocalizationContext;
|
||||
|
||||
import org.apache.struts.taglib.tiles.ComponentConstants;
|
||||
import org.apache.struts.tiles.ComponentContext;
|
||||
import org.apache.struts.tiles.PathAttribute;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.i18n.FixedLocaleResolver;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
/**
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
*/
|
||||
public class TilesViewTests {
|
||||
|
||||
protected StaticWebApplicationContext prepareWebApplicationContext() throws Exception {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
MockServletContext sc = new MockServletContext("/org/springframework/web/servlet/view/tiles/");
|
||||
wac.setServletContext(sc);
|
||||
wac.refresh();
|
||||
|
||||
TilesConfigurer tc = new TilesConfigurer();
|
||||
tc.setDefinitions(new String[] {"tiles-test.xml"});
|
||||
tc.setValidateDefinitions(true);
|
||||
tc.setApplicationContext(wac);
|
||||
tc.afterPropertiesSet();
|
||||
|
||||
return wac;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tilesView() throws Exception {
|
||||
WebApplicationContext wac = prepareWebApplicationContext();
|
||||
|
||||
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
|
||||
irvr.setApplicationContext(wac);
|
||||
irvr.setViewClass(TilesView.class);
|
||||
View view = irvr.resolveViewName("testTile", new Locale("nl", ""));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(wac.getServletContext());
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver());
|
||||
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
ComponentContext cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
PathAttribute attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/content.jsp", attr.getValue());
|
||||
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/content.jsp", attr.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tilesJstlView() throws Exception {
|
||||
Locale locale = !Locale.GERMAN.equals(Locale.getDefault()) ? Locale.GERMAN : Locale.FRENCH;
|
||||
|
||||
StaticWebApplicationContext wac = prepareWebApplicationContext();
|
||||
|
||||
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
|
||||
irvr.setApplicationContext(wac);
|
||||
irvr.setViewClass(TilesJstlView.class);
|
||||
View view = irvr.resolveViewName("testTile", new Locale("nl", ""));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(wac.getServletContext());
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale));
|
||||
wac.addMessage("code1", locale, "messageX");
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
ComponentContext cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
PathAttribute attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/content.jsp", attr.getValue());
|
||||
|
||||
assertEquals(locale, Config.get(request, Config.FMT_LOCALE));
|
||||
LocalizationContext lc = (LocalizationContext) Config.get(request, Config.FMT_LOCALIZATION_CONTEXT);
|
||||
assertEquals("messageX", lc.getResourceBundle().getString("code1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tilesJstlViewWithContextParam() throws Exception {
|
||||
Locale locale = !Locale.GERMAN.equals(Locale.getDefault()) ? Locale.GERMAN : Locale.FRENCH;
|
||||
|
||||
StaticWebApplicationContext wac = prepareWebApplicationContext();
|
||||
((MockServletContext) wac.getServletContext()).addInitParameter(
|
||||
Config.FMT_LOCALIZATION_CONTEXT, "org/springframework/web/servlet/view/tiles/context-messages");
|
||||
|
||||
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
|
||||
irvr.setApplicationContext(wac);
|
||||
irvr.setViewClass(TilesJstlView.class);
|
||||
View view = irvr.resolveViewName("testTile", new Locale("nl", ""));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(wac.getServletContext());
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
wac.addMessage("code1", locale, "messageX");
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new FixedLocaleResolver(locale));
|
||||
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
ComponentContext cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
PathAttribute attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/content.jsp", attr.getValue());
|
||||
|
||||
LocalizationContext lc = (LocalizationContext) Config.get(request, Config.FMT_LOCALIZATION_CONTEXT);
|
||||
assertEquals("message1", lc.getResourceBundle().getString("code1"));
|
||||
assertEquals("message2", lc.getResourceBundle().getString("code2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void tilesViewWithController() throws Exception {
|
||||
WebApplicationContext wac = prepareWebApplicationContext();
|
||||
|
||||
InternalResourceViewResolver irvr = new InternalResourceViewResolver();
|
||||
irvr.setApplicationContext(wac);
|
||||
irvr.setViewClass(TilesView.class);
|
||||
View view = irvr.resolveViewName("testTileWithController", new Locale("nl", ""));
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest(wac.getServletContext());
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
request.setAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE, new AcceptHeaderLocaleResolver());
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
ComponentContext cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
PathAttribute attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/otherContent.jsp", attr.getValue());
|
||||
assertEquals("testVal", request.getAttribute("testAttr"));
|
||||
|
||||
view.render(new HashMap<String, Object>(), request, response);
|
||||
assertEquals("/WEB-INF/jsp/layout.jsp", response.getForwardedUrl());
|
||||
cc = (ComponentContext) request.getAttribute(ComponentConstants.COMPONENT_CONTEXT);
|
||||
assertNotNull(cc);
|
||||
attr = (PathAttribute) cc.getAttribute("content");
|
||||
assertEquals("/WEB-INF/jsp/otherContent.jsp", attr.getValue());
|
||||
assertEquals("testVal", request.getAttribute("testAttr"));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* Copyright 2002-2005 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.apache.struts.action.ActionForward;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
import org.apache.struts.action.ActionServlet;
|
||||
import org.apache.struts.config.ModuleConfig;
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 09.04.2004
|
||||
*/
|
||||
public class StrutsSupportTests {
|
||||
|
||||
@Test
|
||||
public void actionSupportWithContextLoaderPlugIn() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
ActionSupport action = new ActionSupport() {
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void actionSupportWithRootContext() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
ActionSupport action = new ActionSupport() {
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchActionSupportWithContextLoaderPlugIn() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
DispatchActionSupport action = new DispatchActionSupport() {
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatchActionSupportWithRootContext() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
DispatchActionSupport action = new DispatchActionSupport() {
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupDispatchActionSupportWithContextLoaderPlugIn() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
LookupDispatchActionSupport action = new LookupDispatchActionSupport() {
|
||||
@Override
|
||||
protected Map getKeyMethodMap() {
|
||||
return new HashMap();
|
||||
}
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lookupDispatchActionSupportWithRootContext() throws ServletException {
|
||||
StaticWebApplicationContext wac = new StaticWebApplicationContext();
|
||||
wac.addMessage("test", Locale.getDefault(), "testmessage");
|
||||
final ServletContext servletContext = new MockServletContext();
|
||||
wac.setServletContext(servletContext);
|
||||
wac.refresh();
|
||||
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
|
||||
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
LookupDispatchActionSupport action = new LookupDispatchActionSupport() {
|
||||
@Override
|
||||
protected Map getKeyMethodMap() {
|
||||
return new HashMap();
|
||||
}
|
||||
};
|
||||
action.setServlet(actionServlet);
|
||||
|
||||
assertEquals(wac, action.getWebApplicationContext());
|
||||
assertEquals(servletContext, action.getServletContext());
|
||||
assertEquals("testmessage", action.getMessageSourceAccessor().getMessage("test"));
|
||||
|
||||
action.setServlet(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelegatingActionProxy() throws Exception {
|
||||
final MockServletContext servletContext = new MockServletContext("/org/springframework/web/struts/");
|
||||
ContextLoaderPlugIn plugin = new ContextLoaderPlugIn();
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public String getServletName() {
|
||||
return "action";
|
||||
}
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
|
||||
ModuleConfig moduleConfig = createMock(ModuleConfig.class);
|
||||
expect(moduleConfig.getPrefix()).andReturn("").anyTimes();
|
||||
replay(moduleConfig);
|
||||
|
||||
plugin.init(actionServlet, moduleConfig);
|
||||
assertTrue(servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX) != null);
|
||||
|
||||
DelegatingActionProxy proxy = new DelegatingActionProxy();
|
||||
proxy.setServlet(actionServlet);
|
||||
ActionMapping mapping = new ActionMapping();
|
||||
mapping.setPath("/test");
|
||||
mapping.setModuleConfig(moduleConfig);
|
||||
ActionForward forward = proxy.execute(
|
||||
mapping, null, new MockHttpServletRequest(servletContext), new MockHttpServletResponse());
|
||||
assertEquals("/test", forward.getPath());
|
||||
|
||||
TestAction testAction = (TestAction) plugin.getWebApplicationContext().getBean("/test");
|
||||
assertTrue(testAction.getServlet() != null);
|
||||
proxy.setServlet(null);
|
||||
plugin.destroy();
|
||||
assertTrue(testAction.getServlet() == null);
|
||||
|
||||
verify(moduleConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegatingActionProxyWithModule() throws Exception {
|
||||
final MockServletContext servletContext = new MockServletContext("/org/springframework/web/struts/WEB-INF");
|
||||
ContextLoaderPlugIn plugin = new ContextLoaderPlugIn();
|
||||
plugin.setContextConfigLocation("action-servlet.xml");
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public String getServletName() {
|
||||
return "action";
|
||||
}
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
|
||||
ModuleConfig moduleConfig = createMock(ModuleConfig.class);
|
||||
expect(moduleConfig.getPrefix()).andReturn("/module").anyTimes();
|
||||
replay(moduleConfig);
|
||||
|
||||
plugin.init(actionServlet, moduleConfig);
|
||||
assertTrue(servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX) == null);
|
||||
assertTrue(servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + "/module") != null);
|
||||
|
||||
DelegatingActionProxy proxy = new DelegatingActionProxy();
|
||||
proxy.setServlet(actionServlet);
|
||||
ActionMapping mapping = new ActionMapping();
|
||||
mapping.setPath("/test2");
|
||||
mapping.setModuleConfig(moduleConfig);
|
||||
ActionForward forward = proxy.execute(
|
||||
mapping, null, new MockHttpServletRequest(servletContext), new MockHttpServletResponse());
|
||||
assertEquals("/module/test2", forward.getPath());
|
||||
|
||||
TestAction testAction = (TestAction) plugin.getWebApplicationContext().getBean("/module/test2");
|
||||
assertTrue(testAction.getServlet() != null);
|
||||
proxy.setServlet(null);
|
||||
plugin.destroy();
|
||||
assertTrue(testAction.getServlet() == null);
|
||||
|
||||
verify(moduleConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegatingActionProxyWithModuleAndDefaultContext() throws Exception {
|
||||
final MockServletContext servletContext = new MockServletContext("/org/springframework/web/struts/WEB-INF");
|
||||
ContextLoaderPlugIn plugin = new ContextLoaderPlugIn();
|
||||
plugin.setContextConfigLocation("action-servlet.xml");
|
||||
ActionServlet actionServlet = new ActionServlet() {
|
||||
@Override
|
||||
public String getServletName() {
|
||||
return "action";
|
||||
}
|
||||
@Override
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
};
|
||||
|
||||
ModuleConfig defaultModuleConfig = createMock(ModuleConfig.class);
|
||||
expect(defaultModuleConfig.getPrefix()).andReturn("").anyTimes();
|
||||
|
||||
ModuleConfig moduleConfig = createMock(ModuleConfig.class);
|
||||
expect(moduleConfig.getPrefix()).andReturn("/module").anyTimes();
|
||||
|
||||
replay(defaultModuleConfig, moduleConfig);
|
||||
|
||||
plugin.init(actionServlet, defaultModuleConfig);
|
||||
assertTrue(servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX) != null);
|
||||
assertTrue(servletContext.getAttribute(ContextLoaderPlugIn.SERVLET_CONTEXT_PREFIX + "/module") == null);
|
||||
|
||||
DelegatingActionProxy proxy = new DelegatingActionProxy();
|
||||
proxy.setServlet(actionServlet);
|
||||
ActionMapping mapping = new ActionMapping();
|
||||
mapping.setPath("/test2");
|
||||
mapping.setModuleConfig(moduleConfig);
|
||||
ActionForward forward = proxy.execute(
|
||||
mapping, null, new MockHttpServletRequest(servletContext), new MockHttpServletResponse());
|
||||
assertEquals("/module/test2", forward.getPath());
|
||||
|
||||
TestAction testAction = (TestAction) plugin.getWebApplicationContext().getBean("/module/test2");
|
||||
assertTrue(testAction.getServlet() != null);
|
||||
proxy.setServlet(null);
|
||||
plugin.destroy();
|
||||
assertTrue(testAction.getServlet() == null);
|
||||
|
||||
verify(defaultModuleConfig, moduleConfig);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.web.struts;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts.action.Action;
|
||||
import org.apache.struts.action.ActionForm;
|
||||
import org.apache.struts.action.ActionForward;
|
||||
import org.apache.struts.action.ActionMapping;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 09.04.2004
|
||||
*/
|
||||
public class TestAction extends Action implements BeanNameAware {
|
||||
|
||||
private String beanName;
|
||||
|
||||
public void setBeanName(String beanName) {
|
||||
this.beanName = beanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionForward execute(
|
||||
ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response){
|
||||
|
||||
return new ActionForward(this.beanName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||
|
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
|
||||
|
||||
<!-- Appenders -->
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Target" value="System.out" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework.beans">
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.binding">
|
||||
<level value="debug" />
|
||||
</logger>
|
||||
|
||||
<!-- Root Logger -->
|
||||
<root>
|
||||
<priority value="warn" />
|
||||
<appender-ref ref="console" />
|
||||
</root>
|
||||
|
||||
</log4j:configuration>
|
|
@ -0,0 +1,6 @@
|
|||
code1=message1
|
||||
code2=message2
|
||||
|
||||
# Example taken from the javadocs for the java.text.MessageFormat class
|
||||
message.format.example1=At '{1,time}' on "{1,date}", there was "{2}" on planet {0,number,integer}.
|
||||
message.format.example2=This is a test message in the message catalog with no args.
|
|
@ -0,0 +1,2 @@
|
|||
# Example taken from the javadocs for the java.text.MessageFormat class
|
||||
message.format.example1=At '{1,time}' on "{1,date}", there was "{2}" on station number {0,number,integer}.
|
|
@ -0,0 +1,5 @@
|
|||
code1=message1
|
||||
|
||||
# Example taken from the javadocs for the java.text.MessageFormat class
|
||||
message.format.example1=At '{1,time}' on "{1,date}", there was "{2}" on planet {0,number,integer}.
|
||||
message.format.example2=This is a test message in the message catalog with no args.
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
|
||||
<!DOCTYPE tiles-definitions PUBLIC
|
||||
"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
|
||||
"http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">
|
||||
|
||||
<tiles-definitions>
|
||||
|
||||
<definition name="testTile" path="/WEB-INF/jsp/layout.jsp">
|
||||
<put name="content" value="/WEB-INF/jsp/content.jsp" type="page"/>
|
||||
</definition>
|
||||
|
||||
<definition name="testTileWithController" controllerClass="org.springframework.web.servlet.view.tiles.TestComponentController">
|
||||
<put name="content" value="/WEB-INF/jsp/otherContent.jsp" type="page"/>
|
||||
</definition>
|
||||
|
||||
</tiles-definitions>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<bean name="/test" class="org.springframework.web.struts.TestAction"/>
|
||||
|
||||
<bean name="/module/test2" class="org.springframework.web.struts.TestAction"/>
|
||||
|
||||
</beans>
|
|
@ -0,0 +1,19 @@
|
|||
Bundle-SymbolicName: org.springframework.web.struts
|
||||
Bundle-Name: Spring Web Struts
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
javax.servlet.*;version="[2.4.0, 3.0.0)",
|
||||
org.apache.commons.beanutils.*;version="[1.7.0, 2.0.0)",
|
||||
org.apache.commons.logging.*;version="[1.0.4, 2.0.0)",
|
||||
org.apache.struts.*;version="[1.2.9, 2.0.0)",
|
||||
org.springframework.beans.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.context.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.util.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.validation.*;version="[3.0.0, 3.0.1)",
|
||||
org.springframework.web.*;version="[3.0.0, 3.0.1)"
|
||||
Ignored-Existing-Headers:
|
||||
Bnd-LastModified,
|
||||
Import-Package,
|
||||
Export-Package,
|
||||
Tool
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="beans" />
|
||||
<orderEntry type="module" module-name="context" />
|
||||
<orderEntry type="module" module-name="core" />
|
||||
<orderEntry type="module" module-name="test" />
|
||||
<orderEntry type="module" module-name="web" />
|
||||
<orderEntry type="library" name="Commons Logging" level="project" />
|
||||
<orderEntry type="library" name="javax.servlet" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/org.apache.struts/com.springsource.org.apache.struts/1.2.9/com.springsource.org.apache.struts-1.2.9.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/org.apache.struts/com.springsource.org.apache.struts/1.2.9/com.springsource.org.apache.struts-sources-1.2.9.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="JUnit" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.beanutils/1.7.0/com.springsource.org.apache.commons.beanutils-1.7.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/org.apache.commons/com.springsource.org.apache.commons.beanutils/1.7.0/com.springsource.org.apache.commons.beanutils-sources-1.7.0.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="EasyMock" level="project" />
|
||||
<orderEntry type="module" module-name="web-servlet" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-1.1.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/javax.servlet/com.springsource.javax.servlet.jsp.jstl/1.1.2/com.springsource.javax.servlet.jsp.jstl-sources-1.1.2.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-2.1.0.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/javax.servlet/com.springsource.javax.servlet.jsp/2.1.0/com.springsource.javax.servlet.jsp-sources-2.1.0.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
|
Loading…
Reference in New Issue