www.pudn.com > d4j.zip > AppClassLoader.java


// AppClassLoader: Load an application class... 
// $Id: AppClassLoader.java,v 1.2 1999/02/04 17:53:10 tron Exp tron $ 
/*  
 * Copyright (c) 1999 Carlos G Mendioroz. 
 * 
 *  This file is part of D4J. 
 * 
 *  D4J is free software; you can redistribute it and/or 
 *  modify it under the terms of the GNU Lesser General Public 
 *  License as published by the Free Software Foundation; either 
 *  version 2 of the License, or (at your option) any later version. 
 *   
 *  D4J is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 *  Lesser General Public License for more details. 
 *   
 *  You should have received a copy of the GNU Lesser General Public 
 *  License along with this library; if not, write to the 
 *  Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 *  Boston, MA  02111-1307, USA. 
 * 
 * Report problems and direct all questions to: 
 * 
 *	tron@acm.org 
 */ 
 
import java.io.*; 
import java.util.*; 
import local.dialogic.*; 
 
public class AppClassLoader extends ClassLoader { 
  
    // Static "hash" is kept along a timestamp for the home/class 
    // to enable dynamic loading of changes... 
    static Hashtable cache = new Hashtable(); 
    static Hashtable timeStamp = new Hashtable(); 
     
    String home = "."; 
     
    public AppClassLoader(String homeDir) { 
        super(); 
        home = homeDir; 
    } 
 
    /** A convenience method that calls the 2-argument form of this method */ 
    public synchronized Class loadClass(String name) throws ClassNotFoundException {  
        return loadClass(name, true);  
    } 
 
    /** 
    * This is one abstract method of ClassLoader that all subclasses must 
    * define.  Its job is to load an array of bytes from somewhere and to 
    * pass them to defineClass().  If the resolve argument is true, it must 
    * also call resolveClass(), which will do things like verify the presence 
    * of the superclass.  Because of this second step, this method may be 
    * called to load superclasses that are system classes, and it must take  
    * this into account. 
    **/ 
    public Class loadClass(String classname, boolean resolve)  
                throws ClassNotFoundException { 
        Class result = null; 
             
        try { 
            String filename = home + File.separator + classname + ".class"; 
            // Create a File object.  Interpret the filename relative to the 
            // current directory 
            File file = new File(filename); 
            // Cope with 8.3 file names 
            if (!file.exists()) { 
                filename = home + File.separator + classname + ".cla"; 
                file = new File(filename); 
            } 
                
            if (file.isFile()) { 
                // Check file time with cached, if cached exists 
                result = (Class)cache.get(filename); 
                if (result != null) { 
                    long cachedTime =  
                        ((Long)timeStamp.get(filename)).longValue(); 
                    if (cachedTime == file.lastModified()) { 
                        return result; 
                    } 
                } 
                         
                // Get the length of the class file, allocate an array of bytes 
                // for it, and read it in all at once. 
                int length = (int) file.length(); 
                byte[] classbytes = new byte[length]; 
                DataInputStream in = new DataInputStream( 
                    new FileInputStream(file)); 
                in.readFully(classbytes); 
                in.close(); 
 
                // Now call an inherited method to convert those bytes 
                // into a Class 
                result = defineClass(classname, classbytes, 0, length); 
                cache.put(filename, result); 
                timeStamp.put(filename, new Long(file.lastModified())); 
            } else { 
                result = super.findSystemClass(classname); 
            } 
 
            if (result == null) { 
                throw new ClassNotFoundException(); 
            } 
                
            // If the resolve argument is true, call the inherited resolveClass 
            // method. 
            if (resolve) resolveClass(result); 
 
            // And we're done.  Return the Class object we've loaded. 
            return result; 
                
        } catch (IOException e) { 
            throw new ClassNotFoundException(e.toString()); 
        } 
    } 
}