Annotation of java/classes/org/w3c/jigsaw/servlet/AutoReloadServletLoader.java, revision 1.1

1.1     ! bmahe       1: // AutoReloadServletLoader.java
        !             2: // $Id$
        !             3: // (c) COPYRIGHT MIT and INRIA, 1998.
        !             4: // Please first read the full copyright statement in file COPYRIGHT.html
        !             5:  
        !             6: package org.w3c.jigsaw.servlet;
        !             7: 
        !             8: import java.io.*;
        !             9: import java.net.*;
        !            10: import java.util.*;
        !            11: 
        !            12: class ServletClassEntry {
        !            13:   
        !            14:     long   classStamp   = 0;
        !            15:     Class  servletClass = null;
        !            16:     File   classFile    = null;
        !            17:     boolean systemClass = false;
        !            18: 
        !            19:     public boolean isModified() {
        !            20:        if (! systemClass)
        !            21:            return (classFile.lastModified() > classStamp);
        !            22:        return false;
        !            23:     }
        !            24: 
        !            25:     public void update() {
        !            26:        if (! systemClass)
        !            27:            classStamp   = classFile.lastModified();
        !            28:     }
        !            29: 
        !            30:     public ServletClassEntry(Class servletClass) {
        !            31:        this.servletClass = servletClass;
        !            32:        this.systemClass  = true;
        !            33:     }
        !            34: 
        !            35:     public ServletClassEntry (File classFile, 
        !            36:                              Class servletClass)
        !            37:     {
        !            38:        this.classFile    = classFile;
        !            39:        this.servletClass = servletClass;
        !            40:        if (classFile != null)
        !            41:            this.classStamp   = classFile.lastModified();
        !            42:        this.systemClass  =  false;
        !            43:     }
        !            44: 
        !            45: }
        !            46: 
        !            47: /**
        !            48:  * @version $Revision$
        !            49:  * @author  Benoît Mahé (bmahe@w3.org)
        !            50:  */
        !            51: public class AutoReloadServletLoader extends ClassLoader {
        !            52:     private static final boolean debug = false;
        !            53:     private Hashtable classes = null;
        !            54:     private int CLASSES_DEFAULT_SIZE = 13;
        !            55: 
        !            56:     JigsawServletContext context = null;
        !            57: 
        !            58:     private void trace(String msg) {
        !            59:        trace(msg,true);
        !            60:     }
        !            61: 
        !            62:     private void trace(String msg, boolean display) {
        !            63:        if (display)
        !            64:            System.out.println("["+context.getServletDirectory()+"]: "+msg);
        !            65:     }
        !            66: 
        !            67:     private String removeSpace(String string) {
        !            68:        int start = -1;
        !            69:        int end = string.length();
        !            70:        boolean spaces = false;
        !            71:        while (string.charAt(++start) == ' '){ spaces = true; };
        !            72:        while (string.charAt(--end) == ' '){ spaces = true; };
        !            73:        if (spaces)
        !            74:            return string.substring(start, ++end);
        !            75:        else
        !            76:            return new String(string);
        !            77:     }
        !            78: 
        !            79:     private String packaged(String name) {
        !            80:        String cname = removeSpace(name);
        !            81:        try {
        !            82:            if (cname.endsWith(".class")) {
        !            83:                int idx = cname.lastIndexOf('.');
        !            84:                if (idx != -1)
        !            85:                    cname = cname.substring(0,idx);
        !            86:            }
        !            87:            return cname.replace('.', '/')+".class";
        !            88:        } catch (Exception ex) {
        !            89:            return name;
        !            90:        }
        !            91:     }
        !            92: 
        !            93:     private String noext(String name) {
        !            94:        int idx = name.lastIndexOf(".class");
        !            95:        if (idx != -1) {
        !            96:            return name.substring(0,idx);
        !            97:        }
        !            98:        return name;
        !            99:     }
        !           100: 
        !           101:     protected boolean classChanged(String name) {
        !           102:        ServletClassEntry entry = (ServletClassEntry)classes.get(noext(name));
        !           103:        if (entry != null) {
        !           104:            if (debug) {
        !           105:                System.out.println("entry    : "+name);
        !           106:                if (!entry.systemClass) {
        !           107:                    System.out.println("file     : "+
        !           108:                                       entry.classFile.getAbsolutePath());
        !           109:                    System.out.println("Stamp    : "+entry.classStamp);
        !           110:                }
        !           111:                System.out.println("System   : "+entry.systemClass);
        !           112:                System.out.println("modified : "+entry.isModified());
        !           113:            }
        !           114:            return entry.isModified();
        !           115:        }
        !           116:        return false; //true
        !           117:     }
        !           118: 
        !           119:     protected final Class getCachedClass(String name, boolean resolve) 
        !           120:        throws ClassNotFoundException
        !           121:     {
        !           122:        ServletClassEntry entry = (ServletClassEntry)classes.get(noext(name));
        !           123:        if (entry != null) {
        !           124:            if (! entry.isModified()) {
        !           125:                trace(name+": not modified",debug);
        !           126:                return entry.servletClass;
        !           127:            } else if (! entry.systemClass) {
        !           128:                entry.servletClass =  loadClassFile(entry.classFile);
        !           129:                if ( resolve )
        !           130:                    resolveClass(entry.servletClass);
        !           131:                entry.update();
        !           132:                trace(name+": reloaded",debug);
        !           133:                return entry.servletClass;
        !           134:            }
        !           135:        }
        !           136:        return null;
        !           137:     }
        !           138: 
        !           139:     protected void checkPackageAccess(String name) {
        !           140:        SecurityManager s = System.getSecurityManager();
        !           141:        if ( s != null ) {
        !           142:            int i = name.lastIndexOf('.');
        !           143:            if ( i >= 0 )
        !           144:                s.checkPackageAccess(name.substring(0, i));
        !           145:        }
        !           146:     }
        !           147: 
        !           148:     /**
        !           149:      * Given the class name, return its File name.
        !           150:      * @param name The class to be loaded.
        !           151:      * @return The File for the class.
        !           152:      */
        !           153:     protected File locateClass(String name) {
        !           154:        File classfile = null;
        !           155:        File base = context.getServletDirectory();
        !           156:        String cname = null;
        !           157: 
        !           158:        cname = packaged(name);
        !           159:        classfile = new File(base, cname);
        !           160: 
        !           161:        if (classfile != null)
        !           162:            if (classfile.exists()) return classfile;
        !           163:     
        !           164:        return null;
        !           165:     }
        !           166: 
        !           167:     protected Class loadClassFile(File file) 
        !           168:        throws ClassNotFoundException
        !           169:     {
        !           170:        byte data[] = null;
        !           171:        if ( file == null )
        !           172:            throw new ClassNotFoundException("invalid servlet base");
        !           173:        trace("located at "+file,debug);
        !           174:        try {
        !           175:            BufferedInputStream in      = 
        !           176:                new BufferedInputStream( new FileInputStream( file) );
        !           177:            ByteArrayOutputStream out   = new ByteArrayOutputStream(512);
        !           178:            byte                  buf[] = new byte[512];
        !           179:            for (int got = 0 ; (got = in.read(buf)) > 0 ; )
        !           180:                out.write(buf, 0, got);
        !           181:            data = out.toByteArray();
        !           182:            in.close();
        !           183:        } catch (Exception ex) {
        !           184:            if (debug) 
        !           185:                ex.printStackTrace();
        !           186:            throw new ClassNotFoundException(file.getAbsolutePath());
        !           187:        }
        !           188:        // Define the class:
        !           189:        return defineClass(data, 0, data.length);
        !           190:     }
        !           191: 
        !           192:     protected final Class getNewClass(File classfile, 
        !           193:                                      String name, 
        !           194:                                      boolean resolve) 
        !           195:        throws ClassNotFoundException
        !           196:     {
        !           197:        Class c = null;
        !           198:        c       = loadClassFile(classfile);
        !           199:        if ( resolve )
        !           200:            resolveClass(c);
        !           201:        classes.put(noext(name), new ServletClassEntry(classfile,c));
        !           202:        trace(name+": loading new class done.",debug);
        !           203:        return c;
        !           204:     }
        !           205:     
        !           206:     protected Class loadClass(String name, boolean resolve)
        !           207:        throws ClassNotFoundException
        !           208:     {
        !           209:        Class c = null;
        !           210:        trace(name+": loading class",debug);
        !           211:        // Look for a cached class first:
        !           212:        c = getCachedClass(name,resolve);
        !           213:        if (c != null) return c;
        !           214: 
        !           215:        checkPackageAccess(name);
        !           216:        
        !           217:        File  file    = locateClass(name);
        !           218: 
        !           219:        if (file == null) {
        !           220:            // Then look for a system class:
        !           221:            try {
        !           222:                if ((c = findSystemClass(name)) != null) {
        !           223:                    trace(name+": system class",debug);
        !           224:                    classes.put(noext(name), new ServletClassEntry(c));
        !           225:                    return c;
        !           226:                } else 
        !           227:                    throw new ClassNotFoundException(name);
        !           228:            } catch (Exception ex) {
        !           229:                throw new ClassNotFoundException(name);
        !           230:            }
        !           231:        }
        !           232:        
        !           233:        // load the class
        !           234:        return getNewClass(file,name,resolve);
        !           235:     }
        !           236: 
        !           237:     protected AutoReloadServletLoader(AutoReloadServletLoader loader) {
        !           238:        super();
        !           239:        this.context = loader.context;
        !           240:        //int classesSize = loader.classes.size();
        !           241:        //if (classesSize < CLASSES_DEFAULT_SIZE ) 
        !           242:        //classesSize = CLASSES_DEFAULT_SIZE;
        !           243:        //this.classes = new Hashtable(classesSize);
        !           244:        this.classes = loader.classes;
        !           245:     }
        !           246: 
        !           247:     protected AutoReloadServletLoader(JigsawServletContext context) {
        !           248:        super();
        !           249:        this.context = context;
        !           250:        this.classes = new Hashtable(CLASSES_DEFAULT_SIZE);
        !           251:     }
        !           252: }

Webmaster