You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@locus.apache.org on 2000/08/22 02:14:05 UTC

cvs commit: jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core ApplicationFilterConfig.java ApplicationFilterWrapper.java LocalStrings.properties StandardWrapper.java StandardWrapperValve.java

craigmcc    00/08/21 17:14:04

  Modified:    catalina/src/share/org/apache/catalina/core
                        LocalStrings.properties StandardWrapper.java
                        StandardWrapperValve.java
  Added:       catalina/src/share/org/apache/catalina/core
                        ApplicationFilterConfig.java
                        ApplicationFilterWrapper.java
  Log:
  Initial implementation of request filtering, as described in the Servlet
  2.3 (public draft 1) specification.  Nothing breaks when no filters are
  defined, but this needs extensive testing.  It is also by no means
  optimized for performance (the Filter and FilterConfig objects are
  instantiated individually per request rather than being pooled), but that
  sort of thing can be optimized later after the functionality is validated.
  
  Revision  Changes    Path
  1.4       +2 -0      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/LocalStrings.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LocalStrings.properties	2000/08/17 18:41:32	1.3
  +++ LocalStrings.properties	2000/08/22 00:14:02	1.4
  @@ -48,6 +48,7 @@
   standardWrapper.allocate=Error allocating a servlet instance
   standardWrapper.allocateException=Allocate exception for servlet {0}
   standardWrapper.containerServlet=Loading container servlet {0}
  +standardWrapper.createFilters=Create filters exception for servlet {0}
   standardWrapper.deallocateException=Deallocate exception for servlet {0}
   standardWrapper.destroyException=Servlet.destroy() for servlet {0} threw exception
   standardWrapper.exception0=Tomcat Exception Report
  @@ -64,6 +65,7 @@
   standardWrapper.notClass=No servlet class has been specified for servlet {0}
   standardWrapper.notContext=Parent container of a Wrapper must be a Context
   standardWrapper.notServlet=Class {0} is not a Servlet
  +standardWrapper.releaseFilters=Release filters exception for servlet {0}
   standardWrapper.serviceException=Servlet.service() for servlet {0} threw exception
   standardWrapper.statusHeader=HTTP Status {0} - {1}
   standardWrapper.statusTitle=Tomcat Error Report
  
  
  
  1.2       +4 -6      jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java
  
  Index: StandardWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StandardWrapper.java	2000/08/11 23:40:45	1.1
  +++ StandardWrapper.java	2000/08/22 00:14:02	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.1 2000/08/11 23:40:45 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2000/08/11 23:40:45 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapper.java,v 1.2 2000/08/22 00:14:02 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2000/08/22 00:14:02 $
    *
    * ====================================================================
    *
  @@ -100,7 +100,7 @@
    * make them efficient are counter-productive.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2000/08/11 23:40:45 $
  + * @version $Revision: 1.2 $ $Date: 2000/08/22 00:14:02 $
    */
   
   public final class StandardWrapper
  @@ -952,8 +952,6 @@
   
   	if (classname.startsWith("org.apache.catalina."))
   	    return (true);
  -	else if (classname.startsWith("org.apache.jasper."))
  -	    return (true);	// FIXME - Only because of internal dependencies!
   	else
   	    return (false);
   
  
  
  
  1.3       +268 -6    jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapperValve.java
  
  Index: StandardWrapperValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapperValve.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StandardWrapperValve.java	2000/08/19 05:29:16	1.2
  +++ StandardWrapperValve.java	2000/08/22 00:14:02	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapperValve.java,v 1.2 2000/08/19 05:29:16 remm Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/08/19 05:29:16 $
  + * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/StandardWrapperValve.java,v 1.3 2000/08/22 00:14:02 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/08/22 00:14:02 $
    *
    * ====================================================================
    *
  @@ -67,6 +67,8 @@
   
   import java.io.IOException;
   import java.io.PrintWriter;
  +import javax.servlet.Filter;
  +import javax.servlet.FilterConfig;
   import javax.servlet.RequestDispatcher;
   import javax.servlet.Servlet;
   import javax.servlet.ServletContext;
  @@ -88,6 +90,8 @@
   import org.apache.catalina.Response;
   import org.apache.catalina.Wrapper;
   import org.apache.catalina.deploy.ErrorPage;
  +import org.apache.catalina.deploy.FilterDef;
  +import org.apache.catalina.deploy.FilterMap;
   import org.apache.catalina.util.InstanceSupport;
   import org.apache.catalina.util.StringManager;
   import org.apache.catalina.valves.ValveBase;
  @@ -98,7 +102,7 @@
    * <code>StandardWrapper</code> container implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2000/08/19 05:29:16 $
  + * @version $Revision: 1.3 $ $Date: 2000/08/22 00:14:02 $
    */
   
   final class StandardWrapperValve
  @@ -111,10 +115,16 @@
       /**
        * The debugging detail level for this component.
        */
  -    private int debug = 0;
  +    private int debug = 3;
   
   
       /**
  +     * The filter definition for our container-provided filter.
  +     */
  +    private FilterDef filterDef = null;
  +
  +
  +    /**
        * The string manager for this package.
        */
       private static final StringManager sm =
  @@ -187,18 +197,35 @@
   	    exception(request, response, e);
   	    servlet = null;
   	}
  +
  +	// Create the filter stack for this request
  +	ApplicationFilterConfig filters = null;
  +	try {
  +	    if (servlet != null) {
  +		filters = createFilters(request, servlet);
  +	    }
  +	} catch (Throwable e) {
  +	    log(sm.getString("standardWrapper.createFilters",
  +			     wrapper.getName()), e);
  +	    throwable = e;
  +	    exception(request, response, e);
  +	    servlet = null;
  +	}
   
  -	// Call the service() method of this instance
  +	// Call the filter stack for this request
   	try {
   	    if (servlet != null) {
   		support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
   					  servlet);
  +		filters.getFilter().doFilter(sreq, sres);
  +		/*
   		if ((servlet instanceof HttpServlet) &&
   		    (hreq != null) && (hres != null)) {
   		    ((HttpServlet) servlet).service(hreq, hres);
   		} else {
   		    servlet.service(sreq, sres);
   		}
  +		*/
   		support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
   					  servlet);
   	    }
  @@ -233,6 +260,16 @@
   	    exception(request, response, e);
   	}
   
  +	// Release the filter stack (if any) for this request
  +	try {
  +	    releaseFilters(request, filters);
  +	} catch (Throwable e) {
  +	    log(sm.getString("standardWrapper.releaseFilters",
  +			     wrapper.getName()), e);
  +	    throwable = e;
  +	    exception(request, response, e);
  +	}
  +
   	// Deallocate the allocated servlet instance
   	try {
   	    if (servlet != null) {
  @@ -262,6 +299,127 @@
   
   
       /**
  +     * Construct and return a linked list of <code>FilterConfig</code>
  +     * objects, and their associated <code>Filters</code>, that are relevant
  +     * for this request.  A container-supplied filter to call the servlet
  +     * method will always be appended, so this method is guaranteed to
  +     * return at least one filter.
  +     * <p>
  +     * <strong>IMPLEMENTATION NOTE</strong>:  This initial implementation is
  +     * not at all optimized, because it dynamically instantiates the relevant
  +     * filter instances every time, with no pooling.  Functionality first,
  +     * then optimization.
  +     *
  +     * @param request The request we are processing
  +     * @param servlet The servlet we are wrapping
  +     *
  +     * @exception Exception if an exception occurs while creating the
  +     *  filter list
  +     */
  +    private ApplicationFilterConfig createFilters(Request request,
  +						  Servlet servlet)
  +	throws Exception {
  +
  +	// Acquire the filter mappings for this Context
  +	Wrapper wrapper = (Wrapper) getContainer();
  +	Context context = (Context) wrapper.getParent();
  +	FilterMap filterMaps[] = context.findFilterMaps();
  +
  +	// Acquire the information we will need to match filter mappings
  +	String requestPath = null;
  +	if (request instanceof HttpRequest) {
  +	    HttpServletRequest hreq =
  +		(HttpServletRequest) request.getRequest();
  +	    String contextPath = hreq.getContextPath();
  +	    if (contextPath == null)
  +		contextPath = "";
  +	    String requestURI = hreq.getRequestURI();
  +	    if (requestURI.length() >= contextPath.length())
  +		requestPath = requestURI.substring(contextPath.length());
  +	}
  +	String servletName = wrapper.getName();
  +
  +	if (debug >= 1)
  +	    log("Creating filter stack for request path '" + requestPath +
  +		"' and servlet '" + servlet + "'");
  +
  +	// Create a stack of the relevant filters only
  +	int n = 0;
  +	ApplicationFilterConfig first = null;
  +	ApplicationFilterConfig last = null;
  +	ApplicationFilterConfig next = null;
  +
  +	// Add filters that match on URL pattern first
  +	for (int i = 0; i < filterMaps.length; i++) {
  +	    if (!matchFiltersURL(filterMaps[i], requestPath))
  +		continue;
  +	    FilterDef filterDef =
  +		context.findFilterDef(filterMaps[i].getFilterName());
  +	    if (filterDef == null) {
  +		;	// FIXME - log configuration problem
  +		continue;
  +	    }
  +	    if (debug >= 2)
  +		log(" Adding filter '" + filterDef.getFilterName() + "'");
  +	    next = new ApplicationFilterConfig(filterDef, context);
  +	    if (first == null)
  +		first = next;
  +	    if (last != null)
  +		last.setNextConfig(next);
  +	    last = next;
  +	    n++;
  +	}
  +
  +	// Add filters that match on servlet name second
  +	for (int i = 0; i < filterMaps.length; i++) {
  +	    if (!matchFiltersServlet(filterMaps[i], servletName))
  +		continue;
  +	    FilterDef filterDef =
  +		context.findFilterDef(filterMaps[i].getFilterName());
  +	    if (filterDef == null) {
  +		;	// FIXME - log configuration problem
  +		continue;
  +	    }
  +	    if (debug >= 2)
  +		log(" Adding filter '" + filterDef.getFilterName() + "'");
  +	    next = new ApplicationFilterConfig(filterDef, context);
  +	    if (first == null)
  +		first = next;
  +	    if (last != null)
  +		last.setNextConfig(next);
  +	    last = next;
  +	    n++;
  +	}
  +
  +	// Add an internal filter to call the servlet itself third
  +	if (debug >= 2)
  +	    log(" Adding container-provided wrapper filter");
  +	if (this.filterDef == null) {
  +	    FilterDef newDef = new FilterDef();
  +	    newDef.setFilterClass("org.apache.catalina.core.ApplicationFilterWrapper");
  +	    newDef.setFilterName("org.apache.catalina.core.ApplicationFilterWrapper");
  +	    this.filterDef = newDef;
  +	}
  +	next = new ApplicationFilterConfig(this.filterDef, context);
  +	ApplicationFilterWrapper filter =
  +	    (ApplicationFilterWrapper) next.getFilter();
  +	filter.setServlet(servlet);
  +	if (first == null)
  +	    first = next;
  +	if (last != null)
  +	    last.setNextConfig(next);
  +	last = next;
  +	n++;
  +	if (debug >= 1)
  +	    log(" Total of " + n + " filters configured");
  +
  +	// Return the constructed filter chain
  +	return (first);
  +
  +    }
  +
  +
  +    /**
        * Handle an HTTP status code or Java exception by forwarding control
        * to the location included in the specified errorPage object.  It is
        * assumed that the caller has already recorded any request attributes
  @@ -474,6 +632,110 @@
   
       }
   
  +
  +    /**
  +     * Return <code>true</code> if the specified servlet name matches
  +     * the requirements of the specified filter mapping; otherwise
  +     * return <code>false</code>.
  +     *
  +     * @param filterMap Filter mapping being checked
  +     * @param servletName Servlet name being checked
  +     */
  +    private boolean matchFiltersServlet(FilterMap filterMap,
  +					String servletName) {
  +
  +	if (debug >= 3)
  +	    log("  Matching servlet name '" + servletName +
  +		"' against mapping " + filterMap);
  +
  +	if (servletName == null)
  +	    return (false);
  +	else
  +	    return (servletName.equals(filterMap.getServletName()));
  +
  +    }
  +
  +
  +    /**
  +     * Return <code>true</code> if the context-relative request path
  +     * matches the requirements of the specified filter mapping;
  +     * otherwise, return <code>null</code>.
  +     *
  +     * @param filterMap Filter mapping being checked
  +     * @param requestPath Context-relative request path of this request
  +     */
  +    private boolean matchFiltersURL(FilterMap filterMap,
  +				    String requestPath) {
  +
  +	if (debug >= 3)
  +	    log("  Matching request path '" + requestPath +
  +		"' against mapping " + filterMap);
  +
  +	if (requestPath == null)
  +	    return (false);
  +
  +	// Match on context relative request path
  +	String testPath = filterMap.getURLPattern();
  +	if (testPath == null)
  +	    return (false);
  +
  +	// Case 1 - Exact Match
  +	if (testPath.equals(requestPath))
  +	    return (true);
  +
  +	// Case 2 - Path Match ("/.../*")
  +	if (testPath.equals("/*"))
  +	    return (true);	// Optimize a common case
  +	if (testPath.endsWith("/*")) {
  +	    String comparePath = requestPath;
  +	    while (true) {
  +		if (testPath.equals(comparePath + "/*"))
  +		    return (true);
  +		int slash = comparePath.lastIndexOf("/");
  +		if (slash < 0)
  +		    break;
  +		comparePath = comparePath.substring(0, slash);
  +	    }
  +	    return (false);
  +	}
  +
  +	// Case 3 - Extension Match
  +	if (testPath.startsWith("*.")) {
  +	    int slash = requestPath.lastIndexOf("/");
  +	    int period = requestPath.lastIndexOf(".");
  +	    if ((slash >= 0) && (period > slash))
  +		return (testPath.equals("*." +
  +					requestPath.substring(period + 1)));
  +	}
  +
  +
  +	// Case 4 - "Default" Match
  +	return (false);	// NOTE - Not relevant for selecting filters
  +
  +    }
  +
  +
  +    /**
  +     * Release the specified filter stack associated with this request.
  +     *
  +     * @param request The request being processed
  +     * @param filters The filter stack being released
  +     *
  +     * @exception Exception if an exception occurs during the release
  +     */
  +    private void releaseFilters(Request request,
  +				ApplicationFilterConfig filters)
  +	throws Exception {
  +
  +	while (filters != null) {
  +	    filters.getFilter().setFilterConfig(null);
  +	    filters.setFilter(null);
  +	    ApplicationFilterConfig next = filters.getNextConfig();
  +	    filters.setNextConfig(null);
  +	    filters = next;
  +	}
  +
  +    }
   
       /**
        * Handle the HTTP status code (and corresponding message) generated
  
  
  
  1.1                  jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationFilterConfig.java
  
  Index: ApplicationFilterConfig.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationFilterConfig.java,v 1.1 2000/08/22 00:14:02 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/08/22 00:14:02 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.catalina.core;
  
  
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.Map;
  import javax.servlet.Filter;
  import javax.servlet.FilterConfig;
  import javax.servlet.ServletContext;
  import org.apache.catalina.Context;
  import org.apache.catalina.deploy.FilterDef;
  import org.apache.catalina.util.Enumerator;
  
  
  /**
   * Implementation of a <code>javax.servlet.FilterConfig</code> useful in
   * constructing stacks of filters for a particular request.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/08/22 00:14:02 $
   */
  
  final class ApplicationFilterConfig implements FilterConfig {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new ApplicationFilterConfig for the specified filter
       * definition.
       *
       * @param filterDef Filter definition for which a FilterConfig is to be
       *  constructed
       * @param context The Context with which we are associated
       *
       * @exception ClassCastException if the specified class does not implement
       *  the <code>javax.servlet.Filter</code> interface
       * @exception ClassNotFoundException if the filter class cannot be found
       * @exception IllegalAccessException if the filter class cannot be
       *  publicly instantiated
       * @exception InstantiationException if an exception occurs while
       *  instantiating the filter object
       */
      public ApplicationFilterConfig(FilterDef filterDef, Context context)
  	throws ClassCastException, ClassNotFoundException,
  	       IllegalAccessException, InstantiationException {
  
  	super();
  	setContext(context);
  	setFilterDef(filterDef);
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Context with which we are associated.
       */
      private Context context = null;
  
  
      /**
       * The application Filter we are configured for.
       */
      private Filter filter = null;
  
  
      /**
       * The <code>FilterDef</code> that defines our associated Filter.
       */
      private FilterDef filterDef = null;
  
  
      /**
       * The <code>ApplicationFilterConfig</code> of the next filter in our
       * configured filter stack.
       */
      private ApplicationFilterConfig nextConfig = null;
  
  
      // --------------------------------------------------- FilterConfig Methods
  
  
      /**
       * Return the name of the filter we are configuring.
       */
      public String getFilterName() {
  
  	return (filterDef.getFilterName());
  
      }
  
  
      /**
       * Return the remaining Filter objects in the Filter stack, in the order
       * they have been configured.
       */
      public Iterator getFilters() {
  
  	// NOTE - The list of filters we are about to accumulate includes
  	// the container-provided filter at the end that wraps the call to
  	// the servlet's service() method
  	ArrayList list = new ArrayList();
  	ApplicationFilterConfig next = getNextConfig();
  	while (next != null) {
  	    list.add(next.getFilter());
  	    next = next.getNextConfig();
  	}
  
  	// NOTE - The iterator we are about to return probably does support
  	// remove(), but calling it has no impact on the actual functionality
  	// of filter processing so I don't see it as a big issue
  	return (list.iterator());
  
      }
  
  
      /**
       * Return a <code>String</code> containing the value of the named
       * initialization parameter, or <code>null</code> if the parameter
       * does not exist.
       *
       * @param name Name of the requested initialization parameter
       */
      public String getInitParameter(String name) {
  
  	Map map = filterDef.getParameterMap();
  	if (map == null)
  	    return (null);
  	else
  	    return ((String) map.get(name));
  
      }
  
  
      /**
       * Return an <code>Enumeration</code> of the names of the initialization
       * parameters for this Filter.
       */
      public Enumeration getInitParameterNames() {
  
  	Map map = filterDef.getParameterMap();
  	if (map == null)
  	    return (new Enumerator(new ArrayList()));
  	else
  	    return (new Enumerator(map.keySet()));
  
      }
  
  
      /**
       * Return the next Filter object in the filter stack.
       */
      public Filter getNext() {
  
  	if (nextConfig == null)
  	    return (null);
  	else
  	    return (nextConfig.getFilter());
  
      }
  
  
      /**
       * Return the ServletContext of our associated web application.
       */
      public ServletContext getServletContext() {
  
  	return (this.context.getServletContext());
  
      }
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Return the Context we are configured for.
       */
      Context getContext() {
  
  	return (this.context);
  
      }
  
  
      /**
       * Set the Context we are configured for.
       *
       * @param context The new Context
       */
      void setContext(Context context) {
  
  	this.context = context;
  
      }
  
  
      /**
       * Return the application Filter we are configured for.
       */
      Filter getFilter() {
  
  	return (this.filter);
  
      }
  
  
      /**
       * Set the application Filter we are configured for.
       *
       * @param filter The new application Filter
       */
      void setFilter(Filter filter) {
  
  	this.filter = filter;
  
      }
  
  
      /**
       * Return the filter definition we are configured for.
       */
      FilterDef getFilterDef() {
  
  	return (this.filterDef);
  
      }
  
  
      /**
       * Set the filter definition we are configured for.  This has the side
       * effect of instantiating an instance of the corresponding filter class.
       *
       * @param filterDef The new filter definition
       *
       * @exception ClassCastException if the specified class does not implement
       *  the <code>javax.servlet.Filter</code> interface
       * @exception ClassNotFoundException if the filter class cannot be found
       * @exception IllegalAccessException if the filter class cannot be
       *  publicly instantiated
       * @exception InstantiationException if an exception occurs while
       *  instantiating the filter object
       */
      void setFilterDef(FilterDef filterDef)
  	throws ClassCastException, ClassNotFoundException,
  	       IllegalAccessException, InstantiationException {
  
  	this.filterDef = filterDef;
  	if (filterDef == null) {
  
  	    // Release any previously allocated filter instance
  	    if (this.filter != null)
  		this.filter.setFilterConfig(null);
  	    this.filter = null;
  
  	} else {
  
  	    // Identify the class loader we will be using
  	    String filterClass = filterDef.getFilterClass();
  	    ClassLoader classLoader = null;
  	    // FIXME - share this test with StandardWrapper somehow
  	    if (filterClass.startsWith("org.apache.catalina."))
  		classLoader = this.getClass().getClassLoader();
  	    else
  		classLoader = context.getLoader().getClassLoader();
  
  	    // Instantiate a new instance of this filter
  	    Class clazz = classLoader.loadClass(filterClass);
  	    this.filter = (Filter) clazz.newInstance();
  	    filter.setFilterConfig(this);
  	}
  
      }
  
  
      /**
       * Return the <code>ApplicationFilterConfig</code> of the next filter
       * in our filter stack.
       */
      ApplicationFilterConfig getNextConfig() {
  
  	return (nextConfig);
  
      }
  
  
      /**
       * Set the <code>ApplicationFilterConfig</code> of the next filter
       * in our filter stack.
       *
       * @param nextConfig The next filter configuration object
       */
      void setNextConfig(ApplicationFilterConfig nextConfig) {
  
  	this.nextConfig = nextConfig;
  	if (nextConfig == null) {
  	    this.filter = null;
  	    this.context = null;
  	}
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
  }
  
  
  
  1.1                  jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationFilterWrapper.java
  
  Index: ApplicationFilterWrapper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/core/ApplicationFilterWrapper.java,v 1.1 2000/08/22 00:14:02 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/08/22 00:14:02 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  
  package org.apache.catalina.core;
  
  
  import java.io.IOException;
  import javax.servlet.Filter;
  import javax.servlet.FilterConfig;
  import javax.servlet.Servlet;
  import javax.servlet.ServletException;
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  
  
  /**
   * This is the container-provided Filter that wraps the ultimate call to
   * a servlet's <code>service()</code> method.  It is appended to the filter
   * stack for every request, so that application filters need not take
   * special measures if they are the last filter in the stack.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/08/22 00:14:02 $
   */
  
  public final class ApplicationFilterWrapper implements Filter {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new wrapper filter with default parameters.
       */
      public ApplicationFilterWrapper() {
  
  	this(null);
  
      }
  
  
      /**
       * Construct a new wrapper filter with the specified parameters.
       *
       * @param servlet The servlet being wrapped
       */
      public ApplicationFilterWrapper(Servlet servlet) {
  
  	super();
  	this.servlet = servlet;
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The filter configuration object for this filter.
       */
      private FilterConfig filterConfig = null;
  
  
      /**
       * The servlet that is being wrapped by this filter.
       */
      private Servlet servlet = null;
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Implement the functionality provided by this filter.  In this case,
       * all we are doing is calling the appropriate <code>service()</code>
       * method of the wrapped servlet, depending on whether or not this is
       * an HTTP or non-HTTP environment.
       *
       * @param request The servlet request being processed
       * @param response The servlet response being created
       *
       * @exception IOException if an input/output error occurs
       * @exception ServletException if the servlet itself throws this
       */
      public void doFilter(ServletRequest request, ServletResponse response)
  	throws IOException, ServletException {
  
  	// Call the appropriate service() method
  	if ((servlet instanceof HttpServlet) &&
  	    (request instanceof HttpServletRequest) &&
  	    (response instanceof HttpServletResponse)) {
  	    HttpServletRequest hrequest = (HttpServletRequest) request;
  	    HttpServletResponse hresponse =
  		(HttpServletResponse) response;
  	    ((HttpServlet) servlet).service(hrequest, hresponse);
  	} else {
  	    servlet.service(request, response);
  	}
  
  	// NOTE - Do *not* call the next filter, because this request
  	// has been handled and the corresponding response created
  
      }
  
  
      /**
       * Return the filter configuration object for this Filter.
       */
      public FilterConfig getFilterConfig() {
  
  	return (this.filterConfig);
  
      }
  
  
      /**
       * Set the filter configuration object for this Filter.
       *
       * @param filterConfig The new filter configuration object
       */
      public void setFilterConfig(FilterConfig filterConfig) {
  
  	this.filterConfig = filterConfig;
  	if (filterConfig == null)
  	    this.servlet = null;
  
      }
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Return the servlet instance we are filtering.
       */
      Servlet getServlet() {
  
  	return (this.servlet);
  
      }
  
  
      /**
       * Set the servlet instance we are filtering.
       *
       * @param servlet The new servlet instance
       */
      void setServlet(Servlet servlet) {
  
  	this.servlet = servlet;
  
      }
  
  
  }