]> WPIA git - gigi.git/blobdiff - lib/jetty/org/eclipse/jetty/servlet/ServletHolder.java
updating jetty to jetty-9.2.16.v2016040
[gigi.git] / lib / jetty / org / eclipse / jetty / servlet / ServletHolder.java
index 1df08b33dc6d793e558a4bc736fe88d8dcad780b..73e1ccf864faa4a0ab62e1e75c5e9a15d82187d6 100644 (file)
@@ -1,6 +1,6 @@
 //
 //  ========================================================================
-//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+//  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
 //  ------------------------------------------------------------------------
 //  All rights reserved. This program and the accompanying materials
 //  are made available under the terms of the Eclipse Public License v1.0
@@ -18,6 +18,7 @@
 
 package org.eclipse.jetty.servlet;
 
+import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -69,18 +70,19 @@ import org.eclipse.jetty.util.log.Logger;
 @ManagedObject("Servlet Holder")
 public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable<ServletHolder>
 {
-    private static final Logger LOG = Log.getLogger(ServletHolder.class);
 
     /* ---------------------------------------------------------------- */
+    private static final Logger LOG = Log.getLogger(ServletHolder.class);
     private int _initOrder = -1;
     private boolean _initOnStartup=false;
+    private boolean _initialized = false;
     private Map<String, String> _roleMap;
     private String _forcedPath;
     private String _runAsRole;
     private RunAsToken _runAsToken;
     private IdentityService _identityService;
     private ServletRegistration.Dynamic _registration;
-
+    private JspContainer _jspContainer;
 
     private transient Servlet _servlet;
     private transient Config _config;
@@ -88,8 +90,11 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
     private transient boolean _enabled = true;
     private transient UnavailableException _unavailableEx;
 
+    public static final String GLASSFISH_SENTINEL_CLASS = "org.glassfish.jsp.api.ResourceInjector";
+    public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
     public static final  String JSP_GENERATED_PACKAGE_NAME = "org.eclipse.jetty.servlet.jspPackagePrefix";
     public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
+    public static enum JspContainer {GLASSFISH, APACHE, OTHER}; 
 
     /* ---------------------------------------------------------------- */
     /** Constructor .
@@ -289,11 +294,13 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         {
             // Look for a precompiled JSP Servlet
             String precompiled=getClassNameForJsp(_forcedPath);
-            LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
+            if (LOG.isDebugEnabled())
+                LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
             ServletHolder jsp=getServletHandler().getServlet(precompiled);
-            if (jsp!=null)
+            if (jsp!=null && jsp.getClassName() !=  null)
             {
-                LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
+                if (LOG.isDebugEnabled())
+                    LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
                 // set the className for this servlet to the precompiled one
                 setClassName(jsp.getClassName());
             }
@@ -305,7 +312,8 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
                     jsp=getServletHandler().getServlet("jsp");
                     if (jsp!=null)
                     {
-                        LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
+                        if (LOG.isDebugEnabled())
+                            LOG.debug("JSP file {} for {} mapped to Servlet class {}",_forcedPath, getName(),jsp.getClassName());
                         setClassName(jsp.getClassName());
                         //copy jsp init params that don't exist for this servlet
                         for (Map.Entry<String, String> entry:jsp.getInitParameters().entrySet())
@@ -313,9 +321,11 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
                             if (!_initParams.containsKey(entry.getKey()))
                                 setInitParameter(entry.getKey(), entry.getValue());
                         }
-                        //jsp specific: set up the jsp-file on the JspServlet so it can precompile iff load-on-startup is >=0
-                        if (_initOnStartup)
-                            setInitParameter("jspFile", _forcedPath);
+                        //jsp specific: set up the jsp-file on the JspServlet. If load-on-startup is >=0 and the jsp container supports
+                        //precompilation, the jsp will be compiled when this holder is initialized. If not load on startup, or the
+                        //container does not support startup precompilation, it will be compiled at runtime when handling a request for this jsp.
+                        //See also adaptForcedPathToJspContainer
+                        setInitParameter("jspFile", _forcedPath);
                     }                       
                 }
             }
@@ -368,7 +378,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
 
         if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
             _servlet = new SingleThreadedWrapper();
-     
+
     }
     
     
@@ -377,21 +387,24 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
     public void initialize ()
     throws Exception
     {
-        super.initialize();
-        if (_extInstance || _initOnStartup)
-        {
-            try
-            {
-                initServlet();
-            }
-            catch(Exception e)
+        if(!_initialized){
+            super.initialize();
+            if (_extInstance || _initOnStartup)
             {
-                if (_servletHandler.isStartWithUnavailable())
-                    LOG.ignore(e);
-                else
-                    throw e;
+                try
+                {
+                    initServlet();
+                }
+                catch(Exception e)
+                {
+                    if (_servletHandler.isStartWithUnavailable())
+                        LOG.ignore(e);
+                    else
+                        throw e;
+                }
             }
         }
+        _initialized = true;
     }
     
     
@@ -424,6 +437,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
             _servlet=null;
 
         _config=null;
+        _initialized = false;
     }
 
     /* ------------------------------------------------------------ */
@@ -565,7 +579,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
 
     /* ------------------------------------------------------------ */
     private void initServlet()
-       throws ServletException
+        throws ServletException
     {
         Object old_run_as = null;
         try
@@ -587,11 +601,18 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
             if (isJspServlet())
             {
                 initJspServlet();
+                detectJspContainer();
             }
 
             initMultiPart();
 
-            LOG.debug("Filter.init {}",_servlet);
+            if (_forcedPath != null && _jspContainer == null)
+            {
+                detectJspContainer();
+            }
+
+            if (LOG.isDebugEnabled())
+                LOG.debug("Servlet.init {} for {}",_servlet,getName());
             _servlet.init(_config);
         }
         catch (UnavailableException e)
@@ -642,10 +663,23 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         if ("?".equals(getInitParameter("classpath")))
         {
             String classpath = ch.getClassPath();
-            LOG.debug("classpath=" + classpath);
+            if (LOG.isDebugEnabled())
+                LOG.debug("classpath=" + classpath);
             if (classpath != null)
                 setInitParameter("classpath", classpath);
         }
+        
+        /* ensure scratch dir */
+        File scratch = null;
+        if (getInitParameter("scratchdir") == null)
+        {
+            File tmp = (File)getServletHandler().getServletContext().getAttribute(ServletContext.TEMPDIR);
+            scratch = new File(tmp, "jsp");
+            setInitParameter("scratchdir", scratch.getAbsolutePath());
+        }
+     
+        scratch = new File (getInitParameter("scratchdir"));
+        if (!scratch.exists()) scratch.mkdir();
     }
 
     /* ------------------------------------------------------------ */
@@ -701,9 +735,50 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
     {
         _runAsRole = role;
     }
+    
+    /* ------------------------------------------------------------ */
+    /**
+     * Prepare to service a request.
+     * 
+     * @param baseRequest
+     * @param request
+     * @param response
+     * @throws ServletException
+     * @throws UnavailableException
+     */
+    protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
+    throws ServletException, UnavailableException
+    {
+        ensureInstance();
+        MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
+        if (mpce != null)
+            baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
+    }
+    
+    public synchronized Servlet ensureInstance()
+    throws ServletException, UnavailableException
+    {
+        if (_class==null)
+            throw new UnavailableException("Servlet Not Initialized");
+        Servlet servlet=_servlet;
+        if (!isStarted())
+            throw new UnavailableException("Servlet not initialized", -1);
+        if (_unavailable!=0 || (!_initOnStartup && servlet==null))
+            servlet=getServlet();
+        if (servlet==null)
+            throw new UnavailableException("Could not instantiate "+_class);    
+        
+        return servlet;
+    }
 
     /* ------------------------------------------------------------ */
     /** Service a request with this servlet.
+     * @param baseRequest
+     * @param request
+     * @param response
+     * @throws ServletException
+     * @throws UnavailableException
+     * @throws IOException
      */
     public void handle(Request baseRequest,
                        ServletRequest request,
@@ -715,16 +790,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         if (_class==null)
             throw new UnavailableException("Servlet Not Initialized");
 
-        Servlet servlet=_servlet;
-        synchronized(this)
-        {
-            if (!isStarted())
-                throw new UnavailableException("Servlet not initialized", -1);
-            if (_unavailable!=0 || (!_initOnStartup && servlet==null))
-                servlet=getServlet();
-            if (servlet==null)
-                throw new UnavailableException("Could not instantiate "+_class);
-        }
+        Servlet servlet = ensureInstance();
 
         // Service the request
         boolean servlet_error=true;
@@ -734,8 +800,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         {
             // Handle aliased path
             if (_forcedPath!=null)
-                // TODO complain about poor naming to the Jasper folks
-                request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
+                adaptForcedPathToJspContainer(request);
 
             // Handle run as
             if (_identityService!=null)
@@ -744,10 +809,6 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
             if (!isAsyncSupported())
                 baseRequest.setAsyncSupported(false);
 
-            MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
-            if (mpce != null)
-                request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
-
             servlet.service(request,response);
             servlet_error=false;
         }
@@ -777,7 +838,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         if (_servlet == null)
             return false;
 
-        Class c = _servlet.getClass();
+        Class<?> c = _servlet.getClass();
 
         boolean result = false;
         while (c != null && !result)
@@ -797,8 +858,51 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
             return false;
         return ("org.apache.jasper.servlet.JspServlet".equals(classname));
     }
-    
-    
+
+    /* ------------------------------------------------------------ */
+    private void adaptForcedPathToJspContainer (ServletRequest request)
+    {
+        if (_forcedPath != null && _jspContainer != null && JspContainer.GLASSFISH.equals(_jspContainer))
+        {
+            //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
+            //ensure the delegate jsp will be compiled
+
+            request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
+        }
+    }
+
+    /* ------------------------------------------------------------ */
+    private void detectJspContainer ()
+    {
+        if (_jspContainer == null)
+        {
+            //check for glassfish
+            try
+            {
+                //if container is glassfish, set the request attribute org.apache.catalina.jsp_file to
+                //ensure the delegate jsp will be compiled
+                Loader.loadClass(Holder.class, GLASSFISH_SENTINEL_CLASS);
+                if (LOG.isDebugEnabled())LOG.debug("Glassfish jasper detected");
+                _jspContainer = JspContainer.GLASSFISH;
+            }
+            catch (ClassNotFoundException e)
+            {
+                try
+                {
+                    //check for apache
+                    Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS);
+                    if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
+                    _jspContainer = JspContainer.APACHE;
+                }
+                catch (ClassNotFoundException x)
+                {
+                    if (LOG.isDebugEnabled())LOG.debug("Other jasper detected");
+                    _jspContainer = JspContainer.OTHER;
+                }
+            }
+        }
+    }
+
     /* ------------------------------------------------------------ */
     private String getNameOfJspClass (String jsp)
     {
@@ -809,7 +913,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
         jsp = jsp.substring(i);
         try
         {
-            Class jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
+            Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
             Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
             return (String)makeJavaIdentifier.invoke(null, jsp);
         }
@@ -835,7 +939,7 @@ public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope
             return "";
         try
         {
-            Class jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
+            Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
             Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
             return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
         }