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/07/28 01:08:21 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/util WARUtil.java

costin      00/07/27 16:08:21

  Modified:    src/etc  server.xml
               src/share/org/apache/tomcat/context LoaderInterceptor1.java
               src/share/org/apache/tomcat/core Context.java
                        ContextManager.java ServletWrapper.java
               src/share/org/apache/tomcat/loader
                        AdaptiveServletLoader.java
               src/share/org/apache/tomcat/util WARUtil.java
  Added:       src/share/org/apache/tomcat/depend DependClassLoader.java
                        DependManager.java Dependency.java package.html
               src/share/org/apache/tomcat/request ReloadInterceptor.java
  Log:
  - Added ReloadInterceptor. As promised, the reloading will be re-written
  and improved, and this is the first step. Right now we implement almost
  the same scheme as before ( so it's not a fix ), but we can move the
  whole mess in a repaceable component.
  
  - Added DependManager. It is a (stand-alone) component, with no deps on
  tomcat that is able to detect a change in a set of files. It will be
  improved in time, but so far it provides enough for tomcat.
  It is able to minimize the number of file accesses and perform good
  enough.
  
  - Context: on reload, all servlets will be cleaned up.
  
  - started to phase out ServletLoader. AdaptiveServletLoader will still
  be around ( to ensure continuity and stability ). The interface will be
  removed in few days unless someone is using it ( for new class loaders)
  
  - removed deprecated methods in context.
  
  Revision  Changes    Path
  1.34      +6 -0      jakarta-tomcat/src/etc/server.xml
  
  Index: server.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/etc/server.xml,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- server.xml	2000/07/27 17:57:04	1.33
  +++ server.xml	2000/07/27 23:08:17	1.34
  @@ -135,6 +135,12 @@
           <RequestInterceptor 
               className="org.apache.tomcat.request.StaticInterceptor" 
               debug="0" listings="true" />
  +        
  +	<!-- Handle reloads - will be moved to per/context
  +          -->
  +        <RequestInterceptor 
  +            className="org.apache.tomcat.request.ReloadInterceptor" 
  +            debug="0" />
   
           <!-- Plug a session manager. You can plug in more advanced session
                modules.
  
  
  
  1.2       +24 -2     jakarta-tomcat/src/share/org/apache/tomcat/context/LoaderInterceptor1.java
  
  Index: LoaderInterceptor1.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/LoaderInterceptor1.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LoaderInterceptor1.java	2000/07/27 19:02:33	1.1
  +++ LoaderInterceptor1.java	2000/07/27 23:08:17	1.2
  @@ -64,6 +64,7 @@
   import org.apache.tomcat.core.Constants;
   import org.apache.tomcat.request.*;
   import org.apache.tomcat.util.*;
  +import org.apache.tomcat.depend.*;
   import java.io.*;
   import java.net.*;
   import java.util.*;
  @@ -135,12 +136,33 @@
       {
           ContextManager cm = context.getContextManager();
   	URL urls[]=context.getClassPath();
  -	
  +
  +	DependManager dm=context.getDependManager();
  +	if( dm==null ) {
  +	    dm=new DependManager();
  +	    context.setDependManager( dm );
  +	}
   	URLClassLoader urlLoader=URLClassLoader.newInstance( urls );
  +	DependClassLoader dcl=new DependClassLoader( dm, urlLoader);
   
  -	context.setClassLoader( urlLoader );
  +	context.setClassLoader( dcl );
       }
   
  +    public void reload( Request req, Context context) throws TomcatException {
  +	log( "Reload event " );
  +	
  +	ContextManager cm = context.getContextManager();
  +	URL urls[]=context.getClassPath();
  +
  +	DependManager dm=new DependManager();
  +	context.setDependManager( dm );
  +
  +	URLClassLoader urlLoader=URLClassLoader.newInstance( urls );
  +	DependClassLoader dcl=new DependClassLoader( dm, urlLoader);
  +	
  +	context.setClassLoader( dcl );
  +    }
  +    
       private void getJars(Vector v, File f) {
           FilenameFilter jarfilter = new FilenameFilter() {
   		public boolean accept(File dir, String fname) {
  
  
  
  1.104     +42 -169   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.103
  retrieving revision 1.104
  diff -u -r1.103 -r1.104
  --- Context.java	2000/07/27 18:47:31	1.103
  +++ Context.java	2000/07/27 23:08:18	1.104
  @@ -62,6 +62,7 @@
   
   import org.apache.tomcat.context.*;
   import org.apache.tomcat.facade.*;
  +import org.apache.tomcat.depend.*;
   import org.apache.tomcat.util.*;
   import java.security.*;
   import java.lang.reflect.*;
  @@ -372,14 +373,20 @@
   	    // be able to access classloader and classpath
   	    
   	    if (name.equals("org.apache.tomcat.jsp_classpath")) {
  -		String cp= getServletLoader().getClassPath();
  -		return cp;
  +		String separator = System.getProperty("path.separator", ":");
  +		StringBuffer cpath=new StringBuffer();
  +		for(int i=0; i< classPath.size(); i++ ) {
  +		    URL cp = (URL)classPath.elementAt(i);
  +		    if (cpath.length()>0) cpath.append( separator );
  +		    cpath.append(cp.getFile());
  +		}
  +		return cpath.toString();
   	    }
   	    if( name.equals( "org.apache.tomcat.protection_domain") ) {
   		return getProtectionDomain();
   	    }
   	    if(name.equals("org.apache.tomcat.classloader")) {
  -		return this.getServletLoader().getClassLoader();
  +		return this.getClassLoader();
   	    }
   	    if( name.equals(FacadeManager.FACADE_ATTRIBUTE)) {
   		if( ! allowAttribute(name) ) return null;
  @@ -660,7 +667,7 @@
       boolean reload;
       // Vector<URL>, using URLClassLoader conventions
       Vector classPath=new Vector();
  -    
  +    DependManager dependM;
       
       /** The current class loader. This value may change if reload
        *  is used, you shouldn't cache the result
  @@ -680,6 +687,8 @@
       public boolean shouldReload() {
   	if( servletL!=null) // backward compat
   	    return servletL.shouldReload();
  +	if( dependM != null )
  +	    return dependM.shouldReload();
   	return reload;
       }
   
  @@ -690,6 +699,11 @@
       public void reload() {
   	if( servletL!=null) // backward compat
   	    servletL.reload();
  +	Enumeration sE=servlets.elements();
  +	while( sE.hasMoreElements() ) {
  +	    ServletWrapper sw=(ServletWrapper)sE.nextElement();
  +	    sw.reload();
  +	}
   	// XXX todo
       }
   
  @@ -705,15 +719,23 @@
   	}
   	return urls;
       }
  -	
  +
  +    public void setDependManager(DependManager dm ) {
  +	dependM=dm;
  +    }
  +
  +    public DependManager getDependManager( ) {
  +	return dependM;
  +    }
  +    
       // deprecated
  -    private ServletLoader servletL;
  +    private org.apache.tomcat.loader.AdaptiveServletLoader servletL;
   
  -    public void setServletLoader(ServletLoader loader ) {
  +    public void setServletLoader(org.apache.tomcat.loader.AdaptiveServletLoader loader ) {
   	this.servletL=loader;
       }
   
  -    private ServletLoader getServletLoader() {
  +    private org.apache.tomcat.loader.AdaptiveServletLoader getServletLoader() {
   	return servletL;
       }
   
  @@ -869,63 +891,10 @@
   
       // -------------------- Deprecated
       // tomcat specific properties
  -    private boolean isWorkDirPersistent = false;
       private String engineHeader = null;
  -    private URL documentBase;
  -    private URL servletBase = null;
  -    private boolean isInvokerEnabled = false;
  -    // for serving WARs directly
  -    private File warDir = null;
  -    private boolean isWARExpanded = false;
  -    private boolean isWARValidated = false;
  -
  -
  -
  -    /**  @deprecated
  -     */
  -    public boolean isInvokerEnabled() {
  -        return isInvokerEnabled;
  -    }
   
       /**  @deprecated
        */
  -    public void setInvokerEnabled(boolean isInvokerEnabled) {
  -        this.isInvokerEnabled = isInvokerEnabled;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public boolean isWorkDirPersistent() {
  -        return this.isWorkDirPersistent;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public void setWorkDirPersistent( boolean b ) {
  -	isWorkDirPersistent=b;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public File getWorkDir() {
  -	return workDir;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public void setWorkDir(File workDir) {
  -	this.workDir = workDir;
  -    }
  -
  -    /** Set work dir using a String property
  -     *  @deprecated
  -     */
  -    public void setWorkDirPath(String workDir) {
  -	this.workDir=new File(workDir);
  -    }
  -
  -    /**  @deprecated
  -     */
       public String getEngineHeader() {
   	return engineHeader;
       }
  @@ -936,81 +905,29 @@
           engineHeader=s;
       }
   
  -//     /**  @deprecated
  -//      */
  -//     public void setRequestSecurityProvider(RequestSecurityProvider rsProvider) {
  -// 	this.rsProvider = rsProvider;
  -//     }
  -
  -//     /**  @deprecated
  -//      */
  -//     public RequestSecurityProvider getRequestSecurityProvider() {
  -// 	return this.rsProvider;
  -//     }
  -
  -    /**  @deprecated
  -     */
  -    public File getWARDir() {
  -        return this.warDir;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public void setWARDir( File f ) {
  -	warDir=f;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public boolean isWARExpanded() {
  -        return this.isWARExpanded;
  -    }
  -
       /**  @deprecated
        */
  -    public void setIsWARExpanded(boolean isWARExpanded) {
  -        this.isWARExpanded = isWARExpanded;
  -    }
  -
  -    /**  @deprecated
  -     */
  -    public boolean isWARValidated() {
  -        return this.isWARValidated;
  +    public File getWorkDir() {
  +	return workDir;
       }
   
       /**  @deprecated
        */
  -    public void setIsWARValidated(boolean isWARValidated) {
  -        this.isWARValidated = isWARValidated;
  +    public void setWorkDir(File workDir) {
  +	this.workDir = workDir;
       }
   
  -    /**  @deprecated
  -     */
  -    public void addContextInterceptor( ContextInterceptor ci) {
  -	getContainer().addContextInterceptor(ci);
  +    
  +    public Object getProtectionDomain() {
  +	return protectionDomain;
       }
   
  -    /** @deprecated
  -     */
  -     public ContextInterceptor[] getContextInterceptors() {
  -	 return getContainer().getContextInterceptors();
  -     }
  -
  -    /**  @deprecated
  -     */
  -    public void addRequestInterceptor( RequestInterceptor ci) {
  -	getContainer().addRequestInterceptor(ci);
  +    public void setProtectionDomain(Object o) {
  +	protectionDomain=o;
       }
   
  -    /** @deprecated
  -     */
  -    public RequestInterceptor[] getRequestInterceptors() {
  -	return getContainer().getRequestInterceptors();
  -    }
  - 
  -     /**
  +    /**
         * Get the SecurityManager Permissions for this Context.
  -      *@deprecated Included in PD
         */
       public Object getPermissions() {
   	return perms;
  @@ -1019,53 +936,9 @@
       public void setPermissions( Object o ) {
   	perms=o;
       }
  -    
  -    public Object getProtectionDomain() {
  -	return protectionDomain;
  -    }
  -
  -    public void setProtectionDomain(Object o) {
  -	protectionDomain=o;
  -    }
  -
   
  -    /** @deprecated - use getDocBase and URLUtil if you need it as URL
  -     *  NOT USED INSIDE TOMCAT - ONLY IN OLD J2EE CONNECTORS !
  -     */
  -    public URL getDocumentBase() {
  -	if( documentBase == null ) {
  -	    if( docBase == null)
  -		return null;
  -	    try {
  -		String absPath=docBase;
  -
  -		// detect absolute path ( use the same logic in all tomcat )
  -		if (FileUtil.isAbsolute( docBase ) )
  -		    absPath=docBase;
  -	        else
  -		    absPath = contextM.getHome() + File.separator + docBase;
  -
  -		try {
  -		    absPath = new File(absPath).getCanonicalPath();
  -		} catch (IOException npe) {
  -		}
  -
  -		documentBase = new URL("file", "", absPath);
  -
  -	    } catch( MalformedURLException ex ) {
  -		log("bad URL " + absPath, ex);
  -	    }
  -	}
  -        return documentBase;
  -    }
  -
  -    /** @deprecated - use setDocBase
  -     */
  -    public void setDocumentBase(URL s) {
  -	// Used only by startup, will be removed
  -        this.documentBase=s;
  -    }
  -
  +    // -------------------- Virtual host support --------------------
  +    
       /** Make this context visible as part of a virtual host
        */
       public void setHost( String h ) {
  
  
  
  1.105     +3 -1      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.104
  retrieving revision 1.105
  diff -u -r1.104 -r1.105
  --- ContextManager.java	2000/07/27 18:40:57	1.104
  +++ ContextManager.java	2000/07/27 23:08:18	1.105
  @@ -514,7 +514,9 @@
   	contextsV.removeElement(context);
       }
   
  -    void doReload( Request req, Context context ) throws TomcatException {
  +    public void doReload( Request req, Context context )
  +	throws TomcatException
  +    {
   	if( context==null ) return;
   
   	if( debug>0 ) log( "Reloading context " + context.toString());
  
  
  
  1.64      +19 -6     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.63
  retrieving revision 1.64
  diff -u -r1.63 -r1.64
  --- ServletWrapper.java	2000/07/27 18:47:32	1.63
  +++ ServletWrapper.java	2000/07/27 23:08:18	1.64
  @@ -175,6 +175,19 @@
   	initialized=false;
       }
   
  +    public void reload() {
  +	if( initialized ) {
  +	    try {
  +		destroy();
  +	    } catch(Exception ex ) {
  +		log( "Error in destroy ", ex );
  +	    }
  +	}
  +	servlet=null;
  +	servletClass=null;
  +	initialized=false;
  +    }
  +    
       /** Security Role Ref represent a mapping between servlet role names and
        *  server roles
        */
  @@ -326,12 +339,12 @@
       */
       public void service(Request req, Response res) 
       {
  -	try {
  -	    handleReload(req);
  -	} catch( TomcatException ex ) {
  -	    // what to do ?
  -	    log("in handleReload request=" + req, ex);
  -	}
  +// 	try {
  +// 	    handleReload(req);
  +// 	} catch( TomcatException ex ) {
  +// 	    // what to do ?
  +// 	    log("in handleReload request=" + req, ex);
  +// 	}
   
   	// <servlet><jsp-file> case
   	if( path!=null ) {
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/depend/DependClassLoader.java
  
  Index: DependClassLoader.java
  ===================================================================
  /*
   * Copyright (c) 1997-1999 The Java Apache Project.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and 
   *    "Java Apache Project" must not be used to endorse or promote products 
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without 
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *    
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  package org.apache.tomcat.depend;
  
  import java.io.*;
  import java.lang.*;
  import java.net.*;
  import java.text.*;
  import java.util.*;
  import java.util.zip.*;
  import java.security.*;
  
  /**
   * This is a wrapper class loader that will delegate all calls to
   * the parent. It will also generate events for every loaded class,
   * for use in maintaining dependencies.
   *
   * In order to keep this generic we'll use findResource() to find the
   * source of the class, and then forward to the class loader - that
   * means we duplicate the search operation.
   * 
   * Class loading happens only once per request, and this will have probably
   * little effect.
   * Also, the alternative is to use custom class loaders - there are many
   * reasons to avoid this.
   *
   * In "production" sites reloading should be turned off anyway, so the
   * class loader will not be "wrapped"
   * 
   */
  public class DependClassLoader extends ClassLoader {
      protected ClassLoader parent;
      final static int debug=10;
      DependManager dependM;
  
      public DependClassLoader( DependManager depM, ClassLoader parent ) {
  	super(); // will check permissions 
  	this.parent=parent;
  	dependM=depM;
      }
  
      // debug only 
      final void log( String s ) {
  	System.out.println("DependClassLoader: " + s );
      }
  
      /**
       * Resolves the specified name to a Class. The method loadClass()
       * is called by the virtual machine.  As an abstract method,
       * loadClass() must be defined in a subclass of ClassLoader.
       *
       * @param      name the name of the desired Class.
       * @param      resolve true if the Class needs to be resolved;
       *             false if the virtual machine just wants to determine
       *             whether the class exists or not
       * @return     the resulting Class.
       * @exception  ClassNotFoundException  if the class loader cannot
       *             find a the requested class.
       */
      protected synchronized Class loadClass(String name, boolean resolve)
          throws ClassNotFoundException
      {
          if( debug>0) log( "loadClass() " + name + " " + resolve);
  	// The class object that will be returned.
          Class c = null;
  
  	// check if  we already loaded this class
  	c = findLoadedClass( name );
  	if (c!= null ) {
  	    if(resolve) resolveClass(c);
  	    return c;
          }
          String classFileName = name.replace('.', '/' ) + ".class";
  
  	URL res=getResource( classFileName );
  	if( res==null ) {
  	    if( debug >0  )  log( "Resource not found !!! " + name + " " + classFileName);
  	}
  	
  	try {
  	    c = parent.loadClass(name);
  	    if (c != null) {
  		if (resolve) resolveClass(c);
  		dependency( c, res );
  		return c;
  	    }
  	} catch (Exception e) {
  	    c = null;
  	}
  
          throw new ClassNotFoundException(name);
      }
  
      public URL getResource(String name) {
  	return parent.getResource(name);
      }
  
      public InputStream getResourceAsStream(String name) {
  	return parent.getResourceAsStream( name );
      }
  
      private void dependency( Class c, URL res ) {
  	if( res==null) return;
  	File f=null;
  	if( "file".equals( res.getProtocol() )) {
  	    f=new File( res.getFile());
  	    if( debug > 0 ) log( "File dep "  +f );
  	    if( ! f.exists()) f=null;
  	}
  	if( "jar".equals( res.getProtocol() )) {
  	    String fileN=res.getFile();
  	    int idx=fileN.indexOf( "!" );
  	    if( idx>=0 )
  		fileN=fileN.substring( 0, idx) ;
  	    f=new File( fileN );
  	    if( debug > 0 ) log( "Jar dep "  +f );
  	    if( ! f.exists()) f=null;
  	}
  
  	if( f==null ) return;
  	Dependency dep=new Dependency();
  	dep.setLastModified( System.currentTimeMillis() );
  	dep.setTarget( c );
  	dep.setOrigin( f );
  	
  	dependM.addDependency( dep );
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/depend/DependManager.java
  
  Index: DependManager.java
  ===================================================================
  /*
   * Copyright (c) 1997-1999 The Java Apache Project.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and 
   *    "Java Apache Project" must not be used to endorse or promote products 
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without 
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *    
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  package org.apache.tomcat.depend;
  
  import java.io.*;
  import java.lang.*;
  import java.net.*;
  import java.text.*;
  import java.util.*;
  import java.util.zip.*;
  import java.security.*;
  
  /** How it works:
      - A DependManager gets loaded with a number of Dependency
      - each Dependency includes a File and a timestamp.
      - If any of the Files is changed after timestamp this DependManager
      will set "expired" to true
      - One check at a time, but without sync
      - if a check was done recently ( delay property ) - assume nothing changed
  
      It is also possible to do the checks in background, but for big
      servers ( with many contexts) it have scalability problems.
   */
  public class DependManager {
      int delay=4000;
      Dependency deps[]=new Dependency[32];
      int depsCount=0;
      long lastCheck=0;
      boolean checking=false;
      long checkTime=0;
      int checkCount=0;
  
      boolean expired=false;
      
      public DependManager() {
      }
  
      public void setDelay( int d ) {
  	delay=d;
      }
  
      // statistics
      public long getCheckTime() {
  	return checkTime;
      }
  
      public long getCheckCount() {
  	return checkCount;
      }
      
      // Not synchronized - we do that inside
      public boolean shouldReload() {
  	// somebody else is checking, so we don't know yet.
  	// assume we're fine - reduce the need for sync
  	if( checking ) return expired;
  
  	synchronized(this) {
  	    try {
  		// someone else got here and did it before me
  		if( checking ) return expired;
  			
  		// did a check in the last N seconds
  		long startCheck=System.currentTimeMillis();
  		if( startCheck - lastCheck < delay )
  		    return expired;
  		
  		checking=true;
  
  		// it's ok if a new dep is added - this is not
  		//exact science ( and no dep can be removed)
  		for( int i=0; i<depsCount; i++ ) {
  		    Dependency d=deps[i];
  		    long lm=d.getLastModified();
  		    File f=d.getOrigin();
  		    if( lm < f.lastModified() ) {
  			// something got modified
  			expired=true;
  		    }
  		}
  		checkTime += lastCheck-startCheck;
  		checkCount++;
  		lastCheck=startCheck;
  	    } finally {
  		checking=false;
  	    }
  	    return expired;
  	}
      }
  
      public synchronized void addDependency( Dependency dep ) {
  	if( depsCount >= deps.length ) {
  	    Dependency deps1[]=new Dependency[ deps.length *2 ];
  	    System.arraycopy( deps, 0, deps1, 0 , depsCount );
  	    deps=deps1;
  	}
  	deps[depsCount++]= dep ;
  	if( debug>2) log( "Added " + dep.getOrigin() + " " + dep.getTarget());
      }
      
      // -------------------- Private 
  
      private static final int debug=10;
      
      void log( String s ) {
  	System.out.println("DependManager: " + s );
      }
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/depend/Dependency.java
  
  Index: Dependency.java
  ===================================================================
  /*
   * Copyright (c) 1997-1999 The Java Apache Project.  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. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and 
   *    "Java Apache Project" must not be used to endorse or promote products 
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without 
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *    
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "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 JAVA APACHE PROJECT 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 Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  package org.apache.tomcat.depend;
  
  import java.io.*;
  import java.lang.*;
  import java.net.*;
  import java.text.*;
  import java.util.*;
  import java.util.zip.*;
  import java.security.*;
  
  /**
   */
  public class Dependency {
  
  
      public Dependency() {
      }
  
      long lastModified;
      
      /**
       * Get the value of lastModified.
       * @return Value of lastModified.
       */
      public long getLastModified() {return lastModified;}
      
      /**
       * Set the value of lastModified.
       * @param v  Value to assign to lastModified.
       */
      public void setLastModified(long  v) {this.lastModified = v;}
  
      
      File origin;
      
      /**
         * Get the value of origin.
         * @return Value of origin.
         */
      public File getOrigin() {return origin;}
      
      /**
         * Set the value of origin.
         * @param v  Value to assign to origin.
         */
      public void setOrigin(File  v) {this.origin = v;}
      
      Object target;
      
      /**
         * Get the value of target.
         * @return Value of target.
         */
      public Object getTarget() {return target;}
      
      /**
         * Set the value of target.
         * @param v  Value to assign to target.
         */
      public void setTarget(Object  v) {this.target = v;}
      
  
  }
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/depend/package.html
  
  Index: package.html
  ===================================================================
  <h2>org.apache.tomcat.depend</h2>
  
  This package will implement a (generic) dependency manager that
  can be used in tomcat or other projects that need to maintain 
  a list of dependencies.
  
  
  1.10      +1 -1      jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveServletLoader.java
  
  Index: AdaptiveServletLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveServletLoader.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- AdaptiveServletLoader.java	2000/07/27 18:47:35	1.9
  +++ AdaptiveServletLoader.java	2000/07/27 23:08:20	1.10
  @@ -73,7 +73,7 @@
    * @deprecated No longer needed.
    */
   public class AdaptiveServletLoader  extends AdaptiveClassLoader
  -    implements ServletLoader
  +    //    implements ServletLoader
   {
       AdaptiveClassLoader classL;
       static boolean jdk12=false;
  
  
  
  1.1                  jakarta-tomcat/src/share/org/apache/tomcat/request/ReloadInterceptor.java
  
  Index: ReloadInterceptor.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.request;
  
  import org.apache.tomcat.core.*;
  import org.apache.tomcat.util.*;
  import java.io.*;
  import java.net.*;
  import java.util.*;
  
  /**
   * This interceptor deals with context reloading.
   *  This should be "AT_END" - just after the context is mapped, it
   *  will determine if the context needs reload.
   *
   */
  public class ReloadInterceptor extends  BaseInterceptor
  {
      public ReloadInterceptor() {
      }
  
      public int contextMap( Request request ) {
  	Context ctx=request.getContext();
  	if( ctx==null) return 0;
  	
  	// XXX This interceptor will be added per/context.
  	if( ! ctx.getReloadable() ) return 0;
  
  	if( ! ctx.shouldReload() ) return 0;
  
  	try {
  	    // Reload context.	
  	    ContextManager cm=ctx.getContextManager();
  	    ctx.reload();
  	    
  	    cm.doReload( request, ctx );
  	    
  
  	    // XXX XXX XXX
  	    // The right policy is ( IMHO ) to stop and start
  	    // the context. This way the requests that are executing
  	    // will finish, and all new requests will see a fresh new context.
  
  	    //	cm.removeContext( ctx );
  
  	} catch( TomcatException ex) {
  	    log( "Error reloading " + ex );
  	}
  	return 0;
      }
  }
  
  
  
  1.5       +3 -42     jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java
  
  Index: WARUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- WARUtil.java	2000/07/11 03:49:06	1.4
  +++ WARUtil.java	2000/07/27 23:08:20	1.5
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v 1.4 2000/07/11 03:49:06 alex Exp $
  - * $Revision: 1.4 $
  - * $Date: 2000/07/11 03:49:06 $
  + * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/util/WARUtil.java,v 1.5 2000/07/27 23:08:20 costin Exp $
  + * $Revision: 1.5 $
  + * $Date: 2000/07/27 23:08:20 $
    *
    * ====================================================================
    *
  @@ -134,43 +134,4 @@
   
           return s;
       }
  -
  -    
  -    /** Construct a URL from a base and a relative path
  -     */
  -    public static URL createURL( Context ctx, String mappedPath )
  -	throws MalformedURLException
  -    {
  -	// XXX need rework, we should remove war until we know better
  -	// or have an architecture for it
  -	URL docBase = ctx.getDocumentBase();
  -	URL url=null;
  -	if (ctx.isWARExpanded()) {
  -	    File f = new File(ctx.getWARDir().toString());
  -	    String absPath = f.getAbsolutePath();
  -	    
  -	    // take care of File.getAbsolutePath() troubles
  -	    // on jdk1.1.x/win
  -	    
  -	    absPath = FileUtil.patch(absPath);
  -	    
  -	    if (! absPath.startsWith("/")) {
  -		absPath = "/" + absPath;
  -	    }
  -	    
  -	    url = new URL("file://localhost" + absPath + "/" +
  -			  mappedPath);
  -	} else {
  -	    String documentBase = docBase.toString();
  -	    
  -	    if (documentBase.endsWith("/")) {
  -		documentBase = documentBase.substring(0,
  -						      documentBase.length() - 1);
  -	    }
  -	    
  -	    url = new URL(documentBase + "!" + mappedPath);
  -	}
  -	return url;
  -    }
  -    
   }