Source code: mijava/ClassLoader.java
1 /*
2 @(#) $Id: ClassLoader.java,v 1.5 2002/03/25 20:42:52 hobb0001 Exp $
3 Copyright 2002 Michael Hobbs
4
5 This file is part of MIJava.
6
7 MIJava is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 MIJava is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with MIJava; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 package mijava;
23
24 import java.io.File;
25 import java.io.InputStream;
26 import java.io.IOException;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.ArrayList;
30 import java.util.zip.ZipFile;
31 import java.util.zip.ZipEntry;
32
33
34
35 class ClassLoader
36 extends java.lang.ClassLoader
37 {
38
39 private List classPath = new ArrayList();
40
41 protected Class loadClass(String name, boolean resolve)
42 throws ClassNotFoundException
43 {
44 Class result = findLoadedClass(name);
45 if (result == null) {
46 try {
47 result = findClass(name);
48 } catch (ClassNotFoundException e) {
49 // Odds are that if findClass() didn't find the class, then it's a
50 // class located in the system library. We call the parent class's
51 // loadClass() method to pick those up.
52 result = getParent().loadClass(name);
53 }
54 }
55 // At this point either 'result' has a value, or this method has thrown a
56 // ClassNotFoundException. So if we get to this point, then we know that
57 // 'result' has a value.
58 if (resolve) {
59 resolveClass(result);
60 }
61 return result;
62 }
63
64 protected Class findClass(String name)
65 throws ClassNotFoundException
66 {
67 String fileName = name.replace('.', File.separatorChar);
68 for (Iterator i=classPath.iterator(); i.hasNext(); ) {
69 String dirName = (String) i.next();
70 File dirFile = new File(dirName);
71 byte[] buffer = null;
72 if (dirFile.isDirectory()) {
73 File classFile = new File(dirName, fileName + ".class");
74 if (classFile.canRead()) {
75 try {
76 buffer = MIJava.readFile(classFile);
77 } catch (IOException e) {
78 throw new ClassNotFoundException(name, e);
79 }
80 }
81 } else {
82 // The dirFile is probably an archive file.
83 try {
84 buffer = readArchive(dirFile, fileName + ".class");
85 } catch (IOException e) {
86 throw new ClassNotFoundException(name, e);
87 }
88 }
89 if (buffer != null) {
90 return defineClass(name, buffer, 0, buffer.length);
91 }
92 } // for -- each item in classpath
93 throw new ClassNotFoundException(name);
94 }
95
96 protected void setClassPath(String classPath)
97 {
98 this.classPath.clear();
99 String[] paths = classPath.split(File.pathSeparator + "+");
100 for (int i=0; i<paths.length; ++i) {
101 this.classPath.add(paths[i]);
102 }
103 }
104
105 protected void prependToClassPath(String path)
106 {
107 classPath.add(0, path);
108 }
109
110 private static final byte[] readArchive(File archive, String fileName)
111 throws IOException
112 {
113 ZipFile zipFile = new ZipFile(archive);
114 ZipEntry entry = zipFile.getEntry(fileName);
115 if (entry == null) return null;
116 int remaining = (int) entry.getSize();
117 byte[] result = new byte[remaining];
118 InputStream inStream = zipFile.getInputStream(entry);
119 for (int offset = 0; remaining > 0;) {
120 int bytesRead = inStream.read(result, offset, remaining);
121 if (bytesRead == -1) break;
122 offset += bytesRead;
123 remaining -= bytesRead;
124 }
125 zipFile.close();
126 return result;
127 }
128
129 private static final String _ID_ =
130 "@(#) $Id: ClassLoader.java,v 1.5 2002/03/25 20:42:52 hobb0001 Exp $";
131 }
132
133