alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Spring Framework example source code file (ContextLoaderPlugIn.java)

This example Spring Framework source code file (ContextLoaderPlugIn.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Spring Framework tags/keywords

actionservlet, actionservlet, class, configurablewebapplicationcontext, contextloaderplugin, default_context_class, default_namespace_suffix, moduleconfig, servlet, string, string, struts, struts, webapplicationcontext, webapplicationcontext

The Spring Framework ContextLoaderPlugIn.java source code

/*
 * 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.
 * 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
 */
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 getActionServlet()
	 * and/or <code>getModuleConfig() 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();
		}
	}

}

Other Spring Framework examples (source code examples)

Here is a short list of links related to this Spring Framework ContextLoaderPlugIn.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.