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/05/22 22:11:21 UTC

cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core HttpContextMapper.java HttpEngineMapper.java HttpHostMapper.java ApplicationContext.java ContainerBase.java LocalStrings.properties StandardContext.java StandardContextValve.java StandardEngine.java StandardEngineValve.java StandardHost.java StandardHostValve.java StandardWrapper.java

craigmcc    00/05/22 13:11:19

  Modified:    proposals/catalina/src/conf server.xml
               proposals/catalina/src/share/org/apache/tomcat
                        Container.java Context.java Engine.java Host.java
               proposals/catalina/src/share/org/apache/tomcat/core
                        ApplicationContext.java ContainerBase.java
                        LocalStrings.properties StandardContext.java
                        StandardContextValve.java StandardEngine.java
                        StandardEngineValve.java StandardHost.java
                        StandardHostValve.java StandardWrapper.java
  Added:       proposals/catalina/src/share/org/apache/tomcat Mapper.java
               proposals/catalina/src/share/org/apache/tomcat/core
                        HttpContextMapper.java HttpEngineMapper.java
                        HttpHostMapper.java
  Log:
  Abstract the method "map(Request request, boolean update)", which was
  common to many Container implementation classes, into a new component type
  called a Mapper.
  
  Allow run-time configuration of Mappers per Container (not yet complete).
  If more than one is present, the one to be used is based on the protocol
  used on this request (so, for example, you could have a webapp that
  served both http and ftp requests using the same resources, but used
  different mapping rules).  If only one Mapper is configured for a
  particular Container (the default case), it is used for all protocols.
  
  Revision  Changes    Path
  1.28      +1 -1      jakarta-tomcat/proposals/catalina/src/conf/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/conf/server.xml,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- server.xml	2000/05/21 02:39:56	1.27
  +++ server.xml	2000/05/22 20:10:54	1.28
  @@ -7,7 +7,7 @@
     <!-- Define all the connectors to associate with the following container -->
   
     <Connector className="org.apache.tomcat.connector.test.HttpConnector"
  -             port="8080" minProcessors="5" maxProcessors="60"
  +             port="8080" minProcessors="5" maxProcessors="75"
   	     acceptCount="10" debug="0"/>
   
     <!-- Define the top level container in our container hierarchy -->
  
  
  
  1.6       +81 -20    jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Container.java
  
  Index: Container.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Container.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Container.java	2000/04/10 18:44:39	1.5
  +++ Container.java	2000/05/22 20:11:00	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Container.java,v 1.5 2000/04/10 18:44:39 craigmcc Exp $
  - * $Revision: 1.5 $
  - * $Date: 2000/04/10 18:44:39 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Container.java,v 1.6 2000/05/22 20:11:00 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2000/05/22 20:11:00 $
    *
    * ====================================================================
    *
  @@ -119,7 +119,7 @@
    * </ul>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2000/04/10 18:44:39 $
  + * @version $Revision: 1.6 $ $Date: 2000/05/22 20:11:00 $
    */
   
   public interface Container {
  @@ -136,6 +136,13 @@
   
   
       /**
  +     * The ContainerEvent event type sent when a Mapper is added
  +     * by <code>addMapper()</code>.
  +     */
  +    public static final String ADD_MAPPER_EVENT = "addMapper";
  +
  +
  +    /**
        * The ContainerEvent event type sent when a valve is added
        * by <code>addValve()</code>, if this Container supports pipelines.
        */
  @@ -150,6 +157,13 @@
   
   
       /**
  +     * The ContainerEvent event type sent when a Mapper is removed
  +     * by <code>removeMapper()</code>.
  +     */
  +    public static final String REMOVE_MAPPER_EVENT = "removeMapper";
  +
  +
  +    /**
        * The ContainerEvent event type sent when a valve is removed
        * by <code>removeValve()</code>, if this Container supports pipelines.
        */
  @@ -294,22 +308,6 @@
   
   
       /**
  -     * Add a container event listener to this component.
  -     *
  -     * @param listener The listener to add
  -     */
  -    public void addContainerListener(ContainerListener listener);
  -
  -
  -    /**
  -     * Add a property change listener to this component.
  -     *
  -     * @param listener The listener to add
  -     */
  -    public void addPropertyChangeListener(PropertyChangeListener listener);
  -
  -
  -    /**
        * Add a new child Container to those associated with this Container,
        * if supported.  Prior to adding this Container to the set of children,
        * the child's <code>setParent()</code> method must be called, with this
  @@ -330,6 +328,33 @@
   
   
       /**
  +     * Add a container event listener to this component.
  +     *
  +     * @param listener The listener to add
  +     */
  +    public void addContainerListener(ContainerListener listener);
  +
  +
  +    /**
  +     * Add the specified Mapper associated with this Container.
  +     *
  +     * @param mapper The corresponding Mapper implementation
  +     *
  +     * @exception IllegalArgumentException if this exception is thrown by
  +     *  the <code>setContainer()</code> method of the Mapper
  +     */
  +    public void addMapper(Mapper mapper);
  +
  +
  +    /**
  +     * Add a property change listener to this component.
  +     *
  +     * @param listener The listener to add
  +     */
  +    public void addPropertyChangeListener(PropertyChangeListener listener);
  +
  +
  +    /**
        * Return the child Container, associated with this Container, with
        * the specified name (if any); otherwise, return <code>null</code>
        *
  @@ -346,6 +371,23 @@
   
   
       /**
  +     * Return the Mapper associated with the specified protocol, if there
  +     * is one.  If there is only one defined Mapper, use it for all protocols.
  +     * If there is no matching Mapper, return <code>null</code>.
  +     *
  +     * @param protocol Protocol for which to find a Mapper
  +     */
  +    public Mapper findMapper(String protocol);
  +
  +
  +    /**
  +     * Return the set of Mappers associated with this Container.  If this
  +     * Container has no Mappers, a zero-length array is returned.
  +     */
  +    public Mapper[] findMappers();
  +
  +
  +    /**
        * Process the specified Request, and generate the corresponding Response,
        * according to the design of this particular Container.
        *
  @@ -362,6 +404,17 @@
   
   
       /**
  +     * Return the child Container that should be used to process this Request,
  +     * based upon its characteristics.  If no such child Container can be
  +     * identified, return <code>null</code> instead.
  +     *
  +     * @param request Request being processed
  +     * @param update Update the Request to reflect the mapping selection?
  +     */
  +    public Container map(Request request, boolean update);
  +
  +
  +    /**
        * Remove an existing child Container from association with this parent
        * Container.
        *
  @@ -376,6 +429,14 @@
        * @param listener The listener to remove
        */
       public void removeContainerListener(ContainerListener listener);
  +
  +
  +    /**
  +     * Remove a Mapper associated with this Container, if any.
  +     *
  +     * @param mapper The Mapper to be removed
  +     */
  +    public void removeMapper(Mapper mapper);
   
   
       /**
  
  
  
  1.11      +4 -15     jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Context.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Context.java	2000/05/12 21:59:32	1.10
  +++ Context.java	2000/05/22 20:11:01	1.11
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Context.java,v 1.10 2000/05/12 21:59:32 craigmcc Exp $
  - * $Revision: 1.10 $
  - * $Date: 2000/05/12 21:59:32 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Context.java,v 1.11 2000/05/22 20:11:01 craigmcc Exp $
  + * $Revision: 1.11 $
  + * $Date: 2000/05/22 20:11:01 $
    *
    * ====================================================================
    *
  @@ -90,7 +90,7 @@
    * <p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.10 $ $Date: 2000/05/12 21:59:32 $
  + * @version $Revision: 1.11 $ $Date: 2000/05/22 20:11:01 $
    */
   
   public interface Context extends Container {
  @@ -530,17 +530,6 @@
        * defined, a zero-length array is returned.
        */
       public String[] findWelcomeFiles();
  -
  -
  -    /**
  -     * Return the Wrapper associated with the servlet that matches the
  -     * specified context-relative URI, if any; otherwise return
  -     * <code>null</code>.
  -     *
  -     * @param request Request to be processed
  -     * @param update Update request to reflect this mapping?
  -     */
  -    public Wrapper map(Request request, boolean update);
   
   
       /**
  
  
  
  1.3       +4 -15     jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Engine.java
  
  Index: Engine.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Engine.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Engine.java	2000/04/23 01:42:27	1.2
  +++ Engine.java	2000/05/22 20:11:01	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Engine.java,v 1.2 2000/04/23 01:42:27 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/04/23 01:42:27 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Engine.java,v 1.3 2000/05/22 20:11:01 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2000/05/22 20:11:01 $
    *
    * ====================================================================
    *
  @@ -88,24 +88,13 @@
    * throw <code>IllegalArgumentException</code>.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2000/04/23 01:42:27 $
  + * @version $Revision: 1.3 $ $Date: 2000/05/22 20:11:01 $
    */
   
   public interface Engine extends Container {
   
   
       // --------------------------------------------------------- Public Methods
  -
  -
  -    /**
  -     * Return the Host that should be used to process this request,
  -     * based on the server name that was included.  If no such Host
  -     * can be identified, return <code>null</code> instead.
  -     *
  -     * @param request Request being processed
  -     * @param update Update the request to reflect this mapping?
  -     */
  -    public Host map(Request request, boolean update);
   
   
   }
  
  
  
  1.5       +4 -16     jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Host.java
  
  Index: Host.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Host.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Host.java	2000/05/20 22:13:30	1.4
  +++ Host.java	2000/05/22 20:11:03	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Host.java,v 1.4 2000/05/20 22:13:30 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/05/20 22:13:30 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Host.java,v 1.5 2000/05/22 20:11:03 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/05/22 20:11:03 $
    *
    * ====================================================================
    *
  @@ -91,7 +91,7 @@
    * an individual servlet context), depending upon the Engine implementation.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2000/05/20 22:13:30 $
  + * @version $Revision: 1.5 $ $Date: 2000/05/22 20:11:03 $
    */
   
   public interface Host extends Container {
  @@ -177,18 +177,6 @@
        * a zero length array is returned.
        */
       public String[] findAliases();
  -
  -
  -    /**
  -     * Return the Context that should be used to process this request,
  -     * based on matching the longest possible context path (or selecting
  -     * the default context).  If no such Context can be identified,
  -     * return <code>null</code> instead.
  -     *
  -     * @param request Request to be processed
  -     * @param update Update request to reflect this mapping?
  -     */
  -    public Context map(Request request, boolean update);
   
   
       /**
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Mapper.java
  
  Index: Mapper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/Mapper.java,v 1.1 2000/05/22 20:11:03 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/05/22 20:11:03 $
   *
   * ====================================================================
   *
   * 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.tomcat;
  
  
  /**
   * Interface defining methods that a parent Container may implement to select
   * a subordinate Container to process a particular Request, optionally
   * modifying the properties of the Request to reflect the selections made.
   * <p>
   * A typical Container may be associated with a single Mapper that processes
   * all requests to that Container, or a Mapper per request protocol that allows
   * the same Container to support multiple protocols at once.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/05/22 20:11:03 $
   */
  
  public interface Mapper {
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the Container with which this Mapper is associated.
       */
      public Container getContainer();
  
  
      /**
       * Set the Container with which this Mapper is associated.
       *
       * @param container The newly associated Container
       *
       * @exception IllegalArgumentException if this Container is not
       *  acceptable to this Mapper
       */
      public void setContainer(Container container);
  
  
      /**
       * Return the protocol for which this Mapper is responsible.
       */
      public String getProtocol();
  
  
      /**
       * Set the protocol for which this Mapper is responsible.
       *
       * @param protocol The newly associated protocol
       */
      public void setProtocol(String protocol);
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the child Container that should be used to process this Request,
       * based upon its characteristics.  If no such child Container can be
       * identified, return <code>null</code> instead.
       *
       * @param request Request being processed
       * @param update Update the Request to reflect the mapping selection?
       */
      public Container map(Request request, boolean update);
  
  
  }
  
  
  
  1.9       +5 -5      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ApplicationContext.java
  
  Index: ApplicationContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ApplicationContext.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- ApplicationContext.java	2000/05/12 00:47:24	1.8
  +++ ApplicationContext.java	2000/05/22 20:11:09	1.9
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ApplicationContext.java,v 1.8 2000/05/12 00:47:24 craigmcc Exp $
  - * $Revision: 1.8 $
  - * $Date: 2000/05/12 00:47:24 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ApplicationContext.java,v 1.9 2000/05/22 20:11:09 craigmcc Exp $
  + * $Revision: 1.9 $
  + * $Date: 2000/05/22 20:11:09 $
    *
    * ====================================================================
    *
  @@ -91,7 +91,7 @@
    * associated with each instance of <code>StandardContext</code>.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.8 $ $Date: 2000/05/12 00:47:24 $
  + * @version $Revision: 1.9 $ $Date: 2000/05/22 20:11:09 $
    */
   
   final class ApplicationContext
  @@ -363,7 +363,7 @@
   	request.setContextPath(context.getPath());
   	request.setRequestURI(contextPath + relativeURI);
   	request.setQueryString(queryString);
  -	Wrapper wrapper = context.map(request, true);
  +	Wrapper wrapper = (Wrapper) context.map(request, true);
   	if (wrapper == null)
   	    return (null);
   
  
  
  
  1.17      +220 -28   jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ContainerBase.java
  
  Index: ContainerBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ContainerBase.java,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- ContainerBase.java	2000/05/01 23:13:42	1.16
  +++ ContainerBase.java	2000/05/22 20:11:09	1.17
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ContainerBase.java,v 1.16 2000/05/01 23:13:42 craigmcc Exp $
  - * $Revision: 1.16 $
  - * $Date: 2000/05/01 23:13:42 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/ContainerBase.java,v 1.17 2000/05/22 20:11:09 craigmcc Exp $
  + * $Revision: 1.17 $
  + * $Date: 2000/05/22 20:11:09 $
    *
    * ====================================================================
    *
  @@ -82,6 +82,7 @@
   import org.apache.tomcat.Loader;
   import org.apache.tomcat.Logger;
   import org.apache.tomcat.Manager;
  +import org.apache.tomcat.Mapper;
   import org.apache.tomcat.Pipeline;
   import org.apache.tomcat.Realm;
   import org.apache.tomcat.Request;
  @@ -149,7 +150,7 @@
    * class comments of the implementation class.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.16 $ $Date: 2000/05/01 23:13:42 $
  + * @version $Revision: 1.17 $ $Date: 2000/05/22 20:11:09 $
    */
   
   public abstract class ContainerBase
  @@ -214,6 +215,24 @@
   
   
       /**
  +     * The one and only Mapper associated with this Container, if any.
  +     */
  +    protected Mapper mapper = null;
  +
  +
  +    /**
  +     * The set of Mappers associated with this Container, keyed by protocol.
  +     */
  +    protected Hashtable mappers = new Hashtable();
  +
  +
  +    /**
  +     * The Java class name of the default Mapper class for this Container.
  +     */
  +    protected String mapperClass = null;
  +
  +
  +    /**
        * The human-readable name of this Container.
        */
       protected String name = null;
  @@ -727,30 +746,6 @@
   
   
       /**
  -     * Add a container event listener to this component.
  -     *
  -     * @param listener The listener to add
  -     */
  -    public void addContainerListener(ContainerListener listener) {
  -
  -	listeners.addElement(listener);
  -
  -    }
  -
  -
  -    /**
  -     * Add a property change listener to this component.
  -     *
  -     * @param listener The listener to add
  -     */
  -    public void addPropertyChangeListener(PropertyChangeListener listener) {
  -
  -	support.addPropertyChangeListener(listener);
  -
  -    }
  -
  -
  -    /**
        * Add a new child Container to those associated with this Container,
        * if supported.  Prior to adding this Container to the set of children,
        * the child's <code>setParent()</code> method must be called, with this
  @@ -792,6 +787,66 @@
   
   
       /**
  +     * Add a container event listener to this component.
  +     *
  +     * @param listener The listener to add
  +     */
  +    public void addContainerListener(ContainerListener listener) {
  +
  +	listeners.addElement(listener);
  +
  +    }
  +
  +
  +    /**
  +     * Add the specified Mapper associated with this Container.
  +     *
  +     * @param mapper The corresponding Mapper implementation
  +     *
  +     * @exception IllegalArgumentException if this exception is thrown by
  +     *  the <code>setContainer()</code> method of the Mapper
  +     */
  +    public void addMapper(Mapper mapper) {
  +
  +	synchronized(mappers) {
  +	    if (mappers.get(mapper.getProtocol()) != null)
  +		throw new IllegalArgumentException("addMapper:  Protocol '" +
  +						   mapper.getProtocol() +
  +						   "' is not unique");
  +	    mapper.setContainer((Container) this);	// May throw IAE
  +	    if (started && (mapper instanceof Lifecycle)) {
  +		try {
  +		    ((Lifecycle) mapper).start();
  +		} catch (LifecycleException e) {
  +		    log("ContainerBase.addMapper: start: ", e);
  +		    throw new IllegalStateException
  +			("ContainerBase.addMapper: start: " + e);
  +		}
  +	    }
  +	    mappers.put(mapper.getProtocol(), mapper);
  +	    if (mappers.size() == 1)
  +		this.mapper = mapper;
  +	    else
  +		this.mapper = null;
  +	    fireContainerEvent(ADD_MAPPER_EVENT, mapper);
  +	}
  +
  +    }
  +
  +
  +    /**
  +     * Add a property change listener to this component.
  +     *
  +     * @param listener The listener to add
  +     */
  +    public void addPropertyChangeListener(PropertyChangeListener listener) {
  +
  +	support.addPropertyChangeListener(listener);
  +
  +    }
  +
  +
  +    /**
        * Return the child Container, associated with this Container, with
        * the specified name (if any); otherwise, return <code>null</code>
        *
  @@ -825,6 +880,44 @@
   
   
       /**
  +     * Return the Mapper associated with the specified protocol, if there
  +     * is one.  If there is only one defined Mapper, use it for all protocols.
  +     * If there is no matching Mapper, return <code>null</code>.
  +     *
  +     * @param protocol Protocol for which to find a Mapper
  +     */
  +    public Mapper findMapper(String protocol) {
  +
  +	if (mapper != null)
  +	    return (mapper);
  +	else
  +	    return ((Mapper) mappers.get(protocol));
  +
  +    }
  +
  +
  +    /**
  +     * Return the set of Mappers associated with this Container.  If this
  +     * Container has no Mappers, a zero-length array is returned.
  +     */
  +    public Mapper[] findMappers() {
  +
  +	synchronized (mappers) {
  +	    int i = 0;
  +	    int n = mappers.size();
  +	    Mapper results[] = new Mapper[n];
  +	    Enumeration keys = mappers.keys();
  +	    while (keys.hasMoreElements()) {
  +		String key = (String) keys.nextElement();
  +		results[i++] = (Mapper) mappers.get(key);
  +	    }
  +	    return (results);
  +	}
  +
  +    }
  +
  +
  +    /**
        * Process the specified Request, to produce the corresponding Response,
        * by invoking the first Valve in our pipeline (if any), or the basic
        * Valve otherwise.
  @@ -854,6 +947,27 @@
   
   
       /**
  +     * Return the child Container that should be used to process this Request,
  +     * based upon its characteristics.  If no such child Container can be
  +     * identified, return <code>null</code> instead.
  +     *
  +     * @param request Request being processed
  +     * @param update Update the Request to reflect the mapping selection?
  +     */
  +    public Container map(Request request, boolean update) {
  +
  +	// Select the Mapper we will use
  +	Mapper mapper = findMapper(request.getRequest().getProtocol());
  +	if (mapper == null)
  +	    return (null);
  +
  +	// Use this Mapper to perform this mapping
  +	return (mapper.map(request, update));
  +
  +    }
  +
  +
  +    /**
        * Remove an existing child Container from association with this parent
        * Container.
        *
  @@ -892,6 +1006,39 @@
   
   
       /**
  +     * Remove a Mapper associated with this Container, if any.
  +     *
  +     * @param mapper The Mapper to be removed
  +     */
  +    public void removeMapper(Mapper mapper) {
  +
  +	synchronized(mappers) {
  +
  +	    if (mappers.get(mapper.getProtocol()) == null)
  +		return;
  +	    mappers.remove(mapper.getProtocol());
  +	    if (started && (mapper instanceof Lifecycle)) {
  +		try {
  +		    ((Lifecycle) mapper).stop();
  +		} catch (LifecycleException e) {
  +		    log("ContainerBase.removeMapper: stop: ", e);
  +		    throw new IllegalStateException
  +			("ContainerBase.removeMapper: stop: " + e);
  +		}
  +	    }
  +	    if (mappers.size() != 1)
  +		this.mapper = null;
  +	    else {
  +		Enumeration elements = mappers.elements();
  +	        this.mapper = (Mapper) elements.nextElement();
  +	    }
  +	    fireContainerEvent(REMOVE_MAPPER_EVENT, mapper);
  +	}
  +
  +    }
  +
  +
  +    /**
        * Remove a property change listener from this component.
        *
        * @param listener The listener to remove
  @@ -959,6 +1106,16 @@
   	if ((resources != null) && (resources instanceof Lifecycle))
   	    ((Lifecycle) resources).start();
   
  +	// Add a default Mapper if none have been defined
  +	addDefaultMapper(this.mapperClass);
  +
  +	// Start our Mappers, if any
  +	Mapper mappers[] = findMappers();
  +	for (int i = 0; i < mappers.length; i++) {
  +	    if (mappers[i] instanceof Lifecycle)
  +		((Lifecycle) mappers[i]).start();
  +	}
  +
   	// Start our child containers, if any
   	Container children[] = findChildren();
   	for (int i = 0; i < children.length; i++) {
  @@ -1010,6 +1167,13 @@
   		((Lifecycle) children[(children.length-1)-i]).stop();
   	}
   
  +	// Stop our Mappers, if any
  +	Mapper mappers[] = findMappers();
  +	for (int i = 0; i < mappers.length; i++) {
  +	    if (mappers[(mappers.length-1)-i] instanceof Lifecycle)
  +		((Lifecycle) mappers[(mappers.length-1)-i]).stop();
  +	}
  +
   	// Stop our subordinate components, if any
   	if ((resources != null) && (resources instanceof Lifecycle))
   	    ((Lifecycle) resources).stop();
  @@ -1140,6 +1304,34 @@
   
   
       // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * Add a default Mapper implementation if none have been configured
  +     * explicitly.
  +     *
  +     * @param mapperClass Java class name of the default Mapper
  +     */
  +    protected void addDefaultMapper(String mapperClass) {
  +
  +	// Do we need a default Mapper?
  +	if (mapperClass == null)
  +	    return;
  +	if (mappers.size() >= 1)
  +	    return;
  +
  +	// Instantiate and add a default Mapper
  +	try {
  +	    Class clazz = Class.forName(mapperClass);
  +	    Mapper mapper = (Mapper) clazz.newInstance();
  +	    mapper.setProtocol("http");
  +	    addMapper(mapper);
  +	} catch (Exception e) {
  +	    log(sm.getString("containerBase.addDefaultMapper", mapperClass),
  +		e);
  +	}
  +
  +    }
   
   
       /**
  
  
  
  1.17      +4 -0      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/LocalStrings.properties,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- LocalStrings.properties	2000/05/16 21:31:18	1.16
  +++ LocalStrings.properties	2000/05/22 20:11:11	1.17
  @@ -2,9 +2,13 @@
   applicationDispatcher.forward.ise=Cannot forward after response has been committed
   applicationDispatcher.forward.throw=Forwarded resource threw an exception
   applicationDispatcher.include.throw=Included resource threw an exception
  +containerBase.addDefaultMapper=Exception configuring default mapper of class {0}
   containerBase.alreadyStarted=Container has already been started
   containerBase.notConfigured=No basic Valve has been configured
   containerBase.notStarted=Container has not been started
  +httpContextMapper.container=This container is not a StandardContext
  +httpEngineMapper.container=This container is not a StandardEngine
  +httpHostMapper.container=This container is not a StandardHost
   interceptorValve.alreadyStarted=InterceptorValve has already been started
   interceptorValve.notStarted=InterceptorValve has not yet been started
   standardContext.alreadyStarted=Context has already been started
  
  
  
  1.20      +24 -125   jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java
  
  Index: StandardContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- StandardContext.java	2000/05/12 21:59:33	1.19
  +++ StandardContext.java	2000/05/22 20:11:12	1.20
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java,v 1.19 2000/05/12 21:59:33 craigmcc Exp $
  - * $Revision: 1.19 $
  - * $Date: 2000/05/12 21:59:33 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContext.java,v 1.20 2000/05/22 20:11:12 craigmcc Exp $
  + * $Revision: 1.20 $
  + * $Date: 2000/05/22 20:11:12 $
    *
    * ====================================================================
    *
  @@ -96,7 +96,7 @@
    * requests directed to a particular servlet.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.19 $ $Date: 2000/05/12 21:59:33 $
  + * @version $Revision: 1.20 $ $Date: 2000/05/22 20:11:12 $
    */
   
   public final class StandardContext
  @@ -178,6 +178,13 @@
   
   
       /**
  +     * The Java class name of the default Mapper class for this Container.
  +     */
  +    private String mapperClass =
  +	"org.apache.tomcat.core.HttpContextMapper";
  +
  +
  +    /**
        * The MIME mappings for this web application, keyed by extension.
        */
       private Hashtable mimeMappings = new Hashtable();
  @@ -1186,127 +1193,6 @@
   
   
       /**
  -     * Return the Wrapper associated with the servlet that matches the
  -     * specified context-relative URI, if any; otherwise return
  -     * <code>null</code>.
  -     *
  -     * @param request Request to be processed
  -     * @param update Update request to reflect this mapping?
  -     */
  -    public Wrapper map(Request request, boolean update) {
  -
  -	// Has this request already been mapped?
  -	if (update && (request.getWrapper() != null))
  -	    return (request.getWrapper());
  -
  -	// Identify the context-relative URI to be mapped
  -	String contextPath =
  -	    ((HttpServletRequest) request.getRequest()).getContextPath();
  -	String requestURI =
  -	    ((HttpServletRequest) request.getRequest()).getRequestURI();
  -	String relativeURI = requestURI.substring(contextPath.length());
  -	if (debug > 0)
  -	    log("Mapping contextPath='" + contextPath +
  -		"' with requestURI='" + requestURI +
  -		"' and relativeURI='" + relativeURI + "'");
  -
  -	// Apply the standard request URI mapping rules from the specification
  -	Wrapper wrapper = null;
  -	String servletPath = relativeURI;
  -	String pathInfo = null;
  -	String name = null;
  -
  -	// Rule 1 -- Exact Match
  -	if (wrapper == null) {
  -	    if (debug > 1)
  -		log("  Trying exact match");
  -	    name = (String) servletMappings.get(relativeURI);
  -	    if (name != null)
  -		wrapper = (Wrapper) findChild(name);
  -	    if (wrapper != null) {
  -		servletPath = relativeURI;
  -		pathInfo = null;
  -	    }
  -	}
  -
  -	// Rule 2 -- Prefix Match
  -	if (wrapper == null) {
  -	    if (debug > 1)
  -		log("  Trying prefix match");
  -	    servletPath = relativeURI;
  -	    while (true) {
  -		name = (String) servletMappings.get(servletPath + "/*");
  -		if (name != null)
  -		    wrapper = (Wrapper) findChild(name);
  - 		if (wrapper != null) {
  -		    pathInfo = relativeURI.substring(servletPath.length());
  -		    if (pathInfo.length() == 0)
  -			pathInfo = null;
  -		    break;
  -		}
  -		int slash = servletPath.lastIndexOf("/");
  -		if (slash < 0)
  -		    break;
  -		servletPath = servletPath.substring(0, slash);
  -	    }
  -	}
  -
  -	// Rule 3 -- Extension Match
  -	if (wrapper == null) {
  -	    if (debug > 1)
  -		log("  Trying extension match");
  -	    int slash = relativeURI.lastIndexOf("/");
  -	    if (slash >= 0) {
  -		String last = relativeURI.substring(slash);
  -		int period = last.lastIndexOf(".");
  -		if (period >= 0) {
  -		    String pattern = "*" + last.substring(period);
  -		    name = (String) servletMappings.get(pattern);
  -		    if (name != null)
  -			wrapper = (Wrapper) findChild(name);
  -		    if (wrapper != null) {
  -			servletPath = relativeURI;
  -			pathInfo = null;
  -		    }
  -		}
  -	    }
  -	}
  -
  -	// Rule 4 -- Default Match
  -	if (wrapper == null) {
  -	    if (debug > 1)
  -		log("  Trying default match");
  -	    name = (String) servletMappings.get("/");
  -	    if (name != null)
  -		wrapper = (Wrapper) findChild(name);
  -	    if (wrapper != null) {
  -		servletPath = relativeURI;
  -		pathInfo = null;
  -	    }
  -	}
  -
  -	// Complain if there is no match at all
  -	if (wrapper == null) {
  -	    log(sm.getString("standardContext.mappingError", relativeURI));
  -	    return (null);
  -	}
  -
  -	// Update the Request (if requested) and return this Wrapper
  -	if (debug > 0)
  -	    log(" Mapped to servlet '" + wrapper.getName() +
  -		"' with servlet path '" + servletPath +
  -		"' and path info '" + pathInfo + "' and update=" + update);
  -	if (update) {
  -	    request.setWrapper(wrapper);
  -	    ((HttpRequest) request).setServletPath(servletPath);
  -	    ((HttpRequest) request).setPathInfo(pathInfo);
  -	}
  -	return (wrapper);
  -
  -    }
  -
  -
  -    /**
        * Post a copy of our current list of welcome files as a servlet context
        * attribute, so that the default servlet can find them.
        */
  @@ -1643,6 +1529,19 @@
   
   
       // -------------------------------------------------------- Private Methods
  +
  +
  +    /**
  +     * Add a default Mapper implementation if none have been configured
  +     * explicitly.
  +     *
  +     * @param mapperClass Java class name of the default Mapper
  +     */
  +    protected void addDefaultMapper(String mapperClass) {
  +
  +	super.addDefaultMapper(this.mapperClass);
  +
  +    }
   
   
       /**
  
  
  
  1.6       +5 -5      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContextValve.java
  
  Index: StandardContextValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContextValve.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- StandardContextValve.java	2000/04/30 01:23:21	1.5
  +++ StandardContextValve.java	2000/05/22 20:11:12	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContextValve.java,v 1.5 2000/04/30 01:23:21 craigmcc Exp $
  - * $Revision: 1.5 $
  - * $Date: 2000/04/30 01:23:21 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardContextValve.java,v 1.6 2000/05/22 20:11:12 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2000/05/22 20:11:12 $
    *
    * ====================================================================
    *
  @@ -85,7 +85,7 @@
    * when processing HTTP requests.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2000/04/30 01:23:21 $
  + * @version $Revision: 1.6 $ $Date: 2000/05/22 20:11:12 $
    */
   
   final class StandardContextValve
  @@ -127,7 +127,7 @@
   
   	// Select the Wrapper to be used for this Request
   	StandardContext context = (StandardContext) getContainer();
  -	Wrapper wrapper = context.map(request, true);
  +	Wrapper wrapper = (Wrapper) context.map(request, true);
   	if (wrapper == null) {
   	    ((HttpServletResponse) response.getResponse()).sendError
   		(HttpServletResponse.SC_NOT_FOUND,
  
  
  
  1.8       +27 -66    jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java
  
  Index: StandardEngine.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- StandardEngine.java	2000/05/01 23:13:43	1.7
  +++ StandardEngine.java	2000/05/22 20:11:13	1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java,v 1.7 2000/05/01 23:13:43 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2000/05/01 23:13:43 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngine.java,v 1.8 2000/05/22 20:11:13 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2000/05/22 20:11:13 $
    *
    * ====================================================================
    *
  @@ -82,7 +82,7 @@
    * fully qualified host name of that virtual host.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2000/05/01 23:13:43 $
  + * @version $Revision: 1.8 $ $Date: 2000/05/22 20:11:13 $
    */
   
   public final class StandardEngine
  @@ -121,6 +121,13 @@
   	"org.apache.tomcat.core.StandardEngine/1.0";
   
   
  +    /**
  +     * The Java class name of the default Mapper class for this Container.
  +     */
  +    private String mapperClass =
  +	"org.apache.tomcat.core.HttpEngineMapper";
  +
  +
       // ------------------------------------------------------------- Properties
   
   
  @@ -181,68 +188,6 @@
   
   
       /**
  -     * Return the Host that should be used to process this request,
  -     * based on the server name that was included.  If no such Host
  -     * can be identified, return <code>null</code> instead.
  -     *
  -     * @param request Request being processed
  -     * @param update Update the request to reflect this mapping?
  -     */
  -    public Host map(Request request, boolean update) {
  -
  -	// Extract the requested server name
  -	String server = request.getRequest().getServerName();
  -	if (server == null)
  -	    server = defaultHost;
  -	else
  -	    server = server.toLowerCase();
  -	if (server == null)
  -	    return (null);
  -	if (debug > 0)
  -	    log("Mapping server name '" + server + "'");
  -
  -	// Find the matching child Host directly
  -	if (debug > 1)
  -	    log(" Trying a direct match");
  -	Host host = (Host) findChild(server);
  -
  -	// Find a matching Host by alias.  FIXME - Optimize this!
  -	if (host == null) {
  -	    if (debug > 1)
  -		log(" Trying an alias match");
  -	    Container children[] = findChildren();
  -	    for (int i = 0; i < children.length; i++) {
  -		String aliases[] = ((Host) children[i]).findAliases();
  -		for (int j = 0; j < aliases.length; j++) {
  -		    if (server.equals(aliases[j])) {
  -			host = (Host) children[i];
  -			break;
  -		    }
  -		}
  -		if (host != null)
  -		    break;
  -	    }
  -	}
  -
  -	// Trying the "default" host if any
  -	if (host == null) {
  -	    if (debug > 1)
  -		log(" Trying the default host");
  -	    host = (Host) findChild(defaultHost);
  -	}
  -
  -	// Complain if no host was found
  -	if (host == null)
  -	    log(sm.getString("standardEngine.mappingError", server));
  -
  -	// Update the request if requested, and return the selected host
  -	;	// No update to the request is required
  -	return (host);
  -
  -    }
  -
  -
  -    /**
        * Disallow any attempt to set a parent for this Container, since an
        * Engine is supposed to be at the top of the Container hierarchy.
        *
  @@ -265,6 +210,22 @@
   	sb.append(getName());
   	sb.append("]");
   	return (sb.toString());
  +
  +    }
  +
  +
  +    // -------------------------------------------------------- Private Methods
  +
  +
  +    /**
  +     * Add a default Mapper implementation if none have been configured
  +     * explicitly.
  +     *
  +     * @param mapperClass Java class name of the default Mapper
  +     */
  +    protected void addDefaultMapper(String mapperClass) {
  +
  +	super.addDefaultMapper(this.mapperClass);
   
       }
   
  
  
  
  1.6       +5 -5      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngineValve.java
  
  Index: StandardEngineValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngineValve.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- StandardEngineValve.java	2000/05/05 22:32:16	1.5
  +++ StandardEngineValve.java	2000/05/22 20:11:13	1.6
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngineValve.java,v 1.5 2000/05/05 22:32:16 nacho Exp $
  - * $Revision: 1.5 $
  - * $Date: 2000/05/05 22:32:16 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardEngineValve.java,v 1.6 2000/05/22 20:11:13 craigmcc Exp $
  + * $Revision: 1.6 $
  + * $Date: 2000/05/22 20:11:13 $
    *
    * ====================================================================
    *
  @@ -85,7 +85,7 @@
    * when processing HTTP requests.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.5 $ $Date: 2000/05/05 22:32:16 $
  + * @version $Revision: 1.6 $ $Date: 2000/05/22 20:11:13 $
    */
   
   final class StandardEngineValve
  @@ -127,7 +127,7 @@
   
   	// Select the Host to be used for this Request
   	StandardEngine engine = (StandardEngine) getContainer();
  -	Host host = engine.map(request, true);
  +	Host host = (Host) engine.map(request, true);
   	if (host == null) {
   	    ((HttpServletResponse) response.getResponse()).sendError
   		(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  
  
  
  1.11      +27 -37    jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java
  
  Index: StandardHost.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- StandardHost.java	2000/05/20 22:13:31	1.10
  +++ StandardHost.java	2000/05/22 20:11:14	1.11
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java,v 1.10 2000/05/20 22:13:31 craigmcc Exp $
  - * $Revision: 1.10 $
  - * $Date: 2000/05/20 22:13:31 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHost.java,v 1.11 2000/05/22 20:11:14 craigmcc Exp $
  + * $Revision: 1.11 $
  + * $Date: 2000/05/22 20:11:14 $
    *
    * ====================================================================
    *
  @@ -84,7 +84,7 @@
    * requests directed to a particular web application.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.10 $ $Date: 2000/05/20 22:13:31 $
  + * @version $Revision: 1.11 $ $Date: 2000/05/22 20:11:14 $
    */
   
   public final class StandardHost
  @@ -129,6 +129,13 @@
   
   
       /**
  +     * The Java class name of the default Mapper class for this Container.
  +     */
  +    private String mapperClass =
  +	"org.apache.tomcat.core.HttpHostMapper";
  +
  +
  +    /**
        * Should we return a root context?
        */
       private boolean root = false;
  @@ -318,39 +325,6 @@
   
   
       /**
  -     * Return the Context that should be used to process this request,
  -     * based on matching the longest possible context path (or selecting
  -     * the default context).  If no such Context can be identified,
  -     * return <code>null</code> instead.
  -     *
  -     * @param request Request to be processed
  -     * @param update Update request to reflect this mapping?
  -     */
  -    public Context map(Request request, boolean update) {
  -
  -	// Has this request already been mapped?
  -	if (update && (request.getContext() != null))
  -	    return (request.getContext());
  -
  -	// Perform mapping on our request URI
  -	String uri =
  -	    ((HttpServletRequest) request.getRequest()).getRequestURI();
  -	Context context = map(uri);
  -
  -	// Update the request (if requested) and return the selected Context
  -	if (update) {
  -	    request.setContext(context);
  -	    if (context != null)
  -		((HttpRequest) request).setContextPath(context.getPath());
  -	    else
  -		((HttpRequest) request).setContextPath(null);
  -	}
  -	return (context);
  -
  -    }
  -
  -
  -    /**
        * Return the Context that would be used to process the specified
        * host-relative request URI, if any; otherwise return <code>null</code>.
        *
  @@ -446,6 +420,22 @@
   	sb.append(getName());
   	sb.append("]");
   	return (sb.toString());
  +
  +    }
  +
  +
  +    // -------------------------------------------------------- Private Methods
  +
  +
  +    /**
  +     * Add a default Mapper implementation if none have been configured
  +     * explicitly.
  +     *
  +     * @param mapperClass Java class name of the default Mapper
  +     */
  +    protected void addDefaultMapper(String mapperClass) {
  +
  +	super.addDefaultMapper(this.mapperClass);
   
       }
   
  
  
  
  1.5       +5 -5      jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHostValve.java
  
  Index: StandardHostValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHostValve.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- StandardHostValve.java	2000/04/23 01:42:34	1.4
  +++ StandardHostValve.java	2000/05/22 20:11:15	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHostValve.java,v 1.4 2000/04/23 01:42:34 craigmcc Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/04/23 01:42:34 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardHostValve.java,v 1.5 2000/05/22 20:11:15 craigmcc Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/05/22 20:11:15 $
    *
    * ====================================================================
    *
  @@ -85,7 +85,7 @@
    * when processing HTTP requests.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.4 $ $Date: 2000/04/23 01:42:34 $
  + * @version $Revision: 1.5 $ $Date: 2000/05/22 20:11:15 $
    */
   
   final class StandardHostValve
  @@ -127,7 +127,7 @@
   
   	// Select the Context to be used for this Request
   	StandardHost host = (StandardHost) getContainer();
  -	Context context = host.map(request, true);
  +	Context context = (Context) host.map(request, true);
   	if (context == null) {
   	    ((HttpServletResponse) response.getResponse()).sendError
   		(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
  
  
  
  1.14      +17 -4     jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java
  
  Index: StandardWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- StandardWrapper.java	2000/05/16 20:25:50	1.13
  +++ StandardWrapper.java	2000/05/22 20:11:15	1.14
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v 1.13 2000/05/16 20:25:50 craigmcc Exp $
  - * $Revision: 1.13 $
  - * $Date: 2000/05/16 20:25:50 $
  + * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/StandardWrapper.java,v 1.14 2000/05/22 20:11:15 craigmcc Exp $
  + * $Revision: 1.14 $
  + * $Date: 2000/05/22 20:11:15 $
    *
    * ====================================================================
    *
  @@ -97,7 +97,7 @@
    * make them efficient are counter-productive.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.13 $ $Date: 2000/05/16 20:25:50 $
  + * @version $Revision: 1.14 $ $Date: 2000/05/22 20:11:15 $
    */
   
   public final class StandardWrapper
  @@ -872,6 +872,19 @@
   
   
       // -------------------------------------------------------- Private Methods
  +
  +
  +    /**
  +     * Add a default Mapper implementation if none have been configured
  +     * explicitly.
  +     *
  +     * @param mapperClass Java class name of the default Mapper
  +     */
  +    protected void addDefaultMapper(String mapperClass) {
  +
  +	;	// No need for a default Mapper on a Wrapper
  +
  +    }
   
   
       /**
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpContextMapper.java
  
  Index: HttpContextMapper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpContextMapper.java,v 1.1 2000/05/22 20:11:11 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/05/22 20:11:11 $
   *
   * ====================================================================
   *
   * 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.tomcat.core;
  
  
  import javax.servlet.http.HttpServletRequest;
  import org.apache.tomcat.Container;
  import org.apache.tomcat.Context;
  import org.apache.tomcat.HttpRequest;
  import org.apache.tomcat.Mapper;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.Wrapper;
  import org.apache.tomcat.util.StringManager;
  
  
  /**
   * Implementation of <code>Mapper</code> for a <code>Context</code>,
   * designed to process HTTP requests.  This mapper selects an appropriate
   * <code>Wrapper</code> based on the request URI included in the request.
   * <p>
   * <b>IMPLEMENTATION NOTE</b>:  This Mapper only works with a
   * <code>StandardContext</code>, because it relies on internal APIs.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/05/22 20:11:11 $
   */
  
  public final class HttpContextMapper
      implements Mapper {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Container with which this Mapper is associated.
       */
      private StandardContext context = null;
  
  
      /**
       * The protocol with which this Mapper is associated.
       */
      private String protocol = null;
  
  
      /**
       * The string manager for this package.
       */
      private static final StringManager sm =
  	StringManager.getManager(Constants.Package);
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the Container with which this Mapper is associated.
       */
      public Container getContainer() {
  
  	return (context);
  
      }
  
  
      /**
       * Set the Container with which this Mapper is associated.
       *
       * @param container The newly associated Container
       *
       * @exception IllegalArgumentException if this Container is not
       *  acceptable to this Mapper
       */
      public void setContainer(Container container) {
  
  	if (!(container instanceof StandardContext))
  	    throw new IllegalArgumentException
  		(sm.getString("httpContextMapper.container"));
  	context = (StandardContext) container;
  
      }
  
  
      /**
       * Return the protocol for which this Mapper is responsible.
       */
      public String getProtocol() {
  
  	return (this.protocol);
  
      }
  
  
      /**
       * Set the protocol for which this Mapper is responsible.
       *
       * @param protocol The newly associated protocol
       */
      public void setProtocol(String protocol) {
  
  	this.protocol = protocol;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the child Container that should be used to process this Request,
       * based upon its characteristics.  If no such child Container can be
       * identified, return <code>null</code> instead.
       *
       * @param request Request being processed
       * @param update Update the Request to reflect the mapping selection?
       */
      public Container map(Request request, boolean update) {
  
  	int debug = context.getDebug();
  
  	// Has this request already been mapped?
  	if (update && (request.getWrapper() != null))
  	    return (request.getWrapper());
  
  	// Identify the context-relative URI to be mapped
  	String contextPath =
  	    ((HttpServletRequest) request.getRequest()).getContextPath();
  	String requestURI =
  	    ((HttpServletRequest) request.getRequest()).getRequestURI();
  	String relativeURI = requestURI.substring(contextPath.length());
  	if (debug >= 1)
  	    context.log("Mapping contextPath='" + contextPath +
  			"' with requestURI='" + requestURI +
  			"' and relativeURI='" + relativeURI + "'");
  
  	// Apply the standard request URI mapping rules from the specification
  	Wrapper wrapper = null;
  	String servletPath = relativeURI;
  	String pathInfo = null;
  	String name = null;
  
  	// Rule 1 -- Exact Match
  	if (wrapper == null) {
  	    if (debug >= 2)
  		context.log("  Trying exact match");
  	    name = context.findServletMapping(relativeURI);
  	    if (name != null)
  		wrapper = (Wrapper) context.findChild(name);
  	    if (wrapper != null) {
  		servletPath = relativeURI;
  		pathInfo = null;
  	    }
  	}
  
  	// Rule 2 -- Prefix Match
  	if (wrapper == null) {
  	    if (debug >= 2)
  		context.log("  Trying prefix match");
  	    servletPath = relativeURI;
  	    while (true) {
  		name = context.findServletMapping(servletPath + "/*");
  		if (name != null)
  		    wrapper = (Wrapper) context.findChild(name);
   		if (wrapper != null) {
  		    pathInfo = relativeURI.substring(servletPath.length());
  		    if (pathInfo.length() == 0)
  			pathInfo = null;
  		    break;
  		}
  		int slash = servletPath.lastIndexOf("/");
  		if (slash < 0)
  		    break;
  		servletPath = servletPath.substring(0, slash);
  	    }
  	}
  
  	// Rule 3 -- Extension Match
  	if (wrapper == null) {
  	    if (debug >= 2)
  		context.log("  Trying extension match");
  	    int slash = relativeURI.lastIndexOf("/");
  	    if (slash >= 0) {
  		String last = relativeURI.substring(slash);
  		int period = last.lastIndexOf(".");
  		if (period >= 0) {
  		    String pattern = "*" + last.substring(period);
  		    name = context.findServletMapping(pattern);
  		    if (name != null)
  			wrapper = (Wrapper) context.findChild(name);
  		    if (wrapper != null) {
  			servletPath = relativeURI;
  			pathInfo = null;
  		    }
  		}
  	    }
  	}
  
  	// Rule 4 -- Default Match
  	if (wrapper == null) {
  	    if (debug >= 2)
  		context.log("  Trying default match");
  	    name = context.findServletMapping("/");
  	    if (name != null)
  		wrapper = (Wrapper) context.findChild(name);
  	    if (wrapper != null) {
  		servletPath = relativeURI;
  		pathInfo = null;
  	    }
  	}
  
  	// Update the Request (if requested) and return this Wrapper
  	if ((debug >= 1) && (wrapper != null))
  	    context.log(" Mapped to servlet '" + wrapper.getName() +
  			"' with servlet path '" + servletPath +
  			"' and path info '" + pathInfo +
  			"' and update=" + update);
  	if (update) {
  	    request.setWrapper(wrapper);
  	    ((HttpRequest) request).setServletPath(servletPath);
  	    ((HttpRequest) request).setPathInfo(pathInfo);
  	}
  	return (wrapper);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpEngineMapper.java
  
  Index: HttpEngineMapper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpEngineMapper.java,v 1.1 2000/05/22 20:11:11 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/05/22 20:11:11 $
   *
   * ====================================================================
   *
   * 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.tomcat.core;
  
  
  import org.apache.tomcat.Container;
  import org.apache.tomcat.Engine;
  import org.apache.tomcat.Host;
  import org.apache.tomcat.Mapper;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.util.StringManager;
  
  
  /**
   * Implementation of <code>Mapper</code> for an <code>Engine</code>,
   * designed to process HTTP requests.  This mapper selects an appropriate
   * <code>Host</code> based on the server name included in the request.
   * <p>
   * <b>IMPLEMENTATION NOTE</b>:  This Mapper only works with a
   * <code>StandardEngine</code>, because it relies on internal APIs.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/05/22 20:11:11 $
   */
  
  public final class HttpEngineMapper
      implements Mapper {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Container with which this Mapper is associated.
       */
      private StandardEngine engine = null;
  
  
      /**
       * The protocol with which this Mapper is associated.
       */
      private String protocol = null;
  
  
      /**
       * The string manager for this package.
       */
      private static final StringManager sm =
  	StringManager.getManager(Constants.Package);
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the Container with which this Mapper is associated.
       */
      public Container getContainer() {
  
  	return (engine);
  
      }
  
  
      /**
       * Set the Container with which this Mapper is associated.
       *
       * @param container The newly associated Container
       *
       * @exception IllegalArgumentException if this Container is not
       *  acceptable to this Mapper
       */
      public void setContainer(Container container) {
  
  	if (!(container instanceof StandardEngine))
  	    throw new IllegalArgumentException
  		(sm.getString("httpEngineMapper.container"));
  	engine = (StandardEngine) container;
  
      }
  
  
      /**
       * Return the protocol for which this Mapper is responsible.
       */
      public String getProtocol() {
  
  	return (this.protocol);
  
      }
  
  
      /**
       * Set the protocol for which this Mapper is responsible.
       *
       * @param protocol The newly associated protocol
       */
      public void setProtocol(String protocol) {
  
  	this.protocol = protocol;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the child Container that should be used to process this Request,
       * based upon its characteristics.  If no such child Container can be
       * identified, return <code>null</code> instead.
       *
       * @param request Request being processed
       * @param update Update the Request to reflect the mapping selection?
       */
      public Container map(Request request, boolean update) {
  
  	int debug = engine.getDebug();
  
  	// Extract the requested server name
  	String server = request.getRequest().getServerName();
  	if (server == null)
  	    server = engine.getDefaultHost();
  	else
  	    server = server.toLowerCase();
  	if (server == null)
  	    return (null);
  	if (debug >= 1)
  	    engine.log("Mapping server name '" + server + "'");
  
  	// Find the matching child Host directly
  	if (debug >= 2)
  	    engine.log(" Trying a direct match");
  	Host host = (Host) engine.findChild(server);
  
  	// Find a matching Host by alias.  FIXME - Optimize this!
  	if (host == null) {
  	    if (debug >= 2)
  		engine.log(" Trying an alias match");
  	    Container children[] = engine.findChildren();
  	    for (int i = 0; i < children.length; i++) {
  		String aliases[] = ((Host) children[i]).findAliases();
  		for (int j = 0; j < aliases.length; j++) {
  		    if (server.equals(aliases[j])) {
  			host = (Host) children[i];
  			break;
  		    }
  		}
  		if (host != null)
  		    break;
  	    }
  	}
  
  	// Trying the "default" host if any
  	if (host == null) {
  	    if (debug >= 2)
  		engine.log(" Trying the default host");
  	    host = (Host) engine.findChild(engine.getDefaultHost());
  	}
  
  	// Update the Request if requested, and return the selected Host
  	;	// No update to the Request is required
  	return (host);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpHostMapper.java
  
  Index: HttpHostMapper.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/core/HttpHostMapper.java,v 1.1 2000/05/22 20:11:11 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/05/22 20:11:11 $
   *
   * ====================================================================
   *
   * 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.tomcat.core;
  
  
  import javax.servlet.http.HttpServletRequest;
  import org.apache.tomcat.Container;
  import org.apache.tomcat.Context;
  import org.apache.tomcat.Host;
  import org.apache.tomcat.HttpRequest;
  import org.apache.tomcat.Mapper;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.util.StringManager;
  
  
  /**
   * Implementation of <code>Mapper</code> for a <code>Host</code>,
   * designed to process HTTP requests.  This mapper selects an appropriate
   * <code>Context</code> based on the request URI included in the request.
   * <p>
   * <b>IMPLEMENTATION NOTE</b>:  This Mapper only works with a
   * <code>StandardHost</code>, because it relies on internal APIs.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/05/22 20:11:11 $
   */
  
  public final class HttpHostMapper
      implements Mapper {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Container with which this Mapper is associated.
       */
      private StandardHost host = null;
  
  
      /**
       * The protocol with which this Mapper is associated.
       */
      private String protocol = null;
  
  
      /**
       * The string manager for this package.
       */
      private static final StringManager sm =
  	StringManager.getManager(Constants.Package);
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the Container with which this Mapper is associated.
       */
      public Container getContainer() {
  
  	return (host);
  
      }
  
  
      /**
       * Set the Container with which this Mapper is associated.
       *
       * @param container The newly associated Container
       *
       * @exception IllegalArgumentException if this Container is not
       *  acceptable to this Mapper
       */
      public void setContainer(Container container) {
  
  	if (!(container instanceof StandardHost))
  	    throw new IllegalArgumentException
  		(sm.getString("httpHostMapper.container"));
  	host = (StandardHost) container;
  
      }
  
  
      /**
       * Return the protocol for which this Mapper is responsible.
       */
      public String getProtocol() {
  
  	return (this.protocol);
  
      }
  
  
      /**
       * Set the protocol for which this Mapper is responsible.
       *
       * @param protocol The newly associated protocol
       */
      public void setProtocol(String protocol) {
  
  	this.protocol = protocol;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return the child Container that should be used to process this Request,
       * based upon its characteristics.  If no such child Container can be
       * identified, return <code>null</code> instead.
       *
       * @param request Request being processed
       * @param update Update the Request to reflect the mapping selection?
       */
      public Container map(Request request, boolean update) {
  
  	// Has this request already been mapped?
  	if (update && (request.getContext() != null))
  	    return (request.getContext());
  
  	// Perform mapping on our request URI
  	String uri =
  	    ((HttpServletRequest) request.getRequest()).getRequestURI();
  	Context context = host.map(uri);
  
  	// Update the request (if requested) and return the selected Context
  	if (update) {
  	    request.setContext(context);
  	    if (context != null)
  		((HttpRequest) request).setContextPath(context.getPath());
  	    else
  		((HttpRequest) request).setContextPath(null);
  	}
  	return (context);
  
      }
  
  
  }