KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > ZipLoader


1 // Copyright (c) 1997 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.bytecode;
5
6 /** Load classes from a Zip archive.
7  * @author Per Bothner
8  */

9
10 public class ZipLoader extends ClassLoader JavaDoc
11 {
12   /** The zip archive from which we will load the classes.
13    * The format of the archive is the same as classes.zip. */

14   java.util.zip.ZipFile JavaDoc zar;
15
16   /** Number of classes managed by this loader. */
17   int size;
18
19   /** name of ZipFile */
20   private String JavaDoc zipname;
21
22   /* #ifdef JAVA5 */
23   // /* A list of pairs of (name, class) of already loaded classes. */
24
// private java.util.Vector<Object> loadedClasses;
25
/* #else */
26   private java.util.Vector JavaDoc loadedClasses;
27   /* #endif */
28
29   public ZipLoader (String JavaDoc name) throws java.io.IOException JavaDoc
30   {
31     this.zipname=name;
32     this.zar = new java.util.zip.ZipFile JavaDoc(name);
33     size = 0;
34     java.util.Enumeration JavaDoc e = this.zar.entries();
35     while (e.hasMoreElements())
36       {
37     java.util.zip.ZipEntry JavaDoc ent = (java.util.zip.ZipEntry JavaDoc) e.nextElement();
38     if (! ent.isDirectory())
39       size++;
40       }
41     /* #ifdef JAVA5 */
42     // loadedClasses = new java.util.Vector<Object>(size);
43
/* #else */
44     loadedClasses = new java.util.Vector JavaDoc(size);
45     /* #endif */
46   }
47
48   public Class JavaDoc loadClass (String JavaDoc name, boolean resolve)
49        throws ClassNotFoundException JavaDoc
50   {
51     Class JavaDoc clas;
52     int index = loadedClasses.indexOf(name);
53     if (index >= 0)
54       clas = (Class JavaDoc) loadedClasses.elementAt(index+1);
55     else if (zar == null && loadedClasses.size() == 2*size)
56       clas = Class.forName(name);
57     else
58       {
59     boolean reopened=false;
60     String JavaDoc member_name = name.replace ('.', '/') + ".class";
61     if (this.zar == null)
62       {
63         try {
64           this.zar=new java.util.zip.ZipFile JavaDoc(zipname);
65           reopened=true;
66         }
67         catch (java.io.IOException JavaDoc ex)
68           {
69         throw new
70           ClassNotFoundException JavaDoc ("IOException while loading "
71                       + member_name + " from ziparchive \""
72                       + name + "\": " + ex.toString ());
73           }
74       }
75     java.util.zip.ZipEntry JavaDoc member = zar.getEntry(member_name);
76     if (member == null) {
77       if (reopened) {
78         try {
79           close();
80         } catch (java.io.IOException JavaDoc e) {
81           throw new RuntimeException JavaDoc("failed to close \""+zipname+"\"");
82         }
83       }
84       clas = Class.forName(name);
85     }
86     else
87       {
88         try
89           {
90         int member_size = (int) member.getSize();
91         java.io.InputStream JavaDoc strm = zar.getInputStream(member);
92         byte[] bytes = new byte[member_size];
93         new java.io.DataInputStream JavaDoc(strm).readFully(bytes);
94         clas = defineClass (name, bytes, 0, member_size);
95         loadedClasses.addElement(name);
96         loadedClasses.addElement(clas);
97         if (2 * size == loadedClasses.size())
98           close();
99           }
100         catch (java.io.IOException JavaDoc ex)
101           {
102         throw new
103           ClassNotFoundException JavaDoc ("IOException while loading "
104                       + member_name + " from ziparchive \""
105                       + name + "\": " + ex.toString ());
106           }
107       }
108       }
109
110     if (resolve)
111       resolveClass (clas);
112     return clas;
113   }
114
115   /** Load all classes immediately from zip archive, close archive.
116    * @return main class (1st class in archive).
117    */

118   public Class JavaDoc loadAllClasses ()
119     throws java.io.IOException JavaDoc
120   {
121     java.util.Enumeration JavaDoc e = this.zar.entries();
122     Class JavaDoc mainClass = null;
123     while (e.hasMoreElements())
124       {
125     java.util.zip.ZipEntry JavaDoc member =
126       (java.util.zip.ZipEntry JavaDoc) e.nextElement();
127     String JavaDoc name=member.getName().replace('/','.');
128     name=name.substring(0,name.length()-"/class".length());
129     int member_size = (int) member.getSize();
130     java.io.InputStream JavaDoc strm = zar.getInputStream(member);
131     byte[] bytes = new byte[member_size];
132     new java.io.DataInputStream JavaDoc(strm).readFully(bytes);
133     Class JavaDoc clas = defineClass (name, bytes, 0, member_size);
134         if (mainClass == null)
135           mainClass = clas;
136     loadedClasses.addElement(name);
137     loadedClasses.addElement(clas);
138       }
139     close();
140     return mainClass;
141   }
142
143   /** Close the zip archive - loadClass will reopen if necessary. */
144   public void close()
145     throws java.io.IOException JavaDoc
146   {
147     if (zar != null)
148       zar.close ();
149     zar = null;
150   }
151
152 }
153
Popular Tags