home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / browser / ns405lyc / nav40.z / java40.jar / netscape / applet / AppletClassLoader.class (.txt) < prev    next >
Encoding:
Java Class File  |  1998-03-24  |  14.5 KB  |  933 lines

  1. package netscape.applet;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.net.MalformedURLException;
  10. import java.net.URL;
  11. import java.net.URLConnection;
  12. import java.util.Enumeration;
  13. import java.util.Hashtable;
  14. import java.util.Vector;
  15. import java.util.zip.ZipEntry;
  16. import java.util.zip.ZipFile;
  17. import netscape.misc.WeakLink;
  18. import netscape.security.AppletSecurity;
  19. import netscape.security.AppletSecurityException;
  20. import netscape.security.Principal;
  21. import netscape.security.PrivilegeManager;
  22. import netscape.security.Target;
  23.  
  24. public class AppletClassLoader extends ClassLoader {
  25.    URL codeBaseURL;
  26.    URL[] archiveURL;
  27.    MozillaAppletContext context;
  28.    static boolean wantTiming;
  29.    long loaderTime;
  30.    String scriptOrigin;
  31.    boolean isReusable;
  32.    Principal codeBasePrincipal;
  33.    Principal[] matchPrincipalAry;
  34.    public static final String MANIFEST_FILENAME = "META-INF/manifest.mf";
  35.    private Hashtable nameToArchive;
  36.    private String[] archiveFile;
  37.    private boolean[] capturedArchive;
  38.    private int[] nativeArchive;
  39.    private int[] nativeZig;
  40.    byte[] inputBuf;
  41.    static Vector classloaders = new Vector(10);
  42.    private static boolean capturingClasses;
  43.    private static final boolean MARIMBA_ENABLED = true;
  44.    private CastanetChannelInfo channelInfo;
  45.    private Hashtable codebaseEnv;
  46.  
  47.    String grabArchiveFile(int var1) throws IOException {
  48.       return this.grabArchiveFile(var1, this.archiveURL[var1]);
  49.    }
  50.  
  51.    private String grabArchiveFile(int var1, URL var2) throws IOException {
  52.       String var3 = var2.getFile();
  53.       if (!var3.endsWith(".jar") && !var3.endsWith(".zip")) {
  54.          return null;
  55.       } else {
  56.          String var4;
  57.          if (capturingClasses) {
  58.             int var5 = var3.lastIndexOf(47);
  59.             String var6 = var3.substring(var5 + 1);
  60.             var4 = this.getCaptureDir() + "/" + var6;
  61.          } else {
  62.             var4 = this.getTempName();
  63.             if (var4 == null) {
  64.                return null;
  65.             }
  66.          }
  67.  
  68.          SecurityManager.enablePrivilege("UniversalFileAccess");
  69.          SecurityManager.enablePrivilege("UniversalConnect");
  70.          FileOutputStream var16 = new FileOutputStream(var4);
  71.          long var17 = 0L;
  72.          if (wantTiming) {
  73.             var17 = System.currentTimeMillis();
  74.          }
  75.  
  76.          InputStream var8 = null;
  77.  
  78.          try {
  79.             URLConnection var11 = var2.openConnection();
  80.             var11.setAllowUserInteraction(false);
  81.             var8 = var11.getInputStream();
  82.             if (this.inputBuf == null) {
  83.                this.inputBuf = new byte[4096];
  84.             }
  85.  
  86.             Thread var13 = Thread.currentThread();
  87.  
  88.             int var12;
  89.             while((var12 = var8.read(this.inputBuf)) >= 0 && !var13.isInterrupted()) {
  90.                var16.write(this.inputBuf, 0, var12);
  91.             }
  92.  
  93.             if (var13.isInterrupted()) {
  94.                throw new IOException("interrupted: " + this);
  95.             }
  96.          } finally {
  97.             if (var8 != null) {
  98.                var8.close();
  99.             }
  100.  
  101.             if (var16 != null) {
  102.                var16.close();
  103.             }
  104.  
  105.          }
  106.  
  107.          SecurityManager.revertPrivilege();
  108.          if (wantTiming) {
  109.             long var9 = System.currentTimeMillis();
  110.             long var18 = var9 - var17;
  111.             this.loaderTime += var18;
  112.             System.err.println("# Archive download time: " + var2 + ": " + var18 + " (total = " + this.loaderTime + ")");
  113.          }
  114.  
  115.          if (capturingClasses) {
  116.             System.err.println("#\tCaptured archive " + var4);
  117.             this.capturedArchive[var1] = true;
  118.          } else if (this.context != null && MozillaAppletContext.debug >= 2) {
  119.             System.err.println("# Loading classes from downloaded archive file: " + var2);
  120.          }
  121.  
  122.          return var4;
  123.       }
  124.    }
  125.  
  126.    native String getTempName();
  127.  
  128.    private native int openArchive0(String var1) throws IOException;
  129.  
  130.    private native byte[] loadFromArchive0(int var1, String var2) throws IOException;
  131.  
  132.    private native void closeArchive0(int var1) throws IOException;
  133.  
  134.    void openArchive(int var1) {
  135.       this.openArchive(var1, this.archiveURL[var1]);
  136.    }
  137.  
  138.    private void openArchive(int var1, URL var2) {
  139.       try {
  140.          this.archiveFile[var1] = this.grabArchiveFile(var1, var2);
  141.          if (this.archiveFile[var1] == null) {
  142.             return;
  143.          }
  144.  
  145.          this.nativeArchive[var1] = this.openArchive0(this.archiveFile[var1]);
  146.          if (this.nativeArchive[var1] != 0) {
  147.             this.nativeZig[var1] = this.setupZignature();
  148.             if (this.nativeZig[var1] != 0) {
  149.                if (!this.loadManifest(this.nativeArchive[var1], this.nativeZig[var1], this.codeBaseURL.getFile()) || this.loadSignatures(this.nativeArchive[var1], this.nativeZig[var1], this.codeBaseURL.getFile()) <= 0) {
  150.                   this.nativeZig[var1] = 0;
  151.                }
  152.  
  153.                return;
  154.             }
  155.          }
  156.       } catch (IOException var4) {
  157.          ((Throwable)var4).printStackTrace();
  158.          System.err.println("# Unable to load archive " + this.archiveURL[var1] + ": " + var4);
  159.          this.nativeZig[var1] = 0;
  160.       }
  161.  
  162.    }
  163.  
  164.    byte[] loadFromArchive(String var1, int var2) throws IOException {
  165.       return this.nativeArchive[var2] != 0 ? this.loadFromArchive0(this.nativeArchive[var2], var1) : null;
  166.    }
  167.  
  168.    void closeArchive() {
  169.       for(int var1 = this.archiveURL.length - 1; var1 >= 0; --var1) {
  170.          if (this.nativeArchive[var1] != 0) {
  171.             try {
  172.                this.closeArchive0(this.nativeArchive[var1]);
  173.                if (this.context != null && MozillaAppletContext.debug >= 5) {
  174.                   System.err.println("# Closed downloaded archive: " + this.archiveURL[var1]);
  175.                }
  176.             } catch (IOException var4) {
  177.                if (this.context != null && MozillaAppletContext.debug >= 5) {
  178.                   System.err.println("# Failed to close downloaded archive: " + this.archiveURL[var1]);
  179.                }
  180.             }
  181.  
  182.             this.nativeArchive[var1] = 0;
  183.             if (!this.capturedArchive[var1]) {
  184.                File var2 = new File(this.archiveFile[var1]);
  185.                SecurityManager.enablePrivilege("UniversalFileRead");
  186.                SecurityManager.enablePrivilege("UniversalFileDelete");
  187.                boolean var3 = var2.delete();
  188.                SecurityManager.revertPrivilege();
  189.                if (this.context != null && MozillaAppletContext.debug >= 5) {
  190.                   if (var3) {
  191.                      System.err.println("# Deleted downloaded archive: " + this.archiveFile[var1]);
  192.                   } else {
  193.                      System.err.println("# Failed to delete downloaded archive: " + this.archiveFile[var1]);
  194.                   }
  195.                }
  196.             }
  197.          }
  198.       }
  199.  
  200.    }
  201.  
  202.    static synchronized AppletClassLoader getClassLoader(MozillaAppletContext var0, URL var1, URL[] var2, String var3, boolean var4) {
  203.       if (var2 == null) {
  204.          var2 = new URL[0];
  205.       }
  206.  
  207.       boolean var5 = false;
  208.       AppletClassLoader var6 = null;
  209.       SecurityManager.enablePrivilege("UniversalConnect");
  210.       String var8 = var1.getFile();
  211.       int var9 = var8.lastIndexOf(47);
  212.       URL var7 = var1;
  213.       if (var9 > 0 && var9 < var8.length() - 1) {
  214.          try {
  215.             var7 = new URL(var1, var8.substring(0, var9 + 1));
  216.          } catch (MalformedURLException var31) {
  217.          }
  218.       }
  219.  
  220.       for(int var10 = 0; var10 < classloaders.size(); ++var10) {
  221.          WeakLink var11 = (WeakLink)classloaders.elementAt(var10);
  222.          AppletClassLoader var12 = (AppletClassLoader)var11.get();
  223.          if (var12 == null) {
  224.             var5 = true;
  225.          } else if (var7.equals(var12.codeBaseURL)) {
  226.             label145: {
  227.                boolean var10000;
  228.                if (var3 == null) {
  229.                   if (var12.scriptOrigin == null) {
  230.                      break label145;
  231.                   }
  232.  
  233.                   var10000 = false;
  234.                } else {
  235.                   var10000 = var3.equals(var12.scriptOrigin);
  236.                }
  237.  
  238.                if (!var10000) {
  239.                   continue;
  240.                }
  241.             }
  242.  
  243.             if ((var3 == null || var0 == var12.context) && var12.isReusable) {
  244.                if (!var4) {
  245.                   var6 = var12;
  246.                   int var13 = var12.archiveURL.length;
  247.                   int var14 = var13 + var2.length;
  248.                   URL[] var15 = new URL[var14];
  249.                   String[] var16 = new String[var14];
  250.                   boolean[] var17 = new boolean[var14];
  251.                   int[] var18 = new int[var14];
  252.                   int[] var19 = new int[var14];
  253.  
  254.                   for(int var20 = var2.length - 1; var20 >= 0; --var20) {
  255.                      var15[var13 + var20] = var2[var20];
  256.                      var16[var13 + var20] = null;
  257.                      var17[var13 + var20] = false;
  258.                      var18[var13 + var20] = 0;
  259.                      var19[var13 + var20] = 0;
  260.  
  261.                      for(int var21 = var13 - 1; var21 >= 0; --var21) {
  262.                         if (var6.archiveURL[var21] != null && var2[var20].getFile().equals(var6.archiveURL[var21].getFile())) {
  263.                            var15[var13 + var20] = null;
  264.                            --var14;
  265.                            break;
  266.                         }
  267.                      }
  268.                   }
  269.  
  270.                   for(int var34 = var13 - 1; var34 >= 0; --var34) {
  271.                      var15[var34] = var6.archiveURL[var34];
  272.                      var16[var34] = var6.archiveFile[var34];
  273.                      var17[var34] = var6.capturedArchive[var34];
  274.                      var18[var34] = var6.nativeArchive[var34];
  275.                      var19[var34] = var6.nativeZig[var34];
  276.                   }
  277.  
  278.                   URL[] var22 = new URL[var14];
  279.                   String[] var23 = new String[var14];
  280.                   boolean[] var24 = new boolean[var14];
  281.                   int[] var25 = new int[var14];
  282.                   int[] var26 = new int[var14];
  283.                   int var27 = var14 - 1;
  284.  
  285.                   for(int var28 = var15.length - 1; var28 >= 0; --var28) {
  286.                      if (var15[var28] != null) {
  287.                         var22[var27] = var15[var28];
  288.                         var23[var27] = var16[var28];
  289.                         var24[var27] = var17[var28];
  290.                         var25[var27] = var18[var28];
  291.                         var26[var27] = var19[var28];
  292.                         --var27;
  293.                      }
  294.                   }
  295.  
  296.                   var6.archiveFile = var23;
  297.                   var6.capturedArchive = var24;
  298.                   var6.nativeArchive = var25;
  299.                   var6.nativeZig = var26;
  300.  
  301.                   for(int var29 = var13; var29 < var22.length; ++var29) {
  302.                      var6.openArchive(var29, var22[var29]);
  303.                   }
  304.  
  305.                   var6.archiveURL = var22;
  306.                   if (MozillaAppletContext.debug >= 8) {
  307.                      System.err.println("#   reusing class loader " + var6 + "\n" + "#\tcontext = " + var0 + "\n" + "#\tcodebase = " + var7);
  308.  
  309.                      for(int var30 = 0; var30 < var6.archiveURL.length; ++var30) {
  310.                         System.err.println("#\tarchive = " + var6.archiveURL[var30]);
  311.                      }
  312.  
  313.                      System.err.println("#\tscriptOrigin = " + var3);
  314.                   }
  315.                   break;
  316.                }
  317.  
  318.                if (MozillaAppletContext.debug >= 8) {
  319.                   System.err.println("#   preventing reuse of " + var12);
  320.                }
  321.  
  322.                var12.isReusable = false;
  323.             }
  324.          }
  325.       }
  326.  
  327.       SecurityManager.revertPrivilege();
  328.       if (var6 == null) {
  329.          var6 = new AppletClassLoader(var0, var1, var2);
  330.          var6.scriptOrigin = var3;
  331.          classloaders.addElement(new WeakLink(var6));
  332.       }
  333.  
  334.       if (var5) {
  335.          for(int var32 = classloaders.size() - 1; var32 >= 0; --var32) {
  336.             WeakLink var33 = (WeakLink)classloaders.elementAt(var32);
  337.             if (var33.get() == null) {
  338.                classloaders.removeElementAt(var32);
  339.             }
  340.  
  341.             if (MozillaAppletContext.debug >= 8) {
  342.                System.err.println("#   classloader was removed");
  343.             }
  344.          }
  345.       }
  346.  
  347.       return var6;
  348.    }
  349.  
  350.    AppletClassLoader(MozillaAppletContext var1, URL var2, URL[] var3) {
  351.       this.nameToArchive = new Hashtable();
  352.       this.scriptOrigin = null;
  353.       this.isReusable = true;
  354.       this.codeBasePrincipal = new Principal(var2);
  355.       String var4 = var2.getFile();
  356.       int var5 = var4.lastIndexOf(47);
  357.       if (var5 > 0 && var5 < var4.length() - 1) {
  358.          try {
  359.             var2 = new URL(var2, var4.substring(0, var5 + 1));
  360.          } catch (MalformedURLException var8) {
  361.          }
  362.       }
  363.  
  364.       this.codeBaseURL = var2;
  365.       if (var3 == null) {
  366.          var3 = new URL[0];
  367.       }
  368.  
  369.       this.archiveURL = var3;
  370.       this.context = var1;
  371.       int var6 = var3.length;
  372.       this.archiveFile = new String[var6];
  373.       this.capturedArchive = new boolean[var6];
  374.       this.nativeArchive = new int[var6];
  375.       this.nativeZig = new int[var6];
  376.  
  377.       for(int var9 = var6 - 1; var9 >= 0; --var9) {
  378.          this.archiveFile[var9] = null;
  379.          this.capturedArchive[var9] = false;
  380.          this.nativeArchive[var9] = 0;
  381.          this.nativeZig[var9] = 0;
  382.       }
  383.  
  384.       if (MozillaAppletContext.debug > 5) {
  385.          System.err.println("#   new class loader " + this + "\n" + "#\tcontext = " + var1 + "\n" + "#\tcodebase = " + var2);
  386.  
  387.          for(int var7 = 0; var7 < var6; ++var7) {
  388.             System.err.println("#\tarchive = " + var3[var7]);
  389.          }
  390.       }
  391.  
  392.       for(int var10 = var6 - 1; var10 >= 0; --var10) {
  393.          if (this.archiveURL[var10] != null) {
  394.             this.openArchive(var10);
  395.          }
  396.       }
  397.  
  398.    }
  399.  
  400.    void close() {
  401.       if (this.archiveURL != null) {
  402.          this.closeArchive();
  403.       }
  404.  
  405.       if (this.channelInfo != null) {
  406.          this.channelInfo.closeZips();
  407.       }
  408.  
  409.    }
  410.  
  411.    protected void finalize() {
  412.       this.close();
  413.       if (MozillaAppletContext.debug >= 8) {
  414.          System.err.println("# finalized: " + this);
  415.       }
  416.  
  417.    }
  418.  
  419.    protected AppletClassLoader(URL var1) {
  420.       this((MozillaAppletContext)null, var1, (URL[])null);
  421.    }
  422.  
  423.    String getScriptOrigin() {
  424.       return this.scriptOrigin;
  425.    }
  426.  
  427.    public URL getCodeBase() {
  428.       return this.codeBaseURL;
  429.    }
  430.  
  431.    private Class loadClass(String var1, URL var2, String var3) throws IOException {
  432.       SecurityManager.enablePrivilege("UniversalConnect");
  433.       byte[] var4 = var2.getData();
  434.       SecurityManager.revertPrivilege();
  435.       if (capturingClasses) {
  436.          this.captureClassFile(var1, var4);
  437.       }
  438.  
  439.       return ((ClassLoader)this).defineClass(var1, var4, 0, var4.length, 0, var3);
  440.    }
  441.  
  442.    public Class loadClass(String var1) throws ClassNotFoundException {
  443.       return this.loadClass(var1, true);
  444.    }
  445.  
  446.    protected final Class loadClass(String var1, boolean var2) throws ClassNotFoundException {
  447.       Class var3;
  448.       if (wantTiming) {
  449.          long var4 = System.currentTimeMillis();
  450.          var3 = this.loadClass1(var1, var2);
  451.          long var6 = System.currentTimeMillis();
  452.          long var8 = var6 - var4;
  453.          this.loaderTime += var8;
  454.          System.err.println("# Class load time: " + var1 + ": " + var8 + " (total = " + this.loaderTime + ")");
  455.       } else {
  456.          var3 = this.loadClass1(var1, var2);
  457.       }
  458.  
  459.       return var3;
  460.    }
  461.  
  462.    private Class loadClass1(String var1, boolean var2) throws ClassNotFoundException {
  463.       Class var3 = ((ClassLoader)this).findLoadedClass(var1);
  464.       if (var3 == null) {
  465.          SecurityManager var4 = System.getSecurityManager();
  466.          if (var4 != null) {
  467.             int var5 = var1.lastIndexOf(46);
  468.             if (var5 >= 0) {
  469.                var4.checkPackageAccess(var1.substring(0, var5));
  470.             }
  471.          }
  472.  
  473.          try {
  474.             return ((ClassLoader)this).findSystemClass(var1);
  475.          } catch (NoClassDefFoundError var8) {
  476.             if (this.channelInfo == null) {
  477.                throw var8;
  478.             }
  479.          } catch (ClassNotFoundException var9) {
  480.          }
  481.  
  482.          var3 = this.findClass(var1);
  483.       }
  484.  
  485.       if (var3 == null) {
  486.          throw new ClassNotFoundException(var1);
  487.       } else {
  488.          Integer var10 = (Integer)this.nameToArchive.get(var1);
  489.          if (var10 != null) {
  490.             int var11 = var10;
  491.             if (var11 != -1 && this.nativeArchive[var11] != 0) {
  492.                System.getSecurityManager().checkURLConnect(this.codeBaseURL, this.archiveURL[var11]);
  493.             }
  494.          }
  495.  
  496.          if (var2) {
  497.             try {
  498.                ((ClassLoader)this).resolveClass(var3);
  499.             } catch (NoClassDefFoundError var6) {
  500.                if (this.channelInfo == null) {
  501.                   throw var6;
  502.                }
  503.  
  504.                throw new ClassNotFoundException(var1);
  505.             } catch (UnknownError var7) {
  506.                if (this.channelInfo == null) {
  507.                   throw var7;
  508.                }
  509.  
  510.                throw new ClassNotFoundException(var1);
  511.             }
  512.          }
  513.  
  514.          return var3;
  515.       }
  516.    }
  517.  
  518.    private synchronized Class findClass(String var1) throws ClassNotFoundException {
  519.       boolean var3 = true;
  520.       Class var4 = ((ClassLoader)this).findLoadedClass(var1);
  521.       if (var4 != null) {
  522.          return var4;
  523.       } else {
  524.          if (MozillaAppletContext.debug >= 2) {
  525.             System.err.println("# Loading class " + var1);
  526.          }
  527.  
  528.          SecurityManager var5 = System.getSecurityManager();
  529.          if (var5 != null) {
  530.             int var6 = var1.lastIndexOf(46);
  531.             if (var6 >= 0) {
  532.                var5.checkPackageDefinition(var1.substring(0, var6));
  533.             }
  534.          }
  535.  
  536.          String var15 = var1.replace('.', '/') + ".class";
  537.  
  538.          int var2;
  539.          for(var2 = this.archiveURL.length - 1; var2 >= 0; --var2) {
  540.             if (this.nativeArchive[var2] != 0) {
  541.                try {
  542.                   byte[] var7 = this.loadFromArchive(var15, var2);
  543.                   if (var7 != null) {
  544.                      var4 = ((ClassLoader)this).defineClass(var1, var7, 0, var7.length, this.nativeZig[var2], var15);
  545.                      if (var4 != null && this.context != null && MozillaAppletContext.debug >= 2) {
  546.                         System.err.println("# Loaded " + var15 + " from " + this.archiveURL[var2]);
  547.                      }
  548.  
  549.                      var3 = false;
  550.                      if (var4 != null) {
  551.                         this.nameToArchive.put(var1, new Integer(var2));
  552.                         break;
  553.                      }
  554.                   }
  555.                } catch (IOException var13) {
  556.                   if (MozillaAppletContext.debug >= 2) {
  557.                      System.err.println("# Failed to load " + var15 + " from " + this.archiveURL[var2]);
  558.                   }
  559.                }
  560.             }
  561.          }
  562.  
  563.          if (var4 == null) {
  564.             var2 = -1;
  565.  
  566.             URL var16;
  567.             try {
  568.                var16 = new URL(this.codeBaseURL, var15);
  569.             } catch (MalformedURLException var10) {
  570.                throw new ClassNotFoundException(var1);
  571.             }
  572.  
  573.             if (this.context != null && MozillaAppletContext.debug >= 5) {
  574.                System.err.println("# Fetching " + var16);
  575.             }
  576.  
  577.             try {
  578.                var4 = this.loadClass(var1, var16, var15);
  579.                var3 = false;
  580.             } catch (IOException var11) {
  581.                if (this.channelInfo != null) {
  582.                   try {
  583.                      var4 = this.marimbaLoad(var1);
  584.                      var3 = false;
  585.                   } catch (IOException var9) {
  586.                   }
  587.                }
  588.  
  589.                if (var4 == null) {
  590.                   throw new ClassNotFoundException(var1);
  591.                }
  592.             } catch (SecurityException var12) {
  593.                if (this.context != null && MozillaAppletContext.debug >= 5) {
  594.                   System.err.println("# Exception while loading " + var15 + " from downloaded archive " + var16.toString() + "\n#   Exception: " + ((Throwable)var12).toString());
  595.                }
  596.  
  597.                throw var12;
  598.             }
  599.          }
  600.  
  601.          if (!var1.equals(var4.getName())) {
  602.             Object var14 = null;
  603.             throw new ClassFormatError(var1 + " != " + var4.getName());
  604.          } else {
  605.             if (!var3) {
  606.                this.setPrincipalAry(var4, var15, var2);
  607.             }
  608.  
  609.             return var4;
  610.          }
  611.       }
  612.    }
  613.  
  614.    static boolean getCaptureClassFiles() {
  615.       return capturingClasses;
  616.    }
  617.  
  618.    static void setCaptureClassFiles(boolean var0) {
  619.       capturingClasses = var0;
  620.    }
  621.  
  622.    String getCaptureDir() throws IOException {
  623.       String var1 = this.codeBaseURL.toString();
  624.       if (var1.startsWith("http://")) {
  625.          var1 = var1.substring(7);
  626.       }
  627.  
  628.       if (var1.endsWith("/")) {
  629.          var1 = var1.substring(0, var1.length() - 1);
  630.       }
  631.  
  632.       var1 = var1.replace('/', '_').replace(':', '_');
  633.       SecurityManager.enablePrivilege("UniversalFileRead");
  634.       SecurityManager.enablePrivilege("UniversalFileWrite");
  635.       File var2 = new File(var1);
  636.       if ((!var2.exists() || !var2.isDirectory()) && !var2.mkdir()) {
  637.          throw new IOException(var2 + " is not a directory");
  638.       } else {
  639.          return var1;
  640.       }
  641.    }
  642.  
  643.    void captureClassFile(String var1, byte[] var2) {
  644.       try {
  645.          String var3 = this.getCaptureDir();
  646.          SecurityManager.enablePrivilege("UniversalFileRead");
  647.          SecurityManager.enablePrivilege("UniversalFileWrite");
  648.  
  649.          File var6;
  650.          do {
  651.             int var4 = var1.indexOf(46);
  652.             if (var4 == -1) {
  653.                File var9 = new File(var3 + "/" + var1 + ".class");
  654.                FileOutputStream var10 = new FileOutputStream(var9);
  655.                var10.write(var2, 0, var2.length);
  656.                System.err.println("#\tCaptured class " + var9);
  657.                var10.close();
  658.                return;
  659.             }
  660.  
  661.             String var5 = var1.substring(0, var4);
  662.             var1 = var1.substring(var4 + 1);
  663.             var3 = var3 + "/" + var5;
  664.             var6 = new File(var3);
  665.          } while(var6.exists() && var6.isDirectory() || var6.mkdir());
  666.  
  667.          throw new IOException("Can't create " + var6);
  668.       } catch (SecurityException var7) {
  669.          System.err.println("#\tCan't capture class: " + var7);
  670.       } catch (IOException var8) {
  671.          System.err.println("#\tCan't capture class: " + var8);
  672.       }
  673.    }
  674.  
  675.    byte[] getResource(URL var1) {
  676.       byte[] var2 = null;
  677.       String var3 = var1.getFile();
  678.       String var4 = this.codeBaseURL.getFile();
  679.       if (!var3.startsWith(var4)) {
  680.          return null;
  681.       } else {
  682.          String var5 = var3.substring(var4.length());
  683.  
  684.          for(int var6 = this.archiveURL.length - 1; var6 >= 0; --var6) {
  685.             try {
  686.                var2 = this.loadFromArchive(var5, var6);
  687.                if (var2 != null && this.context != null && MozillaAppletContext.debug >= 5) {
  688.                   System.err.println("# Loaded " + var5 + " from " + this.archiveURL[var6]);
  689.                }
  690.  
  691.                if (var2 != null) {
  692.                   break;
  693.                }
  694.  
  695.                if (var2 == null && this.context != null && MozillaAppletContext.debug >= 5) {
  696.                   System.err.println("# " + var5 + " in " + this.archiveURL[var6] + " not found.");
  697.                }
  698.             } catch (IOException var7) {
  699.                if (MozillaAppletContext.debug >= 5) {
  700.                   System.err.println("# Failed to load " + var5 + " from " + this.archiveURL[var6]);
  701.                }
  702.             }
  703.          }
  704.  
  705.          return var2;
  706.       }
  707.    }
  708.  
  709.    public InputStream getResourceAsStream(String var1) {
  710.       System.getSecurityManager().checkResourceAccess(var1);
  711.       Object var2 = null;
  712.  
  713.       try {
  714.          URL var5 = new URL(this.codeBaseURL, var1);
  715.          byte[] var3 = this.getResource(var5);
  716.          return var3 == null ? null : new ByteArrayInputStream(var3);
  717.       } catch (MalformedURLException var4) {
  718.          return null;
  719.       }
  720.    }
  721.  
  722.    private boolean setPrincipalAry(Class var1, String var2) {
  723.       return this.setPrincipalAry(var1, var2, 0);
  724.    }
  725.  
  726.    private boolean setPrincipalAry(Class var1, String var2, int var3) {
  727.       Object var4 = null;
  728.       int var5 = 1;
  729.       Object[] var6 = null;
  730.       if (var3 >= 0 && var3 < this.archiveURL.length) {
  731.          var6 = getCertificates(this.nativeZig[var3], var1, var2);
  732.          if (var6 != null) {
  733.             var5 += var6.length;
  734.          }
  735.       }
  736.  
  737.       Principal[] var13 = new Principal[var5];
  738.  
  739.       for(int var7 = var5 - 1; var7-- > 0; var13[var7] = new Principal(14, (byte[])var6[var7], var1)) {
  740.       }
  741.  
  742.       var13[var5 - 1] = this.codeBasePrincipal;
  743.  
  744.       try {
  745.          if (this.matchPrincipalAry != null) {
  746.             PrivilegeManager var10 = AppletSecurity.getPrivilegeManager();
  747.             if (var10 != null && var10.comparePrincipalArray(var13, this.matchPrincipalAry) == 1) {
  748.                var13 = new Principal[]{this.codeBasePrincipal};
  749.                throw new AppletSecurityException("mismatch of principals");
  750.             }
  751.          }
  752.       } finally {
  753.          this.setPrincipals(var1, var13);
  754.       }
  755.  
  756.       return true;
  757.    }
  758.  
  759.    public boolean checkMatchPrincipalAlways(int var1) {
  760.       PrivilegeManager var5 = AppletSecurity.getPrivilegeManager();
  761.       if (var5 == null) {
  762.          return true;
  763.       } else {
  764.          this.matchPrincipalAry = var5.getClassPrincipalsFromStack(var1 + 1);
  765.          Enumeration var2 = ((ClassLoader)this).getClassNames();
  766.  
  767.          while(var2.hasMoreElements()) {
  768.             String var4 = (String)var2.nextElement();
  769.             Class var3 = ((ClassLoader)this).findLoadedClass(var4);
  770.             if (var3 != null && !var5.checkMatchPrincipal(var3, var1 + 1)) {
  771.                return false;
  772.             }
  773.          }
  774.  
  775.          return true;
  776.       }
  777.    }
  778.  
  779.    private native int setupZignature();
  780.  
  781.    private native int destroyZignature(int var1);
  782.  
  783.    private native boolean loadManifest(int var1, int var2, String var3);
  784.  
  785.    private native int loadSignatures(int var1, int var2, String var3);
  786.  
  787.    private native boolean verifySignature(int var1, Class var2, String var3);
  788.  
  789.    private static native Object[] getCertificates(int var0, Class var1, String var2);
  790.  
  791.    private native void setPrincipals(Class var1, Principal[] var2);
  792.  
  793.    public AppletClassLoader(URL var1, CastanetChannelInfo var2) {
  794.       this((MozillaAppletContext)null, var1, (URL[])null);
  795.       this.channelInfo = var2;
  796.    }
  797.  
  798.    public Class classFromBytes(byte[] var1, String var2) {
  799.       if (this.channelInfo == null) {
  800.          return null;
  801.       } else {
  802.          Class var3 = ((ClassLoader)this).findLoadedClass(var2);
  803.          if (var3 != null) {
  804.             return var3;
  805.          } else {
  806.             try {
  807.                var3 = ((ClassLoader)this).findSystemClass(var2);
  808.                if (var3 != null) {
  809.                   return var3;
  810.                }
  811.             } catch (NoClassDefFoundError var8) {
  812.             } catch (ClassNotFoundException var9) {
  813.             }
  814.  
  815.             SecurityManager var4 = System.getSecurityManager();
  816.             if (var4 != null) {
  817.                int var5 = var2.lastIndexOf(46);
  818.                if (var5 >= 0) {
  819.                   var4.checkPackageDefinition(var2.substring(0, var5));
  820.                }
  821.             }
  822.  
  823.             PrivilegeManager var12 = PrivilegeManager.getPrivilegeManager();
  824.             if (var12 != null) {
  825.                Target var6 = Target.findTarget("MarimbaInternalTarget");
  826.                if (var6 == null) {
  827.                   throw new AppletSecurityException("classFromBytes call denied");
  828.                }
  829.  
  830.                var12.checkPrivilegeEnabled(var6);
  831.             }
  832.  
  833.             try {
  834.                var3 = ((ClassLoader)this).defineClass(var2, var1, 0, var1.length);
  835.                return var3;
  836.             } catch (NoClassDefFoundError var7) {
  837.                return null;
  838.             }
  839.          }
  840.       }
  841.    }
  842.  
  843.    private Class marimbaLoad(String var1) throws IOException, ClassNotFoundException {
  844.       if (this.channelInfo == null) {
  845.          return null;
  846.       } else {
  847.          Class var2 = null;
  848.          int var3 = this.channelInfo.getPathlen();
  849.          if (var3 != 0) {
  850.             String var4 = var1.replace('.', '/') + ".class";
  851.  
  852.             for(int var5 = 0; var5 < var3; ++var5) {
  853.                URL var6 = this.channelInfo.getURL(var5);
  854.                if (var6 != null) {
  855.                   try {
  856.                      var2 = this.loadClass(var1, new URL(var6, var4), var4);
  857.                      if (var2 != null) {
  858.                         return var2;
  859.                      }
  860.                   } catch (NoClassDefFoundError var14) {
  861.                   } catch (MalformedURLException var15) {
  862.                   } catch (FileNotFoundException var16) {
  863.                   }
  864.                }
  865.  
  866.                ZipFile var7 = this.channelInfo.getZip(var5);
  867.                if (var7 != null) {
  868.                   ZipEntry var8 = var7.getEntry(var4);
  869.                   if (var8 != null) {
  870.                      int var9 = (int)var8.getSize();
  871.                      byte[] var10 = new byte[var9];
  872.                      InputStream var11 = var7.getInputStream(var8);
  873.  
  874.                      for(int var12 = 0; var12 < var9; var12 += var11.read(var10, var12, var9 - var12)) {
  875.                      }
  876.  
  877.                      var11.close();
  878.  
  879.                      try {
  880.                         var2 = ((ClassLoader)this).defineClass(var1, var10, 0, var10.length);
  881.                      } catch (NoClassDefFoundError var13) {
  882.                      }
  883.  
  884.                      if (var2 != null) {
  885.                         return var2;
  886.                      }
  887.                   }
  888.                }
  889.             }
  890.          }
  891.  
  892.          return null;
  893.       }
  894.    }
  895.  
  896.    public boolean marimbaCheckRead(String var1, boolean var2) {
  897.       return this.channelInfo != null ? this.channelInfo.checkRead(var1, var2) : false;
  898.    }
  899.  
  900.    public boolean marimbaCheckWrite(String var1, boolean var2) {
  901.       return this.channelInfo != null ? this.channelInfo.checkWrite(var1, var2) : false;
  902.    }
  903.  
  904.    public String marimbaGetHost() {
  905.       return this.channelInfo != null ? this.channelInfo.getHost() : null;
  906.    }
  907.  
  908.    boolean marimbaCheckThreadGroup(ThreadGroup var1) {
  909.       return this.channelInfo == null ? false : this.channelInfo.checkThreadGroup(var1);
  910.    }
  911.  
  912.    void marimbaCheckTopLevelWindow(Object var1) {
  913.       if (this.channelInfo != null) {
  914.          this.channelInfo.checkTopLevelWindow(var1);
  915.       }
  916.    }
  917.  
  918.    Hashtable getCodebaseEnv() {
  919.       if (this.codebaseEnv == null) {
  920.          this.initCodebaseEnv();
  921.       }
  922.  
  923.       return this.codebaseEnv;
  924.    }
  925.  
  926.    synchronized void initCodebaseEnv() {
  927.       if (this.codebaseEnv == null) {
  928.          this.codebaseEnv = new Hashtable();
  929.       }
  930.  
  931.    }
  932. }
  933.