package junit.extensions.abbot; import java.io.*; import java.util.*; import java.util.zip.*; import java.net.URLClassLoader; import java.net.URL; import java.lang.reflect.*; import junit.framework.*; import junit.runner.*; import abbot.Log; import abbot.Platform; import abbot.util.PathClassLoader; /** Collects all available classes derived from ScriptTestCase in the current * classpath. */ public class ScriptTestCollector extends LoadingTestCollector { private ClassLoader loader; private static final String PACKAGE = "junit.extensions.abbot."; public ScriptTestCollector() { this(null); } public ScriptTestCollector(ClassLoader loader) { if (loader == null) { String path = System.getProperty("java.class.path"); loader = new PathClassLoader(path); } this.loader = loader; } private String convertURLsToClasspath(URL[] urls) { String PS = System.getProperty("path.separator"); String path = ""; for (int i=0;i < urls.length;i++) { if (!"".equals(path)) path += PS; URL url = urls[i]; if (url.getProtocol().equals("file")) { String file = url.getFile(); if (Platform.isWindows() && file.startsWith("/")) file = file.substring(1); path += file; } } return path; } /** Override to use something other than java.class.path. */ public Enumeration collectTests() { String jcp = System.getProperty("java.class.path"); String classPath = loader instanceof URLClassLoader ? convertURLsToClasspath(((URLClassLoader)loader).getURLs()) : jcp; Hashtable hash = collectFilesInPath(classPath); if (loader instanceof URLClassLoader) hash.putAll(collectFilesInPath(jcp)); return hash.elements(); } private ArrayList splitClassPath(String classPath) { ArrayList result= new ArrayList(); String separator= System.getProperty("path.separator"); StringTokenizer tokenizer= new StringTokenizer(classPath, separator); while (tokenizer.hasMoreTokens()) result.add(tokenizer.nextToken()); return result; } /** Collect files in zip archives as well as raw class files. */ public Hashtable collectFilesInPath(String classPath) { Hashtable hash = super.collectFilesInPath(classPath); Collection paths = splitClassPath(classPath); Iterator iter = paths.iterator(); while (iter.hasNext()) { String el = (String)iter.next(); if (el.endsWith(".zip") || el.endsWith(".jar")) { hash.putAll(scanArchive(el)); } } return hash; } protected Map scanArchive(String name) { Map map = new HashMap(); try { ZipFile zip = new ZipFile(name); Enumeration en = zip.entries(); while (en.hasMoreElements()) { ZipEntry entry = (ZipEntry)en.nextElement(); if (!entry.isDirectory()) { String filename = entry.getName(); if (isTestClass(filename)) { String cname = classNameFromFile(filename); map.put(cname, cname); } } } } catch(IOException e) { } return map; } protected boolean isTestClass(String classFileName) { boolean isTest = classFileName.endsWith(".class") && classFileName.indexOf("Test") > 0 && classFileName.indexOf('$') == -1; if (isTest) { String className = classNameFromFile(classFileName); try { Class testClass = Class.forName(className, true, loader); Class scriptFixture = Class.forName(PACKAGE + "ScriptFixture", true, loader); Class scriptSuite = Class.forName(PACKAGE + "ScriptTestSuite", true, loader); return (scriptFixture.isAssignableFrom(testClass) || scriptSuite.isAssignableFrom(testClass)) && Modifier.isPublic(testClass.getModifiers()) && TestSuite.getTestConstructor(testClass) != null; } catch(ClassNotFoundException e) { } catch(NoClassDefFoundError e) { } catch(NoSuchMethodException e) { } } return false; } protected String classNameFromFile(String classFileName) { String name = super.classNameFromFile(classFileName); return name.replace('/', '.'); } }