home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 January / PCO0198.ISO / 1&1 / java.z / java_301 / netscape / applet / AppletClassLoader.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-10-20  |  8.2 KB  |  318 lines

  1. package netscape.applet;
  2.  
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.net.MalformedURLException;
  6. import java.net.URL;
  7. import java.net.URLConnection;
  8. import java.util.Hashtable;
  9. import java.util.Vector;
  10.  
  11. final class AppletClassLoader extends ClassLoader {
  12.    Hashtable classes;
  13.    URL codeBaseURL;
  14.    URL archiveURL;
  15.    MozillaAppletContext context;
  16.    int nativeZipFile;
  17.    static boolean wantTiming;
  18.    long loaderTime;
  19.    boolean mayScript = false;
  20.    static Vector classloaders = new Vector(10);
  21.    int refCount = 0;
  22.  
  23.    static synchronized AppletClassLoader getClassLoader(MozillaAppletContext cx, URL codebase, URL archive, boolean mayScript) {
  24.       AppletClassLoader loader = null;
  25.  
  26.       for(int i = 0; i < classloaders.size(); ++i) {
  27.          AppletClassLoader test = (AppletClassLoader)classloaders.elementAt(i);
  28.          if (codebase.equals(test.codeBaseURL) && archive.equals(test.archiveURL) && mayScript == test.mayScript && (!mayScript || cx == test.context)) {
  29.             loader = test;
  30.             break;
  31.          }
  32.       }
  33.  
  34.       if (loader == null) {
  35.          loader = new AppletClassLoader(cx, codebase, archive);
  36.          loader.mayScript = mayScript;
  37.          classloaders.addElement(loader);
  38.       }
  39.  
  40.       ++loader.refCount;
  41.       return loader;
  42.    }
  43.  
  44.    void releaseClassLoader() {
  45.       if (this.refCount == 0) {
  46.          throw new InternalError("tried to release unshared classloader");
  47.       } else {
  48.          if (MozillaAppletContext.debug > 0) {
  49.             System.err.println("# released reference to: " + this);
  50.          }
  51.  
  52.          if (--this.refCount == 0) {
  53.             classloaders.removeElement(this);
  54.             if (MozillaAppletContext.debug > 0) {
  55.                System.err.println("# removed: " + this);
  56.             }
  57.          }
  58.  
  59.       }
  60.    }
  61.  
  62.    AppletClassLoader(MozillaAppletContext cx, URL codebase, URL archive) {
  63.       String file = archive.getFile();
  64.       if (file.endsWith(".zip")) {
  65.          try {
  66.             if (wantTiming) {
  67.                long before = System.currentTimeMillis();
  68.                this.nativeZipFile = this.openZipFile(archive.openStream());
  69.                long after = System.currentTimeMillis();
  70.                long duration = after - before;
  71.                this.loaderTime += duration;
  72.                System.err.println("# Zip download time: " + archive + ": " + duration + " (total = " + this.loaderTime + ")");
  73.             } else {
  74.                this.nativeZipFile = this.openZipFile(archive.openStream());
  75.             }
  76.  
  77.             if (this.context != null && MozillaAppletContext.debug > 0) {
  78.                System.err.println("# Loading classes from downloaded zip file: " + archive);
  79.             }
  80.          } catch (IOException var12) {
  81.             System.err.println("# Failed to pull over zip file " + archive);
  82.          }
  83.       }
  84.  
  85.       file = codebase.getFile();
  86.       int i = file.lastIndexOf(47);
  87.       if (i > 0 && i < file.length() - 1) {
  88.          try {
  89.             codebase = new URL(codebase, file.substring(0, i + 1));
  90.          } catch (MalformedURLException var11) {
  91.          }
  92.       }
  93.  
  94.       this.codeBaseURL = codebase;
  95.       this.archiveURL = archive;
  96.       this.context = cx;
  97.       this.classes = new Hashtable();
  98.    }
  99.  
  100.    native int openZipFile(InputStream var1) throws IOException;
  101.  
  102.    native byte[] loadFromZipFile(int var1, String var2) throws IOException;
  103.  
  104.    native void closeZipFile(int var1) throws IOException;
  105.  
  106.    void close() {
  107.       if (this.nativeZipFile != 0) {
  108.          try {
  109.             this.closeZipFile(this.nativeZipFile);
  110.             if (this.context != null && MozillaAppletContext.debug > 0) {
  111.                System.err.println("# Closed downloaded zip file: " + this.codeBaseURL);
  112.             }
  113.          } catch (IOException var1) {
  114.             if (this.context != null && MozillaAppletContext.debug > 0) {
  115.                System.err.println("# Failed to close downloaded zip file: " + this.codeBaseURL);
  116.             }
  117.          }
  118.  
  119.          this.nativeZipFile = 0;
  120.       }
  121.  
  122.    }
  123.  
  124.    protected void finalize() {
  125.       this.close();
  126.       if (MozillaAppletContext.debug > 0) {
  127.          System.err.println("# finalized: " + this);
  128.       }
  129.  
  130.    }
  131.  
  132.    boolean mayScript() {
  133.       return this.mayScript;
  134.    }
  135.  
  136.    private Class loadClass(String name, URL url) throws IOException {
  137.       byte[] data = this.readURL(url);
  138.       return ((ClassLoader)this).defineClass(name, data, 0, data.length);
  139.    }
  140.  
  141.    public Class loadClass(String name) throws ClassNotFoundException {
  142.       return this.loadClass(name, true);
  143.    }
  144.  
  145.    protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
  146.       Class clazz;
  147.       if (wantTiming) {
  148.          long before = System.currentTimeMillis();
  149.          clazz = this.loadClass1(name, resolve);
  150.          long after = System.currentTimeMillis();
  151.          long duration = after - before;
  152.          this.loaderTime += duration;
  153.          System.err.println("# Class load time: " + name + ": " + duration + " (total = " + this.loaderTime + ")");
  154.       } else {
  155.          clazz = this.loadClass1(name, resolve);
  156.       }
  157.  
  158.       return clazz;
  159.    }
  160.  
  161.    Class loadClass1(String name, boolean resolve) throws ClassNotFoundException {
  162.       Class cl = (Class)this.classes.get(name);
  163.       if (cl == null) {
  164.          SecurityManager security = System.getSecurityManager();
  165.          if (security != null) {
  166.             int i = name.lastIndexOf(46);
  167.             if (i >= 0) {
  168.                security.checkPackageAccess(name.substring(0, i));
  169.             }
  170.          }
  171.  
  172.          try {
  173.             return ((ClassLoader)this).findSystemClass(name);
  174.          } catch (ClassNotFoundException var6) {
  175.             cl = this.findClass(name);
  176.          }
  177.       }
  178.  
  179.       if (cl == null) {
  180.          throw new ClassNotFoundException(name);
  181.       } else {
  182.          if (this.nativeZipFile != 0) {
  183.             SecurityManager.checksURLConnect(this.archiveURL);
  184.          }
  185.  
  186.          if (resolve) {
  187.             ((ClassLoader)this).resolveClass(cl);
  188.          }
  189.  
  190.          return cl;
  191.       }
  192.    }
  193.  
  194.    private synchronized Class findClass(String name) throws ClassNotFoundException {
  195.       Class cl = (Class)this.classes.get(name);
  196.       if (cl != null) {
  197.          return cl;
  198.       } else {
  199.          if (this.context != null && MozillaAppletContext.debug > 0) {
  200.             System.err.println("# Find class " + name);
  201.          }
  202.  
  203.          SecurityManager security = System.getSecurityManager();
  204.          if (security != null) {
  205.             int i = name.lastIndexOf(46);
  206.             if (i >= 0) {
  207.                security.checkPackageDefinition(name.substring(0, i));
  208.             }
  209.          }
  210.  
  211.          String cname = name.replace('.', '/') + ".class";
  212.          if (this.nativeZipFile != 0) {
  213.             try {
  214.                byte[] data = this.loadFromZipFile(this.nativeZipFile, cname);
  215.                if (data != null) {
  216.                   cl = ((ClassLoader)this).defineClass(name, data, 0, data.length);
  217.                   if (cl != null && this.context != null && MozillaAppletContext.debug > 0) {
  218.                      System.err.println("# Loaded " + cname + " from downloaded zip file.");
  219.                   }
  220.                }
  221.             } catch (IOException var8) {
  222.                if (MozillaAppletContext.debug > 0) {
  223.                   System.err.println("# Failed to load " + cname + " from downloaded zip file.");
  224.                }
  225.             }
  226.          }
  227.  
  228.          if (cl == null) {
  229.             URL url;
  230.             try {
  231.                url = new URL(this.codeBaseURL, cname);
  232.             } catch (MalformedURLException var7) {
  233.                throw new ClassNotFoundException(name);
  234.             }
  235.  
  236.             if (this.context != null && MozillaAppletContext.debug > 0) {
  237.                System.err.println("# Fetching " + url);
  238.             }
  239.  
  240.             try {
  241.                cl = this.loadClass(name, url);
  242.             } catch (IOException var6) {
  243.                throw new ClassNotFoundException(name);
  244.             }
  245.          }
  246.  
  247.          if (!name.equals(cl.getName())) {
  248.             Class oldcl = cl;
  249.             Class var9 = null;
  250.             throw new ClassFormatError(name + " != " + oldcl.getName());
  251.          } else {
  252.             this.classes.put(name, cl);
  253.             return cl;
  254.          }
  255.       }
  256.    }
  257.  
  258.    byte[] getResource(URL url) {
  259.       byte[] data = null;
  260.       String urlFile = url.getFile();
  261.       String codebaseFile = this.codeBaseURL.getFile();
  262.       System.out.println("url=" + url + " codebase=" + this.codeBaseURL);
  263.       if (!urlFile.startsWith(codebaseFile)) {
  264.          return null;
  265.       } else {
  266.          String resourcePath = urlFile.substring(codebaseFile.length());
  267.          System.out.println("resourcePath=" + resourcePath);
  268.  
  269.          try {
  270.             data = this.loadFromZipFile(this.nativeZipFile, resourcePath);
  271.             if (data != null && this.context != null && MozillaAppletContext.debug > 0) {
  272.                System.err.println("# Loaded " + resourcePath + " from downloaded zip file.");
  273.             }
  274.          } catch (IOException var6) {
  275.             if (MozillaAppletContext.debug > 0) {
  276.                System.err.println("# Failed to load " + resourcePath + " from downloaded zip file.");
  277.             }
  278.          }
  279.  
  280.          return data;
  281.       }
  282.    }
  283.  
  284.    byte[] readURL(URL url) throws IOException {
  285.       InputStream in = null;
  286.  
  287.       byte[] data;
  288.       try {
  289.          URLConnection c = url.openConnection();
  290.          c.setAllowUserInteraction(false);
  291.          in = c.getInputStream();
  292.          int len = c.getContentLength();
  293.          data = new byte[len == -1 ? 4096 : len];
  294.          int total = 0;
  295.  
  296.          int n;
  297.          while((n = in.read(data, total, data.length - total)) >= 0) {
  298.             if ((total += n) == data.length) {
  299.                if (len >= 0) {
  300.                   break;
  301.                }
  302.  
  303.                byte[] newdata = new byte[total * 2];
  304.                System.arraycopy(data, 0, newdata, 0, total);
  305.                data = newdata;
  306.             }
  307.          }
  308.       } finally {
  309.          if (in != null) {
  310.             in.close();
  311.          }
  312.  
  313.       }
  314.  
  315.       return data;
  316.    }
  317. }
  318.