All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testng.internal.PackageUtils Maven / Gradle / Ivy

There is a newer version: 7.10.1
Show newest version
package org.testng.internal;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;

import org.testng.collections.Lists;

/**
 * Utility class that finds all the classes in a given package.
 *
 * 

Created on Feb 24, 2006 * * @author Cedric Beust */ public class PackageUtils { private static final String UTF_8 = "UTF-8"; private static final String PACKAGE_UTILS = PackageUtils.class.getSimpleName(); private static String[] testClassPaths; /** The additional class loaders to find classes in. */ private static final Collection classLoaders = new ConcurrentLinkedDeque<>(); private PackageUtils() { // Utility class. Defeat instantiation. } /** Add a class loader to the searchable loaders. */ public static void addClassLoader(final ClassLoader loader) { classLoaders.add(loader); } /** * @param packageName - The package name * @param included - The inclusion list. * @param excluded - The exclusion list * @return - The list of all the classes inside this package * @throws IOException - if there is an exception. */ public static String[] findClassesInPackage( String packageName, List included, List excluded) throws IOException { String packageOnly = packageName; boolean recursive = false; if (packageName.endsWith(".*")) { packageOnly = packageName.substring(0, packageName.lastIndexOf(".*")); recursive = true; } List vResult = Lists.newArrayList(); String packageDirName = packageOnly.replace('.', '/') + (packageOnly.length() > 0 ? "/" : ""); List dirs = Lists.newArrayList(); // go through additional class loaders List allClassLoaders = ClassHelper.appendContextualClassLoaders(Lists.newArrayList(classLoaders)); for (ClassLoader classLoader : allClassLoaders) { if (null == classLoader) { continue; } Enumeration dirEnumeration = classLoader.getResources(packageDirName); while (dirEnumeration.hasMoreElements()) { URL dir = dirEnumeration.nextElement(); dirs.add(dir); } } for (URL url : dirs) { String protocol = url.getProtocol(); if (!matchTestClasspath(url, packageDirName, recursive)) { continue; } if ("file".equals(protocol)) { findClassesInDirPackage( packageOnly, included, excluded, URLDecoder.decode(url.getFile(), UTF_8), recursive, vResult); } else if ("jar".equals(protocol)) { JarFile jar = ((JarURLConnection) url.openConnection()).getJarFile(); Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); if (name.charAt(0) == '/') { name = name.substring(1); } if (name.startsWith(packageDirName)) { int idx = name.lastIndexOf('/'); if (idx != -1) { packageName = name.substring(0, idx).replace('/', '.'); } if (recursive || packageName.equals(packageOnly)) { // it's not inside a deeper dir Utils.log(PACKAGE_UTILS, 4, "Package name is " + packageName); if (name.endsWith(".class") && !entry.isDirectory()) { String className = name.substring(packageName.length() + 1, name.length() - 6); Utils.log( PACKAGE_UTILS, 4, "Found class " + className + ", seeing it if it's included or excluded"); includeOrExcludeClass(packageName, className, included, excluded, vResult); } } } } } else if ("bundleresource".equals(protocol)) { try { Class[] params = {}; // BundleURLConnection URLConnection connection = url.openConnection(); Method thisMethod = url.openConnection().getClass().getDeclaredMethod("getFileURL", params); Object[] paramsObj = {}; URL fileUrl = (URL) thisMethod.invoke(connection, paramsObj); findClassesInDirPackage( packageOnly, included, excluded, URLDecoder.decode(fileUrl.getFile(), UTF_8), recursive, vResult); } catch (Exception ex) { // ignore - probably not an Eclipse OSGi bundle } } } return vResult.toArray(new String[0]); } private static String[] getTestClasspath() { if (null != testClassPaths) { return testClassPaths; } String testClasspath = RuntimeBehavior.getTestClasspath(); if (null == testClasspath) { return null; } String[] classpathFragments = Utils.split(testClasspath, File.pathSeparator); testClassPaths = new String[classpathFragments.length]; for (int i = 0; i < classpathFragments.length; i++) { String path; if (classpathFragments[i].toLowerCase().endsWith(".jar") || classpathFragments[i].toLowerCase().endsWith(".zip")) { path = classpathFragments[i] + "!/"; } else { if (classpathFragments[i].endsWith(File.separator)) { path = classpathFragments[i]; } else { path = classpathFragments[i] + "/"; } } testClassPaths[i] = path.replace('\\', '/'); } return testClassPaths; } private static boolean matchTestClasspath(URL url, String lastFragment, boolean recursive) { String[] classpathFragments = getTestClasspath(); if (null == classpathFragments) { return true; } String fileName = ""; try { fileName = URLDecoder.decode(url.getFile(), UTF_8); } catch (UnsupportedEncodingException ueex) { // ignore. should never happen } for (String classpathFrag : classpathFragments) { String path = classpathFrag + lastFragment; int idx = fileName.indexOf(path); if ((idx == -1) || (idx > 0 && fileName.charAt(idx - 1) != '/')) { continue; } if (fileName.endsWith(classpathFrag + lastFragment) || (recursive && fileName.charAt(idx + path.length()) == '/')) { return true; } } return false; } private static void findClassesInDirPackage( String packageName, List included, List excluded, String packagePath, final boolean recursive, List classes) { File dir = new File(packagePath); if (!dir.exists() || !dir.isDirectory()) { return; } File[] dirfiles = dir.listFiles( file -> (recursive && file.isDirectory()) || (file.getName().endsWith(".class")) || (file.getName().endsWith(".groovy"))); Utils.log(PACKAGE_UTILS, 4, "Looking for test classes in the directory: " + dir); if (dirfiles == null) { return; } for (File file : dirfiles) { if (file.isDirectory()) { findClassesInDirPackage( makeFullClassName(packageName, file.getName()), included, excluded, file.getAbsolutePath(), recursive, classes); } else { String className = file.getName().substring(0, file.getName().lastIndexOf('.')); Utils.log( PACKAGE_UTILS, 4, "Found class " + className + ", seeing it if it's included or excluded"); includeOrExcludeClass(packageName, className, included, excluded, classes); } } } private static String makeFullClassName(String pkg, String cls) { return pkg.length() > 0 ? pkg + "." + cls : cls; } private static void includeOrExcludeClass( String packageName, String className, List included, List excluded, List classes) { if (isIncluded(packageName, included, excluded)) { Utils.log(PACKAGE_UTILS, 4, "... Including class " + className); classes.add(makeFullClassName(packageName, className)); } else { Utils.log(PACKAGE_UTILS, 4, "... Excluding class " + className); } } /** @return true if name should be included. */ private static boolean isIncluded(String name, List included, List excluded) { boolean result; // // If no includes nor excludes were specified, return true. // if (included.isEmpty() && excluded.isEmpty()) { result = true; } else { boolean isIncluded = PackageUtils.find(name, included); boolean isExcluded = PackageUtils.find(name, excluded); if (isIncluded && !isExcluded) { result = true; } else if (isExcluded) { result = false; } else { result = included.isEmpty(); } } return result; } private static boolean find(String name, List list) { for (String regexpStr : list) { if (Pattern.matches(regexpStr, name)) { return true; } } return false; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy