KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > jetty > servlet > ServletHolder


1 // ========================================================================
2
// $Id: ServletHolder.java,v 1.53 2005/11/03 08:52:48 gregwilkins Exp $
3
// Copyright 199-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.jetty.servlet;
17
18 import java.io.IOException JavaDoc;
19 import java.security.Principal JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Stack JavaDoc;
24
25 import javax.servlet.Servlet JavaDoc;
26 import javax.servlet.ServletConfig JavaDoc;
27 import javax.servlet.ServletContext JavaDoc;
28 import javax.servlet.ServletException JavaDoc;
29 import javax.servlet.ServletRequest JavaDoc;
30 import javax.servlet.ServletResponse JavaDoc;
31 import javax.servlet.UnavailableException JavaDoc;
32
33 import org.apache.commons.logging.Log;
34 import org.mortbay.log.LogFactory;
35 import org.mortbay.http.HttpRequest;
36 import org.mortbay.http.UserRealm;
37
38
39 /* --------------------------------------------------------------------- */
40 /** Servlet Instance and Context Holder.
41  * Holds the name, params and some state of a javax.servlet.Servlet
42  * instance. It implements the ServletConfig interface.
43  * This class will organise the loading of the servlet when needed or
44  * requested.
45  *
46  * @version $Id: ServletHolder.java,v 1.53 2005/11/03 08:52:48 gregwilkins Exp $
47  * @author Greg Wilkins
48  */

49 public class ServletHolder extends Holder
50     implements Comparable JavaDoc
51 {
52     private static Log log = LogFactory.getLog(ServletHolder.class);
53
54     /* ---------------------------------------------------------------- */
55     
56     private int _initOrder;
57     private boolean _initOnStartup=false;
58     private Map JavaDoc _roleMap;
59     private String JavaDoc _forcedPath;
60     private String JavaDoc _runAs;
61     private UserRealm _realm;
62
63     
64     private transient Stack JavaDoc _servlets;
65     private transient Servlet JavaDoc _servlet;
66     private transient Config JavaDoc _config;
67     private transient long _unavailable;
68     private transient UnavailableException JavaDoc _unavailableEx;
69
70     
71     /* ---------------------------------------------------------------- */
72     /** Constructor for Serialization.
73      */

74     public ServletHolder()
75     {}
76     
77
78     /* ---------------------------------------------------------------- */
79     /** Constructor.
80      * @param handler The ServletHandler instance for this servlet.
81      * @param name The name of the servlet.
82      * @param className The class name of the servlet.
83      */

84     public ServletHolder(ServletHandler handler,
85                          String JavaDoc name,
86                          String JavaDoc className)
87     {
88         super(handler,(name==null)?className:name,className);
89     }
90
91     /* ---------------------------------------------------------------- */
92     /** Constructor.
93      * @param handler The ServletHandler instance for this servlet.
94      * @param name The name of the servlet.
95      * @param className The class name of the servlet.
96      * @param forcedPath If non null, the request attribute
97      * javax.servlet.include.servlet_path will be set to this path before
98      * service is called.
99      */

100     public ServletHolder(ServletHandler handler,
101                          String JavaDoc name,
102                          String JavaDoc className,
103                          String JavaDoc forcedPath)
104     {
105         this(handler,(name==null)?className:name,className);
106         _forcedPath=forcedPath;
107     }
108
109     
110     /* ------------------------------------------------------------ */
111     public int getInitOrder()
112     {
113         return _initOrder;
114     }
115
116     /* ------------------------------------------------------------ */
117     /** Set the initialize order.
118      * Holders with order<0, are initialized on use. Those with
119      * order>=0 are initialized in increasing order when the handler
120      * is started.
121      */

122     public void setInitOrder(int order)
123     {
124         _initOnStartup=true;
125         _initOrder = order;
126     }
127
128     /* ------------------------------------------------------------ */
129     /** Comparitor by init order.
130      */

131     public int compareTo(Object JavaDoc o)
132     {
133         if (o instanceof ServletHolder)
134         {
135             ServletHolder sh= (ServletHolder)o;
136             if (sh==this)
137                 return 0;
138             if (sh._initOrder<_initOrder)
139                 return 1;
140             if (sh._initOrder>_initOrder)
141                 return -1;
142             int c=_className.compareTo(sh._className);
143             if (c==0)
144                 c=_name.compareTo(sh._name);
145             if (c==0)
146                 c=this.hashCode()>o.hashCode()?1:-1;
147             return c;
148         }
149         return 1;
150     }
151
152     /* ------------------------------------------------------------ */
153     public boolean equals(Object JavaDoc o)
154     {
155         return compareTo(o)==0;
156     }
157
158     /* ------------------------------------------------------------ */
159     public int hashCode()
160     {
161         return _name.hashCode();
162     }
163
164     /* ---------------------------------------------------------------- */
165     public ServletContext JavaDoc getServletContext()
166     {
167         return ((ServletHandler)_httpHandler).getServletContext();
168     }
169
170     /* ------------------------------------------------------------ */
171     /** Link a user role.
172      * Translate the role name used by a servlet, to the link name
173      * used by the container.
174      * @param name The role name as used by the servlet
175      * @param link The role name as used by the container.
176      */

177     public synchronized void setUserRoleLink(String JavaDoc name,String JavaDoc link)
178     {
179         if (_roleMap==null)
180             _roleMap=new HashMap JavaDoc();
181         _roleMap.put(name,link);
182     }
183     
184     /* ------------------------------------------------------------ */
185     /** get a user role link.
186      * @param name The name of the role
187      * @return The name as translated by the link. If no link exists,
188      * the name is returned.
189      */

190     public String JavaDoc getUserRoleLink(String JavaDoc name)
191     {
192         if (_roleMap==null)
193             return name;
194         String JavaDoc link=(String JavaDoc)_roleMap.get(name);
195         return (link==null)?name:link;
196     }
197
198     /* ------------------------------------------------------------ */
199     /**
200      * @param role Role name that is added to UserPrincipal when this servlet
201      * is called.
202      */

203     public void setRunAs(String JavaDoc role)
204     {
205         _runAs=role;
206     }
207     
208     /* ------------------------------------------------------------ */
209     public String JavaDoc getRunAs()
210     {
211         return _runAs;
212     }
213     
214     /* ------------------------------------------------------------ */
215     public void start()
216         throws Exception JavaDoc
217     {
218         _unavailable=0;
219         super.start();
220         
221         if (!javax.servlet.Servlet JavaDoc.class
222             .isAssignableFrom(_class))
223         {
224             Exception JavaDoc ex = new IllegalStateException JavaDoc("Servlet "+_class+
225                                             " is not a javax.servlet.Servlet");
226             super.stop();
227             throw ex;
228         }
229
230         _config=new Config JavaDoc();
231         if (_runAs!=null)
232             _realm=_httpHandler.getHttpContext().getRealm();
233
234         if (javax.servlet.SingleThreadModel JavaDoc.class
235             .isAssignableFrom(_class))
236             _servlets=new Stack JavaDoc();
237
238         if (_initOnStartup)
239         {
240             _servlet=(Servlet JavaDoc)newInstance();
241             try
242             {
243                 initServlet(_servlet,_config);
244             }
245             catch(Throwable JavaDoc e)
246             {
247                 _servlet=null;
248                 _config=null;
249                 if (e instanceof Exception JavaDoc)
250                     throw (Exception JavaDoc) e;
251                 else if (e instanceof Error JavaDoc)
252                     throw (Error JavaDoc)e;
253                 else
254                     throw new ServletException JavaDoc(e);
255             }
256         }
257     }
258
259     /* ------------------------------------------------------------ */
260     public void stop()
261     {
262         Principal JavaDoc user=null;
263         try
264         {
265             // Handle run as
266
if (_runAs!=null && _realm!=null)
267                 user=_realm.pushRole(null,_runAs);
268                 
269             if (_servlet!=null)
270                 _servlet.destroy();
271             _servlet=null;
272             
273             while (_servlets!=null && _servlets.size()>0)
274             {
275                 Servlet JavaDoc s = (Servlet JavaDoc)_servlets.pop();
276                 s.destroy();
277             }
278             _config=null;
279         }
280         finally
281         {
282             super.stop();
283             // pop run-as role
284
if (_runAs!=null && _realm!=null && user!=null)
285                 _realm.popRole(user);
286         }
287     }
288     
289
290     /* ------------------------------------------------------------ */
291     /** Get the servlet.
292      * @return The servlet
293      */

294     public synchronized Servlet JavaDoc getServlet()
295         throws ServletException JavaDoc
296     {
297         // Handle previous unavailability
298
if (_unavailable!=0)
299         {
300             if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
301                 throw _unavailableEx;
302             _unavailable=0;
303             _unavailableEx=null;
304         }
305         
306         try
307         {
308             if (_servlets!=null)
309             {
310                 Servlet JavaDoc servlet=null;
311                 if (_servlets.size()==0)
312                 {
313                     servlet= (Servlet JavaDoc)newInstance();
314                     if (_config==null)
315                         _config=new Config JavaDoc();
316                     initServlet(servlet,_config);
317                 }
318                 else
319                     servlet = (Servlet JavaDoc)_servlets.pop();
320
321                 return servlet;
322             }
323             
324             if (_servlet==null)
325             {
326                 _servlet=(Servlet JavaDoc)newInstance();
327                 if (_config==null)
328                     _config=new Config JavaDoc();
329                 initServlet(_servlet,_config);
330             }
331         
332             return _servlet;
333         }
334         catch(UnavailableException JavaDoc e)
335         {
336             _servlet=null;
337             _config=null;
338             return makeUnavailable(e);
339         }
340         catch(ServletException JavaDoc e)
341         {
342             _servlet=null;
343             _config=null;
344             throw e;
345         }
346         catch(Throwable JavaDoc e)
347         {
348             _servlet=null;
349             _config=null;
350             throw new ServletException JavaDoc("init",e);
351         }
352     }
353
354     /* ------------------------------------------------------------ */
355     private Servlet JavaDoc makeUnavailable(UnavailableException JavaDoc e)
356       throws UnavailableException JavaDoc
357     {
358         _unavailableEx=e;
359         _unavailable=-1;
360         if (e.isPermanent())
361             _unavailable=-1;
362         else
363     {
364             if (_unavailableEx.getUnavailableSeconds()>0)
365                 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
366             else
367                 _unavailable=System.currentTimeMillis()+5000; // TODO configure
368
}
369    
370         throw _unavailableEx;
371     }
372
373     /* ------------------------------------------------------------ */
374     private void initServlet(Servlet JavaDoc servlet, ServletConfig JavaDoc config)
375         throws ServletException JavaDoc
376     {
377         Principal JavaDoc user=null;
378         try
379         {
380             // Handle run as
381
if (_runAs!=null && _realm!=null)
382                 user=_realm.pushRole(null,_runAs);
383             servlet.init(config);
384         }
385         finally
386         {
387             // pop run-as role
388
if (_runAs!=null && _realm!=null && user!=null)
389                 _realm.popRole(user);
390         }
391     }
392     
393     /* ------------------------------------------------------------ */
394     /** Service a request with this servlet.
395      */

396     public void handle(ServletRequest JavaDoc request,
397                        ServletResponse JavaDoc response)
398         throws ServletException JavaDoc,
399                UnavailableException JavaDoc,
400                IOException JavaDoc
401     {
402         if (_class==null)
403             throw new UnavailableException JavaDoc("Servlet Not Initialized");
404         
405         Servlet JavaDoc servlet=(!_initOnStartup||_servlets!=null)?getServlet():_servlet;
406         if (servlet==null)
407             throw new UnavailableException JavaDoc("Could not instantiate "+_class);
408
409         // Service the request
410
boolean servlet_error=true;
411         Principal JavaDoc user=null;
412         HttpRequest http_request=null;
413         try
414         {
415             // Handle aliased path
416
if (_forcedPath!=null)
417                 // TODO complain about poor naming to the Jasper folks
418
request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
419
420             // Handle run as
421
if (_runAs!=null && _realm!=null)
422             {
423                 http_request=getHttpContext().getHttpConnection().getRequest();
424                 user=_realm.pushRole(http_request.getUserPrincipal(),_runAs);
425                 http_request.setUserPrincipal(user);
426             }
427             
428             servlet.service(request,response);
429             servlet_error=false;
430         }
431         catch(UnavailableException JavaDoc e)
432         {
433             if (_servlets!=null && servlet!=null)
434                 stop();
435             makeUnavailable(e);
436         }
437         finally
438         {
439             // pop run-as role
440
if (_runAs!=null && _realm!=null && user!=null)
441             {
442                 user=_realm.popRole(user);
443                 http_request.setUserPrincipal(user);
444             }
445
446             // Handle error params.
447
if (servlet_error)
448                 request.setAttribute("javax.servlet.error.servlet_name",getName());
449
450             // Return to singleThreaded pool
451
synchronized(this)
452             {
453                 if (_servlets!=null && servlet!=null)
454                     _servlets.push(servlet);
455             }
456         }
457     }
458
459  
460     /* ------------------------------------------------------------ */
461     /* ------------------------------------------------------------ */
462     /* ------------------------------------------------------------ */
463     class Config implements ServletConfig JavaDoc
464     {
465         /* -------------------------------------------------------- */
466         public String JavaDoc getServletName()
467         {
468             return getName();
469         }
470         
471         /* -------------------------------------------------------- */
472         public ServletContext JavaDoc getServletContext()
473         {
474             return ((ServletHandler)_httpHandler).getServletContext();
475         }
476
477         /* -------------------------------------------------------- */
478         public String JavaDoc getInitParameter(String JavaDoc param)
479         {
480             return ServletHolder.this.getInitParameter(param);
481         }
482     
483         /* -------------------------------------------------------- */
484         public Enumeration JavaDoc getInitParameterNames()
485         {
486             return ServletHolder.this.getInitParameterNames();
487         }
488     }
489 }
490
491
492
493
494
495
Popular Tags