01: package net.sf.mockcreator.codegeneration;
02:
03: import java.io.BufferedInputStream;
04: import java.io.FileInputStream;
05: import java.io.FileNotFoundException;
06: import java.io.IOException;
07:
08: import java.util.zip.ZipEntry;
09: import java.util.zip.ZipFile;
10: import java.util.zip.ZipInputStream;
11:
12: /**
13: * Loads class from either one of given directories, or from
14: * parent classloader.
15: *
16: * TODO: usage? why created?
17: */
18: public class DirClassLoader extends ClassLoader {
19: String[] dirs;
20:
21: public DirClassLoader(ClassLoader parent, String[] directories) {
22: super (parent);
23: dirs = directories;
24: }
25:
26: protected Class findClass(String classname)
27: throws ClassNotFoundException {
28: if (dirs != null) {
29: for (int i = 0; i < dirs.length; ++i) {
30: try {
31: return loadClass(classname, dirs[i]);
32: } catch (Throwable ex) {
33: }
34:
35: try {
36: return loadClassFromJar(classname, dirs[i]);
37: } catch (Throwable ex) {
38: }
39: }
40: }
41:
42: return super .findClass(classname);
43: }
44:
45: private Class loadClassFromJar(String classname, String jar)
46: throws IOException, ClassNotFoundException {
47: classname = classname.replace('.', '/');
48: classname += ".class";
49:
50: ZipFile zf = new ZipFile(jar);
51: ZipEntry ze = zf.getEntry(classname);
52: int siz = (int) ze.getSize();
53:
54: FileInputStream fis = new FileInputStream(jar);
55: BufferedInputStream bis = new BufferedInputStream(fis);
56: ZipInputStream zis = new ZipInputStream(bis);
57:
58: while ((ze = zis.getNextEntry()) != null) {
59: if (!ze.getName().equals(classname)) {
60: continue;
61: }
62:
63: byte[] buf = new byte[siz];
64: int off = 0;
65:
66: while ((siz - off) > 0) {
67: int chunk = zis.read(buf, off, siz - off);
68: off += chunk;
69: }
70:
71: return super .defineClass(buf, 0, siz);
72: }
73:
74: throw new ClassNotFoundException(classname);
75: }
76:
77: private Class loadClass(String classname, String dir)
78: throws FileNotFoundException, IOException, ClassFormatError {
79: String subpath = classname.replace('.', '/');
80: subpath += ".class";
81:
82: String filename = dir + "/" + subpath;
83: FileInputStream fir = new FileInputStream(filename);
84:
85: byte[] buf = new byte[fir.available()];
86: int off = 0;
87: int len = fir.available();
88:
89: while (fir.available() > 0) {
90: int read = fir.read(buf, off, len);
91: off += read;
92: len -= read;
93: }
94:
95: return super .defineClass(buf, 0, buf.length);
96: }
97: }
|