You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/02/13 21:49:46 UTC

cvs commit: jakarta-tomcat/src/shell tomcat.sh

costin      00/02/13 12:49:46

  Modified:    src/etc  server.xml
               src/share/org/apache/tomcat/context DefaultCMSetter.java
                        LoadOnStartupInterceptor.java
               src/share/org/apache/tomcat/core BaseInterceptor.java
                        Context.java ContextManager.java RequestImpl.java
                        ServletWrapper.java
               src/share/org/apache/tomcat/logging TomcatLogger.java
               src/share/org/apache/tomcat/request SessionInterceptor.java
               src/share/org/apache/tomcat/startup Tomcat.java
               src/share/org/apache/tomcat/util/xml XmlMapper.java
               src/shell tomcat.sh
  Added:       src/share/org/apache/tomcat/context LogEvents.java
  Log:
  - XmlMapper - added support for int and bool in SetProperties, no deps on
  InvocationHelper, less magic on property setting ( still has setProperty(name,
  value) if no setter is found )
  
  - Tomcat startup will set the interceptors from server.xml
  
  - ContextManager, DefaultSetter - removed magic in intereptor setup, i
  DefaultCMSetter will no longer set defaults. You can either set the
   interceptors using the API or server.xml, or CM.setDefaults() will be called.
  
  - Context, SessionInterceptor - now session removal is handled by SessionInt,
  not hardcoded in Context shutdown.
  
  - Context, CM - initContext, shutdownContext in ContextManager replace
  Context.init() and shutdown(). ( CM manages the intereptors, it simplifies
  a lot the logic in Context)
  
  - Context - removed old code, moved all 'deprecated' ( old code we can't remove
  now ) at the end of the file, moved few methods up and down ( to group by
  functionality )
  
  - LoadOnStartup - fix a bug ( servlets loaded multiple times )
  
  - server.xml - added the loggers, moved Logger at top level.
  
  - add EventLog interceptor - it will show all notifications of add/remove
  context, mappings, servlets, etc.
  
  Revision  Changes    Path
  1.6       +45 -28    jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- server.xml	2000/02/13 06:47:39	1.5
  +++ server.xml	2000/02/13 20:49:37	1.6
  @@ -1,44 +1,61 @@
   <?xml version="1.0" encoding="ISO-8859-1"?>
   
   <Server>
  -    <ContextManager port="8080" hostName="" inet="">
  +    <!-- Debug low-level events in XmlMapper startup -->
  +    <xmlmapper:debug level="0" />
   
  -        <!-- This is quite flexible; we can either have a log file per
  -             module in Tomcat (example: ContextManager) or we can have
  -	     one for Servlets and one for Jasper, or we can just have
  -	     one tomcat.log for both Servlet and Jasper.
  -
  -	     If you omit "path" there, then stderr should be used.
  -
  -	     verbosityLevel values can be: 
  -			    FATAL
  -			    ERROR
  -			    WARNING 
  -			    INFORMATION
  -			    DEBUG
  -
  +    <!-- This is quite flexible; we can either have a log file per
  +         module in Tomcat (example: ContextManager) or we can have
  +         one for Servlets and one for Jasper, or we can just have
  +	 one tomcat.log for both Servlet and Jasper.
  +
  +	 If you omit "path" there, then stderr should be used.
  +
  +	 verbosityLevel values can be: 
  +	    FATAL
  +	    ERROR
  +	    WARNING 
  +            INFORMATION
  +            DEBUG
            -->
  +
  +    <Logger name="CTXMGR_LOG" 
  +	    verbosityLevel = "DEBUG" />
   
  -	<Logger name="CTXMGR_LOG" 
  -	        path="logs/tomcat.log" 
  -		verbosityLevel = "DEBUG" />
  -
  -	<Logger name="STARTUP_LOG"
  -		path="logs/tomcat.log"
  -		verbosityLevel = "DEBUG"
  -		timestamp = "no" />
  -
  -	<Logger name="JASPER_LOG" 
  -	        path="logs/jasper.log"
  -		verbosityLevel = "INFORMATION" />
  +    <Logger name="STARTUP_LOG"
  +            verbosityLevel = "DEBUG"
  +	    timestamp = "no" />
  +
  +    <Logger name="JASPER_LOG" 
  +	    path="logs/jasper.log"
  +            verbosityLevel = "INFORMATION" />
  +
  +    <ContextManager debug="0" home="." workDir="work" >
  +        <!-- ContextInterceptor className="org.apache.tomcat.context.LogEvents" / -->
  +        <ContextInterceptor className="org.apache.tomcat.context.AutoSetup" />
  +        <ContextInterceptor className="org.apache.tomcat.context.DefaultCMSetter" />
  +        <ContextInterceptor className="org.apache.tomcat.context.WorkDirInterceptor" />
  +        <ContextInterceptor className="org.apache.tomcat.context.WebXmlReader" />
  +        <ContextInterceptor className="org.apache.tomcat.context.LoadOnStartupInterceptor" />
  +        <!-- Request processing -->
  +        <RequestInterceptor className="org.apache.tomcat.request.SimpleMapper" />
  +        <RequestInterceptor className="org.apache.tomcat.request.SessionInterceptor" />
   
           <Connector className="org.apache.tomcat.service.http.HttpAdapter">
  +            <Parameter name="port" value="8080"/>
           </Connector>
   
  -        <!-- AJP12 - current JServ module -->
           <Connector className="org.apache.tomcat.service.TcpEndpointConnector">
               <Parameter name="handler" value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
               <Parameter name="port" value="8007"/>
           </Connector>
  +
  +        <!-- example - how to override AutoSetup actions -->
  +        <Context path="/examples" docBase="webapps/examples" debug="1" reloadable="true" > 
  +        </Context>
  +        <!-- example - how to override AutoSetup actions -->
  +        <Context path="" docBase="webapps/ROOT" debug="1" reloadable="true" > 
  +        </Context>
  +
       </ContextManager>
   </Server>
  
  
  
  1.13      +0 -37     jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java
  
  Index: DefaultCMSetter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- DefaultCMSetter.java	2000/02/13 06:24:22	1.12
  +++ DefaultCMSetter.java	2000/02/13 20:49:39	1.13
  @@ -81,28 +81,6 @@
       public DefaultCMSetter() {
       }
   	
  -    public void engineInit(ContextManager cm)  {
  -	// set a default connector ( http ) if none defined yet
  -	Enumeration conn=cm.getConnectors();
  -	if( ! conn.hasMoreElements() ) {
  -	    // Make the default customizable!
  -	    cm.addServerConnector(  new org.apache.tomcat.service.http.HttpAdapter() );
  -	}
  -	
  - 	RequestInterceptor rI[]=cm.getRequestInterceptors();
  -	if( rI.length ==0  ) {
  -	    // nothing set up by starter, add default ones
  -	    cm.log("Setting default interceptors ", Logger.INFORMATION);
  -
  -	    // Use the simplified mapper - revert if too many bugs and
  -	    SimpleMapper smap=new SimpleMapper();
  -	    smap.setContextManager( cm );
  -	    cm.addRequestInterceptor(smap);
  -
  -	    cm.addRequestInterceptor(new SessionInterceptor());
  -	}
  -    }
  -
       /** Called when a new context is added to the server.
        *
        *  - Check it and set defaults for WorkDir, EngineHeader and SessionManager.
  @@ -112,8 +90,6 @@
        *  - Set up defaults for context interceptors and session if nothing is set
        */
       public void addContext(ContextManager cm, Context ctx) {
  -	// Make sure context knows about its manager.
  -	ctx.setContextManager( cm );
   	setEngineHeader( ctx );
   
   	if( ctx.getWorkDir() == null)
  @@ -125,19 +101,6 @@
   
   	//  Alternative: org.apache.tomcat.session.ServerSessionManager.getManager();
   
  -	// If no ContextInterceptors are set up use defaults
  -	ContextInterceptor cI[]=ctx.getContextInterceptors();
  -	if( cI.length==0 ) {
  -	    // set up work dir ( attribute + creation )
  -	    ctx.addContextInterceptor(new WorkDirInterceptor());
  -	    
  -	    // Read context's web.xml
  -	    // new WebXmlInterceptor().contextInit( this );
  -	    ctx.addContextInterceptor( new WebXmlReader());
  -	    
  -	    // load initial servlets
  -	    ctx.addContextInterceptor(new LoadOnStartupInterceptor());
  -	}	
   	// XXX Loader properties - need to be set on loader!!
   	//ctx.setServletLoader( new org.apache.tomcat.loader.ServletClassLoaderImpl());
   	ctx.setServletLoader( new org.apache.tomcat.loader.AdaptiveServletLoader());
  
  
  
  1.7       +18 -39    jakarta-tomcat/src/share/org/apache/tomcat/context/LoadOnStartupInterceptor.java
  
  Index: LoadOnStartupInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/LoadOnStartupInterceptor.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- LoadOnStartupInterceptor.java	2000/02/12 03:38:49	1.6
  +++ LoadOnStartupInterceptor.java	2000/02/13 20:49:39	1.7
  @@ -77,19 +77,16 @@
    */
   public class LoadOnStartupInterceptor extends BaseInterceptor {
       private static StringManager sm =StringManager.getManager("org.apache.tomcat.context");
  -    int debug=0;
       
       public LoadOnStartupInterceptor() {
       }
   
  -    public void setDebug( int i ) {
  -	debug=i;
  -    }
  -    
       public void contextInit(Context ctx) {
  -	init(ctx);
  +	Hashtable loadableServlets = new Hashtable();
  +	init(ctx,loadableServlets);
  +	
   	Vector orderedKeys = new Vector();
  -	Enumeration e=getInitLevels();
  +	Enumeration e=  loadableServlets.keys();
   		
   	// order keys
   	while (e.hasMoreElements()) {
  @@ -119,14 +116,12 @@
   
   	for (int i = 0; i < orderedKeys.size(); i ++) {
   	    Integer key = (Integer)orderedKeys.elementAt(i);
  -
  -	    Enumeration sOnLevel = getLoadableServlets( key );
  -
  +	    Enumeration sOnLevel =  ((Vector)loadableServlets.get( key )).elements();
   	    while (sOnLevel.hasMoreElements()) {
   		String servletName = (String)sOnLevel.nextElement();
   		ServletWrapper  result = ctx.getServletByName(servletName);
   
  -		if( debug > 0 ) ctx.log("Loading " + key + " "  + servletName );
  +		if( ctx.getDebug() > 0 ) ctx.log("Loading " + key + " "  + servletName );
   		if(result==null)
   		    System.out.println("Warning: we try to load an undefined servlet " + servletName);
   		else {
  @@ -193,40 +188,24 @@
       // -------------------- 
       // Old logic from Context - probably something cleaner can replace it.
   
  -    private Hashtable loadableServlets = new Hashtable();
  -
  -    void init(Context ctx) {
  +    void init(Context ctx, Hashtable loadableServlets ) {
   	Enumeration enum=ctx.getServletNames();
   	while(enum.hasMoreElements()) {
   	    String name=(String)enum.nextElement();
   	    ServletWrapper sw=ctx.getServletByName( name );
   	    int i=sw.getLoadOnStartUp();
  -	    if( i!= 0)
  -		addLoadableServlet( new Integer(i), name );
  +	    Integer level=new Integer(i);
  +	    if( i!= 0) {
  +		Vector v;
  +		if( loadableServlets.get(level) != null ) 
  +		    v=(Vector)loadableServlets.get(level);
  +		else
  +		    v=new Vector();
  +		
  +		v.addElement(name);
  +		loadableServlets.put(level, v);
  +	    }
   	}
  -    }
  -    
  -    Enumeration getInitLevels() {
  -	return loadableServlets.keys();
  -    }
  -
  -    Enumeration getLoadableServlets( Integer level ) {
  -	return ((Vector)loadableServlets.get( level )).elements();
  -    }
  -
  -    void setLoadableServlets( Integer level, Vector servlets ) {
  -	loadableServlets.put( level, servlets );
  -    }
  -
  -    void addLoadableServlet( Integer level,String name ) {
  -	Vector v;
  -	if( loadableServlets.get(level) != null ) 
  -	    v=(Vector)loadableServlets.get(level);
  -	else
  -	    v=new Vector();
  -	
  -	v.addElement(name);
  -	loadableServlets.put(level, v);
       }
       
   
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/context/LogEvents.java
  
  Index: LogEvents.java
  ===================================================================
  /*
   * ====================================================================
   *
   * 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.context;
  
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.util.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  import javax.servlet.http.*;
  
  /** Log all Context events
   */
  public class LogEvents extends BaseInterceptor {
      
      public LogEvents() {
      }
  
      // -------------------- Request notifications --------------------
      public int requestMap(Request request ) {
  	request.getContext().log( "Request map " + request);
  	return 0;
      }
  
      public int contextMap( Request request ) {
  	return 0;
      }
  
      public int preService(Request request, Response response) {
  	request.getContext().log( "Pre service " + request);
  	return 0;
      }
  
      public int beforeBody( Request request, Response response ) {
  	request.getContext().log( "Before body " + request);
  	return 0;
      }
  
      public int beforeCommit( Request request, Response response) {
  	request.getContext().log( "Before commit " + request);
  	return 0;
      }
  
  
      public int afterBody( Request request, Response response) {
  	request.getContext().log( "After Body " + request);
  	return 0;
      }
  
      public int postService(Request request, Response response) {
  	request.getContext().log( "Post service " + request);
  	return 0;
      }
  
      public Enumeration getMethods()  {
  	return methods.elements();
      }
  
      // -------------------- Context notifications --------------------
      public void contextInit(Context ctx) throws TomcatException {
  	ctx.log( "Context Init ");
      }
  
      public void contextShutdown(Context ctx) throws TomcatException {
  	ctx.log( "Context Shutdown ");
      }
  
      /** Notify when a new servlet is added
       */
      public void addServlet( Context ctx, ServletWrapper sw) throws TomcatException {
  	ctx.log( "Add servlet " + sw);
      }
      
      /** Notify when a servlet is removed from context
       */
      public void removeServlet( Context ctx, ServletWrapper sw) throws TomcatException {
  	ctx.log( "Remove servlet " + sw);
      }
  
      public void addMapping( Context ctx, String path, ServletWrapper servlet) throws TomcatException {
  	ctx.log( "Add mapping " + path + "->" + servlet);
      }
  
  
      public void removeMapping( Context ctx, String path ) throws TomcatException {
  	ctx.log( "Remove mapping ");
      }
  
      /** Called when the ContextManger is started
       */
      public void engineInit(ContextManager cm) throws TomcatException {
  	cm.log( "Engine init");
      }
  
      /** Called before the ContextManager is stoped.
       *  You need to stop any threads and remove any resources.
       */
      public void engineShutdown(ContextManager cm) throws TomcatException {
  	cm.log( "Engine shutdown");
      }
  
  
      /** Called when a context is added to a CM
       */
      public void addContext( ContextManager cm, Context ctx ) throws TomcatException {
  	ctx.log( "Add context");
      }
  
      /** Called when a context is removed from a CM
       */
      public void removeContext( ContextManager cm, Context ctx ) throws TomcatException {
  	ctx.log( "Remove context");
      }
  
      /** Servlet Init  notification
       */
      public void preServletInit( Context ctx, ServletWrapper sw ) throws TomcatException {
  	ctx.log( "Pre servlet init " + sw);
      }
  
      
      public void postServletInit( Context ctx, ServletWrapper sw ) throws TomcatException {
  	ctx.log( "Post servlet init " + sw);
      }
  
      /** Servlet Destroy  notification
       */
      public void preServletDestroy( Context ctx, ServletWrapper sw ) throws TomcatException {
  	ctx.log( "Pre servlet destroy " + sw);
      }
  
      
      public void postServletDestroy( Context ctx, ServletWrapper sw ) throws TomcatException {
  	ctx.log( "Post servlet destroy " + sw);
      }
  
  }
  
  
  
  1.2       +5 -1      jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java
  
  Index: BaseInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseInterceptor.java	2000/02/12 03:38:50	1.1
  +++ BaseInterceptor.java	2000/02/13 20:49:40	1.2
  @@ -70,12 +70,16 @@
   /**
    */
   public class BaseInterceptor implements RequestInterceptor, ContextInterceptor {
  -    
  +    ContextManager cm; 
       protected Vector methods=new Vector();
       
       public BaseInterceptor() {
       }
   
  +    public void setContextManager( ContextManager cm ) {
  +	this.cm=cm;
  +    }
  +    
       // -------------------- Request notifications --------------------
       public int requestMap(Request request ) {
   	return 0;
  
  
  
  1.53      +287 -334  jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- Context.java	2000/02/13 01:43:41	1.52
  +++ Context.java	2000/02/13 20:49:40	1.53
  @@ -165,6 +165,13 @@
   	//	System.out.println("New Context ");
       }
   	
  +    ServletContextFacade getFacade() {
  +        if(contextFacade==null )
  +	    contextFacade = new ServletContextFacade(contextM, this);
  +	return contextFacade;
  +    }
  +
  +
       // -------------------- Settable context properties --------------------
       // -------------------- Required properties
       public ContextManager getContextManager() {
  @@ -212,7 +219,11 @@
       }
   
       // -------------------- Tomcat specific properties
  -
  +    // workaround for XmlMapper unable to set anything but strings
  +    public void setReloadable( String s ) {
  +	reloadable=new Boolean( s ).booleanValue();
  +    }
  +    
       public void setReloadable( boolean b ) {
   	reloadable=b;
       }
  @@ -222,281 +233,8 @@
       public boolean getReloadable() {
   	return reloadable;
       }
  -    
  -    public String getEngineHeader() {
  -	return engineHeader;
  -    }
  -
  -    public void setEngineHeader(String s) {
  -        engineHeader=s;
  -    }
  -
  -    public boolean isInvokerEnabled() {
  -        return isInvokerEnabled;
  -    }
  -
  -    
  -    public void setInvokerEnabled(boolean isInvokerEnabled) {
  -        this.isInvokerEnabled = isInvokerEnabled;
  -    }
  -
  -    public File getWorkDir() {
  -	return workDir;
  -    }
  -
  -    public void setWorkDir(File workDir) {
  -	this.workDir = workDir;
  -    }
  -
  -    /** Set work dir using a String property
  -     */
  -    public void setWorkDirPath(String workDir) {
  -	this.workDir=new File(workDir);
  -    }
  -
  -    public boolean isWorkDirPersistent() {
  -        return this.isWorkDirPersistent;
  -    }
  -
  -    public void setWorkDirPersistent( boolean b ) {
  -	isWorkDirPersistent=b;
  -    }
  -    
  -    // -------------------- Internal tomcat attributes 
  -    public void setRequestSecurityProvider(RequestSecurityProvider rsProvider) {
  -	this.rsProvider = rsProvider;
  -    }
  -
  -    public RequestSecurityProvider getRequestSecurityProvider() {
  -	return this.rsProvider;
  -    }
  -
  -    public RequestDispatcher getRequestDispatcher(String path) {
  -	if ( path == null  || ! path.startsWith("/")) {
  -	    return null; // spec say "return null if we can't return a dispather
  -	}
  -
  -	RequestDispatcherImpl rD=new RequestDispatcherImpl( this );
  -	rD.setPath( path );
  -
  -	return rD;
  -    }
  -
  -    public RequestDispatcher getNamedDispatcher(String name) {
  -        if (name == null)
  -	    return null;
  -
  -	// We need to do the checks 
  -	ServletWrapper wrapper = getServletByName( name );
  -	if (wrapper == null)
  -	    return null;
  -	RequestDispatcherImpl rD=new RequestDispatcherImpl( this );
  -	rD.setName( name );
  -
  -	return rD;
  -    }
  -
  -    /** Implements getResource() - use a sub-request to let interceptors do the job.
  -     */
  -    public URL getResource(String rpath) throws MalformedURLException {
  -        URL url = null;
  -
  -	if ("".equals(rpath)) 
  -	    return getDocumentBase();
  -	
  -        if (rpath == null)
  -	    return null;
  -
  -	if ( ! rpath.startsWith("/")) {
  -	    rpath="/" + rpath;
  -	}
  -
  -	// Create a Sub-Request, do the request processing stage
  -	// that will take care of aliasing and set the paths
  -	Request lr=contextM.createRequest( this, rpath );
  -	getContextManager().processRequest(lr);
  -
  -	String mappedPath = lr.getMappedPath();
  -
  -	// XXX workaround for mapper bugs
  -	if( mappedPath == null ) {
  -	    mappedPath=lr.getPathInfo();
  -	}
  -	if(mappedPath == null )
  -	    mappedPath=lr.getLookupPath();
  -	
  -        URL docBase = getDocumentBase();
  -
  -	url=new URL(docBase.getProtocol(), docBase.getHost(),
  -		       docBase.getPort(), docBase.getFile() + mappedPath);
  -	if( debug>0) log( "getResourceURL=" + url + " request=" + lr );
  -	return url;
  -    }
  -
  -    
  -    Context getContext(String path) {
  -	if (! path.startsWith("/")) {
  -	    return null; // according to spec, null is returned
  -	    // if we can't  return a servlet, so it's more probable
  -	    // servlets will check for null than IllegalArgument
  -	}
  -	Request lr=contextM.createRequest( this, path );
  -	getContextManager().processRequest(lr);
  -        return lr.getContext();
  -    }
  -
  -    public void log(String msg, Throwable t) {
  -	System.err.println(msg);
  -	t.printStackTrace(System.err);
  -    }
  -
  -    /**
  -     * 
  -     */
  -    String getRealPath( String path) {
  -	//	Real Path is the same as PathTranslated for a new request
  -	
  -	Context base=this; // contextM.getContext("");
  -	Request req=contextM.createRequest( base , FileUtil.normPath(path) );
  -	contextM.processRequest(req);
  -	
  -	String mappedPath = req.getMappedPath();
  -
  -	// XXX workaround - need to fix mapper to return mapped path
  -	if( mappedPath == null ) 
  -	    mappedPath=req.getPathInfo();
  -	if(mappedPath == null )
  -	    mappedPath=req.getLookupPath();
  -	
  -	String realPath= this.getDocBase() + mappedPath;
  -
  -	// Probably not needed - it will be used on the local FS
  -	realPath = FileUtil.patch(realPath);
  -
  -	return realPath;
  -    }
  -
  -    public File getWARDir() {
  -        return this.warDir;
  -    }
  -
  -    public void setWARDir( File f ) {
  -	warDir=f;
  -    }
  -
  -    public boolean isWARExpanded() {
  -        return this.isWARExpanded;
  -    }
  -
  -    public void setIsWARExpanded(boolean isWARExpanded) {
  -        this.isWARExpanded = isWARExpanded;
  -    }
  -
  -    public boolean isWARValidated() {
  -        return this.isWARValidated;
  -    }
  -
  -    public void setIsWARValidated(boolean isWARValidated) {
  -        this.isWARValidated = isWARValidated;
  -    }
  -    
  -    /**
  -     * Initializes this context to take on requests. This action
  -     * will cause the context to load it's configuration information
  -     * from the webapp directory in the docbase.
  -     *
  -     * <p>This method may only be called once and must be called
  -     * before any requests are handled by this context and after setContextManager()
  -     * is called.
  -     */
  -    public synchronized void init() throws TomcatException {
  -	// XXX Context is a mostly a "data" object, it contain all
  -	// context properties. We should use ContextManager.initContext() instead.
  -	if (this.initialized) {
  -	    String msg = sm.getString("context.init.alreadyinit");
  -	    throw new IllegalStateException(msg);
  -	}
  -	this.initialized = true;
  -	
  -	// All interceptor logic is in ContextManager.
  -	contextM.initContext( this );
  -    }
  -
  -    public void addContextInterceptor( ContextInterceptor ci) {
  -	contextInterceptors.addElement( ci );
  -    }
  -
  -    ContextInterceptor cInterceptors[];
  -
  -    /** Return the context interceptors as an array.
  -	For performance reasons we use an array instead of
  -	returning the vector - the interceptors will not change at
  -	runtime and array access is faster and easier than vector
  -	access
  -    */
  -    public ContextInterceptor[] getContextInterceptors() {
  -	if( cInterceptors == null || cInterceptors.length != contextInterceptors.size()) {
  -	    cInterceptors=new ContextInterceptor[contextInterceptors.size()];
  -	    for( int i=0; i<cInterceptors.length; i++ ) {
  -		cInterceptors[i]=(ContextInterceptor)contextInterceptors.elementAt(i);
  -	    }
  -	}
  -	return cInterceptors;
  -    }
  -
  -    public void addRequestInterceptor( RequestInterceptor ci) {
  -	requestInterceptors.addElement( ci );
  -    }
  -
  -    RequestInterceptor rInterceptors[];
  -    
  -    /** Return the context interceptors as an array.
  -	For performance reasons we use an array instead of
  -	returning the vector - the interceptors will not change at
  -	runtime and array access is faster and easier than vector
  -	access
  -    */
  -    public RequestInterceptor[] getRequestInterceptors() {
  -	if( rInterceptors == null || rInterceptors.length != requestInterceptors.size()) {
  -	    rInterceptors=new RequestInterceptor[requestInterceptors.size()];
  -	    for( int i=0; i<rInterceptors.length; i++ ) {
  -		rInterceptors[i]=(RequestInterceptor)requestInterceptors.elementAt(i);
  -	    }
  -	}
  -	return rInterceptors;
  -    }
  -
  -    public SessionManager getSessionManager() {
  -	return sessionManager;
  -    }
  -
  -    public void setSessionManager( SessionManager manager ) {
  -	sessionManager= manager;
  -    }
  -    
  -    public void shutdown() throws TomcatException {
  -	// shut down container
  -	initialized=false;
  -	Enumeration enum = servlets.keys();
  -
  -	while (enum.hasMoreElements()) {
  -	    String key = (String)enum.nextElement();
  -	    ServletWrapper wrapper = (ServletWrapper)servlets.get(key);
  -
  -	    servlets.remove(key);
  -	    wrapper.destroy();
  -	}
  -	// shut down any sessions
  -
  -	getSessionManager().removeSessions(this);
  -
  -	for( int i=0; i< contextInterceptors.size(); i++ ) {
  -	    ((ContextInterceptor)contextInterceptors.elementAt(i)).contextShutdown( this );
  -	}
  -
  -	System.out.println("Context: " + this + " down");
  -    }
       
  +    // -------------------- Web.xml properties --------------------
       public Enumeration getWelcomeFiles() {
   	return welcomeFiles.elements();
       }
  @@ -597,27 +335,6 @@
           attributes.remove(name);
       }
       
  -    /** @deprecated - use getDocBase and URLUtil if you need it as URL
  -     */
  -    public URL getDocumentBase() {
  -	if( documentBase == null ) {
  -	    if( docBase != null)
  -		try {
  -		    documentBase=URLUtil.resolve( docBase );
  -		} catch( MalformedURLException ex ) {
  -		    ex.printStackTrace();
  -		}
  -	}
  -        return documentBase;
  -    }
  -
  -    /** @deprecated - use setDocBase
  -     */
  -    public void setDocumentBase(URL s) {
  -	// Used only by startup, will be removed
  -        this.documentBase=s;
  -    }
  -
       public String getDescription() {
           return this.description;
       }
  @@ -699,42 +416,7 @@
   	this.formErrorPage=formErrorPage;
       }   
       
  -    ServletContextFacade getFacade() {
  -        if(contextFacade==null )
  -	    contextFacade = new ServletContextFacade(contextM, this);
  -	return contextFacade;
  -    }
  -
  -    // --------------------
  -
  -    /** Remove all servlets with a specific class name
  -     */
  -    void removeServletByClassName(String className)
  -	throws TomcatException
  -    {
  -	Enumeration enum = servlets.keys();
  -	while (enum.hasMoreElements()) {
  -	    String key = (String)enum.nextElement();
  -	    ServletWrapper sw = (ServletWrapper)servlets.get(key);
  -            if (className.equals(sw.getServletClass()))
  -		servlets.remove(sw.getServletName());
  -		contextM.removeServlet( this, sw );
  -	}
  -    }
  -
  -    /** Remove the servlet with a specific name
  -     */
  -    public void removeServletByName(String servletName)
  -	throws TomcatException
  -    {
  -	ServletWrapper wrapper=(ServletWrapper)servlets.get(servletName);
  -	if( wrapper != null ) {
  -	    servlets.remove( servletName );
  -	    contextM.removeServlet( this, wrapper );
  -	}
  -    }
  -
  -    // -------------------- Mappings
  +    // -------------------- Mappings --------------------
       
       /**
        * Maps a named servlet to a particular path or extension.
  @@ -817,6 +499,18 @@
   
       // -------------------- Servlets management --------------------
       
  +    /** Remove the servlet with a specific name
  +     */
  +    public void removeServletByName(String servletName)
  +	throws TomcatException
  +    {
  +	ServletWrapper wrapper=(ServletWrapper)servlets.get(servletName);
  +	if( wrapper != null ) {
  +	    servlets.remove( servletName );
  +	    contextM.removeServlet( this, wrapper );
  +	}
  +    }
  +
       public ServletWrapper getServletByName(String servletName) {
   	return (ServletWrapper)servlets.get(servletName);
       }
  @@ -846,7 +540,15 @@
   	return servlets.keys();
       }
   
  -    // -------------------- Class Loading --------------------
  +    // -------------------- Loading and sessions --------------------
  +    public SessionManager getSessionManager() {
  +	return sessionManager;
  +    }
  +
  +    public void setSessionManager( SessionManager manager ) {
  +	sessionManager= manager;
  +    }
  +
   
       public void setServletLoader(ServletLoader loader ) {
   	this.servletL=loader;
  @@ -861,6 +563,10 @@
   	debug=level;
       }
   
  +    public int getDebug( ) {
  +	return debug;
  +    }
  +
       public void log( String msg ) {
   	System.out.println("Context(" + path  + "): " + msg );
       }
  @@ -869,4 +575,251 @@
   	return "Ctx(" + path + "," + getDocBase() + ")";
   	// + " , " + getDocumentBase() + " ) ";
       }
  +
  +    // -------------------- Facade methods --------------------
  +
  +    public RequestDispatcher getRequestDispatcher(String path) {
  +	if ( path == null  || ! path.startsWith("/")) {
  +	    return null; // spec say "return null if we can't return a dispather
  +	}
  +	RequestDispatcherImpl rD=new RequestDispatcherImpl( this );
  +	rD.setPath( path );
  +
  +	return rD;
  +    }
  +
  +    public RequestDispatcher getNamedDispatcher(String name) {
  +        if (name == null)
  +	    return null;
  +
  +	// We need to do the checks 
  +	ServletWrapper wrapper = getServletByName( name );
  +	if (wrapper == null)
  +	    return null;
  +	RequestDispatcherImpl rD=new RequestDispatcherImpl( this );
  +	rD.setName( name );
  +
  +	return rD;
  +    }
  +
  +    /** Implements getResource() - use a sub-request to let interceptors do the job.
  +     */
  +    public URL getResource(String rpath) throws MalformedURLException {
  +        URL url = null;
  +
  +	if ("".equals(rpath)) 
  +	    return getDocumentBase();
  +	
  +        if (rpath == null)
  +	    return null;
  +
  +	if ( ! rpath.startsWith("/")) {
  +	    rpath="/" + rpath;
  +	}
  +
  +	// Create a Sub-Request, do the request processing stage
  +	// that will take care of aliasing and set the paths
  +	Request lr=contextM.createRequest( this, rpath );
  +	getContextManager().processRequest(lr);
  +
  +	String mappedPath = lr.getMappedPath();
  +
  +	// XXX workaround for mapper bugs
  +	if( mappedPath == null ) {
  +	    mappedPath=lr.getPathInfo();
  +	}
  +	if(mappedPath == null )
  +	    mappedPath=lr.getLookupPath();
  +	
  +        URL docBase = getDocumentBase();
  +
  +	url=new URL(docBase.getProtocol(), docBase.getHost(),
  +		       docBase.getPort(), docBase.getFile() + mappedPath);
  +	if( debug>0) log( "getResourceURL=" + url + " request=" + lr );
  +	return url;
  +    }
  +
  +    
  +    Context getContext(String path) {
  +	if (! path.startsWith("/")) {
  +	    return null; // according to spec, null is returned
  +	    // if we can't  return a servlet, so it's more probable
  +	    // servlets will check for null than IllegalArgument
  +	}
  +	Request lr=contextM.createRequest( this, path );
  +	getContextManager().processRequest(lr);
  +        return lr.getContext();
  +    }
  +
  +    public void log(String msg, Throwable t) {
  +	System.err.println(msg);
  +	t.printStackTrace(System.err);
  +    }
  +
  +    /**
  +     * 
  +     */
  +    String getRealPath( String path) {
  +	//	Real Path is the same as PathTranslated for a new request
  +	
  +	Context base=this; // contextM.getContext("");
  +	Request req=contextM.createRequest( base , FileUtil.normPath(path) );
  +	contextM.processRequest(req);
  +	
  +	String mappedPath = req.getMappedPath();
  +
  +	// XXX workaround - need to fix mapper to return mapped path
  +	if( mappedPath == null ) 
  +	    mappedPath=req.getPathInfo();
  +	if(mappedPath == null )
  +	    mappedPath=req.getLookupPath();
  +	
  +	String realPath= this.getDocBase() + mappedPath;
  +
  +	// Probably not needed - it will be used on the local FS
  +	realPath = FileUtil.patch(realPath);
  +
  +	return realPath;
  +    }
  +
  +    // -------------------- Deprecated
  +    // 
  +
  +    public boolean isInvokerEnabled() {
  +        return isInvokerEnabled;
  +    }
  +
  +    
  +    public void setInvokerEnabled(boolean isInvokerEnabled) {
  +        this.isInvokerEnabled = isInvokerEnabled;
  +    }
  +
  +    public boolean isWorkDirPersistent() {
  +        return this.isWorkDirPersistent;
  +    }
  +
  +    public void setWorkDirPersistent( boolean b ) {
  +	isWorkDirPersistent=b;
  +    }
  +    
  +    public File getWorkDir() {
  +	return workDir;
  +    }
  +
  +    public void setWorkDir(File workDir) {
  +	this.workDir = workDir;
  +    }
  +
  +    /** Set work dir using a String property
  +     */
  +    public void setWorkDirPath(String workDir) {
  +	this.workDir=new File(workDir);
  +    }
  +    public String getEngineHeader() {
  +	return engineHeader;
  +    }
  +
  +    public void setEngineHeader(String s) {
  +        engineHeader=s;
  +    }
  +
  +    public void setRequestSecurityProvider(RequestSecurityProvider rsProvider) {
  +	this.rsProvider = rsProvider;
  +    }
  +
  +    public RequestSecurityProvider getRequestSecurityProvider() {
  +	return this.rsProvider;
  +    }
  +
  +    public File getWARDir() {
  +        return this.warDir;
  +    }
  +
  +    public void setWARDir( File f ) {
  +	warDir=f;
  +    }
  +
  +    public boolean isWARExpanded() {
  +        return this.isWARExpanded;
  +    }
  +
  +    public void setIsWARExpanded(boolean isWARExpanded) {
  +        this.isWARExpanded = isWARExpanded;
  +    }
  +
  +    public boolean isWARValidated() {
  +        return this.isWARValidated;
  +    }
  +
  +    public void setIsWARValidated(boolean isWARValidated) {
  +        this.isWARValidated = isWARValidated;
  +    }
  +    
  +    public void addContextInterceptor( ContextInterceptor ci) {
  +	contextInterceptors.addElement( ci );
  +    }
  +
  +    ContextInterceptor cInterceptors[];
  +
  +    /** Return the context interceptors as an array.
  +	For performance reasons we use an array instead of
  +	returning the vector - the interceptors will not change at
  +	runtime and array access is faster and easier than vector
  +	access
  +    */
  +    public ContextInterceptor[] getContextInterceptors() {
  +	if( cInterceptors == null || cInterceptors.length != contextInterceptors.size()) {
  +	    cInterceptors=new ContextInterceptor[contextInterceptors.size()];
  +	    for( int i=0; i<cInterceptors.length; i++ ) {
  +		cInterceptors[i]=(ContextInterceptor)contextInterceptors.elementAt(i);
  +	    }
  +	}
  +	return cInterceptors;
  +    }
  +
  +    public void addRequestInterceptor( RequestInterceptor ci) {
  +	requestInterceptors.addElement( ci );
  +    }
  +
  +    RequestInterceptor rInterceptors[];
  +    
  +    /** Return the context interceptors as an array.
  +	For performance reasons we use an array instead of
  +	returning the vector - the interceptors will not change at
  +	runtime and array access is faster and easier than vector
  +	access
  +    */
  +    public RequestInterceptor[] getRequestInterceptors() {
  +	if( rInterceptors == null || rInterceptors.length != requestInterceptors.size()) {
  +	    rInterceptors=new RequestInterceptor[requestInterceptors.size()];
  +	    for( int i=0; i<rInterceptors.length; i++ ) {
  +		rInterceptors[i]=(RequestInterceptor)requestInterceptors.elementAt(i);
  +	    }
  +	}
  +	return rInterceptors;
  +    }
  +
  +    /** @deprecated - use getDocBase and URLUtil if you need it as URL
  +     */
  +    public URL getDocumentBase() {
  +	if( documentBase == null ) {
  +	    if( docBase != null)
  +		try {
  +		    documentBase=URLUtil.resolve( docBase );
  +		} catch( MalformedURLException ex ) {
  +		    ex.printStackTrace();
  +		}
  +	}
  +        return documentBase;
  +    }
  +
  +    /** @deprecated - use setDocBase
  +     */
  +    public void setDocumentBase(URL s) {
  +	// Used only by startup, will be removed
  +        this.documentBase=s;
  +    }
  +
  +
  +
   }
  
  
  
  1.39      +102 -50   jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
  
  Index: ContextManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- ContextManager.java	2000/02/13 06:23:58	1.38
  +++ ContextManager.java	2000/02/13 20:49:40	1.39
  @@ -117,6 +117,7 @@
        */
       int port;
   
  +    int debug=0;
       String workDir;
   
       // Instalation directory  
  @@ -132,6 +133,41 @@
       }
   
       // -------------------- Context repository --------------------
  +
  +    /** Set default settings ( interceptors, connectors, loader, manager )
  +     *  It is called from init if no connector is set up  - note that we
  +     *  try to avoid any "magic" - you either set up everything ( using
  +     *  server.xml or alternatives) or you don't set up and then defaults
  +     *  will be used.
  +     * 
  +     *  Set interceptors or call setDefaults before adding contexts.
  +     */
  +    public void setDefaults() {
  +	if(connectors.size()==0) {
  +	    log("Setting default adapter");
  +	    addServerConnector(  new org.apache.tomcat.service.http.HttpAdapter() );
  +	}
  +	
  +	if( contextInterceptors.size()==0) {
  +	    log("Setting default context interceptors");
  +	    addContextInterceptor(new LogEvents());
  +	    addContextInterceptor(new AutoSetup());
  +	    addContextInterceptor(new DefaultCMSetter());
  +	    addContextInterceptor(new WorkDirInterceptor());
  +	    addContextInterceptor( new WebXmlReader());
  +	    addContextInterceptor(new LoadOnStartupInterceptor());
  +	}
  +	
  +	if( requestInterceptors.size()==0) {
  +	    log("Setting default request interceptors");
  +	    SimpleMapper smap=new SimpleMapper();
  +	    smap.setContextManager( this );
  +	    addRequestInterceptor(smap);
  +	    addRequestInterceptor(new SessionInterceptor());
  +	}
  +    }
  +     
  +    
       /**
        * Get the names of all the contexts in this server.
        */
  @@ -140,53 +176,61 @@
       }
   
       /** Init() is called after the context manager is set up
  -     *  and configured
  +     *  and configured. 
        */
       public void init()  throws TomcatException {
  -	long time=System.currentTimeMillis();
  -
  -	(new DefaultCMSetter()).engineInit(this);
  -
  -	
  -	(new AutoSetup()).engineInit(this);
  -	// Initialize and check Context Manager 
  +	//	long time=System.currentTimeMillis();
  +	ContextInterceptor cI[]=getContextInterceptors();
  +	for( int i=0; i< cI.length; i++ ) {
  +	    cI[i].engineInit( this );
  +	}
   	
       	// init contexts
   	Enumeration enum = getContextNames();
   	while (enum.hasMoreElements()) {
               Context context = getContext((String)enum.nextElement());
  -            context.init();
  +            initContext( context );
   	}
  -
  -	log("Time to initialize: "+ (System.currentTimeMillis()-time), Logger.INFORMATION);
  -
  -	// After all context are configured, we can generate Apache configs
  -	org.apache.tomcat.task.ApacheConfig apacheConfig=new  org.apache.tomcat.task.ApacheConfig();
  -	apacheConfig.execute( this );     
  +	//	log("Time to initialize: "+ (System.currentTimeMillis()-time), Logger.INFORMATION);
       }
   
  -    /** Initialize a context. This method is will call all "global"
  -     * interceptors ( set on CM level ) and then context specific
  -     * interceptors.
  +    
  +    /**
  +     * Initializes this context to take on requests. This action
  +     * will cause the context to load it's configuration information
  +     * from the webapp directory in the docbase.
  +     *
  +     * <p>This method may only be called once and must be called
  +     * before any requests are handled by this context and after setContextManager()
  +     * is called.
        */
       public void initContext( Context ctx ) throws TomcatException {
  -	//
   	ContextInterceptor cI[]=getContextInterceptors();
   	for( int i=0; i< cI.length; i++ ) {
   	    cI[i].contextInit( ctx );
   	}
  +    }
  +    
  +    public void shutdownContext( Context ctx ) throws TomcatException {
  +	// shut down and servlet
  +	Enumeration enum = ctx.getServletNames();
  +
  +	while (enum.hasMoreElements()) {
  +	    String key = (String)enum.nextElement();
  +	    ServletWrapper wrapper = ctx.getServletByName( key );
  +	    ctx.removeServletByName( key );
  +	    wrapper.destroy();
  +	}
   	
  -	cI=ctx.getContextInterceptors();
  +	ContextInterceptor cI[]=getContextInterceptors();
   	for( int i=0; i< cI.length; i++ ) {
  -	    cI[i].contextInit( ctx );
  +	    cI[i].contextShutdown( ctx );
   	}
       }
       
       /** Will start the connectors and begin serving requests
        */
       public void start() throws Exception {//TomcatException {
  -	init();
  -	
   	Enumeration connE=getConnectors();
   	while( connE.hasMoreElements() ) {
   	    ((ServerConnector)connE.nextElement()).start();
  @@ -194,27 +238,16 @@
       }
   
       public void stop() throws Exception {//TomcatException {
  -	System.out.println("Stopping context manager ");
  -
  +	log("Stopping context manager ");
   	Enumeration connE=getConnectors();
   	while( connE.hasMoreElements() ) {
   	    ((ServerConnector)connE.nextElement()).stop();
   	}
  -
  -	destroy();
  -    }
   
  -    public void destroy() throws Exception {//TomcatException {
  -	
  +	ContextInterceptor cI[]=getContextInterceptors();
   	Enumeration enum = getContextNames();
   	while (enum.hasMoreElements()) {
  -	    Context context =
  -	        getContext((String)enum.nextElement());
  -	    
  -	    System.out.println("Taking down context: " +
  -			       context.getPath());
  -	    
  -	    context.shutdown();
  +	    removeContext((String)enum.nextElement());
   	}
       }
   
  @@ -227,8 +260,6 @@
       public Context getContext(String name) {
   	return (Context)contexts.get(name);
       }
  -
  -
       
       /**
        * Adds a new Context to the set managed by this ContextManager.
  @@ -236,22 +267,20 @@
        * @param ctx context to be added.
        */
       public void addContext( Context ctx ) throws TomcatException {
  -	// it will replace existing context - it's better than 
  -	// IllegalStateException.
  +	// Make sure context knows about its manager.
  +	ctx.setContextManager( this );
  +
  +	// it will replace existing context - it's better than  IllegalStateException.
   	String path=ctx.getPath();
   	if( getContext( path ) != null ) {
   	    log("Warning: replacing context for " + path, Logger.WARNING);
   	    removeContext(path);
   	}
   
  -	// Set defaults for the context
  -	new DefaultCMSetter().addContext( this, ctx );
  -
   	ContextInterceptor cI[]=getContextInterceptors();
   	for( int i=0; i< cI.length; i++ ) {
   	    cI[i].addContext( this, ctx );
   	}
  -
   	
   	log(" adding " + ctx + " " + ctx.getPath() + " " +  ctx.getDocBase(), Logger.INFORMATION);
   
  @@ -276,7 +305,7 @@
   	}
   
   	if(context != null) {
  -	    context.shutdown();
  +	    shutdownContext( context );
   	    contexts.remove(name);
   	}
       }
  @@ -374,6 +403,9 @@
   	access
       */
       public ContextInterceptor[] getContextInterceptors() {
  +	if( contextInterceptors.size() == 0 ) {
  +	    setDefaults();
  +	}
   	if( cInterceptors == null || cInterceptors.length != contextInterceptors.size()) {
   	    cInterceptors=new ContextInterceptor[contextInterceptors.size()];
   	    for( int i=0; i<cInterceptors.length; i++ ) {
  @@ -411,6 +443,7 @@
        * Sets the port number on which this server listens.
        *
        * @param port The new port number
  +     * @deprecated 
        */
       public void setPort(int port) {
   	this.port=port;
  @@ -418,6 +451,7 @@
   
       /**
        * Gets the port number on which this server listens.
  +     * @deprecated 
        */
       public int getPort() {
   	if(port==0) port=DEFAULT_PORT;
  @@ -428,6 +462,7 @@
        * Sets the virtual host name of this server.
        *
        * @param host The new virtual host name
  +     * @deprecated 
        */
       public void setHostName( String host) {
   	this.hostname=host;
  @@ -435,6 +470,7 @@
   
       /**
        * Gets the virtual host name of this server.
  +     * @deprecated 
        */
       public String getHostName() {
   	if(hostname==null)
  @@ -481,8 +517,8 @@
   	    processRequest( rrequest );
   
   	    if( rrequest.getWrapper() == null ) {
  -		System.out.println("ERROR: mapper returned no wrapper ");
  -		System.out.println(rrequest );
  +		log("ERROR: mapper returned no wrapper ");
  +		log(rrequest.toString() );
   		// XXX send an error - it shouldn't happen, mapper is broken
   	    } else {
   		// do it
  @@ -498,8 +534,8 @@
   	    }
   	    // XXX
   	    // this isn't what we want, we want to log the problem somehow
  -	    System.out.println("HANDLER THREAD PROBLEM: " + e);
  -	    System.out.println("Request: " + rrequest);
  +	    log("HANDLER THREAD PROBLEM: " + e);
  +	    log("Request: " + rrequest);
   	    e.printStackTrace();
   	}
       }
  @@ -570,9 +606,25 @@
   	return lr;
       }
   
  +    public void setDebug( int level ) {
  +	
  +	if( level != 0 ) System.out.println( "Setting level to " + level);
  +	debug=level;
  +    }
  +
       boolean firstLog = true;
       Logger cmLog = null;
       
  +    public final void log(String msg) {
  +	if (firstLog == true) {
  +	    cmLog = Logger.getLogger("CTXMGR_LOG");
  +	    firstLog = false;
  +	}
  +
  +	if (cmLog != null)
  +	    cmLog.log(msg, Logger.DEBUG);
  +    }
  +
       public final void log(String msg, int level) {
   	if (firstLog == true) {
   	    cmLog = Logger.getLogger("CTXMGR_LOG");
  
  
  
  1.16      +11 -3     jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java
  
  Index: RequestImpl.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- RequestImpl.java	2000/02/08 18:50:45	1.15
  +++ RequestImpl.java	2000/02/13 20:49:40	1.16
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v 1.15 2000/02/08 18:50:45 costin Exp $
  - * $Revision: 1.15 $
  - * $Date: 2000/02/08 18:50:45 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/RequestImpl.java,v 1.16 2000/02/13 20:49:40 costin Exp $
  + * $Revision: 1.16 $
  + * $Date: 2000/02/13 20:49:40 $
    *
    * ====================================================================
    *
  @@ -660,6 +660,14 @@
       }
   
       public String toString() {
  +	StringBuffer sb=new StringBuffer();
  +	sb.append( "R( " + getRequestURI() + " ");
  +	if( context!=null) sb.append( context.getPath() );
  +	sb.append(")");
  +	return sb.toString();
  +    }
  +
  +    public String toStringDebug() {
   	StringBuffer sb=new StringBuffer();
   	sb.append( "Request( " + context ).append("\n");
   	sb.append( "    URI:" + getRequestURI()  ).append("\n");
  
  
  
  1.24      +3 -8      jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java
  
  Index: ServletWrapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- ServletWrapper.java	2000/02/13 01:43:41	1.23
  +++ ServletWrapper.java	2000/02/13 20:49:40	1.24
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v 1.23 2000/02/13 01:43:41 costin Exp $
  - * $Revision: 1.23 $
  - * $Date: 2000/02/13 01:43:41 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletWrapper.java,v 1.24 2000/02/13 20:49:40 costin Exp $
  + * $Revision: 1.24 $
  + * $Date: 2000/02/13 20:49:40 $
    *
    * ====================================================================
    *
  @@ -78,11 +78,6 @@
    * @author Harish Prabandham
    * @author costin@dnt.ro
    */
  -
  -//
  -// WARNING: Some of the APIs in this class are used by J2EE. 
  -// Please talk to harishp@eng.sun.com before making any changes.
  -//
   public class ServletWrapper {
       protected StringManager sm = StringManager.getManager("org.apache.tomcat.core");
   
  
  
  
  1.3       +3 -1      jakarta-tomcat/src/share/org/apache/tomcat/logging/TomcatLogger.java
  
  Index: TomcatLogger.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/logging/TomcatLogger.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- TomcatLogger.java	2000/02/13 06:47:40	1.2
  +++ TomcatLogger.java	2000/02/13 20:49:42	1.3
  @@ -109,10 +109,12 @@
   	    w.print(' ');
   
   	    if (message != null)
  -		w.println(message);
  +		w.print(message);
   	    
   	    if (t != null)
   		t.printStackTrace(w);
  +
  +	    w.println("</"+TomcatLogger.this.getName()+"> ");
   
   	    return sw.toString();
   	}
  
  
  
  1.9       +10 -4     jakarta-tomcat/src/share/org/apache/tomcat/request/SessionInterceptor.java
  
  Index: SessionInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/request/SessionInterceptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- SessionInterceptor.java	2000/02/11 02:21:47	1.8
  +++ SessionInterceptor.java	2000/02/13 20:49:43	1.9
  @@ -112,10 +112,6 @@
   	return 0;
       }
   
  -    public int contextMap( Request rrequest ) {
  -	return 0;
  -    }
  -
       public int beforeBody( Request rrequest, Response response ) {
   	String reqSessionId = response.getSessionId();
   	if( reqSessionId==null)
  @@ -135,5 +131,15 @@
   
   	return 0;
       }
  +
  +
  +    /** Notification of context shutdown
  +     */
  +    public void contextShutdown( Context ctx )
  +	throws TomcatException
  +    {
  +	ctx.getSessionManager().removeSessions(ctx);
  +    }
  +
   
   }
  
  
  
  1.9       +22 -5     jakarta-tomcat/src/share/org/apache/tomcat/startup/Tomcat.java
  
  Index: Tomcat.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/Tomcat.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Tomcat.java	2000/02/13 06:19:46	1.8
  +++ Tomcat.java	2000/02/13 20:49:43	1.9
  @@ -43,6 +43,18 @@
   	xh.addRule( "ContextManager", xh.setProperties() );
   	//	xh.addRule( "ContextManager", xh.setParent( "setServer" ) );
   	//	xh.addRule( "ContextManager", xh.addChild( "setContextManager", null) );
  +
  +	xh.addRule( "ContextManager/ContextInterceptor", xh.objectCreate(null, "className"));
  +	xh.addRule( "ContextManager/ContextInterceptor", xh.setProperties() );
  +	xh.addRule( "ContextManager/ContextInterceptor", xh.setParent("setContextManager") );
  +	xh.addRule( "ContextManager/ContextInterceptor", xh.addChild( "addContextInterceptor",
  +								      "org.apache.tomcat.core.ContextInterceptor" ) );
  +	
  +	xh.addRule( "ContextManager/RequestInterceptor", xh.objectCreate(null, "className"));
  +	xh.addRule( "ContextManager/RequestInterceptor", xh.setProperties() );
  +	xh.addRule( "ContextManager/RequestInterceptor", xh.setParent("setContextManager") );
  +	xh.addRule( "ContextManager/RequestInterceptor", xh.addChild( "addRequestInterceptor",
  +								      "org.apache.tomcat.core.RequestInterceptor" ) );
   	
    	xh.addRule( "ContextManager/Context", xh.objectCreate("org.apache.tomcat.core.Context"));
   	xh.addRule( "ContextManager/Context", xh.setParent( "setContextManager") );
  @@ -54,7 +66,7 @@
   	xh.addRule( "ContextManager/Connector", xh.addChild( "addServerConnector", "org.apache.tomcat.core.ServerConnector") );
   
   	
  -	xh.addRule("ContextManager/Logger", 
  +	xh.addRule("ContextManager/Logger",
   		   xh.objectCreate("org.apache.tomcat.logging.TomcatLogger"));
   	xh.addRule("ContextManager/Logger", xh.setProperties());
   	xh.addRule("ContextManager/Logger", 
  @@ -78,15 +90,20 @@
   	xh.setDebug( 0 );
   	ContextManager cm=new ContextManager();
   	setHelper( xh );
  -	//	org.apache.tomcat.server.HttpServer server=new org.apache.tomcat.server.HttpServer();
   	xh.readXml(f,cm);
  -	//	cm=server.getContextManager();
   
  +	// Generate Apache configs
  +	//
  +	org.apache.tomcat.task.ApacheConfig apacheConfig=new  org.apache.tomcat.task.ApacheConfig();
  +	apacheConfig.execute( cm );     
  +
   	if( doStop ) {
  -	    stopTomcat(cm);
  +	    stopTomcat(cm); // stop serving
   	    return;
   	}
  -	cm.start();
  +
  +	cm.init(); // set up contexts
  +	cm.start(); // start serving
       }
       
       public static void main(String args[] ) {
  
  
  
  1.4       +114 -4    jakarta-tomcat/src/share/org/apache/tomcat/util/xml/XmlMapper.java
  
  Index: XmlMapper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/xml/XmlMapper.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XmlMapper.java	2000/02/13 06:22:49	1.3
  +++ XmlMapper.java	2000/02/13 20:49:44	1.4
  @@ -37,7 +37,8 @@
       
       public XmlMapper() {
   	attributeStack = new Object[100]; // depth of the xml doc
  -	tagStack = new String[100]; 
  +	tagStack = new String[100];
  +	initDefaultRules();
       }
       
       public void setDocumentLocator (Locator locator)
  @@ -136,6 +137,7 @@
       // -------------------- Utils --------------------
       // Debug ( to be replaced with the real thing )
       public void setDebug( int level ) {
  +	if(level!=0) log( "Debug level: " + level );
   	debug=level;
       }
   
  @@ -206,6 +208,25 @@
       Rule rules[]=new Rule[100];
       Rule matching[]=new Rule[100];
       int ruleCount=0;
  +
  +    /**
  +     */
  +    private void initDefaultRules() {
  +	// One-time actions, in line
  +	addRule( "xmlmapper:debug",
  +		 new XmlAction() {
  +			 public void start(SaxContext ctx) {
  +			     int top=ctx.getTagCount()-1;
  +			     AttributeList attributes = ctx.getAttributeList( top );
  +			     String levelS=attributes.getValue("level");
  +			     XmlMapper mapper=(XmlMapper)ctx;
  +			     if( levelS!=null)
  +				 mapper.setDebug( new Integer(levelS).intValue());
  +			 }
  +		     }
  +		 );
  +	
  +    }
       
       public void addRule( String path, XmlAction action ) {
   	rules[ruleCount]=new Rule( new PathMatch( path ) , action);
  @@ -396,7 +417,7 @@
       public SetProperties() {
       }
   
  -    public void start( SaxContext ctx) {
  +    public void start( SaxContext ctx ) {
   	Stack st=ctx.getObjectStack();
   	Object elem=st.peek();
   	int top=ctx.getTagCount()-1;
  @@ -406,12 +427,101 @@
   	    String type = attributes.getType (i);
   	    String name=attributes.getName(i);
   	    String value=attributes.getValue(i);
  +
  +	    setProperty( ctx, elem, name, value );
  +	}
  +
  +    }
  +
  +    /** Find a method with the right name
  +	If found, call the method ( if param is int or boolean we'll convert value to
  +	the right type before) - that means you can have setDebug(1).
  +    */
  +    static void setProperty( SaxContext ctx, Object o, String name, String value ) {
  +	if( ctx.getDebug() > 1 ) ctx.log("setProperty(" + o.getClass() + " " +  name + "="  + value  +")" );
  +
  +	String setter= "set" +capitalize(name);
   
  -	    InvocationHelper.setProperty( elem, name, value );
  -	    if( ctx.getDebug() > 0 ) ctx.log("setProperty(" + name + " "  + value  +")" );
  +	try {
  +	    Method methods[]=o.getClass().getMethods();
  +	    Method setPropertyMethod=null;
  +
  +	    // First, the ideal case - a setFoo( String ) method
  +	    for( int i=0; i< methods.length; i++ ) {
  +		Class paramT[]=methods[i].getParameterTypes();
  +		if( setter.equals( methods[i].getName() ) &&
  +		    paramT.length == 1 &&
  +		    "java.lang.String".equals( paramT[0].getName())) {
  +
  +		    methods[i].invoke( o, new Object[] { value } );
  +		    return;
  +		}
  +	    }
  +
  +	    // Try a setFoo ( int ) or ( boolean )
  +	    for( int i=0; i< methods.length; i++ ) {
  +		boolean ok=true;
  +		if( setter.equals( methods[i].getName() ) &&
  +		    methods[i].getParameterTypes().length == 1) {
  +		    
  +		    // match - find the type and invoke it
  +		    Class paramType=methods[i].getParameterTypes()[0];
  +		    Object params[]=new Object[1];
  +		    if ("java.lang.Integer".equals( paramType.getName()) ||
  +			"int".equals( paramType.getName())) {
  +			try {
  +			    params[0]=new Integer(value);
  +			} catch( NumberFormatException ex ) {ok=false;}
  +		    } else if ("java.lang.Boolean".equals( paramType.getName())) {
  +			params[0]=new Boolean(value);
  +		    } else {
  +			ctx.log("Unknown type " + paramType.getName() );
  +		    }
  +
  +		    if( ok ) {
  +			//	System.out.println("XXX: " + methods[i] + " " + o + " " + params[0] );
  +			methods[i].invoke( o, params );
  +			return;
  +		    }
  +		}
  +		
  +		// save "setProperty" for later
  +		if( "setProperty".equals( methods[i].getName())) {
  +		    setPropertyMethod=methods[i];
  +		}
  +	    }
  +
  +	    // Ok, no setXXX found, try a setProperty("name", "value")
  +	    if( setPropertyMethod != null ) {
  +		Object params[]=new Object[2];
  +		params[0]=name;
  +		params[1]=value;
  +		setPropertyMethod.invoke( o, params );
  +	    }
  +
  +	} catch( SecurityException ex1 ) {
  +	    if( ctx.getDebug() > 0 ) ctx.log("SecurityException for " + o.getClass() + " " +  name + "="  + value  +")" );
  +	    if( ctx.getDebug() > 1 ) ex1.printStackTrace();
  +	} catch (IllegalAccessException iae) {
  +	    if( ctx.getDebug() > 0 ) ctx.log("IllegalAccessException for " + o.getClass() + " " +  name + "="  + value  +")" );
  +	    if( ctx.getDebug() > 1 ) iae.printStackTrace();
  +	} catch (InvocationTargetException ie) {
  +	    if( ctx.getDebug() > 0 ) ctx.log("InvocationTargetException for " + o.getClass() + " " +  name + "="  + value  +")" );
  +	    if( ctx.getDebug() > 1 ) ie.printStackTrace();
   	}
  +    }
   
  +    /** Reverse of Introspector.decapitalize
  +     */
  +    static String capitalize(String name) {
  +	if (name == null || name.length() == 0) {
  +	    return name;
  +	}
  +	char chars[] = name.toCharArray();
  +	chars[0] = Character.toUpperCase(chars[0]);
  +	return new String(chars);
       }
  +
   }
   
   
  
  
  
  1.11      +1 -2      jakarta-tomcat/src/shell/tomcat.sh
  
  Index: tomcat.sh
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/shell/tomcat.sh,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- tomcat.sh	2000/02/03 07:11:55	1.10
  +++ tomcat.sh	2000/02/13 20:49:45	1.11
  @@ -1,6 +1,6 @@
   #!/bin/sh
   #
  -# $Id: tomcat.sh,v 1.10 2000/02/03 07:11:55 costin Exp $
  +# $Id: tomcat.sh,v 1.11 2000/02/13 20:49:45 costin Exp $
   
   # Shell script to start and stop the server
   
  @@ -68,7 +68,6 @@
   done
   
   CLASSPATH=${CLASSPATH}:${JAVA_HOME}/lib/tools.jar
  -echo XXX $CLASSPATH
   
   
   # Backdoor classpath setting for development purposes when all classes