158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpackage junit.runner;
258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.io.File;
458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.Enumeration;
558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.Hashtable;
658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.StringTokenizer;
758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotimport java.util.Vector;
858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot/**
1058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * An implementation of a TestCollector that consults the
1158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * class path. It considers all classes on the class path
1258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * excluding classes in JARs. It leaves it up to subclasses
1358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * to decide whether a class is a runnable Test.
1458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot *
1558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot * @see TestCollector
1658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot */
1758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabotpublic abstract class ClassPathTestCollector implements TestCollector {
1858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
1958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	static final int SUFFIX_LENGTH= ".class".length();
2058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
2158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public ClassPathTestCollector() {
2258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
2358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
2458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public Enumeration collectTests() {
2558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String classPath= System.getProperty("java.class.path");
2658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Hashtable result = collectFilesInPath(classPath);
2758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return result.elements();
2858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
2958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
3058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	public Hashtable collectFilesInPath(String classPath) {
3158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Hashtable result= collectFilesInRoots(splitClassPath(classPath));
3258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return result;
3358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
3458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
3558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	Hashtable collectFilesInRoots(Vector roots) {
3658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Hashtable result= new Hashtable(100);
3758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Enumeration e= roots.elements();
3858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		while (e.hasMoreElements())
3958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			gatherFiles(new File((String)e.nextElement()), "", result);
4058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return result;
4158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
4258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
4358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	void gatherFiles(File classRoot, String classFileName, Hashtable result) {
4458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		File thisRoot= new File(classRoot, classFileName);
4558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (thisRoot.isFile()) {
4658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			if (isTestClass(classFileName)) {
4758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				String className= classNameFromFile(classFileName);
4858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				result.put(className, className);
4958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			}
5058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return;
5158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
5258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String[] contents= thisRoot.list();
5358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (contents != null) {
5458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			for (int i= 0; i < contents.length; i++)
5558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot				gatherFiles(classRoot, classFileName+File.separatorChar+contents[i], result);
5658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		}
5758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
5858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
5958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	Vector splitClassPath(String classPath) {
6058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		Vector result= new Vector();
6158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String separator= System.getProperty("path.separator");
6258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		StringTokenizer tokenizer= new StringTokenizer(classPath, separator);
6358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		while (tokenizer.hasMoreTokens())
6458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			result.addElement(tokenizer.nextToken());
6558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return result;
6658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
6758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
6858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected boolean isTestClass(String classFileName) {
6958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return
7058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			classFileName.endsWith(".class") &&
7158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			classFileName.indexOf('$') < 0 &&
7258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			classFileName.indexOf("Test") > 0;
7358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
7458a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot
7558a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	protected String classNameFromFile(String classFileName) {
7658a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		// convert /a/b.class to a.b
7758a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String s= classFileName.substring(0, classFileName.length()-SUFFIX_LENGTH);
7858a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		String s2= s.replace(File.separatorChar, '.');
7958a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		if (s2.startsWith("."))
8058a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot			return s2.substring(1);
8158a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot		return s2;
8258a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot	}
8358a8b0aba2dec5695628a2bf25a3fae42c2c3533Brett Chabot}
84