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