KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > core > ApplicationFilterChain


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.core;
20
21
22 import java.io.IOException JavaDoc;
23 import java.security.Principal JavaDoc;
24 import java.security.PrivilegedActionException JavaDoc;
25
26 import javax.servlet.Filter JavaDoc;
27 import javax.servlet.FilterChain JavaDoc;
28 import javax.servlet.Servlet JavaDoc;
29 import javax.servlet.ServletException JavaDoc;
30 import javax.servlet.ServletRequest JavaDoc;
31 import javax.servlet.ServletResponse JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpServletResponse JavaDoc;
34
35 import org.apache.catalina.CometEvent;
36 import org.apache.catalina.CometFilter;
37 import org.apache.catalina.CometFilterChain;
38 import org.apache.catalina.CometProcessor;
39 import org.apache.catalina.Globals;
40 import org.apache.catalina.InstanceEvent;
41 import org.apache.catalina.security.SecurityUtil;
42 import org.apache.catalina.util.InstanceSupport;
43 import org.apache.catalina.util.StringManager;
44
45 /**
46  * Implementation of <code>javax.servlet.FilterChain</code> used to manage
47  * the execution of a set of filters for a particular request. When the
48  * set of defined filters has all been executed, the next call to
49  * <code>doFilter()</code> will execute the servlet's <code>service()</code>
50  * method itself.
51  *
52  * @author Craig R. McClanahan
53  * @version $Revision: 471281 $ $Date: 2006-11-04 23:35:15 +0100 (sam., 04 nov. 2006) $
54  */

55
56 final class ApplicationFilterChain implements FilterChain JavaDoc, CometFilterChain {
57
58     // Used to enforce requirements of SRV.8.2 / SRV.14.2.5.1
59
private final static ThreadLocal JavaDoc lastServicedRequest;
60     private final static ThreadLocal JavaDoc lastServicedResponse;
61
62     static {
63         if (Globals.STRICT_SERVLET_COMPLIANCE) {
64             lastServicedRequest = new ThreadLocal JavaDoc();
65             lastServicedResponse = new ThreadLocal JavaDoc();
66         } else {
67             lastServicedRequest = null;
68             lastServicedResponse = null;
69         }
70     }
71
72     // -------------------------------------------------------------- Constants
73

74
75     public static final int INCREMENT = 10;
76
77
78     // ----------------------------------------------------------- Constructors
79

80
81     /**
82      * Construct a new chain instance with no defined filters.
83      */

84     public ApplicationFilterChain() {
85
86         super();
87
88     }
89
90
91     // ----------------------------------------------------- Instance Variables
92

93
94     /**
95      * Filters.
96      */

97     private ApplicationFilterConfig[] filters =
98         new ApplicationFilterConfig[0];
99
100
101     /**
102      * The int which is used to maintain the current position
103      * in the filter chain.
104      */

105     private int pos = 0;
106
107
108     /**
109      * The int which gives the current number of filters in the chain.
110      */

111     private int n = 0;
112
113
114     /**
115      * The servlet instance to be executed by this chain.
116      */

117     private Servlet JavaDoc servlet = null;
118
119
120     /**
121      * The string manager for our package.
122      */

123     private static final StringManager sm =
124       StringManager.getManager(Constants.Package);
125
126
127     /**
128      * The InstanceSupport instance associated with our Wrapper (used to
129      * send "before filter" and "after filter" events.
130      */

131     private InstanceSupport support = null;
132
133     
134     /**
135      * Static class array used when the SecurityManager is turned on and
136      * <code>doFilter</code> is invoked.
137      */

138     private static Class JavaDoc[] classType = new Class JavaDoc[]{ServletRequest JavaDoc.class,
139                                                    ServletResponse JavaDoc.class,
140                                                    FilterChain JavaDoc.class};
141                                                    
142     /**
143      * Static class array used when the SecurityManager is turned on and
144      * <code>service</code> is invoked.
145      */

146     private static Class JavaDoc[] classTypeUsedInService = new Class JavaDoc[]{
147                                                          ServletRequest JavaDoc.class,
148                                                          ServletResponse JavaDoc.class};
149
150     /**
151      * Static class array used when the SecurityManager is turned on and
152      * <code>doFilterEvent</code> is invoked.
153      */

154     private static Class JavaDoc[] cometClassType =
155         new Class JavaDoc[]{ CometEvent.class, CometFilterChain.class};
156                                                    
157     /**
158      * Static class array used when the SecurityManager is turned on and
159      * <code>event</code> is invoked.
160      */

161     private static Class JavaDoc[] classTypeUsedInEvent =
162         new Class JavaDoc[] { CometEvent.class };
163
164     // ---------------------------------------------------- FilterChain Methods
165

166
167     /**
168      * Invoke the next filter in this chain, passing the specified request
169      * and response. If there are no more filters in this chain, invoke
170      * the <code>service()</code> method of the servlet itself.
171      *
172      * @param request The servlet request we are processing
173      * @param response The servlet response we are creating
174      *
175      * @exception IOException if an input/output error occurs
176      * @exception ServletException if a servlet exception occurs
177      */

178     public void doFilter(ServletRequest JavaDoc request, ServletResponse JavaDoc response)
179         throws IOException JavaDoc, ServletException JavaDoc {
180
181         if( System.getSecurityManager() != null ) {
182             final ServletRequest JavaDoc req = request;
183             final ServletResponse JavaDoc res = response;
184             try {
185                 java.security.AccessController.doPrivileged(
186                     new java.security.PrivilegedExceptionAction JavaDoc() {
187                         public Object JavaDoc run()
188                             throws ServletException JavaDoc, IOException JavaDoc {
189                             internalDoFilter(req,res);
190                             return null;
191                         }
192                     }
193                 );
194             } catch( PrivilegedActionException JavaDoc pe) {
195                 Exception JavaDoc e = pe.getException();
196                 if (e instanceof ServletException JavaDoc)
197                     throw (ServletException JavaDoc) e;
198                 else if (e instanceof IOException JavaDoc)
199                     throw (IOException JavaDoc) e;
200                 else if (e instanceof RuntimeException JavaDoc)
201                     throw (RuntimeException JavaDoc) e;
202                 else
203                     throw new ServletException JavaDoc(e.getMessage(), e);
204             }
205         } else {
206             internalDoFilter(request,response);
207         }
208     }
209
210     private void internalDoFilter(ServletRequest JavaDoc request,
211                                   ServletResponse JavaDoc response)
212         throws IOException JavaDoc, ServletException JavaDoc {
213
214         // Call the next filter if there is one
215
if (pos < n) {
216             ApplicationFilterConfig filterConfig = filters[pos++];
217             Filter JavaDoc filter = null;
218             try {
219                 filter = filterConfig.getFilter();
220                 support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
221                                           filter, request, response);
222                 
223                 if( System.getSecurityManager() != null ) {
224                     final ServletRequest JavaDoc req = request;
225                     final ServletResponse JavaDoc res = response;
226                     Principal JavaDoc principal =
227                         ((HttpServletRequest JavaDoc) req).getUserPrincipal();
228
229                     Object JavaDoc[] args = new Object JavaDoc[]{req, res, this};
230                     SecurityUtil.doAsPrivilege
231                         ("doFilter", filter, classType, args);
232                     
233                     args = null;
234                 } else {
235                     filter.doFilter(request, response, this);
236                 }
237
238                 support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
239                                           filter, request, response);
240             } catch (IOException JavaDoc e) {
241                 if (filter != null)
242                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
243                                               filter, request, response, e);
244                 throw e;
245             } catch (ServletException JavaDoc e) {
246                 if (filter != null)
247                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
248                                               filter, request, response, e);
249                 throw e;
250             } catch (RuntimeException JavaDoc e) {
251                 if (filter != null)
252                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
253                                               filter, request, response, e);
254                 throw e;
255             } catch (Throwable JavaDoc e) {
256                 if (filter != null)
257                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
258                                               filter, request, response, e);
259                 throw new ServletException JavaDoc
260                   (sm.getString("filterChain.filter"), e);
261             }
262             return;
263         }
264
265         // We fell off the end of the chain -- call the servlet instance
266
try {
267             if (Globals.STRICT_SERVLET_COMPLIANCE) {
268                 lastServicedRequest.set(request);
269                 lastServicedResponse.set(response);
270             }
271
272             support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
273                                       servlet, request, response);
274             if ((request instanceof HttpServletRequest JavaDoc) &&
275                 (response instanceof HttpServletResponse JavaDoc)) {
276                     
277                 if( System.getSecurityManager() != null ) {
278                     final ServletRequest JavaDoc req = request;
279                     final ServletResponse JavaDoc res = response;
280                     Principal JavaDoc principal =
281                         ((HttpServletRequest JavaDoc) req).getUserPrincipal();
282                     Object JavaDoc[] args = new Object JavaDoc[]{req, res};
283                     SecurityUtil.doAsPrivilege("service",
284                                                servlet,
285                                                classTypeUsedInService,
286                                                args,
287                                                principal);
288                     args = null;
289                 } else {
290                     servlet.service((HttpServletRequest JavaDoc) request,
291                                     (HttpServletResponse JavaDoc) response);
292                 }
293             } else {
294                 servlet.service(request, response);
295             }
296             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
297                                       servlet, request, response);
298         } catch (IOException JavaDoc e) {
299             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
300                                       servlet, request, response, e);
301             throw e;
302         } catch (ServletException JavaDoc e) {
303             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
304                                       servlet, request, response, e);
305             throw e;
306         } catch (RuntimeException JavaDoc e) {
307             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
308                                       servlet, request, response, e);
309             throw e;
310         } catch (Throwable JavaDoc e) {
311             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
312                                       servlet, request, response, e);
313             throw new ServletException JavaDoc
314               (sm.getString("filterChain.servlet"), e);
315         } finally {
316             if (Globals.STRICT_SERVLET_COMPLIANCE) {
317                 lastServicedRequest.set(null);
318                 lastServicedResponse.set(null);
319             }
320         }
321
322     }
323
324
325     /**
326      * Invoke the next filter in this chain, passing the specified request
327      * and response. If there are no more filters in this chain, invoke
328      * the <code>service()</code> method of the servlet itself.
329      *
330      * @param request The servlet request we are processing
331      * @param response The servlet response we are creating
332      *
333      * @exception IOException if an input/output error occurs
334      * @exception ServletException if a servlet exception occurs
335      */

336     public void doFilterEvent(CometEvent event)
337         throws IOException JavaDoc, ServletException JavaDoc {
338
339         if( System.getSecurityManager() != null ) {
340             final CometEvent ev = event;
341             try {
342                 java.security.AccessController.doPrivileged(
343                     new java.security.PrivilegedExceptionAction JavaDoc() {
344                         public Object JavaDoc run()
345                             throws ServletException JavaDoc, IOException JavaDoc {
346                             internalDoFilterEvent(ev);
347                             return null;
348                         }
349                     }
350                 );
351             } catch( PrivilegedActionException JavaDoc pe) {
352                 Exception JavaDoc e = pe.getException();
353                 if (e instanceof ServletException JavaDoc)
354                     throw (ServletException JavaDoc) e;
355                 else if (e instanceof IOException JavaDoc)
356                     throw (IOException JavaDoc) e;
357                 else if (e instanceof RuntimeException JavaDoc)
358                     throw (RuntimeException JavaDoc) e;
359                 else
360                     throw new ServletException JavaDoc(e.getMessage(), e);
361             }
362         } else {
363             internalDoFilterEvent(event);
364         }
365     }
366
367     
368     /**
369      * The last request passed to a servlet for servicing from the current
370      * thread.
371      *
372      * @return The last request to be serviced.
373      */

374     public static ServletRequest JavaDoc getLastServicedRequest() {
375         return (ServletRequest JavaDoc) lastServicedRequest.get();
376     }
377
378     
379     /**
380      * The last response passed to a servlet for servicing from the current
381      * thread.
382      *
383      * @return The last response to be serviced.
384      */

385     public static ServletResponse JavaDoc getLastServicedResponse() {
386         return (ServletResponse JavaDoc) lastServicedResponse.get();
387     }
388     
389     
390     private void internalDoFilterEvent(CometEvent event)
391         throws IOException JavaDoc, ServletException JavaDoc {
392
393         // Call the next filter if there is one
394
if (pos < n) {
395             ApplicationFilterConfig filterConfig = filters[pos++];
396             CometFilter filter = null;
397             try {
398                 filter = (CometFilter) filterConfig.getFilter();
399                 // FIXME: No instance listener processing for events for now
400
/*
401                 support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
402                         filter, event);
403                         */

404
405                 if( System.getSecurityManager() != null ) {
406                     final CometEvent ev = event;
407                     Principal JavaDoc principal =
408                         ev.getHttpServletRequest().getUserPrincipal();
409
410                     Object JavaDoc[] args = new Object JavaDoc[]{ev, this};
411                     SecurityUtil.doAsPrivilege
412                         ("doFilterEvent", (Filter JavaDoc) filter, cometClassType, args);
413
414                     args = null;
415                 } else {
416                     filter.doFilterEvent(event, this);
417                 }
418
419                 /*support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
420                         filter, event);*/

421             } catch (IOException JavaDoc e) {
422                 /*
423                 if (filter != null)
424                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
425                             filter, event, e);
426                             */

427                 throw e;
428             } catch (ServletException JavaDoc e) {
429                 /*
430                 if (filter != null)
431                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
432                             filter, event, e);
433                             */

434                 throw e;
435             } catch (RuntimeException JavaDoc e) {
436                 /*
437                 if (filter != null)
438                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
439                             filter, event, e);
440                             */

441                 throw e;
442             } catch (Throwable JavaDoc e) {
443                 /*if (filter != null)
444                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
445                             filter, event, e);*/

446                 throw new ServletException JavaDoc
447                     (sm.getString("filterChain.filter"), e);
448             }
449             return;
450         }
451
452         // We fell off the end of the chain -- call the servlet instance
453
try {
454             /*
455             support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
456                     servlet, request, response);
457                     */

458             if( System.getSecurityManager() != null ) {
459                 final CometEvent ev = event;
460                 Principal JavaDoc principal =
461                     ev.getHttpServletRequest().getUserPrincipal();
462                 Object JavaDoc[] args = new Object JavaDoc[]{ ev };
463                 SecurityUtil.doAsPrivilege("event",
464                         servlet,
465                         classTypeUsedInEvent,
466                         args,
467                         principal);
468                 args = null;
469             } else {
470                 ((CometProcessor) servlet).event(event);
471             }
472             /*
473             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
474                     servlet, request, response);*/

475         } catch (IOException JavaDoc e) {
476             /*
477             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
478                     servlet, request, response, e);
479                     */

480             throw e;
481         } catch (ServletException JavaDoc e) {
482             /*
483             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
484                     servlet, request, response, e);
485                     */

486             throw e;
487         } catch (RuntimeException JavaDoc e) {
488             /*
489             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
490                     servlet, request, response, e);
491                     */

492             throw e;
493         } catch (Throwable JavaDoc e) {
494             /*
495             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
496                     servlet, request, response, e);
497                     */

498             throw new ServletException JavaDoc
499                 (sm.getString("filterChain.servlet"), e);
500         }
501
502     }
503
504
505     // -------------------------------------------------------- Package Methods
506

507
508
509     /**
510      * Add a filter to the set of filters that will be executed in this chain.
511      *
512      * @param filterConfig The FilterConfig for the servlet to be executed
513      */

514     void addFilter(ApplicationFilterConfig filterConfig) {
515
516         if (n == filters.length) {
517             ApplicationFilterConfig[] newFilters =
518                 new ApplicationFilterConfig[n + INCREMENT];
519             System.arraycopy(filters, 0, newFilters, 0, n);
520             filters = newFilters;
521         }
522         filters[n++] = filterConfig;
523
524     }
525
526
527     /**
528      * Release references to the filters and wrapper executed by this chain.
529      */

530     void release() {
531
532         n = 0;
533         pos = 0;
534         servlet = null;
535         support = null;
536
537     }
538
539
540     /**
541      * Prepare for reuse of the filters and wrapper executed by this chain.
542      */

543     void reuse() {
544         pos = 0;
545     }
546
547
548     /**
549      * Set the servlet that will be executed at the end of this chain.
550      *
551      * @param servlet The Wrapper for the servlet to be executed
552      */

553     void setServlet(Servlet JavaDoc servlet) {
554
555         this.servlet = servlet;
556
557     }
558
559
560     /**
561      * Set the InstanceSupport object used for event notifications
562      * for this filter chain.
563      *
564      * @param support The InstanceSupport object for our Wrapper
565      */

566     void setSupport(InstanceSupport support) {
567
568         this.support = support;
569
570     }
571
572
573 }
574
Popular Tags