KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > junit > runner > TestCaseClassLoader


1 package junit.runner;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.File JavaDoc;
5 import java.io.FileInputStream JavaDoc;
6 import java.io.IOException JavaDoc;
7 import java.io.InputStream JavaDoc;
8 import java.net.URL JavaDoc;
9 import java.util.Enumeration JavaDoc;
10 import java.util.Properties JavaDoc;
11 import java.util.StringTokenizer JavaDoc;
12 import java.util.Vector JavaDoc;
13 import java.util.zip.ZipEntry JavaDoc;
14 import java.util.zip.ZipFile JavaDoc;
15
16 /**
17  * A custom class loader which enables the reloading
18  * of classes for each test run. The class loader
19  * can be configured with a list of package paths that
20  * should be excluded from loading. The loading
21  * of these packages is delegated to the system class
22  * loader. They will be shared across test runs.
23  * <p>
24  * The list of excluded package paths is specified in
25  * a properties file "excluded.properties" that is located in
26  * the same place as the TestCaseClassLoader class.
27  * <p>
28  * <b>Known limitation:</b> the TestCaseClassLoader cannot load classes
29  * from jar files.
30  */

31
32
33 public class TestCaseClassLoader extends ClassLoader JavaDoc {
34     /** scanned class path */
35     private Vector JavaDoc fPathItems;
36     /** default excluded paths */
37     private String JavaDoc[] defaultExclusions= {
38         "junit.framework.",
39         "junit.extensions.",
40         "junit.runner."
41     };
42     /** name of excluded properties file */
43     static final String JavaDoc EXCLUDED_FILE= "excluded.properties";
44     /** excluded paths */
45     private Vector JavaDoc fExcluded;
46      
47     /**
48      * Constructs a TestCaseLoader. It scans the class path
49      * and the excluded package paths
50      */

51     public TestCaseClassLoader() {
52         this(System.getProperty("java.class.path"));
53     }
54     
55     /**
56      * Constructs a TestCaseLoader. It scans the class path
57      * and the excluded package paths
58      */

59     public TestCaseClassLoader(String JavaDoc classPath) {
60         scanPath(classPath);
61         readExcludedPackages();
62     }
63
64     private void scanPath(String JavaDoc classPath) {
65         String JavaDoc separator= System.getProperty("path.separator");
66         fPathItems= new Vector JavaDoc(10);
67         StringTokenizer JavaDoc st= new StringTokenizer JavaDoc(classPath, separator);
68         while (st.hasMoreTokens()) {
69             fPathItems.addElement(st.nextToken());
70         }
71     }
72     
73     public URL JavaDoc getResource(String JavaDoc name) {
74         return ClassLoader.getSystemResource(name);
75     }
76     
77     public InputStream JavaDoc getResourceAsStream(String JavaDoc name) {
78         return ClassLoader.getSystemResourceAsStream(name);
79     }
80     
81     public boolean isExcluded(String JavaDoc name) {
82         for (int i= 0; i < fExcluded.size(); i++) {
83             if (name.startsWith((String JavaDoc) fExcluded.elementAt(i))) {
84                 return true;
85             }
86         }
87         return false;
88     }
89     
90     public synchronized Class JavaDoc loadClass(String JavaDoc name, boolean resolve)
91         throws ClassNotFoundException JavaDoc {
92             
93         Class JavaDoc c= findLoadedClass(name);
94         if (c != null)
95             return c;
96         //
97
// Delegate the loading of excluded classes to the
98
// standard class loader.
99
//
100
if (isExcluded(name)) {
101             try {
102                 c= findSystemClass(name);
103                 return c;
104             } catch (ClassNotFoundException JavaDoc e) {
105                 // keep searching
106
}
107         }
108         if (c == null) {
109             byte[] data= lookupClassData(name);
110             if (data == null)
111                 throw new ClassNotFoundException JavaDoc();
112             c= defineClass(name, data, 0, data.length);
113         }
114         if (resolve)
115             resolveClass(c);
116         return c;
117     }
118     
119     private byte[] lookupClassData(String JavaDoc className) throws ClassNotFoundException JavaDoc {
120         byte[] data= null;
121         for (int i= 0; i < fPathItems.size(); i++) {
122             String JavaDoc path= (String JavaDoc) fPathItems.elementAt(i);
123             String JavaDoc fileName= className.replace('.', '/')+".class";
124             if (isJar(path)) {
125                 data= loadJarData(path, fileName);
126             } else {
127                 data= loadFileData(path, fileName);
128             }
129             if (data != null)
130                 return data;
131         }
132         throw new ClassNotFoundException JavaDoc(className);
133     }
134         
135     boolean isJar(String JavaDoc pathEntry) {
136         return pathEntry.endsWith(".jar") || pathEntry.endsWith(".zip");
137     }
138
139     private byte[] loadFileData(String JavaDoc path, String JavaDoc fileName) {
140         File JavaDoc file= new File JavaDoc(path, fileName);
141         if (file.exists()) {
142             return getClassData(file);
143         }
144         return null;
145     }
146     
147     private byte[] getClassData(File JavaDoc f) {
148         FileInputStream JavaDoc stream= null;
149         try {
150             stream= new FileInputStream JavaDoc(f);
151             ByteArrayOutputStream JavaDoc out= new ByteArrayOutputStream JavaDoc(1000);
152             byte[] b= new byte[1000];
153             int n;
154             while ((n= stream.read(b)) != -1)
155                 out.write(b, 0, n);
156             stream.close();
157             out.close();
158             return out.toByteArray();
159
160         } catch (IOException JavaDoc e) {
161         }
162         finally {
163             if (stream != null)
164                 try {
165                     stream.close();
166                 } catch (IOException JavaDoc e1) {
167                 }
168         }
169         return null;
170     }
171
172     private byte[] loadJarData(String JavaDoc path, String JavaDoc fileName) {
173         ZipFile JavaDoc zipFile= null;
174         InputStream JavaDoc stream= null;
175         File JavaDoc archive= new File JavaDoc(path);
176         if (!archive.exists())
177             return null;
178         try {
179             zipFile= new ZipFile JavaDoc(archive);
180         } catch(IOException JavaDoc io) {
181             return null;
182         }
183         ZipEntry JavaDoc entry= zipFile.getEntry(fileName);
184         if (entry == null)
185             return null;
186         int size= (int) entry.getSize();
187         try {
188             stream= zipFile.getInputStream(entry);
189             byte[] data= new byte[size];
190             int pos= 0;
191             while (pos < size) {
192                 int n= stream.read(data, pos, data.length - pos);
193                 pos += n;
194             }
195             zipFile.close();
196             return data;
197         } catch (IOException JavaDoc e) {
198         } finally {
199             try {
200                 if (stream != null)
201                     stream.close();
202             } catch (IOException JavaDoc e) {
203             }
204         }
205         return null;
206     }
207     
208     private void readExcludedPackages() {
209         fExcluded= new Vector JavaDoc(10);
210         for (int i= 0; i < defaultExclusions.length; i++)
211             fExcluded.addElement(defaultExclusions[i]);
212             
213         InputStream JavaDoc is= getClass().getResourceAsStream(EXCLUDED_FILE);
214         if (is == null)
215             return;
216         Properties JavaDoc p= new Properties JavaDoc();
217         try {
218             p.load(is);
219         }
220         catch (IOException JavaDoc e) {
221             return;
222         } finally {
223             try {
224                 is.close();
225             } catch (IOException JavaDoc e) {
226             }
227         }
228         for (Enumeration JavaDoc e= p.propertyNames(); e.hasMoreElements(); ) {
229             String JavaDoc key= (String JavaDoc)e.nextElement();
230             if (key.startsWith("excluded.")) {
231                 String JavaDoc path= p.getProperty(key);
232                 path= path.trim();
233                 if (path.endsWith("*"))
234                     path= path.substring(0, path.length()-1);
235                 if (path.length() > 0)
236                     fExcluded.addElement(path);
237             }
238         }
239     }
240 }
Popular Tags