Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.neko233.config233.utils.PackageScannerForConfig233 Maven / Gradle / Ivy
package com.neko233.config233.utils;
import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
public final class PackageScannerForConfig233 {
private PackageScannerForConfig233() {
}
public static Set> scanClass(String packageName, boolean recursive, Class> parentClass) {
if (parentClass == null) {
return Collections.emptySet();
} else {
parentClass.getClass();
return scanClass(packageName, recursive, parentClass::isAssignableFrom);
}
}
public static Set> scanClassRecursive(String packageName, Class> parentClass) {
return scanClass(packageName, true, parentClass);
}
public static Set> scanClass(String packageName, boolean recursive) {
return scanClass(packageName, recursive, (clazz) -> {
return true;
});
}
public static Set> scanClass(Class> appClass) {
return scanClass(appClass.getPackage().getName(), true, (clazz) -> {
return true;
});
}
public static Set> scanClass(Class> appClass, boolean recursive, ClassFilterApi filter) {
return scanClass(appClass.getPackage().getName(), recursive, filter);
}
/**
* 扫描包中的类
*
* @param packageName 包名
* @param recursive 是否递归扫描子目录
* @param filter 过滤器
* @return 类集合
*/
public static Set> scanClass(String packageName, boolean recursive, ClassFilterApi filter) {
Set> resultSet = new HashSet<>();
if (packageName == null || packageName.isEmpty()) {
return resultSet;
}
String packagePath = packageName.replace('.', '/');
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
Enumeration urls = classLoader.getResources(packagePath);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
String protocol = url.getProtocol();
if ("file".equalsIgnoreCase(protocol)) {
// 扫描文件目录中的类
String filePath = URLDecoder.decode(url.getFile(), StandardCharsets.UTF_8.toString());
scanClassFromDir(resultSet, filePath, packageName, recursive, filter);
} else if ("jar".equalsIgnoreCase(protocol)) {
// 扫描 JAR 文件中的类
scanClassFromJar(resultSet, url, packageName, recursive, filter);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return resultSet;
}
/**
* 从文件目录中扫描类
*
* @param resultSet 结果集
* @param filePath 文件路径
* @param packageName 包名
* @param recursive 是否递归扫描子目录
* @param filter 过滤器
*/
private static void scanClassFromDir(Set> resultSet, String filePath, String packageName, boolean recursive, ClassFilterApi filter) {
File dir = new File(filePath);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
File[] files = dir.listFiles(file -> file.isDirectory() || file.getName().endsWith(".class"));
if (files != null) {
for (File file : files) {
if (file.isDirectory() && recursive) {
// 递归扫描子目录
scanClassFromDir(resultSet, file.getAbsolutePath(), packageName + "." + file.getName(), recursive, filter);
} else if (file.getName().endsWith(".class")) {
// 加载类
String className = packageName + '.' + file.getName().substring(0, file.getName().length() - 6);
addClass(resultSet, className, filter);
}
}
}
}
/**
* 从 JAR 文件中扫描类
*
* @param resultSet 结果集
* @param url JAR 文件 URL
* @param packageName 包名
* @param recursive 是否递归扫描子目录
* @param filter 过滤器
*/
private static void scanClassFromJar(Set> resultSet, URL url, String packageName, boolean recursive, ClassFilterApi filter) {
try {
// 打开 Jar 文件连接
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
JarFile jarFile = jarURLConnection.getJarFile();
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.startsWith(packageName.replace('.', '/'))) {
// 匹配包名
int idx = name.lastIndexOf('/');
if ((idx != -1 || recursive) && name.endsWith(".class") && !entry.isDirectory()) {
// 匹配类名-去掉 .class 后缀
String className = name.substring(0, name.length() - 6).replace('/', '.');
addClass(resultSet, className, filter);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 添加类
*
* @param resultSet 结果集
* @param className 类名称
* @param filter 过滤器
*/
private static void addClass(Set> resultSet, String className, ClassFilterApi filter) {
try {
Class> clazz = Class.forName(className);
if (filter == null || filter.isNeed(clazz)) {
resultSet.add(clazz);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Set> scanClassWithJar(String packageName, boolean recursive, ClassFilterApi filter) {
if (packageName != null && !packageName.isEmpty()) {
String packagePath = packageName.replace('.', '/');
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Set> resultSet = new HashSet();
try {
Enumeration urlEnum = cl.getResources(packagePath);
while (urlEnum.hasMoreElements()) {
URL currUrl = (URL) urlEnum.nextElement();
String protocol = currUrl.getProtocol();
Set> tmpSet = null;
if ("FILE".equalsIgnoreCase(protocol)) {
tmpSet = scanClassFromDir(new File(currUrl.getFile()), packageName, recursive, filter);
} else if ("JAR".equalsIgnoreCase(protocol)) {
String fileStr = currUrl.getFile();
if (fileStr.startsWith("file:")) {
fileStr = fileStr.substring(5);
}
if (fileStr.lastIndexOf(33) > 0) {
fileStr = fileStr.substring(0, fileStr.lastIndexOf(33));
}
tmpSet = scanClassFromJar(new File(fileStr), packageName, recursive, filter);
}
if (tmpSet != null) {
resultSet.addAll(tmpSet);
}
}
return resultSet;
} catch (Exception var11) {
throw new RuntimeException(var11);
}
} else {
return null;
}
}
public static Set> scanClassFromDir(File dirFile, String packageName, boolean recursive, ClassFilterApi filter) {
if (dirFile.exists() && dirFile.isDirectory()) {
File[] subFileArr = dirFile.listFiles();
if (subFileArr != null && subFileArr.length > 0) {
Queue fileQ = new LinkedList(Arrays.asList(subFileArr));
Set> resultSet = new HashSet();
while (true) {
while (!fileQ.isEmpty()) {
File currFile = (File) fileQ.poll();
if (currFile.isDirectory() && recursive) {
subFileArr = currFile.listFiles();
if (subFileArr != null && subFileArr.length > 0) {
fileQ.addAll(Arrays.asList(subFileArr));
}
} else if (currFile.isFile() && currFile.getName().endsWith(".class")) {
String clazzName = currFile.getAbsolutePath();
clazzName = clazzName.substring(dirFile.getAbsolutePath().length(), clazzName.lastIndexOf(46));
clazzName = clazzName.replace('\\', '/');
clazzName = trimLeft(clazzName, "/");
clazzName = join(clazzName.split("/"), ".");
clazzName = packageName + "." + clazzName;
try {
Class> clazzObj = Class.forName(clazzName);
if (null == filter || !filter.isNotNeed(clazzObj)) {
resultSet.add(clazzObj);
}
} catch (Exception var10) {
throw new RuntimeException(var10);
}
}
}
return resultSet;
}
} else {
return null;
}
} else {
return null;
}
}
private static Set> scanClassFromJar(File jarFilePath, String packageName, boolean recursive, ClassFilterApi filter) {
if (jarFilePath != null && !jarFilePath.isDirectory()) {
Set> resultSet = new HashSet();
try {
JarInputStream jarIn = new JarInputStream(Files.newInputStream(jarFilePath.toPath()));
while (true) {
Class clazzObj;
do {
String entryName;
String tmpStr;
do {
do {
JarEntry entry;
do {
if ((entry = jarIn.getNextJarEntry()) == null) {
jarIn.close();
return resultSet;
}
} while (entry.isDirectory());
entryName = entry.getName();
} while (!entryName.endsWith(".class"));
if (recursive) {
break;
}
tmpStr = entryName.substring(0, entryName.lastIndexOf(47));
tmpStr = join(tmpStr.split("/"), ".");
} while (!packageName.equals(tmpStr));
tmpStr = entryName.substring(0, entryName.lastIndexOf(46));
tmpStr = join(tmpStr.split("/"), ".");
clazzObj = Class.forName(tmpStr);
} while (null != filter && !filter.isNeed(clazzObj));
resultSet.add(clazzObj);
}
} catch (Exception var10) {
throw new RuntimeException(var10);
}
} else {
return null;
}
}
private static String join(String[] strArr, String joiner) {
if (null != strArr && strArr.length > 0) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < strArr.length; ++i) {
if (i > 0) {
sb.append(joiner);
}
sb.append(strArr[i]);
}
return sb.toString();
} else {
return "";
}
}
private static String trimLeft(String src, String trimStr) {
if (null != src && !src.isEmpty()) {
if (null != trimStr && !trimStr.isEmpty()) {
if (src.equals(trimStr)) {
return "";
} else {
while (src.startsWith(trimStr)) {
src = src.substring(trimStr.length());
}
return src;
}
} else {
return src;
}
} else {
return "";
}
}
@FunctionalInterface
public interface ClassFilterApi {
boolean isNeed(Class> var1);
default boolean isNotNeed(Class> clazz) {
return !this.isNeed(clazz);
}
}
}