Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@2127 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
33 changed files with 3931 additions and 0 deletions
@ -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