Author: costin
Date: Fri Oct 14 23:45:43 2005
New Revision: 321300

URL: http://svn.apache.org/viewcvs?rev=321300&view=rev
Log:
More refactoring ( this package is not used in any existing code AFAIK,
please let me know if I'm wrong ). This code is based on tomcat loader,
but modified to make it more flexible and support reloading of tomcat
components.

Added:
    
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/RepositoryClassLoader.java
Modified:
    
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Loader.java
    
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Module.java
    
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/ModuleClassLoader.java
    
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Repository.java

Modified: 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Loader.java
URL: 
http://svn.apache.org/viewcvs/tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Loader.java?rev=321300&r1=321299&r2=321300&view=diff
==============================================================================
--- 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Loader.java 
(original)
+++ 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Loader.java 
Fri Oct 14 23:45:43 2005
@@ -854,7 +854,7 @@
     }
 
     void notifyModuleStop(Module module) {
-        listener.moduleStop(module);
+        if( listener!=null ) listener.moduleStop(module);
     }
     
     /** Add a module listener. 

Modified: 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Module.java
URL: 
http://svn.apache.org/viewcvs/tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Module.java?rev=321300&r1=321299&r2=321300&view=diff
==============================================================================
--- 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Module.java 
(original)
+++ 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Module.java 
Fri Oct 14 23:45:43 2005
@@ -167,6 +167,8 @@
                 ("Already started");
         started = true;
 
+        log("start()");
+
         // Construct a class loader based on our current repositories list
         try {
 

Modified: 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/ModuleClassLoader.java
URL: 
http://svn.apache.org/viewcvs/tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/ModuleClassLoader.java?rev=321300&r1=321299&r2=321300&view=diff
==============================================================================
--- 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/ModuleClassLoader.java
 (original)
+++ 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/ModuleClassLoader.java
 Fri Oct 14 23:45:43 2005
@@ -191,13 +191,16 @@
     }
     
     private boolean dirCheck(File dir ) {
-        log("Checking " + dir );
+        //log("Checking " + dir );
         File subd[]=dir.listFiles();
         for( int i=0; i< subd.length; i++ ) {
             long lm=subd[i].lastModified();
-            if( lm > lastModified ) return true;
+            if( lm > lastModified ) {
+                log("Modified file: " + dir + " " + subd[i] + " " + lm + " " + 
lastModified);
+                return true;
+            }
             if( subd[i].isDirectory() ) {
-                if( dirCheck(subd[i]) ) return true;
+                return  dirCheck(subd[i]);
             }
         }
         return false;
@@ -215,10 +218,13 @@
             for (int i = 0; i <cp.length; i++) {
                 File f=new File(cp[i].getFile());
                 long lm=f.lastModified();
-                if( lm > lastModified ) return true;
+                if( lm > lastModified ) {
+                    log( "Modified file: " + f + " " + lm + " " + 
lastModified);
+                    return true;
+                }
                 // assume dirs are used only for debug and small
                 if( f.isDirectory() ) {
-                    if( dirCheck(f) ) return true;
+                    return dirCheck(f);
                 }
             }
         }
@@ -242,7 +248,14 @@
      * @exception ClassNotFoundException if the class was not found
      */
     public Class findClass(String name) throws ClassNotFoundException {
-
+        return findClass2(name, true);
+    }
+    
+    public Class findClass2(String name, boolean del2repo) throws 
ClassNotFoundException {
+        if( del2repo ) {
+            return 
((RepositoryClassLoader)repository.getClassLoader()).findClass(name);           
 
+        } // else 
+ 
         Class clazz = null;
             
         try {
@@ -309,6 +322,13 @@
      * @param name Name of the resource to be found
      */
     public URL findResource(final String name) {
+        return findResource2( name, true);
+    }
+        
+    public URL findResource2(final String name, boolean del2repo ) {
+        if( del2repo ) {
+            return 
((RepositoryClassLoader)repository.getClassLoader()).findResource(name);
+        } // else:
 
         URL url = null;
 
@@ -339,18 +359,15 @@
      * @exception IOException if an input/output error occurs
      */
     public Enumeration findResources(String name) throws IOException {
-        Vector result=new Vector();
-        
-        Enumeration myRes=super.findResources(name);
-        if( myRes!=null ) {
-            while( myRes.hasMoreElements() ) {
-                result.addElement(myRes.nextElement());
-            }
+        return findResources2(name, true);
+    }
+    
+    Enumeration findResources2(String name, boolean del2repo) throws 
IOException {
+        if( del2repo ) {
+            return 
((RepositoryClassLoader)repository.getClassLoader()).findResources(name);
+        } else {
+            return super.findResources(name);
         }
-        // TODO: same in repository ( parent ? ) 
-        
-        return result.elements();
-
     }
 
     // Next methods implement the search alghoritm - parent, repo, delegation, 
etc 
@@ -359,6 +376,14 @@
      * 
      */
     public URL getResource(String name) {
+        return getResource2( name, null, true);
+    }
+
+    /** getResource() - same thing, but don't delegate to repo if called 
+     * from repo 
+     * 
+     */
+    URL getResource2(String name, ClassLoader originator, boolean 
delegate2repo ) {
 
         URL url = null;
 
@@ -379,7 +404,7 @@
 
         // Finally, try the group loaders ( via super() in StandardClassLoader 
).
         // not found using normal loading mechanism. load from one of the 
classes in the group
-        if( repository!=null ) {
+        if( delegate2repo && repository!=null ) {
             url=repository.findResource(this, name);
             if(url!=null ) {
                 if( DEBUG )
@@ -402,6 +427,7 @@
 
     }
 
+    
     // to avoid duplication - get resource from parent, when delegating
     private URL getResourceParentDelegate(String name) {
         URL url=null;
@@ -455,13 +481,20 @@
     public Class loadClass(String name, boolean resolve)
         throws ClassNotFoundException
     {
+        return loadClass2( name, resolve, true );
+    }
+    
+    public Class loadClass2(String name, boolean resolve, boolean del2repo)
+        throws ClassNotFoundException
+    {
 
         Class clazz = null;
 
         // Don't load classes if class loader is stopped
         if (!started) {
-            //log("Not started " + this + " " + module);
-            throw new ThreadDeath();
+            log("Not started " + this + " " + module);
+            //throw new ThreadDeath();
+            start();
         }
 
         // (0) Check our previously loaded local class cache
@@ -526,7 +559,7 @@
 
         // Finally, try the group loaders ( via super() in StandardClassLoader 
).
         // not found using normal loading mechanism. load from one of the 
classes in the group
-        if( repository!=null ) {
+        if( del2repo && repository!=null ) {
             Class cls=repository.findClass(this, name);
             if(cls!=null ) {
                 if( DEBUG )

Modified: 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Repository.java
URL: 
http://svn.apache.org/viewcvs/tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Repository.java?rev=321300&r1=321299&r2=321300&view=diff
==============================================================================
--- 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Repository.java
 (original)
+++ 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/Repository.java
 Fri Oct 14 23:45:43 2005
@@ -57,7 +57,7 @@
     private Vector grpModules=new Vector();
     private transient Loader loader;
     
-    private transient ModuleClassLoader groupClassLoader;
+    private transient RepositoryClassLoader groupClassLoader;
     private Hashtable prefixes=new Hashtable();
 
     // For delegation
@@ -119,14 +119,17 @@
         return grpModules.elements();
     }
     
+    /** Reload any module that is modified
+     */
     public void checkReload() {
         try {
         Enumeration mE=grpModules.elements();
         while( mE.hasMoreElements() ) {
             Module m=(Module)mE.nextElement();
-            log("Modified " + m + " " + m.modified());
+            boolean modif=m.modified();
+            log("Modified " + m + " " + modif);
             
-            if( m.modified() ) {
+            if( modif ) {
                 m.stop();
                 m.start();
             }
@@ -135,10 +138,44 @@
             t.printStackTrace();
         }
     }
+
+    /** Verify if any module is modified. This is a deep search, including 
dirs.
+     *  Expensive operation.
+     *  
+     * @return
+     */
+    public boolean isModified() {
+        try {
+            Enumeration mE=grpModules.elements();
+            while( mE.hasMoreElements() ) {
+                Module m=(Module)mE.nextElement();
+                boolean modif=m.modified();
+                log("Modified " + m + " " + modif);
+                if( modif ) return true;
+            }
+        } catch( Throwable t ) {
+            t.printStackTrace();
+        }
+        return false;
+    }
     
     Repository getParent() {
         return parent;
     }
+    
+    public String toString() {
+        return "Repository " + name + "(" + getClasspathString() + ")";
+    }
+
+    private String getClasspathString() {
+        StringBuffer sb=new StringBuffer();
+        Enumeration mE=grpModules.elements();
+        while( mE.hasMoreElements() ) {
+            Module m=(Module)mE.nextElement();
+            sb.append( m.getClasspathString() + ":");
+        }
+        return sb.toString();
+    }
 
     /**
      * 
@@ -195,6 +232,7 @@
      */
     public ClassLoader getClassLoader() {
         if( groupClassLoader==null ) {
+            
             ClassLoader pcl=parentClassLoader;
             if( pcl==null && parent!=null ) {
                 pcl=parent.getClassLoader();
@@ -205,13 +243,11 @@
 
             if( pcl == null ) {
                 // allow delegation to embedding app
-                groupClassLoader=new ModuleClassLoader(new URL[0]);
+                groupClassLoader=new RepositoryClassLoader(new URL[0], this);
             } else {
-                groupClassLoader=new ModuleClassLoader(new URL[0], pcl);
+                groupClassLoader=new RepositoryClassLoader(new URL[0], pcl, 
this);
             }
             if( DEBUG ) log("---------- Created repository loader " + pcl );
-            groupClassLoader.start();
-            groupClassLoader.setRepository(this);
         }
         return groupClassLoader;
     }

Added: 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/RepositoryClassLoader.java
URL: 
http://svn.apache.org/viewcvs/tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/RepositoryClassLoader.java?rev=321300&view=auto
==============================================================================
--- 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/RepositoryClassLoader.java
 (added)
+++ 
tomcat/connectors/trunk/util/loader/org/apache/tomcat/util/loader/RepositoryClassLoader.java
 Fri Oct 14 23:45:43 2005
@@ -0,0 +1,253 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package org.apache.tomcat.util.loader;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * Class loader associated with a repository ( common, shared, server, etc ). 
+ *
+ * This class loader will never load any class by itself ( since it has no 
repository ),
+ * it will just delegate to modules. 
+ * 
+ * Refactored as a separate class to make the code cleaner.
+ * Based on catalina loader.
+ *   
+ * @author Costin Manolache
+ * @author Remy Maucherat
+ * @author Craig R. McClanahan
+ */
+public class RepositoryClassLoader
+    extends URLClassLoader
+{
+    private static final boolean DEBUG=false; 
//LoaderProperties.getProperty("loader.debug.ModuleClassLoader") != null;
+    private static final boolean 
DEBUGNF=false;//LoaderProperties.getProperty("loader.debug.ModuleClassLoaderNF")
 != null;
+    
+    // ----------------------------------------------------------- Constructors
+
+    public RepositoryClassLoader(URL repositories[], ClassLoader parent, 
Repository lg) {
+        super(repositories, parent);
+        this.repository=lg;
+    }
+    
+
+    public RepositoryClassLoader(URL repositories[], Repository lg) {
+        super(repositories);
+        this.repository=lg;
+    }
+
+
+    // ----------------------------------------------------- Instance Variables
+
+    private Repository repository;
+
+    // ---------------------------------------------------- ClassLoader Methods
+
+
+    /**
+     * Find the specified class in our local repositories, if possible.  If
+     * not found, throw <code>ClassNotFoundException</code>.
+     *
+     * @param name Name of the class to be loaded
+     *
+     * @exception ClassNotFoundException if the class was not found
+     */
+    public Class findClass(String name) throws ClassNotFoundException {
+
+        Class clazz = null;
+        
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+            try {
+                Module m=(Module)modulesE.nextElement();
+                return 
((ModuleClassLoader)m.getClassLoader()).findClass2(name, false);
+            } catch( ClassNotFoundException ex ) {
+                // ignore
+            }
+        }
+        throw new ClassNotFoundException( name );
+
+    }
+    
+    /** Same as findClass, but also checks if the class has been previously 
+     * loaded.
+     * 
+     * In most implementations, findClass() doesn't check with 
findLoadedClass().
+     * In order to implement repository, we need to ask each loader in the 
group
+     * to load only from it's local resources - however this will lead to 
errors
+     * ( duplicated definition ) if findClass() is used.
+     *
+     * @param name
+     * @return
+     * @throws ClassNotFoundException
+     */
+    public Class findLocalClass(String name) throws ClassNotFoundException
+    {
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+            try {
+                Module m=(Module)modulesE.nextElement();
+                return 
((ModuleClassLoader)m.getClassLoader()).findLocalClass(name);
+            } catch( ClassNotFoundException ex ) {
+                // ignore
+            }
+        }
+        throw new ClassNotFoundException( name );
+    }
+
+
+
+    
+    /**
+     * Find the specified resource in our local repository, and return a
+     * <code>URL</code> refering to it, or <code>null</code> if this resource
+     * cannot be found.
+     *
+     * @param name Name of the resource to be found
+     */
+    public URL findResource(final String name) {
+        URL url = null;
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+                Module m=(Module)modulesE.nextElement();
+                
url=((ModuleClassLoader)m.getClassLoader()).findResource2(name, false);
+                if( url!= null ) {
+                    return url;
+                }
+        }
+        
+        if (url==null && DEBUG) {
+            if (DEBUGNF) log("findResource() NOTFOUND " + name );
+        }
+
+        return null;
+    }
+
+
+    /**
+     * Return an enumeration of <code>URLs</code> representing all of the
+     * resources with the given name.  If no resources with this name are
+     * found, return an empty enumeration.
+     *
+     * @param name Name of the resources to be found
+     *
+     * @exception IOException if an input/output error occurs
+     */
+    public Enumeration findResources(String name) throws IOException {
+        Vector result=new Vector();
+        
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+                Module m=(Module)modulesE.nextElement();
+                Enumeration 
myRes=((ModuleClassLoader)m.getClassLoader()).findResources2(name,false);
+                if( myRes!=null ) {
+                    while( myRes.hasMoreElements() ) {
+                        result.addElement(myRes.nextElement());
+                    }
+                }
+        }
+        
+        return result.elements();
+
+    }
+
+    // Next methods implement the search alghoritm - parent, repo, delegation, 
etc 
+
+    /** getResource() - modified to implement the search alghoritm 
+     * 
+     */
+    public URL getResource(String name) {
+        URL url = null;
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+                Module m=(Module)modulesE.nextElement();
+                url=((ModuleClassLoader)m.getClassLoader()).getResource2(name, 
null, false);
+                if( url!= null ) {
+                    return url;
+                }
+        }
+        
+        if (url==null && DEBUG) {
+            if (DEBUGNF) log("findResource() NOTFOUND " + name );
+        }
+
+        return null;
+    }
+    
+    /**
+     * Load the class with the specified name, searching using the following
+     * algorithm until it finds and returns the class.  If the class cannot
+     * be found, returns <code>ClassNotFoundException</code>.
+     * <ul>
+     * <li>Call <code>findLoadedClass(String)</code> to check if the
+     *     class has already been loaded.  If it has, the same
+     *     <code>Class</code> object is returned.</li>
+     * <li>If the <code>delegate</code> property is set to <code>true</code>,
+     *     call the <code>loadClass()</code> method of the parent class
+     *     loader, if any.</li>
+     * <li>Call <code>findClass()</code> to find this class in our locally
+     *     defined repositories.</li>
+     * <li>Call the <code>loadClass()</code> method of our parent
+     *     class loader, if any.</li>
+     * </ul>
+     * If the class was found using the above steps, and the
+     * <code>resolve</code> flag is <code>true</code>, this method will then
+     * call <code>resolveClass(Class)</code> on the resulting Class object.
+     *
+     * @param name Name of the class to be loaded
+     * @param resolve If <code>true</code> then resolve the class
+     *
+     * @exception ClassNotFoundException if the class was not found
+     */
+    public Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+
+        Class clazz = null;
+        Enumeration modulesE=repository.getModules();
+        while( modulesE.hasMoreElements() ) {
+            try {
+                Module m=(Module)modulesE.nextElement();
+                return 
((ModuleClassLoader)m.getClassLoader()).loadClass2(name, resolve, false);
+            } catch( ClassNotFoundException ex ) {
+                // ignore
+            }
+        }
+        throw new ClassNotFoundException( name );
+
+    }
+
+
+    // ------------------ Local methods ------------------------
+
+    private void log(String s ) {
+        System.err.println("RepositoryClassLoader: " + s);
+    }
+    private void log(String s, Throwable t ) {
+        System.err.println("RepositoryClassLoader: " + s);
+        t.printStackTrace();
+    }
+
+}
+



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to