001: /*
002: * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationFilterChain.java,v 1.11 2001/10/11 23:30:58 craigmcc Exp $
003: * $Revision: 1.11 $
004: * $Date: 2001/10/11 23:30:58 $
005: *
006: * ====================================================================
007: *
008: * The Apache Software License, Version 1.1
009: *
010: * Copyright (c) 1999 The Apache Software Foundation. All rights
011: * reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions
015: * are met:
016: *
017: * 1. Redistributions of source code must retain the above copyright
018: * notice, this list of conditions and the following disclaimer.
019: *
020: * 2. Redistributions in binary form must reproduce the above copyright
021: * notice, this list of conditions and the following disclaimer in
022: * the documentation and/or other materials provided with the
023: * distribution.
024: *
025: * 3. The end-user documentation included with the redistribution, if
026: * any, must include the following acknowlegement:
027: * "This product includes software developed by the
028: * Apache Software Foundation (http://www.apache.org/)."
029: * Alternately, this acknowlegement may appear in the software itself,
030: * if and wherever such third-party acknowlegements normally appear.
031: *
032: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
033: * Foundation" must not be used to endorse or promote products derived
034: * from this software without prior written permission. For written
035: * permission, please contact apache@apache.org.
036: *
037: * 5. Products derived from this software may not be called "Apache"
038: * nor may "Apache" appear in their names without prior written
039: * permission of the Apache Group.
040: *
041: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
042: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
043: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
044: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
045: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
046: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
047: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
048: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
049: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
050: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
051: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
052: * SUCH DAMAGE.
053: * ====================================================================
054: *
055: * This software consists of voluntary contributions made by many
056: * individuals on behalf of the Apache Software Foundation. For more
057: * information on the Apache Software Foundation, please see
058: * <http://www.apache.org/>.
059: *
060: * [Additional notices, if required by prior licensing conditions]
061: *
062: */
063:
064: package org.apache.catalina.core;
065:
066: import java.io.IOException;
067: import java.util.ArrayList;
068: import java.util.Iterator;
069: import java.security.AccessController;
070: import java.security.PrivilegedActionException;
071: import javax.servlet.Filter;
072: import javax.servlet.FilterChain;
073: import javax.servlet.FilterConfig;
074: import javax.servlet.Servlet;
075: import javax.servlet.ServletException;
076: import javax.servlet.ServletRequest;
077: import javax.servlet.ServletResponse;
078: import javax.servlet.http.HttpServletRequest;
079: import javax.servlet.http.HttpServletResponse;
080: import org.apache.catalina.InstanceEvent;
081: import org.apache.catalina.util.InstanceSupport;
082: import org.apache.catalina.util.StringManager;
083:
084: /**
085: * Implementation of <code>javax.servlet.FilterChain</code> used to manage
086: * the execution of a set of filters for a particular request. When the
087: * set of defined filters has all been executed, the next call to
088: * <code>doFilter()</code> will execute the servlet's <code>service()</code>
089: * method itself.
090: *
091: * @author Craig R. McClanahan
092: * @version $Revision: 1.11 $ $Date: 2001/10/11 23:30:58 $
093: */
094:
095: final class ApplicationFilterChain implements FilterChain {
096:
097: // ----------------------------------------------------------- Constructors
098:
099: /**
100: * Construct a new chain instance with no defined filters.
101: */
102: public ApplicationFilterChain() {
103:
104: super ();
105:
106: }
107:
108: // ----------------------------------------------------- Instance Variables
109:
110: /**
111: * The set of filters that will be executed on this chain.
112: */
113: private ArrayList filters = new ArrayList();
114:
115: /**
116: * The iterator that is used to maintain the current position in the filter chain.
117: * This iterator is called the first time that <code>doFilter()</code>
118: * is called.
119: */
120: private Iterator iterator = null;
121:
122: /**
123: * The servlet instance to be executed by this chain.
124: */
125: private Servlet servlet = null;
126:
127: /**
128: * The string manager for our package.
129: */
130: private static final StringManager sm = StringManager
131: .getManager(Constants.Package);
132:
133: /**
134: * The InstanceSupport instance associated with our Wrapper (used to
135: * send "before filter" and "after filter" events.
136: */
137: private InstanceSupport support = null;
138:
139: // ---------------------------------------------------- FilterChain Methods
140:
141: /**
142: * Invoke the next filter in this chain, passing the specified request
143: * and response. If there are no more filters in this chain, invoke
144: * the <code>service()</code> method of the servlet itself.
145: *
146: * @param request The servlet request we are processing
147: * @param response The servlet response we are creating
148: *
149: * @exception IOException if an input/output error occurs
150: * @exception ServletException if a servlet exception occurs
151: */
152: public void doFilter(ServletRequest request,
153: ServletResponse response) throws IOException,
154: ServletException {
155:
156: if (System.getSecurityManager() != null) {
157: final ServletRequest req = request;
158: final ServletResponse res = response;
159: try {
160: java.security.AccessController
161: .doPrivileged(new java.security.PrivilegedExceptionAction() {
162: public Object run()
163: throws ServletException,
164: IOException {
165: internalDoFilter(req, res);
166: return null;
167: }
168: });
169: } catch (PrivilegedActionException pe) {
170: Exception e = pe.getException();
171: if (e instanceof ServletException)
172: throw (ServletException) e;
173: else if (e instanceof IOException)
174: throw (IOException) e;
175: else if (e instanceof RuntimeException)
176: throw (RuntimeException) e;
177: else
178: throw new ServletException(e.getMessage(), e);
179: }
180: } else {
181: internalDoFilter(request, response);
182: }
183: }
184:
185: private void internalDoFilter(ServletRequest request,
186: ServletResponse response) throws IOException,
187: ServletException {
188:
189: // Construct an iterator the first time this method is called
190: if (this .iterator == null)
191: this .iterator = filters.iterator();
192:
193: // Call the next filter if there is one
194: if (this .iterator.hasNext()) {
195: ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) iterator
196: .next();
197: Filter filter = null;
198: try {
199: filter = filterConfig.getFilter();
200: support.fireInstanceEvent(
201: InstanceEvent.BEFORE_FILTER_EVENT, filter,
202: request, response);
203: filter.doFilter(request, response, this );
204: support.fireInstanceEvent(
205: InstanceEvent.AFTER_FILTER_EVENT, filter,
206: request, response);
207: } catch (IOException e) {
208: if (filter != null)
209: support.fireInstanceEvent(
210: InstanceEvent.AFTER_FILTER_EVENT, filter,
211: request, response, e);
212: throw e;
213: } catch (ServletException e) {
214: if (filter != null)
215: support.fireInstanceEvent(
216: InstanceEvent.AFTER_FILTER_EVENT, filter,
217: request, response, e);
218: throw e;
219: } catch (RuntimeException e) {
220: if (filter != null)
221: support.fireInstanceEvent(
222: InstanceEvent.AFTER_FILTER_EVENT, filter,
223: request, response, e);
224: throw e;
225: } catch (Throwable e) {
226: if (filter != null)
227: support.fireInstanceEvent(
228: InstanceEvent.AFTER_FILTER_EVENT, filter,
229: request, response, e);
230: throw new ServletException(sm
231: .getString("filterChain.filter"), e);
232: }
233: return;
234: }
235:
236: // We fell off the end of the chain -- call the servlet instance
237: try {
238: support.fireInstanceEvent(
239: InstanceEvent.BEFORE_SERVICE_EVENT, servlet,
240: request, response);
241: if ((request instanceof HttpServletRequest)
242: && (response instanceof HttpServletResponse)) {
243: servlet.service((HttpServletRequest) request,
244: (HttpServletResponse) response);
245: } else {
246: servlet.service(request, response);
247: }
248: support.fireInstanceEvent(
249: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
250: request, response);
251: } catch (IOException e) {
252: support.fireInstanceEvent(
253: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
254: request, response, e);
255: throw e;
256: } catch (ServletException e) {
257: support.fireInstanceEvent(
258: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
259: request, response, e);
260: throw e;
261: } catch (RuntimeException e) {
262: support.fireInstanceEvent(
263: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
264: request, response, e);
265: throw e;
266: } catch (Throwable e) {
267: support.fireInstanceEvent(
268: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
269: request, response, e);
270: throw new ServletException(sm
271: .getString("filterChain.servlet"), e);
272: }
273:
274: }
275:
276: // -------------------------------------------------------- Package Methods
277:
278: /**
279: * Add a filter to the set of filters that will be executed in this chain.
280: *
281: * @param filterConfig The FilterConfig for the servlet to be executed
282: */
283: void addFilter(ApplicationFilterConfig filterConfig) {
284:
285: this .filters.add(filterConfig);
286:
287: }
288:
289: /**
290: * Release references to the filters and wrapper executed by this chain.
291: */
292: void release() {
293:
294: this .filters.clear();
295: this .iterator = iterator;
296: this .servlet = null;
297:
298: }
299:
300: /**
301: * Set the servlet that will be executed at the end of this chain.
302: *
303: * @param wrapper The Wrapper for the servlet to be executed
304: */
305: void setServlet(Servlet servlet) {
306:
307: this .servlet = servlet;
308:
309: }
310:
311: /**
312: * Set the InstanceSupport object used for event notifications
313: * for this filter chain.
314: *
315: * @param support The InstanceSupport object for our Wrapper
316: */
317: void setSupport(InstanceSupport support) {
318:
319: this.support = support;
320:
321: }
322:
323: }
|