001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.catalina.core;
018:
019: import java.io.IOException;
020: import java.security.Principal;
021: import java.security.PrivilegedActionException;
022:
023: import javax.servlet.Filter;
024: import javax.servlet.FilterChain;
025: import javax.servlet.Servlet;
026: import javax.servlet.ServletException;
027: import javax.servlet.ServletRequest;
028: import javax.servlet.ServletResponse;
029: import javax.servlet.http.HttpServletRequest;
030: import javax.servlet.http.HttpServletResponse;
031:
032: import org.apache.catalina.InstanceEvent;
033: import org.apache.catalina.security.SecurityUtil;
034: import org.apache.catalina.util.InstanceSupport;
035: import org.apache.catalina.util.StringManager;
036:
037: /**
038: * Implementation of <code>javax.servlet.FilterChain</code> used to manage
039: * the execution of a set of filters for a particular request. When the
040: * set of defined filters has all been executed, the next call to
041: * <code>doFilter()</code> will execute the servlet's <code>service()</code>
042: * method itself.
043: *
044: * @author Craig R. McClanahan
045: * @version $Revision: 1.10 $ $Date: 2004/05/26 15:36:20 $
046: */
047:
048: final class ApplicationFilterChain implements FilterChain {
049:
050: // -------------------------------------------------------------- Constants
051:
052: public static final int INCREMENT = 10;
053:
054: // ----------------------------------------------------------- Constructors
055:
056: /**
057: * Construct a new chain instance with no defined filters.
058: */
059: public ApplicationFilterChain() {
060:
061: super ();
062:
063: }
064:
065: // ----------------------------------------------------- Instance Variables
066:
067: /**
068: * Filters.
069: */
070: private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
071:
072: /**
073: * The int which is used to maintain the current position
074: * in the filter chain.
075: */
076: private int pos = 0;
077:
078: /**
079: * The int which gives the current number of filters in the chain.
080: */
081: private int n = 0;
082:
083: /**
084: * The servlet instance to be executed by this chain.
085: */
086: private Servlet servlet = null;
087:
088: /**
089: * The string manager for our package.
090: */
091: private static final StringManager sm = StringManager
092: .getManager(Constants.Package);
093:
094: /**
095: * The InstanceSupport instance associated with our Wrapper (used to
096: * send "before filter" and "after filter" events.
097: */
098: private InstanceSupport support = null;
099:
100: // ---------------------------------------------------- FilterChain Methods
101:
102: /**
103: * Invoke the next filter in this chain, passing the specified request
104: * and response. If there are no more filters in this chain, invoke
105: * the <code>service()</code> method of the servlet itself.
106: *
107: * @param request The servlet request we are processing
108: * @param response The servlet response we are creating
109: *
110: * @exception IOException if an input/output error occurs
111: * @exception ServletException if a servlet exception occurs
112: */
113: public void doFilter(ServletRequest request,
114: ServletResponse response) throws IOException,
115: ServletException {
116:
117: if (System.getSecurityManager() != null) {
118: final ServletRequest req = request;
119: final ServletResponse res = response;
120: try {
121: java.security.AccessController
122: .doPrivileged(new java.security.PrivilegedExceptionAction() {
123: public Object run()
124: throws ServletException,
125: IOException {
126: internalDoFilter(req, res);
127: return null;
128: }
129: });
130: } catch (PrivilegedActionException pe) {
131: Exception e = pe.getException();
132: if (e instanceof ServletException)
133: throw (ServletException) e;
134: else if (e instanceof IOException)
135: throw (IOException) e;
136: else if (e instanceof RuntimeException)
137: throw (RuntimeException) e;
138: else
139: throw new ServletException(e.getMessage(), e);
140: }
141: } else {
142: internalDoFilter(request, response);
143: }
144: }
145:
146: private void internalDoFilter(ServletRequest request,
147: ServletResponse response) throws IOException,
148: ServletException {
149:
150: // Call the next filter if there is one
151: if (pos < n) {
152: ApplicationFilterConfig filterConfig = filters[pos++];
153: Filter filter = null;
154: try {
155: filter = filterConfig.getFilter();
156: support.fireInstanceEvent(
157: InstanceEvent.BEFORE_FILTER_EVENT, filter,
158: request, response);
159:
160: if (System.getSecurityManager() != null) {
161: final ServletRequest req = request;
162: final ServletResponse res = response;
163: Principal principal = ((HttpServletRequest) req)
164: .getUserPrincipal();
165: Class[] classType = new Class[] {
166: ServletRequest.class,
167: ServletResponse.class, FilterChain.class };
168: Object[] args = new Object[] { req, res, this };
169: SecurityUtil.doAsPrivilege("doFilter", filter,
170: classType, args);
171: } else {
172: filter.doFilter(request, response, this );
173: }
174:
175: support.fireInstanceEvent(
176: InstanceEvent.AFTER_FILTER_EVENT, filter,
177: request, response);
178: } catch (IOException e) {
179: if (filter != null)
180: support.fireInstanceEvent(
181: InstanceEvent.AFTER_FILTER_EVENT, filter,
182: request, response, e);
183: throw e;
184: } catch (ServletException e) {
185: if (filter != null)
186: support.fireInstanceEvent(
187: InstanceEvent.AFTER_FILTER_EVENT, filter,
188: request, response, e);
189: throw e;
190: } catch (RuntimeException e) {
191: if (filter != null)
192: support.fireInstanceEvent(
193: InstanceEvent.AFTER_FILTER_EVENT, filter,
194: request, response, e);
195: throw e;
196: } catch (Throwable e) {
197: if (filter != null)
198: support.fireInstanceEvent(
199: InstanceEvent.AFTER_FILTER_EVENT, filter,
200: request, response, e);
201: throw new ServletException(sm
202: .getString("filterChain.filter"), e);
203: }
204: return;
205: }
206:
207: // We fell off the end of the chain -- call the servlet instance
208: try {
209: support.fireInstanceEvent(
210: InstanceEvent.BEFORE_SERVICE_EVENT, servlet,
211: request, response);
212: if ((request instanceof HttpServletRequest)
213: && (response instanceof HttpServletResponse)) {
214:
215: if (System.getSecurityManager() != null) {
216: final ServletRequest req = request;
217: final ServletResponse res = response;
218: Principal principal = ((HttpServletRequest) req)
219: .getUserPrincipal();
220: Class[] classType = new Class[] {
221: ServletRequest.class, ServletResponse.class };
222: Object[] args = new Object[] { req, res };
223: SecurityUtil.doAsPrivilege("service", servlet,
224: classType, args, principal);
225: } else {
226: servlet.service((HttpServletRequest) request,
227: (HttpServletResponse) response);
228: }
229: } else {
230: servlet.service(request, response);
231: }
232: support.fireInstanceEvent(
233: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
234: request, response);
235: } catch (IOException e) {
236: support.fireInstanceEvent(
237: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
238: request, response, e);
239: throw e;
240: } catch (ServletException e) {
241: support.fireInstanceEvent(
242: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
243: request, response, e);
244: throw e;
245: } catch (RuntimeException e) {
246: support.fireInstanceEvent(
247: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
248: request, response, e);
249: throw e;
250: } catch (Throwable e) {
251: support.fireInstanceEvent(
252: InstanceEvent.AFTER_SERVICE_EVENT, servlet,
253: request, response, e);
254: throw new ServletException(sm
255: .getString("filterChain.servlet"), e);
256: }
257:
258: }
259:
260: // -------------------------------------------------------- Package Methods
261:
262: /**
263: * Add a filter to the set of filters that will be executed in this chain.
264: *
265: * @param filterConfig The FilterConfig for the servlet to be executed
266: */
267: void addFilter(ApplicationFilterConfig filterConfig) {
268:
269: if (n == filters.length) {
270: ApplicationFilterConfig[] newFilters = new ApplicationFilterConfig[n
271: + INCREMENT];
272: System.arraycopy(filters, 0, newFilters, 0, n);
273: filters = newFilters;
274: }
275: filters[n++] = filterConfig;
276:
277: }
278:
279: /**
280: * Release references to the filters and wrapper executed by this chain.
281: */
282: void release() {
283:
284: n = 0;
285: pos = 0;
286: servlet = null;
287: support = null;
288:
289: }
290:
291: /**
292: * Set the servlet that will be executed at the end of this chain.
293: *
294: * @param servlet The Wrapper for the servlet to be executed
295: */
296: void setServlet(Servlet servlet) {
297:
298: this .servlet = servlet;
299:
300: }
301:
302: /**
303: * Set the InstanceSupport object used for event notifications
304: * for this filter chain.
305: *
306: * @param support The InstanceSupport object for our Wrapper
307: */
308: void setSupport(InstanceSupport support) {
309:
310: this.support = support;
311:
312: }
313:
314: }
|