Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / jigsaw / servlet / AutoReloadServletLoader.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/servlet/AutoReloadServletLoader.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/jigsaw/servlet/AutoReloadServletLoader.java
new file mode 100644 (file)
index 0000000..06262f6
--- /dev/null
@@ -0,0 +1,328 @@
+// AutoReloadServletLoader.java\r
+// $Id: AutoReloadServletLoader.java,v 1.1 2010/06/15 12:24:14 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1998.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.jigsaw.servlet;\r
+\r
+import java.io.BufferedInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FilterInputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.PrintStream;\r
+\r
+import java.net.MalformedURLException;\r
+import java.net.URL;\r
+import java.net.URLConnection;\r
+\r
+import java.util.Hashtable;\r
+\r
+class ServletClassEntry {\r
+\r
+    long   classStamp   = 0;\r
+    Class  servletClass = null;\r
+    File   classFile    = null;\r
+    boolean systemClass = false;\r
+\r
+    public boolean isModified() {\r
+       if (! systemClass)\r
+           return (classFile.lastModified() > classStamp);\r
+       return false;\r
+    }\r
+\r
+    public void update() {\r
+       if (! systemClass)\r
+           classStamp   = classFile.lastModified();\r
+    }\r
+\r
+    public ServletClassEntry(Class servletClass) {\r
+       this.servletClass = servletClass;\r
+       this.systemClass  = true;\r
+    }\r
+\r
+    public ServletClassEntry (File classFile, \r
+                             Class servletClass)\r
+    {\r
+       this.classFile    = classFile;\r
+       this.servletClass = servletClass;\r
+       if (classFile != null)\r
+           this.classStamp   = classFile.lastModified();\r
+       this.systemClass  =  false;\r
+    }\r
+\r
+}\r
+\r
+/**\r
+ * @version $Revision: 1.1 $\r
+ * @author  Benoît Mahé (bmahe@w3.org)\r
+ */\r
+public class AutoReloadServletLoader extends ClassLoader {\r
+    private static final boolean debug = false;\r
+    private Hashtable classes = null;\r
+    private int CLASSES_DEFAULT_SIZE = 13;\r
+\r
+    JigsawServletContext context = null;\r
+\r
+    private void trace(String msg) {\r
+       trace(msg,true);\r
+    }\r
+\r
+    private void trace(String msg, boolean display) {\r
+       if (display)\r
+           System.out.println("["+context.getServletDirectory()+"]: "+msg);\r
+    }\r
+\r
+    private String removeSpace(String string) {\r
+       int start = -1;\r
+       int end = string.length();\r
+       boolean spaces = false;\r
+       while (string.charAt(++start) == ' '){ spaces = true; };\r
+       while (string.charAt(--end) == ' '){ spaces = true; };\r
+       if (spaces)\r
+           return string.substring(start, ++end);\r
+       else\r
+           return new String(string);\r
+    }\r
+\r
+    private String packaged(String name) {\r
+       String cname = removeSpace(name);\r
+       try {\r
+           if (cname.endsWith(".class")) {\r
+               int idx = cname.lastIndexOf('.');\r
+               if (idx != -1)\r
+                   cname = cname.substring(0,idx);\r
+           }\r
+           return cname.replace('.', '/')+".class";\r
+       } catch (Exception ex) {\r
+           return name;\r
+       }\r
+    }\r
+\r
+    private String noext(String name) {\r
+       int idx = name.lastIndexOf(".class");\r
+       if ((idx != -1) && \r
+           ((idx+6 == name.length()) || \r
+            (Character.isWhitespace(name.charAt(idx+6)))))\r
+       {\r
+           return name.substring(0,idx);\r
+       }\r
+       return name;\r
+    }\r
+\r
+    protected boolean classChanged(String name) {\r
+       ServletClassEntry entry = (ServletClassEntry)classes.get(noext(name));\r
+       if (entry != null) {\r
+           if (debug) {\r
+               System.out.println("entry    : "+name);\r
+               if (!entry.systemClass) {\r
+                   System.out.println("file     : "+\r
+                                      entry.classFile.getAbsolutePath());\r
+                   System.out.println("Stamp    : "+entry.classStamp);\r
+               }\r
+               System.out.println("System   : "+entry.systemClass);\r
+               System.out.println("modified : "+entry.isModified());\r
+           }\r
+           return entry.isModified();\r
+       }\r
+       return false; //true\r
+    }\r
+\r
+    /**\r
+     * Get a cached class.\r
+     * @return a Class instance\r
+     * @exception ClassNotFoundException if the Class can't be found\r
+     */\r
+    protected final Class getCachedClass(String name, boolean resolve) \r
+       throws ClassNotFoundException\r
+    {\r
+       ServletClassEntry entry = (ServletClassEntry)classes.get(noext(name));\r
+       if (entry != null) {\r
+           if (! entry.isModified()) {\r
+               trace(name+": not modified",debug);\r
+               return entry.servletClass;\r
+           } else if (! entry.systemClass) {\r
+               entry.servletClass =  loadClassFile(entry.classFile);\r
+               if ( resolve )\r
+                   resolveClass(entry.servletClass);\r
+               entry.update();\r
+               trace(name+": reloaded",debug);\r
+               return entry.servletClass;\r
+           }\r
+       }\r
+       return null;\r
+    }\r
+\r
+    protected void checkPackageAccess(String name) {\r
+       SecurityManager s = System.getSecurityManager();\r
+       if ( s != null ) {\r
+           int i = name.lastIndexOf('.');\r
+           if ( i >= 0 )\r
+               s.checkPackageAccess(name.substring(0, i));\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Given the class name, return its File name.\r
+     * @param name The class to be loaded.\r
+     * @return The File for the class.\r
+     */\r
+    protected File locateClass(String name) {\r
+       File classfile = null;\r
+       File base = context.getServletDirectory();\r
+       String cname = null;\r
+\r
+       cname = packaged(name);\r
+       classfile = new File(base, cname);\r
+       if (classfile != null)\r
+           if (classfile.exists()) return classfile;\r
+\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Load a Class from its class file..\r
+     * @return a Class instance\r
+     * @exception ClassNotFoundException if the Class can't be found\r
+     */\r
+    protected Class loadClassFile(File file) \r
+       throws ClassNotFoundException\r
+    {\r
+       byte data[] = null;\r
+       if ( file == null )\r
+           throw new ClassNotFoundException("invalid servlet base");\r
+       trace("located at "+file,debug);\r
+       try {\r
+           BufferedInputStream in      = \r
+               new BufferedInputStream( new FileInputStream( file) );\r
+           ByteArrayOutputStream out   = new ByteArrayOutputStream(512);\r
+           byte                  buf[] = new byte[512];\r
+           for (int got = 0 ; (got = in.read(buf)) > 0 ; )\r
+               out.write(buf, 0, got);\r
+           data = out.toByteArray();\r
+           in.close();\r
+       } catch (Exception ex) {\r
+           if (debug) \r
+               ex.printStackTrace();\r
+           throw new ClassNotFoundException(file.getAbsolutePath());\r
+       }\r
+       // Define the class:\r
+       return defineClass(null, data, 0, data.length);\r
+    }\r
+\r
+    /**\r
+     * Get a new class.\r
+     * @return a Class instance\r
+     * @exception ClassNotFoundException if the Class can't be found\r
+     */\r
+    protected final Class getNewClass(File classfile, \r
+                                     String name, \r
+                                     boolean resolve) \r
+       throws ClassNotFoundException\r
+    {\r
+       Class c = null;\r
+       c       = loadClassFile(classfile);\r
+       if ( resolve )\r
+           resolveClass(c);\r
+       classes.put(noext(name), new ServletClassEntry(classfile,c));\r
+       trace(name+": loading new class done.",debug);\r
+       return c;\r
+    }\r
+\r
+    /**\r
+     * Load a class.\r
+     * @return a Class instance\r
+     * @exception ClassNotFoundException if the Class can't be found\r
+     */\r
+    protected Class loadClass(String name, boolean resolve)\r
+       throws ClassNotFoundException\r
+    {\r
+       Class c = null;\r
+       trace(name+": loading class",debug);\r
+       // Look for a cached class first:\r
+       c = getCachedClass(name,resolve);\r
+       if (c != null) {\r
+           return c;\r
+       }\r
+\r
+       synchronized (this) {\r
+           c = getCachedClass(name,resolve);\r
+           if (c != null) return c;\r
+\r
+           checkPackageAccess(name);\r
+           \r
+           File  file    = locateClass(name);\r
+           \r
+           if (file == null) {\r
+               // Then look for a system class:\r
+               try {\r
+                   String noext = noext(name);\r
+                   if ((c = findSystemClass(noext)) != null) {\r
+                       trace(name+": system class",debug);\r
+                       classes.put(noext, new ServletClassEntry(c));\r
+                       return c;\r
+                   } else \r
+                       throw new ClassNotFoundException(name);\r
+               } catch (Exception ex) {\r
+                   throw new ClassNotFoundException(name);\r
+               }\r
+           }\r
+           // load the class\r
+           return getNewClass(file,name,resolve);\r
+       }\r
+    }\r
+\r
+\r
+    public URL getResource(String name) {\r
+       URL resource = getSystemResource(name);\r
+       if (resource != null)\r
+           return resource;\r
+       String url = context.getServletDirectory().getAbsolutePath();\r
+       // Return the location of that resource (name resolved by j.l.Class)\r
+       if ( File.separatorChar != '/' )\r
+           url = url.replace(File.separatorChar, '/');\r
+       File file = new File(url,name);\r
+       if (! file.exists())\r
+           return null;\r
+       try {\r
+           return new URL("file", "localhost", url+"/"+name);\r
+       } catch (MalformedURLException ex) {\r
+           // Shouldn't fall here\r
+           return null;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * Get a resource as a stream.\r
+     * @param name The name of the resource to locate.\r
+     */\r
+\r
+    public InputStream getResourceAsStream(String name) {\r
+       InputStream in = getSystemResourceAsStream(name);\r
+       if (in != null) \r
+           return in;\r
+       URL resource = getResource(name);\r
+       if (resource == null)\r
+           return null;\r
+       try {\r
+           URLConnection c = resource.openConnection();\r
+           return c.getInputStream();\r
+       } catch (IOException ex) {\r
+           return null;\r
+       }\r
+    }\r
+\r
+    protected AutoReloadServletLoader(AutoReloadServletLoader loader) {\r
+       super();\r
+       this.context = loader.context;\r
+       this.classes = loader.classes;\r
+    }\r
+\r
+    protected AutoReloadServletLoader(JigsawServletContext context) {\r
+       super();\r
+       this.context = context;\r
+       this.classes = new Hashtable(CLASSES_DEFAULT_SIZE);\r
+    }\r
+}\r