ClassPathTestCollector.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1package junit.runner;
2
3import java.util.*;
4import java.io.*;
5
6/**
7 * An implementation of a TestCollector that consults the
8 * class path. It considers all classes on the class path
9 * excluding classes in JARs. It leaves it up to subclasses
10 * to decide whether a class is a runnable Test.
11 *
12 * @see TestCollector
13 */
14public abstract class ClassPathTestCollector implements TestCollector {
15
16    static final int SUFFIX_LENGTH= ".class".length();
17
18    public ClassPathTestCollector() {
19    }
20
21    public Enumeration collectTests() {
22        String classPath= System.getProperty("java.class.path");
23        Hashtable result = collectFilesInPath(classPath);
24        return result.elements();
25    }
26
27    public Hashtable collectFilesInPath(String classPath) {
28        Hashtable result= collectFilesInRoots(splitClassPath(classPath));
29        return result;
30    }
31
32    Hashtable collectFilesInRoots(Vector roots) {
33        Hashtable result= new Hashtable(100);
34        Enumeration e= roots.elements();
35        while (e.hasMoreElements())
36            gatherFiles(new File((String)e.nextElement()), "", result);
37        return result;
38    }
39
40    void gatherFiles(File classRoot, String classFileName, Hashtable result) {
41        File thisRoot= new File(classRoot, classFileName);
42        if (thisRoot.isFile()) {
43            if (isTestClass(classFileName)) {
44                String className= classNameFromFile(classFileName);
45                result.put(className, className);
46            }
47            return;
48        }
49        String[] contents= thisRoot.list();
50        if (contents != null) {
51            for (int i= 0; i < contents.length; i++)
52                gatherFiles(classRoot, classFileName+File.separatorChar+contents[i], result);
53        }
54    }
55
56    Vector splitClassPath(String classPath) {
57        Vector result= new Vector();
58        String separator= System.getProperty("path.separator");
59        StringTokenizer tokenizer= new StringTokenizer(classPath, separator);
60        while (tokenizer.hasMoreTokens())
61            result.addElement(tokenizer.nextToken());
62        return result;
63    }
64
65    protected boolean isTestClass(String classFileName) {
66        return
67            classFileName.endsWith(".class") &&
68            classFileName.indexOf('$') < 0 &&
69            classFileName.indexOf("Test") > 0;
70    }
71
72    protected String classNameFromFile(String classFileName) {
73        // convert /a/b.class to a.b
74        String s= classFileName.substring(0, classFileName.length()-SUFFIX_LENGTH);
75        String s2= s.replace(File.separatorChar, '.');
76        if (s2.startsWith("."))
77            return s2.substring(1);
78        return s2;
79    }
80}
81