001: package junit.extensions.abbot;
002:
003: import java.io.*;
004: import java.util.*;
005: import java.util.zip.*;
006: import java.net.URLClassLoader;
007: import java.net.URL;
008: import java.lang.reflect.*;
009:
010: import junit.framework.*;
011: import junit.runner.*;
012: import abbot.Platform;
013: import abbot.util.PathClassLoader;
014:
015: /** Collects all available classes derived from ScriptTestCase in the current
016: * classpath.
017: */
018:
019: public class ScriptTestCollector extends LoadingTestCollector {
020: private ClassLoader loader;
021:
022: private static final String PACKAGE = "junit.extensions.abbot.";
023:
024: public ScriptTestCollector() {
025: this (null);
026: }
027:
028: public ScriptTestCollector(ClassLoader loader) {
029: if (loader == null) {
030: String path = System.getProperty("java.class.path");
031: loader = new PathClassLoader(path);
032: }
033: this .loader = loader;
034: }
035:
036: private String convertURLsToClasspath(URL[] urls) {
037: String PS = System.getProperty("path.separator");
038: String path = "";
039: for (int i = 0; i < urls.length; i++) {
040: if (!"".equals(path))
041: path += PS;
042: URL url = urls[i];
043: if (url.getProtocol().equals("file")) {
044: String file = url.getFile();
045: if (Platform.isWindows() && file.startsWith("/"))
046: file = file.substring(1);
047: path += file;
048: }
049: }
050: return path;
051: }
052:
053: /** Override to use something other than java.class.path. */
054: public Enumeration collectTests() {
055: String jcp = System.getProperty("java.class.path");
056: String classPath = loader instanceof URLClassLoader ? convertURLsToClasspath(((URLClassLoader) loader)
057: .getURLs())
058: : jcp;
059: Hashtable hash = collectFilesInPath(classPath);
060: if (loader instanceof URLClassLoader)
061: hash.putAll(collectFilesInPath(jcp));
062: return hash.elements();
063: }
064:
065: private ArrayList splitClassPath(String classPath) {
066: ArrayList result = new ArrayList();
067: String separator = System.getProperty("path.separator");
068: StringTokenizer tokenizer = new StringTokenizer(classPath,
069: separator);
070: while (tokenizer.hasMoreTokens())
071: result.add(tokenizer.nextToken());
072: return result;
073: }
074:
075: /** Collect files in zip archives as well as raw class files. */
076: public Hashtable collectFilesInPath(String classPath) {
077: Hashtable hash = super .collectFilesInPath(classPath);
078: Collection paths = splitClassPath(classPath);
079: Iterator iter = paths.iterator();
080: while (iter.hasNext()) {
081: String el = (String) iter.next();
082: if (el.endsWith(".zip") || el.endsWith(".jar")) {
083: hash.putAll(scanArchive(el));
084: }
085: }
086: return hash;
087: }
088:
089: protected Map scanArchive(String name) {
090: Map map = new HashMap();
091: try {
092: ZipFile zip = new ZipFile(name);
093: Enumeration en = zip.entries();
094: while (en.hasMoreElements()) {
095: ZipEntry entry = (ZipEntry) en.nextElement();
096: if (!entry.isDirectory()) {
097: String filename = entry.getName();
098: if (isTestClass(filename)) {
099: String cname = classNameFromFile(filename);
100: map.put(cname, cname);
101: }
102: }
103: }
104: } catch (IOException e) {
105: }
106: return map;
107: }
108:
109: protected boolean isTestClass(String classFileName) {
110: boolean isTest = classFileName.endsWith(".class")
111: && classFileName.indexOf("Test") > 0
112: && classFileName.indexOf('$') == -1;
113:
114: if (isTest) {
115: String className = classNameFromFile(classFileName);
116: try {
117: Class testClass = Class
118: .forName(className, true, loader);
119: Class scriptFixture = Class.forName(PACKAGE
120: + "ScriptFixture", true, loader);
121: Class scriptSuite = Class.forName(PACKAGE
122: + "ScriptTestSuite", true, loader);
123: return (scriptFixture.isAssignableFrom(testClass) || scriptSuite
124: .isAssignableFrom(testClass))
125: && Modifier.isPublic(testClass.getModifiers())
126: && TestSuite.getTestConstructor(testClass) != null;
127: } catch (ClassNotFoundException e) {
128: } catch (NoClassDefFoundError e) {
129: } catch (NoSuchMethodException e) {
130: }
131: }
132: return false;
133: }
134:
135: protected String classNameFromFile(String classFileName) {
136: String name = super .classNameFromFile(classFileName);
137: return name.replace('/', '.');
138: }
139: }
|