001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * bstefanescu 011 */ 012package org.nuxeo.ecm.webengine.jaxrs.servlet; 013 014import java.io.IOException; 015 016import javax.servlet.ServletConfig; 017import javax.servlet.ServletException; 018import javax.servlet.http.HttpServlet; 019import javax.servlet.http.HttpServletRequest; 020import javax.servlet.http.HttpServletResponse; 021 022import org.nuxeo.ecm.webengine.jaxrs.BundleNotFoundException; 023import org.nuxeo.ecm.webengine.jaxrs.servlet.config.ListenerSetDescriptor; 024import org.nuxeo.ecm.webengine.jaxrs.servlet.config.ServletDescriptor; 025import org.nuxeo.ecm.webengine.jaxrs.servlet.config.ServletRegistry; 026 027/** 028 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 029 */ 030public class ServletHolder extends HttpServlet { 031 032 private static final long serialVersionUID = 1L; 033 034 protected RequestChain chain; 035 036 protected ServletDescriptor descriptor; 037 038 protected volatile boolean initDone = false; 039 040 protected String getName(ServletConfig config) { 041 String name = config.getInitParameter(ServletRegistry.SERVLET_NAME); 042 if (name == null) { 043 name = config.getServletName(); 044 } 045 return name; 046 } 047 048 protected ServletDescriptor getDescriptor(ServletConfig config) throws ServletException { 049 String name = getName(config); 050 if (name == null) { 051 throw new ServletException("No name defined for the ServletHolder. Check your servlet contributions."); 052 } 053 ServletDescriptor desc = ServletRegistry.getInstance().getServletDescriptor(name); 054 if (desc == null) { 055 throw new ServletException("No such servlet descriptor: " + name); 056 } 057 return desc; 058 } 059 060 @Override 061 public void init(ServletConfig config) throws ServletException { 062 try { 063 descriptor = getDescriptor(config); 064 chain = new RequestChain(descriptor.getServlet(), descriptor.getFilters()); 065 ListenerSetDescriptor listeners = descriptor.getListenerSet(); 066 if (listeners != null) { 067 // initialize listeners if not already initialized 068 listeners.init(config); 069 } 070 super.init(config); 071 // lazy chain.init(descriptor, config); 072 } catch (ServletException e) { 073 throw e; 074 } catch (ReflectiveOperationException | BundleNotFoundException e) { 075 throw new ServletException("Initialization exception for servlet " + config.getServletName(), e); 076 } 077 } 078 079 @Override 080 public void destroy() { 081 super.destroy(); 082 initDone = false; 083 if (chain != null) { 084 chain.destroy(); 085 chain = null; 086 } 087 } 088 089 @Override 090 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, 091 IOException { 092 Thread t = Thread.currentThread(); 093 ClassLoader cl = t.getContextClassLoader(); 094 try { 095 if (!initDone) { 096 lazyInit(); 097 } 098 // use servlet class loader as the context class loader 099 t.setContextClassLoader(chain.servlet.getClass().getClassLoader()); 100 chain.execute(request, response); 101 } finally { 102 t.setContextClassLoader(cl); 103 } 104 } 105 106 protected synchronized void lazyInit() throws ServletException { 107 try { 108 chain.init(descriptor, getServletConfig()); 109 } finally { 110 initDone = true; 111 } 112 } 113 114}