Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mortbay/jetty/servlet/ServletHolder.java


1   // ===========================================================================
2   // Copyright (c) 1996-2003 Mort Bay Consulting Pty. Ltd. All rights reserved.
3   // $Id: ServletHolder.java,v 1.39 2003/09/18 13:29:24 gregwilkins Exp $
4   // ---------------------------------------------------------------------------
5   
6   package org.mortbay.jetty.servlet;
7   
8   import java.io.IOException;
9   import java.security.Principal;
10  import java.util.Enumeration;
11  import java.util.HashMap;
12  import java.util.Map;
13  import java.util.Stack;
14  
15  import javax.servlet.Servlet;
16  import javax.servlet.ServletConfig;
17  import javax.servlet.ServletContext;
18  import javax.servlet.ServletException;
19  import javax.servlet.ServletRequest;
20  import javax.servlet.ServletResponse;
21  import javax.servlet.UnavailableException;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.mortbay.http.HttpRequest;
26  import org.mortbay.http.UserRealm;
27  import org.mortbay.util.LogSupport;
28  
29  
30  /* --------------------------------------------------------------------- */
31  /** Servlet Instance and Context Holder.
32   * Holds the name, params and some state of a javax.servlet.Servlet
33   * instance. It implements the ServletConfig interface.
34   * This class will organise the loading of the servlet when needed or
35   * requested.
36   *
37   * @version $Id: ServletHolder.java,v 1.39 2003/09/18 13:29:24 gregwilkins Exp $
38   * @author Greg Wilkins
39   */
40  public class ServletHolder extends Holder
41      implements Comparable
42  {
43      private static Log log = LogFactory.getLog(ServletHolder.class);
44  
45      /* ---------------------------------------------------------------- */
46      
47      private int _initOrder;
48      private boolean _initOnStartup=false;
49      private Map _roleMap;
50      private String _forcedPath;
51      private String _run_as;
52      private UserRealm _realm;
53  
54      
55      private transient Stack _servlets;
56      private transient Servlet _servlet;
57      private transient Config _config;
58      private transient long _unavailable;
59      private transient UnavailableException _unavailableEx;
60  
61      
62      /* ---------------------------------------------------------------- */
63      /** Constructor for Serialization.
64       */
65      public ServletHolder()
66      {}
67      
68  
69      /* ---------------------------------------------------------------- */
70      /** Constructor.
71       * @param handler The ServletHandler instance for this servlet.
72       * @param name The name of the servlet.
73       * @param className The class name of the servlet.
74       */
75      public ServletHolder(ServletHandler handler,
76                           String name,
77                           String className)
78      {
79          super(handler,(name==null)?className:name,className);
80      }
81  
82      /* ---------------------------------------------------------------- */
83      /** Constructor. 
84       * @param handler The ServletHandler instance for this servlet.
85       * @param name The name of the servlet.
86       * @param className The class name of the servlet.
87       * @param forcedPath If non null, the request attribute
88       * javax.servlet.include.servlet_path will be set to this path before
89       * service is called.
90       */
91      public ServletHolder(ServletHandler handler,
92                           String name,
93                           String className,
94                           String forcedPath)
95      {
96          this(handler,(name==null)?className:name,className);
97          _forcedPath=forcedPath;
98      }
99  
100     
101     /* ------------------------------------------------------------ */
102     public int getInitOrder()
103     {
104         return _initOrder;
105     }
106 
107     /* ------------------------------------------------------------ */
108     /** Set the initialize order.
109      * Holders with order<0, are initialized on use. Those with
110      * order>=0 are initialized in increasing order when the handler
111      * is started.
112      */
113     public void setInitOrder(int order)
114     {
115         _initOnStartup=true;
116         _initOrder = order;
117     }
118 
119     /* ------------------------------------------------------------ */
120     /** Comparitor by init order.
121      */
122     public int compareTo(Object o)
123     {
124         if (o instanceof ServletHolder)
125         {
126             ServletHolder sh= (ServletHolder)o;
127             if (sh==this)
128                 return 0;
129             if (sh._initOrder<_initOrder)
130                 return 1;
131             if (sh._initOrder>_initOrder)
132                 return -1;
133             int c=_className.compareTo(sh._className);
134             if (c==0)
135                 c=_name.compareTo(sh._name);
136             if (c==0)
137                 c=this.hashCode()>o.hashCode()?1:-1;
138             return c;
139         }
140         return 1;
141     }
142 
143     /* ------------------------------------------------------------ */
144     public boolean equals(Object o)
145     {
146         return compareTo(o)==0;
147     }
148 
149     /* ---------------------------------------------------------------- */
150     public ServletContext getServletContext()
151     {
152         return ((ServletHandler)_httpHandler).getServletContext();
153     }
154 
155     /* ------------------------------------------------------------ */
156     /** Link a user role.
157      * Translate the role name used by a servlet, to the link name
158      * used by the container.
159      * @param name The role name as used by the servlet
160      * @param link The role name as used by the container.
161      */
162     public synchronized void setUserRoleLink(String name,String link)
163     {
164         if (_roleMap==null)
165             _roleMap=new HashMap();
166         _roleMap.put(name,link);
167     }
168     
169     /* ------------------------------------------------------------ */
170     /** get a user role link.
171      * @param name The name of the role
172      * @return The name as translated by the link. If no link exists,
173      * the name is returned.
174      */
175     public String getUserRoleLink(String name)
176     {
177         if (_roleMap==null)
178             return name;
179         String link=(String)_roleMap.get(name);
180         return (link==null)?name:link;
181     }
182 
183     /* ------------------------------------------------------------ */
184     /** 
185      * @param role Role name that is added to UserPrincipal when this servlet
186      * is called. 
187      */
188     public void setRunAs(String role)
189     {
190         _run_as=role;
191     }
192     
193     /* ------------------------------------------------------------ */
194     public String getRunAs()
195     {
196         return _run_as;
197     }
198     
199     /* ------------------------------------------------------------ */
200     public void start()
201         throws Exception
202     {
203         _unavailable=0;
204         super.start();
205         
206         if (!javax.servlet.Servlet.class
207             .isAssignableFrom(_class))
208         {
209             Exception ex = new IllegalStateException("Servlet "+_class+
210                                             " is not a javax.servlet.Servlet");
211             super.stop();
212             throw ex;
213         }        
214 
215         if (javax.servlet.SingleThreadModel.class
216             .isAssignableFrom(_class))
217             _servlets=new Stack();
218 
219         if (_initOnStartup)
220         {
221             _servlet=(Servlet)newInstance();
222             _config=new Config();
223             try
224             {
225                 _servlet.init(_config);
226             }
227             catch(Throwable e)
228             {
229                 _servlet=null;
230                 _config=null;
231                 if (e instanceof Exception)
232                     throw (Exception) e;
233                 else if (e instanceof Error)
234                     throw (Error)e;
235                 else
236                     throw new ServletException(e);
237             }            
238         }
239 
240         if (_run_as!=null)
241             _realm=_httpHandler.getHttpContext().getRealm();
242         
243     }
244 
245     /* ------------------------------------------------------------ */
246     public void stop()
247     {
248         if (_servlet!=null)
249             _servlet.destroy();
250         _servlet=null;
251         
252         while (_servlets!=null && _servlets.size()>0)
253         {
254             Servlet s = (Servlet)_servlets.pop();
255             s.destroy();
256         }
257         _config=null;
258         super.stop();
259     }
260     
261 
262     /* ------------------------------------------------------------ */
263     /** Get the servlet.
264      * @return The servlet
265      */
266     public synchronized Servlet getServlet()
267         throws UnavailableException
268     {
269         // Handle previous unavailability
270         if (_unavailable!=0)
271         {
272             if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
273                 throw _unavailableEx;
274             _unavailable=0;
275             _unavailableEx=null;
276         }
277         
278         try
279         {
280             if (_servlets!=null)
281             {
282                 Servlet servlet=null;
283                 if (_servlets.size()==0)
284                 {
285                     servlet= (Servlet)newInstance();
286                     servlet.init(_config);
287                 }
288                 else
289                     servlet = (Servlet)_servlets.pop();
290 
291                 return servlet;
292             }
293             
294             if (_servlet==null)
295                 _servlet=(Servlet)newInstance();
296         
297             if (_config==null)
298             {
299                 _config=new Config();
300                 _servlet.init(_config);
301             }
302 
303             return _servlet;
304         }
305         catch(UnavailableException e)
306         {
307             _servlet=null;
308             _config=null;
309             _unavailableEx=e;
310             _unavailable=-1;
311             if (_unavailableEx.getUnavailableSeconds()>0)
312                 _unavailable=System.currentTimeMillis()+
313                     1000*_unavailableEx.getUnavailableSeconds();
314             throw _unavailableEx;
315         }
316         catch(Exception e)
317         {
318             _servlet=null;
319             _config=null;
320             log.warn(LogSupport.EXCEPTION,e);
321             throw new UnavailableException(_servlet,e.toString());
322         }    
323     }
324     
325     /* ------------------------------------------------------------ */
326     /** Service a request with this servlet.
327      */
328     public void handle(ServletRequest request,
329                        ServletResponse response)
330         throws ServletException,
331                UnavailableException,
332                IOException
333     {
334         if (_class==null)
335             throw new UnavailableException("Servlet Not Initialized");
336         
337         Servlet servlet=(!_initOnStartup||_servlets!=null)?getServlet():_servlet;
338         if (servlet==null)
339             throw new UnavailableException("Could not instantiate "+_class);
340 
341         // Service the request
342         boolean servlet_error=true;
343         Principal user=null;
344         HttpRequest http_request=null;
345         try
346         {
347             // Handle aliased path
348             if (_forcedPath!=null)
349                 request.setAttribute("javax.servlet.include.servlet_path",_forcedPath);
350 
351             // Handle run as
352             if (_run_as!=null && _realm!=null)
353             {
354                 ServletHttpRequest servletHttpRequest=
355                     ServletHttpRequest.unwrap(request);
356                 http_request=servletHttpRequest.getHttpRequest();
357 
358                 user=_realm.pushRole(http_request.getUserPrincipal(),_run_as);
359                 http_request.setUserPrincipal(user);
360             }
361             
362             servlet.service(request,response);
363             servlet_error=false;
364         }
365         catch(UnavailableException e)
366         {
367             if (_servlets!=null && servlet!=null)
368                 servlet.destroy();
369             servlet=null;
370             throw e;
371         }
372         finally
373         {
374             // pop run-as role
375             if (_run_as!=null && _realm!=null && user!=null)
376             {
377                 user=_realm.popRole(user);
378                 http_request.setUserPrincipal(user);
379             }
380 
381             // Handle error params.
382             if (servlet_error)
383                 request.setAttribute("javax.servlet.error.servlet_name",getName());
384 
385             // Return to singleThreaded pool
386             synchronized(this)
387             {
388                 if (_servlets!=null && servlet!=null)
389                     _servlets.push(servlet);
390             }
391         }
392     }
393 
394     /* ------------------------------------------------------------ */
395     /* ------------------------------------------------------------ */
396     /* ------------------------------------------------------------ */
397     class Config implements ServletConfig
398     {   
399         /* -------------------------------------------------------- */
400         public String getServletName()
401         {
402             return getName();
403         }
404         
405         /* -------------------------------------------------------- */
406         public ServletContext getServletContext()
407         {
408             return ((ServletHandler)_httpHandler).getServletContext();
409         }
410 
411         /* -------------------------------------------------------- */
412         public String getInitParameter(String param)
413         {
414             return ServletHolder.this.getInitParameter(param);
415         }
416     
417         /* -------------------------------------------------------- */
418         public Enumeration getInitParameterNames()
419         {
420             return ServletHolder.this.getInitParameterNames();
421         }
422     }
423 }
424 
425 
426 
427 
428