package org.testfun.jee.runner.inject;
import junit.framework.AssertionFailedError;
import org.apache.log4j.Logger;
import org.testfun.jee.runner.EjbWithMockitoRunnerException;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static org.junit.Assert.fail;
public class ClassPathScanner {
private static final Logger LOGGER = Logger.getLogger(ClassPathScanner.class);
public List<String> getResourcesInClassPath() {
boolean jarScanningEnabled = Boolean.getBoolean("org.testfun.jee.enable_jar_scanning");
List<String> resourceNames = new LinkedList<>();
for (String root : getClasPathRoots()) {
File rootFile = new File(root);
if (rootFile.isDirectory())
if (rootFile.exists()) {
if (rootFile.isDirectory()) {
findResourcesFromDirectory(resourceNames, rootFile.getAbsolutePath().length() + 1, rootFile);
} else if (jarScanningEnabled) {
findResourcesFromJarFile(resourceNames, rootFile);
}
}
}
return resourceNames;
}
String[] getClasPathRoots() {
String pathSeparator = System.getProperty("path.separator");
return System.getProperty("java.class.path", ".").split(pathSeparator);
}
public void scan(Handler handler) {
ClassLoader classLoader = getClass().getClassLoader();
for (String resource : getResourcesInClassPath()) {
try {
String className = resource.replace('/', '.');
className = className.substring(0, className.length() - 6); // Remove the ".class" suffix (6 characters) from the resource name
Class<?> aClass = Class.forName(className, false, classLoader);
handler.classFound(aClass);
} catch (Throwable e) {
if (e instanceof AssertionFailedError) {
fail(e.getMessage());//someone wanted this to fail...
}
LOGGER.trace("Failed determining class details for resource: " + resource, e);
}
}
}
public static interface Handler {
public void classFound(Class<?> aClass);
}
private void findResourcesFromJarFile(List<String> resourceNames, File jarFile) {
ZipFile zipFile = null;
try {
zipFile = new ZipFile(jarFile);
Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();
while (zipFileEntries.hasMoreElements()) {
String fileName = zipFileEntries.nextElement().getName();
resourceNames.add(fileName);
}
} catch (Exception e) {
throw new EjbWithMockitoRunnerException("Failed finding resources in JAR: " + jarFile, e);
} finally {
if (zipFile != null) {
try {
zipFile.close();
} catch (IOException e) {
LOGGER.warn("Failed closing a resource", e);
}
}
}
}
private void findResourcesFromDirectory(List<String> resourceNames, int rootLength, File directory) {
File[] fileList = directory.listFiles();
if (fileList != null) {
for (File file : fileList) {
if (file.isDirectory()) {
findResourcesFromDirectory(resourceNames, rootLength, file);
} else {
String fileName = file.getAbsolutePath().substring(rootLength).replace('\\', '/');
resourceNames.add(fileName);
}
}
}
}
}