
net.lightbody.bmp.proxy.jetty.jetty.servlet.ServletHolder Maven / Gradle / Ivy
// ========================================================================
// $Id: ServletHolder.java,v 1.53 2005/11/03 08:52:48 gregwilkins Exp $
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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 net.lightbody.bmp.proxy.jetty.jetty.servlet;
import net.lightbody.bmp.proxy.jetty.http.HttpRequest;
import net.lightbody.bmp.proxy.jetty.http.UserRealm;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import org.apache.commons.logging.Log;
import javax.servlet.*;
import java.io.IOException;
import java.security.Principal;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
/* --------------------------------------------------------------------- */
/** Servlet Instance and Context Holder.
* Holds the name, params and some state of a javax.servlet.Servlet
* instance. It implements the ServletConfig interface.
* This class will organise the loading of the servlet when needed or
* requested.
*
* @version $Id: ServletHolder.java,v 1.53 2005/11/03 08:52:48 gregwilkins Exp $
* @author Greg Wilkins
*/
public class ServletHolder extends Holder
implements Comparable
{
private static Log log = LogFactory.getLog(ServletHolder.class);
/* ---------------------------------------------------------------- */
private int _initOrder;
private boolean _initOnStartup=false;
private Map _roleMap;
private String _forcedPath;
private String _runAs;
private UserRealm _realm;
private transient Stack _servlets;
private transient Servlet _servlet;
private transient Config _config;
private transient long _unavailable;
private transient UnavailableException _unavailableEx;
/* ---------------------------------------------------------------- */
/** Constructor for Serialization.
*/
public ServletHolder()
{}
/* ---------------------------------------------------------------- */
/** Constructor.
* @param handler The ServletHandler instance for this servlet.
* @param name The name of the servlet.
* @param className The class name of the servlet.
*/
public ServletHolder(ServletHandler handler,
String name,
String className)
{
super(handler,(name==null)?className:name,className);
}
/* ---------------------------------------------------------------- */
/** Constructor.
* @param handler The ServletHandler instance for this servlet.
* @param name The name of the servlet.
* @param className The class name of the servlet.
* @param forcedPath If non null, the request attribute
* javax.servlet.include.servlet_path will be set to this path before
* service is called.
*/
public ServletHolder(ServletHandler handler,
String name,
String className,
String forcedPath)
{
this(handler,(name==null)?className:name,className);
_forcedPath=forcedPath;
}
/* ------------------------------------------------------------ */
public int getInitOrder()
{
return _initOrder;
}
/* ------------------------------------------------------------ */
/** Set the initialize order.
* Holders with order<0, are initialized on use. Those with
* order>=0 are initialized in increasing order when the handler
* is started.
*/
public void setInitOrder(int order)
{
_initOnStartup=true;
_initOrder = order;
}
/* ------------------------------------------------------------ */
/** Comparitor by init order.
*/
public int compareTo(Object o)
{
if (o instanceof ServletHolder)
{
ServletHolder sh= (ServletHolder)o;
if (sh==this)
return 0;
if (sh._initOrder<_initOrder)
return 1;
if (sh._initOrder>_initOrder)
return -1;
int c=_className.compareTo(sh._className);
if (c==0)
c=_name.compareTo(sh._name);
if (c==0)
c=this.hashCode()>o.hashCode()?1:-1;
return c;
}
return 1;
}
/* ------------------------------------------------------------ */
public boolean equals(Object o)
{
return compareTo(o)==0;
}
/* ------------------------------------------------------------ */
public int hashCode()
{
return _name.hashCode();
}
/* ---------------------------------------------------------------- */
public ServletContext getServletContext()
{
return ((ServletHandler)_httpHandler).getServletContext();
}
/* ------------------------------------------------------------ */
/** Link a user role.
* Translate the role name used by a servlet, to the link name
* used by the container.
* @param name The role name as used by the servlet
* @param link The role name as used by the container.
*/
public synchronized void setUserRoleLink(String name,String link)
{
if (_roleMap==null)
_roleMap=new HashMap();
_roleMap.put(name,link);
}
/* ------------------------------------------------------------ */
/** get a user role link.
* @param name The name of the role
* @return The name as translated by the link. If no link exists,
* the name is returned.
*/
public String getUserRoleLink(String name)
{
if (_roleMap==null)
return name;
String link=(String)_roleMap.get(name);
return (link==null)?name:link;
}
/* ------------------------------------------------------------ */
/**
* @param role Role name that is added to UserPrincipal when this servlet
* is called.
*/
public void setRunAs(String role)
{
_runAs=role;
}
/* ------------------------------------------------------------ */
public String getRunAs()
{
return _runAs;
}
/* ------------------------------------------------------------ */
public void start()
throws Exception
{
_unavailable=0;
super.start();
if (!javax.servlet.Servlet.class
.isAssignableFrom(_class))
{
Exception ex = new IllegalStateException("Servlet "+_class+
" is not a javax.servlet.Servlet");
super.stop();
throw ex;
}
_config=new Config();
if (_runAs!=null)
_realm=_httpHandler.getHttpContext().getRealm();
if (javax.servlet.SingleThreadModel.class
.isAssignableFrom(_class))
_servlets=new Stack();
if (_initOnStartup)
{
_servlet=(Servlet)newInstance();
try
{
initServlet(_servlet,_config);
}
catch(Throwable e)
{
_servlet=null;
_config=null;
if (e instanceof Exception)
throw (Exception) e;
else if (e instanceof Error)
throw (Error)e;
else
throw new ServletException(e);
}
}
}
/* ------------------------------------------------------------ */
public void stop()
{
Principal user=null;
try
{
// Handle run as
if (_runAs!=null && _realm!=null)
user=_realm.pushRole(null,_runAs);
if (_servlet!=null)
_servlet.destroy();
_servlet=null;
while (_servlets!=null && _servlets.size()>0)
{
Servlet s = (Servlet)_servlets.pop();
s.destroy();
}
_config=null;
}
finally
{
super.stop();
// pop run-as role
if (_runAs!=null && _realm!=null && user!=null)
_realm.popRole(user);
}
}
/* ------------------------------------------------------------ */
/** Get the servlet.
* @return The servlet
*/
public synchronized Servlet getServlet()
throws ServletException
{
// Handle previous unavailability
if (_unavailable!=0)
{
if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
throw _unavailableEx;
_unavailable=0;
_unavailableEx=null;
}
try
{
if (_servlets!=null)
{
Servlet servlet=null;
if (_servlets.size()==0)
{
servlet= (Servlet)newInstance();
if (_config==null)
_config=new Config();
initServlet(servlet,_config);
}
else
servlet = (Servlet)_servlets.pop();
return servlet;
}
if (_servlet==null)
{
_servlet=(Servlet)newInstance();
if (_config==null)
_config=new Config();
initServlet(_servlet,_config);
}
return _servlet;
}
catch(UnavailableException e)
{
_servlet=null;
_config=null;
return makeUnavailable(e);
}
catch(ServletException e)
{
_servlet=null;
_config=null;
throw e;
}
catch(Throwable e)
{
_servlet=null;
_config=null;
throw new ServletException("init",e);
}
}
/* ------------------------------------------------------------ */
private Servlet makeUnavailable(UnavailableException e)
throws UnavailableException
{
_unavailableEx=e;
_unavailable=-1;
if (e.isPermanent())
_unavailable=-1;
else
{
if (_unavailableEx.getUnavailableSeconds()>0)
_unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
else
_unavailable=System.currentTimeMillis()+5000; // TODO configure
}
throw _unavailableEx;
}
/* ------------------------------------------------------------ */
private void initServlet(Servlet servlet, ServletConfig config)
throws ServletException
{
Principal user=null;
try
{
// Handle run as
if (_runAs!=null && _realm!=null)
user=_realm.pushRole(null,_runAs);
servlet.init(config);
}
finally
{
// pop run-as role
if (_runAs!=null && _realm!=null && user!=null)
_realm.popRole(user);
}
}
/* ------------------------------------------------------------ */
/** Service a request with this servlet.
*/
public void handle(ServletRequest request,
ServletResponse response)
throws ServletException,
UnavailableException,
IOException
{
if (_class==null)
throw new UnavailableException("Servlet Not Initialized");
Servlet servlet=(!_initOnStartup||_servlets!=null)?getServlet():_servlet;
if (servlet==null)
throw new UnavailableException("Could not instantiate "+_class);
// Service the request
boolean servlet_error=true;
Principal user=null;
HttpRequest http_request=null;
try
{
// Handle aliased path
if (_forcedPath!=null)
// TODO complain about poor naming to the Jasper folks
request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
// Handle run as
if (_runAs!=null && _realm!=null)
{
http_request=getHttpContext().getHttpConnection().getRequest();
user=_realm.pushRole(http_request.getUserPrincipal(),_runAs);
http_request.setUserPrincipal(user);
}
servlet.service(request,response);
servlet_error=false;
}
catch(UnavailableException e)
{
if (_servlets!=null && servlet!=null)
stop();
makeUnavailable(e);
}
finally
{
// pop run-as role
if (_runAs!=null && _realm!=null && user!=null)
{
user=_realm.popRole(user);
http_request.setUserPrincipal(user);
}
// Handle error params.
if (servlet_error)
request.setAttribute("javax.servlet.error.servlet_name",getName());
// Return to singleThreaded pool
synchronized(this)
{
if (_servlets!=null && servlet!=null)
_servlets.push(servlet);
}
}
}
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
class Config implements ServletConfig
{
/* -------------------------------------------------------- */
public String getServletName()
{
return getName();
}
/* -------------------------------------------------------- */
public ServletContext getServletContext()
{
return ((ServletHandler)_httpHandler).getServletContext();
}
/* -------------------------------------------------------- */
public String getInitParameter(String param)
{
return ServletHolder.this.getInitParameter(param);
}
/* -------------------------------------------------------- */
public Enumeration getInitParameterNames()
{
return ServletHolder.this.getInitParameterNames();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy