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

Quick Search    Search Deep

Source code: org/apache/catalina/core/ApplicationFilterChain.java


1   /*
2    * Copyright 1999,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  
18  package org.apache.catalina.core;
19  
20  
21  import java.io.IOException;
22  import java.security.Principal;
23  import java.security.PrivilegedActionException;
24  
25  import javax.servlet.Filter;
26  import javax.servlet.FilterChain;
27  import javax.servlet.Servlet;
28  import javax.servlet.ServletException;
29  import javax.servlet.ServletRequest;
30  import javax.servlet.ServletResponse;
31  import javax.servlet.http.HttpServletRequest;
32  import javax.servlet.http.HttpServletResponse;
33  
34  import org.apache.catalina.InstanceEvent;
35  import org.apache.catalina.security.SecurityUtil;
36  import org.apache.catalina.util.InstanceSupport;
37  import org.apache.catalina.util.StringManager;
38  
39  /**
40   * Implementation of <code>javax.servlet.FilterChain</code> used to manage
41   * the execution of a set of filters for a particular request.  When the
42   * set of defined filters has all been executed, the next call to
43   * <code>doFilter()</code> will execute the servlet's <code>service()</code>
44   * method itself.
45   *
46   * @author Craig R. McClanahan
47   * @version $Revision: 303523 $ $Date: 2004-11-22 11:35:18 -0500 (Mon, 22 Nov 2004) $
48   */
49  
50  final class ApplicationFilterChain implements FilterChain {
51  
52  
53      // -------------------------------------------------------------- Constants
54  
55  
56      public static final int INCREMENT = 10;
57  
58  
59      // ----------------------------------------------------------- Constructors
60  
61  
62      /**
63       * Construct a new chain instance with no defined filters.
64       */
65      public ApplicationFilterChain() {
66  
67          super();
68  
69      }
70  
71  
72      // ----------------------------------------------------- Instance Variables
73  
74  
75      /**
76       * Filters.
77       */
78      private ApplicationFilterConfig[] filters = 
79          new ApplicationFilterConfig[0];
80  
81  
82      /**
83       * The int which is used to maintain the current position 
84       * in the filter chain.
85       */
86      private int pos = 0;
87  
88  
89      /**
90       * The int which gives the current number of filters in the chain.
91       */
92      private int n = 0;
93  
94  
95      /**
96       * The servlet instance to be executed by this chain.
97       */
98      private Servlet servlet = null;
99  
100 
101     /**
102      * The string manager for our package.
103      */
104     private static final StringManager sm =
105       StringManager.getManager(Constants.Package);
106 
107 
108     /**
109      * The InstanceSupport instance associated with our Wrapper (used to
110      * send "before filter" and "after filter" events.
111      */
112     private InstanceSupport support = null;
113 
114     
115     /**
116      * Static class array used when the SecurityManager is turned on and 
117      * <code>doFilter</code is invoked.
118      */
119     private static Class[] classType = new Class[]{ServletRequest.class, 
120                                                    ServletResponse.class,
121                                                    FilterChain.class};
122                                                    
123     /**
124      * Static class array used when the SecurityManager is turned on and 
125      * <code>service</code is invoked.
126      */                                                 
127     private static Class[] classTypeUsedInService = new Class[]{
128                                                          ServletRequest.class,
129                                                          ServletResponse.class};
130 
131     // ---------------------------------------------------- FilterChain Methods
132 
133 
134     /**
135      * Invoke the next filter in this chain, passing the specified request
136      * and response.  If there are no more filters in this chain, invoke
137      * the <code>service()</code> method of the servlet itself.
138      *
139      * @param request The servlet request we are processing
140      * @param response The servlet response we are creating
141      *
142      * @exception IOException if an input/output error occurs
143      * @exception ServletException if a servlet exception occurs
144      */
145     public void doFilter(ServletRequest request, ServletResponse response)
146         throws IOException, ServletException {
147 
148         if( System.getSecurityManager() != null ) {
149             final ServletRequest req = request;
150             final ServletResponse res = response;
151             try {
152                 java.security.AccessController.doPrivileged(
153                     new java.security.PrivilegedExceptionAction() {
154                         public Object run() 
155                             throws ServletException, IOException {
156                             internalDoFilter(req,res);
157                             return null;
158                         }
159                     }
160                 );
161             } catch( PrivilegedActionException pe) {
162                 Exception e = pe.getException();
163                 if (e instanceof ServletException)
164                     throw (ServletException) e;
165                 else if (e instanceof IOException)
166                     throw (IOException) e;
167                 else if (e instanceof RuntimeException)
168                     throw (RuntimeException) e;
169                 else
170                     throw new ServletException(e.getMessage(), e);
171             }
172         } else {
173             internalDoFilter(request,response);
174         }
175     }
176 
177     private void internalDoFilter(ServletRequest request, 
178                                   ServletResponse response)
179         throws IOException, ServletException {
180 
181         // Call the next filter if there is one
182         if (pos < n) {
183             ApplicationFilterConfig filterConfig = filters[pos++];
184             Filter filter = null;
185             try {
186                 filter = filterConfig.getFilter();
187                 support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
188                                           filter, request, response);
189                 
190                 if( System.getSecurityManager() != null ) {
191                     final ServletRequest req = request;
192                     final ServletResponse res = response;
193                     Principal principal = 
194                         ((HttpServletRequest) req).getUserPrincipal();
195 
196                     Object[] args = new Object[]{req, res, this};
197                     SecurityUtil.doAsPrivilege
198                         ("doFilter", filter, classType, args);
199                     
200                     args = null;
201                 } else {  
202                     filter.doFilter(request, response, this);
203                 }
204 
205                 support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
206                                           filter, request, response);
207             } catch (IOException e) {
208                 if (filter != null)
209                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
210                                               filter, request, response, e);
211                 throw e;
212             } catch (ServletException e) {
213                 if (filter != null)
214                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
215                                               filter, request, response, e);
216                 throw e;
217             } catch (RuntimeException e) {
218                 if (filter != null)
219                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
220                                               filter, request, response, e);
221                 throw e;
222             } catch (Throwable e) {
223                 if (filter != null)
224                     support.fireInstanceEvent(InstanceEvent.AFTER_FILTER_EVENT,
225                                               filter, request, response, e);
226                 throw new ServletException
227                   (sm.getString("filterChain.filter"), e);
228             }
229             return;
230         }
231 
232         // We fell off the end of the chain -- call the servlet instance
233         try {
234             support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
235                                       servlet, request, response);
236             if ((request instanceof HttpServletRequest) &&
237                 (response instanceof HttpServletResponse)) {
238                     
239                 if( System.getSecurityManager() != null ) {
240                     final ServletRequest req = request;
241                     final ServletResponse res = response;
242                     Principal principal = 
243                         ((HttpServletRequest) req).getUserPrincipal();
244                     Object[] args = new Object[]{req, res};
245                     SecurityUtil.doAsPrivilege("service",
246                                                servlet,
247                                                classTypeUsedInService, 
248                                                args,
249                                                principal);   
250                     args = null;
251                 } else {  
252                     servlet.service((HttpServletRequest) request,
253                                     (HttpServletResponse) response);
254                 }
255             } else {
256                 servlet.service(request, response);
257             }
258             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
259                                       servlet, request, response);
260         } catch (IOException e) {
261             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
262                                       servlet, request, response, e);
263             throw e;
264         } catch (ServletException e) {
265             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
266                                       servlet, request, response, e);
267             throw e;
268         } catch (RuntimeException e) {
269             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
270                                       servlet, request, response, e);
271             throw e;
272         } catch (Throwable e) {
273             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
274                                       servlet, request, response, e);
275             throw new ServletException
276               (sm.getString("filterChain.servlet"), e);
277         }
278 
279     }
280 
281 
282     // -------------------------------------------------------- Package Methods
283 
284 
285 
286     /**
287      * Add a filter to the set of filters that will be executed in this chain.
288      *
289      * @param filterConfig The FilterConfig for the servlet to be executed
290      */
291     void addFilter(ApplicationFilterConfig filterConfig) {
292 
293         if (n == filters.length) {
294             ApplicationFilterConfig[] newFilters =
295                 new ApplicationFilterConfig[n + INCREMENT];
296             System.arraycopy(filters, 0, newFilters, 0, n);
297             filters = newFilters;
298         }
299         filters[n++] = filterConfig;
300 
301     }
302 
303 
304     /**
305      * Release references to the filters and wrapper executed by this chain.
306      */
307     void release() {
308 
309         n = 0;
310         pos = 0;
311         servlet = null;
312         support = null;
313 
314     }
315 
316 
317     /**
318      * Set the servlet that will be executed at the end of this chain.
319      *
320      * @param servlet The Wrapper for the servlet to be executed
321      */
322     void setServlet(Servlet servlet) {
323 
324         this.servlet = servlet;
325 
326     }
327 
328 
329     /**
330      * Set the InstanceSupport object used for event notifications
331      * for this filter chain.
332      *
333      * @param support The InstanceSupport object for our Wrapper
334      */
335     void setSupport(InstanceSupport support) {
336 
337         this.support = support;
338 
339     }
340 
341 
342 }