alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (ServletHolder.java)

This example Jetty source code file (ServletHolder.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

config, exception, io, ioexception, principal, security, servlet, servlet, servletconfig, servletexception, servletexception, servletholder, string, string, unavailableexception, unavailableexception, util

The Jetty ServletHolder.java source code

// ========================================================================
// 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 org.mortbay.jetty.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;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.SingleThreadModel;
import javax.servlet.UnavailableException;

import org.mortbay.jetty.HttpConnection;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.handler.ContextHandler;
import org.mortbay.jetty.security.SecurityHandler;
import org.mortbay.jetty.security.UserRealm;
import org.mortbay.log.Log;



/* --------------------------------------------------------------------- */
/** 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.
 *
 * @author Greg Wilkins
 */
public class ServletHolder extends Holder
    implements Comparable
{
    /* ---------------------------------------------------------------- */
    private int _initOrder;
    private boolean _initOnStartup=false;
    private Map _roleMap; 
    private String _forcedPath;
    private String _runAs;
    private UserRealm _realm;    
    
    private transient Servlet _servlet;
    private transient Config _config;
    private transient long _unavailable;
    private transient UnavailableException _unavailableEx;

    
    /* ---------------------------------------------------------------- */
    /** Constructor .
     */
    public ServletHolder()
    {}
    
    /* ---------------------------------------------------------------- */
    /** Constructor for existing servlet.
     */
    public ServletHolder(Servlet servlet)
    {
        setServlet(servlet);
    }

    /* ---------------------------------------------------------------- */
    /** Constructor for existing servlet.
     */
    public ServletHolder(Class servlet)
    {
        super(servlet);
    }
    
    /* ------------------------------------------------------------ */
    public synchronized void setServlet(Servlet servlet)
    {
        if (servlet==null || servlet instanceof SingleThreadModel)
            throw new IllegalArgumentException();

        _extInstance=true;
        _servlet=servlet;
        setHeldClass(servlet.getClass());
        if (getName()==null)
            setName(servlet.getClass().getName()+"-"+super.hashCode());
    }
    
    /* ------------------------------------------------------------ */
    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!=null && sh._className!=null)?_className.compareTo(sh._className):0;
            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==null?System.identityHashCode(this):_name.hashCode();
    }

    /* ------------------------------------------------------------ */
    /** 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;
    }

    /* ------------------------------------------------------------ */
    public Map getRoleMap()
    {
        return _roleMap;
    }
    
    /* ------------------------------------------------------------ */
    /** 
     * @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;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @return Returns the forcedPath.
     */
    public String getForcedPath()
    {
        return _forcedPath;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param forcedPath The forcedPath to set.
     */
    public void setForcedPath(String forcedPath)
    {
        _forcedPath = forcedPath;
    }
    
    /* ------------------------------------------------------------ */
    public void doStart()
    throws Exception
    {
        _unavailable=0;
        try
        {
            super.doStart();
            checkServletType();
        }
        catch (UnavailableException ue)
        {
            makeUnavailable(ue);
        }

        _config=new Config();

        if (_runAs!=null)
            _realm=((SecurityHandler)(ContextHandler.getCurrentContext()
                    .getContextHandler().getChildHandlerByClass(SecurityHandler.class))).getUserRealm();

        if (javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
            _servlet = new SingleThreadedWrapper();

        if (_extInstance || _initOnStartup)
        {
            if (_servlet==null)
                _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 doStop()
    {
        Principal user=null;
        try
        {
            // Handle run as
            if (_runAs!=null && _realm!=null)
                user=_realm.pushRole(null,_runAs);
                
            if (_servlet!=null)
            {                  
                try
                {
                    destroyInstance(_servlet);
                }
                catch (Exception e)
                {
                    Log.warn(e);
                }
            }
            
            if (!_extInstance)
                _servlet=null;
           
            _config=null;
        }
        finally
        {
            super.doStop();
            // pop run-as role
            if (_runAs!=null && _realm!=null && user!=null)
                _realm.popRole(user); 
        }
    }

    /* ------------------------------------------------------------ */
    public void destroyInstance (Object o)
    throws Exception
    {
        if (o==null)
            return;
        Servlet servlet =  ((Servlet)o);
        servlet.destroy();
        getServletHandler().customizeServletDestroy(servlet);
    }

    /* ------------------------------------------------------------ */
    /** 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 (_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);
        }    
    }

    /* ------------------------------------------------------------ */
    /**
     * Check to ensure class of servlet is acceptable.
     * @throws UnavailableException
     */
    public void checkServletType ()
        throws UnavailableException
    {
        if (!javax.servlet.Servlet.class.isAssignableFrom(_class))
        {
            throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
        }
    }

    /* ------------------------------------------------------------ */
    /** 
     * @return true if the holder is started and is not unavailable
     */
    public boolean isAvailable()
    {
        if (isStarted()&& _unavailable==0)
            return true;
        try 
        {
            getServlet();
        }
        catch(Exception e)
        {
            Log.ignore(e);
        }

        return isStarted()&& _unavailable==0;
    }
    
    /* ------------------------------------------------------------ */
    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 any cusomizations of the servlet, such as @postConstruct
            _servlet = getServletHandler().customizeServlet(servlet);
            
            // Handle run as
            if (_runAs!=null && _realm!=null)
                user=_realm.pushRole(null,_runAs);
            servlet.init(config);
        }
        catch (Exception e)
        {
            throw new ServletException(e);
        }
        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=_servlet;
        synchronized(this)
        {
            if (_unavailable!=0 || !_initOnStartup)
            servlet=getServlet();
            if (servlet==null)
                throw new UnavailableException("Could not instantiate "+_class);
        }
        
        // Service the request
        boolean servlet_error=true;
        Principal user=null;
        Request base_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)
            {
                base_request=HttpConnection.getCurrentConnection().getRequest();
                user=_realm.pushRole(base_request.getUserPrincipal(),_runAs);
                base_request.setUserPrincipal(user);
            }
            
            servlet.service(request,response);
            servlet_error=false;
        }
        catch(UnavailableException e)
        {
            makeUnavailable(e);
        }
        finally
        {
            // pop run-as role
            if (_runAs!=null && _realm!=null && user!=null && base_request!=null)
            {
                user=_realm.popRole(user);
                base_request.setUserPrincipal(user);
            }

            // Handle error params.
            if (servlet_error)
                request.setAttribute("javax.servlet.error.servlet_name",getName());
        }
    }

 
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    /* ------------------------------------------------------------ */
    class Config implements ServletConfig
    {   
        /* -------------------------------------------------------- */
        public String getServletName()
        {
            return getName();
        }
        
        /* -------------------------------------------------------- */
        public ServletContext getServletContext()
        {
            return _servletHandler.getServletContext();
        }

        /* -------------------------------------------------------- */
        public String getInitParameter(String param)
        {
            return ServletHolder.this.getInitParameter(param);
        }
    
        /* -------------------------------------------------------- */
        public Enumeration getInitParameterNames()
        {
            return ServletHolder.this.getInitParameterNames();
        }
    }

    /* -------------------------------------------------------- */
    /* -------------------------------------------------------- */
    /* -------------------------------------------------------- */
    private class SingleThreadedWrapper implements Servlet
    {
        Stack _stack=new Stack();
        
        public void destroy()
        {
            synchronized(this)
            {
                while(_stack.size()>0)
                    try { ((Servlet)_stack.pop()).destroy(); } catch (Exception e) { Log.warn(e); }
            }
        }

        public ServletConfig getServletConfig()
        {
            return _config;
        }

        public String getServletInfo()
        {
            return null;
        }

        public void init(ServletConfig config) throws ServletException
        {
            synchronized(this)
            {
                if(_stack.size()==0)
                {
                    try
                    {
                        Servlet s = (Servlet) newInstance();
                        s.init(config);
                        _stack.push(s);
                    }
                    catch(IllegalAccessException e)
                    {
                        throw new ServletException(e);
                    }
                    catch (InstantiationException e)
                    {
                        throw new ServletException(e);
                    }
                }
            }
        }

        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
        {
            Servlet s;
            synchronized(this)
            {
                if(_stack.size()>0)
                    s=(Servlet)_stack.pop();
                else
                {
                    try
                    {
                        s = (Servlet) newInstance();
                        s.init(_config);
                    }
                    catch(IllegalAccessException e)
                    {
                        throw new ServletException(e);
                    }
                    catch (InstantiationException e)
                    {
                        throw new ServletException(e);
                    }
                }
            }
            
            try
            {
                s.service(req,res);
            }
            finally
            {
                synchronized(this)
                {
                    _stack.push(s);
                }
            }
        }
        
    }
}





Other Jetty examples (source code examples)

Here is a short list of links related to this Jetty ServletHolder.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.