001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.servlet.handler;
018:
019: import java.util.Collections;
020: import java.util.Enumeration;
021:
022: import javax.servlet.Servlet;
023: import javax.servlet.ServletConfig;
024: import javax.servlet.ServletContext;
025: import javax.servlet.ServletException;
026:
027: import org.springframework.beans.BeansException;
028: import org.springframework.beans.factory.BeanInitializationException;
029: import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
030: import org.springframework.web.context.ServletConfigAware;
031: import org.springframework.web.context.ServletContextAware;
032:
033: /**
034: * {@link org.springframework.beans.factory.config.BeanPostProcessor}
035: * that applies initialization and destruction callbacks to beans that
036: * implement the {@link javax.servlet.Servlet} interface.
037: *
038: * <p>After initialization of the bean instance, the Servlet <code>init</code>
039: * method will be called with a ServletConfig that contains the bean name
040: * of the Servlet and the ServletContext that it is running in.
041: *
042: * <p>Before destruction of the bean instance, the Servlet <code>destroy</code>
043: * will be called.
044: *
045: * <p><b>Note that this post-processor does not support Servlet initialization
046: * parameters.</b> Bean instances that implement the Servlet interface are
047: * supposed to be configured like any other Spring bean, that is, through
048: * constructor arguments or bean properties.
049: *
050: * <p>For reuse of a Servlet implementation in a plain Servlet container
051: * and as a bean in a Spring context, consider deriving from Spring's
052: * {@link org.springframework.web.servlet.HttpServletBean} base class that
053: * applies Servlet initialization parameters as bean properties, supporting
054: * both the standard Servlet and the Spring bean initialization style.
055: *
056: * <p><b>Alternatively, consider wrapping a Servlet with Spring's
057: * {@link org.springframework.web.servlet.mvc.ServletWrappingController}.</b>
058: * This is particularly appropriate for existing Servlet classes,
059: * allowing to specify Servlet initialization parameters etc.
060: *
061: * @author Juergen Hoeller
062: * @since 1.1.5
063: * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
064: * @see javax.servlet.Servlet#destroy()
065: * @see SimpleServletHandlerAdapter
066: */
067: public class SimpleServletPostProcessor implements
068: DestructionAwareBeanPostProcessor, ServletContextAware,
069: ServletConfigAware {
070:
071: private boolean useSharedServletConfig = true;
072:
073: private ServletContext servletContext;
074:
075: private ServletConfig servletConfig;
076:
077: /**
078: * Set whether to use the shared ServletConfig object passed in
079: * through <code>setServletConfig</code>, if available.
080: * <p>Default is "true". Turn this setting to "false" to pass in
081: * a mock ServletConfig object with the bean name as servlet name,
082: * holding the current ServletContext.
083: * @see #setServletConfig
084: */
085: public void setUseSharedServletConfig(boolean useSharedServletConfig) {
086: this .useSharedServletConfig = useSharedServletConfig;
087: }
088:
089: public void setServletContext(ServletContext servletContext) {
090: this .servletContext = servletContext;
091: }
092:
093: public void setServletConfig(ServletConfig servletConfig) {
094: this .servletConfig = servletConfig;
095: }
096:
097: public Object postProcessBeforeInitialization(Object bean,
098: String beanName) throws BeansException {
099: return bean;
100: }
101:
102: public Object postProcessAfterInitialization(Object bean,
103: String beanName) throws BeansException {
104: if (bean instanceof Servlet) {
105: ServletConfig config = this .servletConfig;
106: if (config == null || !this .useSharedServletConfig) {
107: config = new DelegatingServletConfig(beanName,
108: this .servletContext);
109: }
110: try {
111: ((Servlet) bean).init(config);
112: } catch (ServletException ex) {
113: throw new BeanInitializationException(
114: "Servlet.init threw exception", ex);
115: }
116: }
117: return bean;
118: }
119:
120: public void postProcessBeforeDestruction(Object bean,
121: String beanName) throws BeansException {
122: if (bean instanceof Servlet) {
123: ((Servlet) bean).destroy();
124: }
125: }
126:
127: /**
128: * Internal implementation of the {@link ServletConfig} interface,
129: * to be passed to the wrapped servlet.
130: */
131: private static class DelegatingServletConfig implements
132: ServletConfig {
133:
134: private final String servletName;
135:
136: private final ServletContext servletContext;
137:
138: public DelegatingServletConfig(String servletName,
139: ServletContext servletContext) {
140: this .servletName = servletName;
141: this .servletContext = servletContext;
142: }
143:
144: public String getServletName() {
145: return this .servletName;
146: }
147:
148: public ServletContext getServletContext() {
149: return this .servletContext;
150: }
151:
152: public String getInitParameter(String paramName) {
153: return null;
154: }
155:
156: public Enumeration getInitParameterNames() {
157: return Collections.enumeration(Collections.EMPTY_SET);
158: }
159: }
160:
161: }
|