// $HeadURL$ // $Id$ // // Copyright © 2010 by the President and Fellows of Harvard College. // // Screensaver is an open-source project developed by the ICCB-L and NSRB labs // at Harvard Medical School. This software is distributed under the terms of // the GNU General Public License. package edu.harvard.med.screensaver.ui.arch.util.servlet; import java.io.IOException; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import edu.harvard.med.screensaver.ScreensaverProperties; import edu.harvard.med.screensaver.ui.ApplicationInfo; import edu.harvard.med.screensaver.util.StringUtils; /** * Proxy for a standard Servlet, delegating to a Spring-managed * bean that implements the Servlet interface.<br> * The servlet init-param, "beanName", in <code>web.xml</code>, specifying the name of the * target bean in the Spring application context is required. * <p> * <code>web.xml</code> will usually contain a DelegatingServletProxy definition, with the specified * <code>servlet-name</code> corresponding to a bean name in Spring's root application context. All calls to the servlet * proxy will then be delegated to that bean in the Spring context, which is required to conform to the {@link Servlet} * interface and implement the {@link Servlet#service(ServletRequest, ServletResponse)} method. * <p> * This is useful when it is desired to initialize bean state (parameters) from properties in the * {@link ScreensaverProperties} or the {@link ApplicationInfo} . */ @SuppressWarnings("serial") public class DelegatingServletProxy extends HttpServlet // implements BeanNameAware, ServletContextAware { private static Logger log = Logger.getLogger(DelegatingServletProxy.class); private static final String PARAMETER_BEAN_NAME = "beanName"; private String _beanName; private Servlet _delegate; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { service(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { getDelegate().service(req, res); } public void setBeanName(String name) { _beanName = name; } public String getBeanName() { return _beanName; } private synchronized Servlet getDelegate() { if (this._delegate == null) { WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); if (wac == null) { throw new IllegalStateException("No WebApplicationContext found: no ContextLoaderListener registered?"); } this._delegate = (Servlet) wac.getBean(getBeanName(), Servlet.class); if (_delegate == null) { throw new IllegalStateException("The bean: \"" + getBeanName() + "\" could not be retrieved from the WebApplicationContext."); } } return this._delegate; } /** * Implement the init method, checking for the req'd property: <br> * <b>beanName</b><br> * Initialize the instance to the delegate Spring bean corresponding to the beanName. */ @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); if (servletConfig == null) throw new ServletException("servletConfig must not be null"); if (log.isDebugEnabled()) { log.debug("Initializing filter '" + servletConfig.getServletName() + "'"); } String beanName = servletConfig.getInitParameter(PARAMETER_BEAN_NAME); if (StringUtils.isEmpty(beanName)) { throw new ServletException("The parameter: " + PARAMETER_BEAN_NAME + " must be given."); } setBeanName(beanName); getDelegate(); // force initialization } }