home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 November / PCONLINE_11_99.ISO / filesbbs / OS2 / APCHSSL2.ZIP / OS2HTTPD / jserv / com / bitmechanic / gsp / GspClassLoader.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-02-03  |  10.3 KB  |  444 lines

  1. package com.bitmechanic.gsp;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. import java.net.MalformedURLException;
  9. import java.net.URL;
  10. import java.text.SimpleDateFormat;
  11. import java.util.Enumeration;
  12. import java.util.Hashtable;
  13. import java.util.Vector;
  14. import java.util.zip.ZipEntry;
  15. import java.util.zip.ZipFile;
  16.  
  17. public class GspClassLoader extends ClassLoader implements GspReloadingClassLoader {
  18.    private Hashtable currentClassloaders;
  19.    private Hashtable reloadableClasses;
  20.    private Vector classLoaders;
  21.    private static boolean debug;
  22.    private static boolean debugTracing;
  23.    private static ClassLoader parentLoader;
  24.    private Vector repository;
  25.    private static final SimpleDateFormat traceDateFormat = new SimpleDateFormat("[dd/MM/yyyy HH:mm:ss zz]");
  26.    public static int generationCounter;
  27.  
  28.    protected GspClassLoader() {
  29.       this.classLoaders = new Vector();
  30.       this.currentClassloaders = new Hashtable();
  31.    }
  32.  
  33.    public GspClassLoader(File var1) {
  34.       this(new File[]{var1});
  35.    }
  36.  
  37.    public GspClassLoader(File[] var1) {
  38.       this.currentClassloaders = new Hashtable();
  39.       this.reloadableClasses = new Hashtable();
  40.       this.classLoaders = new Vector();
  41.       parentLoader = this.getClass().getClassLoader();
  42.       GspInternalClassLoader var2 = new GspInternalClassLoader(this, this);
  43.       this.classLoaders.addElement(var2);
  44.       this.repository = new Vector(var1.length);
  45.  
  46.       for(int var3 = 0; var3 < var1.length; ++var3) {
  47.          File var4 = var1[var3];
  48.          if (!var4.exists()) {
  49.             throw new IllegalArgumentException("Repository " + var4.getAbsolutePath() + " doesn't exist!");
  50.          }
  51.  
  52.          if (!var4.canRead()) {
  53.             throw new IllegalArgumentException("Don't have read access for file " + var4.getAbsolutePath());
  54.          }
  55.  
  56.          if (!var4.isDirectory() && !var4.getName().endsWith(".jar") && !var4.getName().endsWith(".zip")) {
  57.             throw new IllegalArgumentException(var4.getAbsolutePath() + " is not a " + "directory or zip/jar file.");
  58.          }
  59.  
  60.          this.repository.addElement(var4);
  61.       }
  62.  
  63.    }
  64.  
  65.    private ClassCacheEntry getCurrentClassCacheEntry(String var1) {
  66.       GspInternalClassLoader var2 = this.getCurrentClassloader(var1);
  67.       return var2.getClassCacheEntry(var1);
  68.    }
  69.  
  70.    private Class getNewClass(String var1, byte[] var2, int var3, int var4, ClassCacheEntry var5) {
  71.       GspInternalClassLoader var6 = this.getNewClassloader(var1);
  72.       Class var7 = var6.defineClass(var1, var2, var3, var4, var5);
  73.       var5.loadedClass = var7;
  74.       return var7;
  75.    }
  76.  
  77.    private GspInternalClassLoader getCurrentClassloader(String var1) {
  78.       Integer var2 = (Integer)this.currentClassloaders.get(var1);
  79.       int var3 = 0;
  80.       if (var2 != null) {
  81.          var3 = var2;
  82.       }
  83.  
  84.       return (GspInternalClassLoader)this.classLoaders.elementAt(var3);
  85.    }
  86.  
  87.    private GspInternalClassLoader getNewClassloader(String var1) {
  88.       Integer var2 = (Integer)this.currentClassloaders.get(var1);
  89.       int var3 = -1;
  90.       if (var2 != null) {
  91.          var3 = var2;
  92.       }
  93.  
  94.       ++var3;
  95.       this.currentClassloaders.put(var1, new Integer(var3));
  96.       Vector var5 = this.classLoaders;
  97.       synchronized(var5){}
  98.  
  99.       GspInternalClassLoader var4;
  100.       try {
  101.          if (var3 >= this.classLoaders.size()) {
  102.             GspInternalClassLoader var7 = new GspInternalClassLoader(this, this);
  103.             this.classLoaders.addElement(var7);
  104.             var4 = var7;
  105.             return var4;
  106.          }
  107.  
  108.          var4 = (GspInternalClassLoader)this.classLoaders.elementAt(var3);
  109.       } catch (Throwable var9) {
  110.          throw var9;
  111.       }
  112.  
  113.       return var4;
  114.    }
  115.  
  116.    private void storeExternalClassDef(String var1, ClassCacheEntry var2) {
  117.       GspInternalClassLoader var3 = this.getCurrentClassloader(var1);
  118.       var3.storeExternalClassDef(var1, var2);
  119.    }
  120.  
  121.    protected synchronized boolean shouldReloadClass(ClassCacheEntry var1) {
  122.       if (var1.isSystemClass()) {
  123.          if (this.reloadableClasses.get(var1.loadedClass.getName()) != null) {
  124.             return true;
  125.          } else {
  126.             this.debugTrace(var1.loadedClass.getName() + " is from system : can't reload.");
  127.             return false;
  128.          }
  129.       } else {
  130.          return var1.origin.lastModified() > var1.lastModified;
  131.       }
  132.    }
  133.  
  134.    protected synchronized boolean shouldReload(String var1) {
  135.       ClassCacheEntry var2 = this.getCurrentClassCacheEntry(var1);
  136.       this.debugTrace("Should we reload " + var1 + "?");
  137.       if (var2 == null) {
  138.          this.debugTrace(var1 + " wasn't even loaded.");
  139.          return false;
  140.       } else {
  141.          boolean var3 = this.shouldReloadClass(var2);
  142.          this.debugTrace(var2.origin.lastModified() + " > " + var2.lastModified + " : " + (var3 ? " yes." : " no."));
  143.          return var3;
  144.       }
  145.    }
  146.  
  147.    private void trace(String var1) {
  148.       if (debug) {
  149.          System.err.println("gcl#" + Integer.toString(generationCounter) + ": " + var1);
  150.       }
  151.  
  152.    }
  153.  
  154.    private void debugTrace(String var1) {
  155.       if (debugTracing) {
  156.          System.err.println("gcl#" + Integer.toString(generationCounter) + ": " + var1);
  157.       }
  158.  
  159.    }
  160.  
  161.    public synchronized Class publicLoadClass(String var1, boolean var2) throws ClassNotFoundException {
  162.       return this.loadClass(var1, var2);
  163.    }
  164.  
  165.    protected synchronized Class loadClass(String var1, boolean var2) throws ClassNotFoundException {
  166.       Class var3 = null;
  167.       this.debugTrace("Asked to load " + var1);
  168.       ClassCacheEntry var4 = this.getCurrentClassCacheEntry(var1);
  169.       if (var4 != null && var4.loadedClass != null) {
  170.          var3 = var4.loadedClass;
  171.          this.debugTrace("Loaded class " + var1 + " from cache.");
  172.          if (var2) {
  173.             ((ClassLoader)this).resolveClass(var3);
  174.          }
  175.  
  176.          if (!this.shouldReloadClass(var4)) {
  177.             return var3;
  178.          }
  179.       }
  180.  
  181.       try {
  182.          if (this.reloadableClasses.get(var1) != null) {
  183.             var3 = this.reloadClass(var1, var2);
  184.          }
  185.       } catch (ClassNotFoundException var7) {
  186.          var3 = null;
  187.       }
  188.  
  189.       if (var3 != null) {
  190.          return var3;
  191.       } else {
  192.          try {
  193.             if (parentLoader != null) {
  194.                var3 = parentLoader.loadClass(var1);
  195.                if (var3 != null) {
  196.                   this.debugTrace("loaded from parent classloader:" + var1);
  197.                } else {
  198.                   this.debugTrace("couldn't load from parent classloader:" + var1);
  199.                }
  200.             } else {
  201.                var3 = this.loadSystemClass(var1, var2);
  202.                if (var3 != null) {
  203.                   this.debugTrace("loaded from system classloader:" + var1);
  204.                } else {
  205.                   this.debugTrace("couldn't load from system classloader:" + var1);
  206.                }
  207.             }
  208.  
  209.             if (var3 != null) {
  210.                ClassCacheEntry var5 = new ClassCacheEntry();
  211.                var5.origin = null;
  212.                var5.loadedClass = var3;
  213.                var5.lastModified = Long.MAX_VALUE;
  214.                this.storeExternalClassDef(var1, var5);
  215.                return var3;
  216.             }
  217.          } catch (ClassNotFoundException var6) {
  218.             this.debugTrace("class " + var1 + " not found by system/parent classloader");
  219.          }
  220.  
  221.          return this.reloadClass(var1, var2);
  222.       }
  223.    }
  224.  
  225.    public void setReloadClass(String var1) {
  226.       this.debugTrace("setting to reloadable: " + var1);
  227.       this.reloadableClasses.put(var1, "true");
  228.    }
  229.  
  230.    private Class reloadClass(String var1, boolean var2) throws ClassNotFoundException {
  231.       Enumeration var3 = this.repository.elements();
  232.       Object var4 = null;
  233.       ClassCacheEntry var5 = new ClassCacheEntry();
  234.  
  235.       while(var3.hasMoreElements()) {
  236.          File var7 = (File)var3.nextElement();
  237.  
  238.          byte[] var6;
  239.          try {
  240.             if (var7.isDirectory()) {
  241.                var6 = this.loadClassFromDirectory(var7, var1, var5);
  242.             } else {
  243.                var6 = this.loadClassFromZipfile(var7, var1, var5);
  244.             }
  245.          } catch (IOException var9) {
  246.             this.trace(((Throwable)var9).toString());
  247.             var6 = null;
  248.          }
  249.  
  250.          if (var6 != null) {
  251.             if (var7.isFile()) {
  252.                this.debugTrace("Loaded class " + var1 + " from zip file " + var7.getName());
  253.             } else {
  254.                this.debugTrace("Loaded class " + var1 + " from directory " + var7.getName());
  255.             }
  256.  
  257.             Class var10 = this.getNewClass(var1, var6, 0, var6.length, var5);
  258.             this.debugTrace("Defined class " + var1);
  259.             if (var2) {
  260.                ((ClassLoader)this).resolveClass(var10);
  261.                this.debugTrace("Resolved class " + var1);
  262.             }
  263.  
  264.             return var10;
  265.          }
  266.       }
  267.  
  268.       this.debugTrace(var1 + " not found in repository");
  269.       throw new ClassNotFoundException(var1 + " not found");
  270.    }
  271.  
  272.    private Class loadSystemClass(String var1, boolean var2) throws NoClassDefFoundError, ClassNotFoundException {
  273.       Class var3 = ((ClassLoader)this).findSystemClass(var1);
  274.       this.debugTrace("Loaded class " + var1 + " from system.");
  275.       if (var2) {
  276.          ((ClassLoader)this).resolveClass(var3);
  277.       }
  278.  
  279.       return var3;
  280.    }
  281.  
  282.    private boolean securityAllowsClass(String var1) {
  283.       try {
  284.          SecurityManager var2 = System.getSecurityManager();
  285.          if (var2 == null) {
  286.             return true;
  287.          } else {
  288.             int var3 = var1.lastIndexOf(46);
  289.             String var4 = var3 > -1 ? var1.substring(0, var3) : "";
  290.             var2.checkPackageDefinition(var4);
  291.             return true;
  292.          }
  293.       } catch (SecurityException var5) {
  294.          return false;
  295.       }
  296.    }
  297.  
  298.    private byte[] loadClassFromDirectory(File var1, String var2, ClassCacheEntry var3) throws IOException {
  299.       String var4 = var2.replace('.', File.separatorChar) + ".class";
  300.       if (!Character.isJavaIdentifierStart(var4.charAt(0))) {
  301.          int var5;
  302.          for(var5 = 1; !Character.isJavaIdentifierStart(var4.charAt(var5)); ++var5) {
  303.          }
  304.  
  305.          var4 = var4.substring(var5);
  306.       }
  307.  
  308.       File var12 = new File(var1, var4);
  309.       if (var12.exists()) {
  310.          var3.origin = var12;
  311.          FileInputStream var6 = new FileInputStream(var12);
  312.  
  313.          byte[] var7;
  314.          try {
  315.             var7 = this.loadBytesFromStream(var6, (int)var12.length());
  316.          } finally {
  317.             ((InputStream)var6).close();
  318.          }
  319.  
  320.          return var7;
  321.       } else {
  322.          return null;
  323.       }
  324.    }
  325.  
  326.    private byte[] loadClassFromZipfile(File var1, String var2, ClassCacheEntry var3) throws IOException {
  327.       String var4 = var2.replace('.', '/') + ".class";
  328.       ZipFile var5 = new ZipFile(var1);
  329.  
  330.       B var6;
  331.       try {
  332.          ZipEntry var9 = var5.getEntry(var4);
  333.          if (var9 == null) {
  334.             var6 = null;
  335.             return (byte[])var6;
  336.          }
  337.  
  338.          var3.origin = var1;
  339.          var6 = this.loadBytesFromStream(var5.getInputStream(var9), (int)var9.getSize());
  340.       } finally {
  341.          var5.close();
  342.       }
  343.  
  344.       return (byte[])var6;
  345.    }
  346.  
  347.    private byte[] loadBytesFromStream(InputStream var1, int var2) throws IOException {
  348.       byte[] var3 = new byte[var2];
  349.  
  350.       int var4;
  351.       for(int var5 = 0; var2 > 0 && (var4 = var1.read(var3, var5, var2)) != -1; var2 -= var4) {
  352.          var5 += var4;
  353.       }
  354.  
  355.       return var3;
  356.    }
  357.  
  358.    public InputStream getResourceAsStream(String var1) {
  359.       InputStream var2 = ClassLoader.getSystemResourceAsStream(var1);
  360.       if (var2 == null) {
  361.          Enumeration var3 = this.repository.elements();
  362.  
  363.          while(var3.hasMoreElements()) {
  364.             File var4 = (File)var3.nextElement();
  365.             if (var4.isDirectory()) {
  366.                var2 = this.loadResourceFromDirectory(var4, var1);
  367.             } else {
  368.                var2 = this.loadResourceFromZipfile(var4, var1);
  369.             }
  370.  
  371.             if (var2 != null) {
  372.                break;
  373.             }
  374.          }
  375.       } else {
  376.          this.debugTrace("Loaded resource " + var1 + " from system.");
  377.       }
  378.  
  379.       return var2;
  380.    }
  381.  
  382.    private InputStream loadResourceFromDirectory(File var1, String var2) {
  383.       String var3 = var2.replace('/', File.separatorChar);
  384.       File var4 = new File(var1, var3);
  385.       if (var4.exists()) {
  386.          try {
  387.             this.debugTrace("Loaded resource " + var2 + " from directory" + var1.getName());
  388.             return new FileInputStream(var4);
  389.          } catch (FileNotFoundException var6) {
  390.             ((Throwable)var6).printStackTrace();
  391.             return null;
  392.          }
  393.       } else {
  394.          return null;
  395.       }
  396.    }
  397.  
  398.    private InputStream loadResourceFromZipfile(File var1, String var2) {
  399.       try {
  400.          ZipFile var3 = new ZipFile(var1);
  401.          ZipEntry var4 = var3.getEntry(var2);
  402.          if (var4 != null) {
  403.             this.debugTrace("Loaded resource " + var2 + " from zip file" + var1.getName());
  404.             return var3.getInputStream(var4);
  405.          } else {
  406.             return null;
  407.          }
  408.       } catch (IOException var5) {
  409.          this.trace(((Throwable)var5).toString());
  410.          return null;
  411.       }
  412.    }
  413.  
  414.    public URL getResource(String var1) {
  415.       URL var2 = ClassLoader.getSystemResource(var1);
  416.       if (var2 != null) {
  417.          this.debugTrace("Loaded resource " + var1 + " from system.");
  418.          return var2;
  419.       } else {
  420.          Enumeration var3 = this.repository.elements();
  421.  
  422.          while(var3.hasMoreElements()) {
  423.             File var4 = (File)var3.nextElement();
  424.             if (var4.isDirectory()) {
  425.                String var5 = var1.replace('/', File.separatorChar);
  426.                File var6 = new File(var4, var5);
  427.                if (var6.exists()) {
  428.                   this.debugTrace("Loaded resource " + var1 + " from directory " + var4.getName());
  429.  
  430.                   try {
  431.                      return new URL("file://" + var6.getAbsolutePath());
  432.                   } catch (MalformedURLException var8) {
  433.                      ((Throwable)var8).printStackTrace();
  434.                      return null;
  435.                   }
  436.                }
  437.             }
  438.          }
  439.  
  440.          return null;
  441.       }
  442.    }
  443. }
  444.