-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
193 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
fabric/src/main/java/cn/evole/mods/mcbot/util/ClassUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package cn.evole.mods.mcbot.util; | ||
|
||
|
||
import cn.evole.mods.mcbot.Const; | ||
|
||
import java.io.File; | ||
import java.net.JarURLConnection; | ||
import java.net.URL; | ||
import java.util.ArrayList; | ||
import java.util.Enumeration; | ||
import java.util.List; | ||
import java.util.jar.JarEntry; | ||
import java.util.jar.JarFile; | ||
/** | ||
* ClassUtil | ||
* | ||
* @author cnlimiter | ||
* @version 1.0 | ||
* @description 获取接口的所有实现类 理论上也可以用来获取类的所有子类 | ||
* 查询路径有限制,只局限于接口所在模块下,比如pandora-gateway,而非整个pandora(会递归搜索该文件夹下所以的实现类) | ||
* 路径中不可含中文,否则会异常。若要支持中文路径,需对该模块代码中url.getPath() 返回值进行urldecode. | ||
* @date 2024/3/11 13:31 | ||
*/ | ||
public class ClassUtil { | ||
public static ArrayList<Class> getAllClassByInterface(Class clazz) { | ||
ArrayList<Class> list = new ArrayList<>(); | ||
// 判断是否是一个接口 | ||
if (clazz.isInterface()) { | ||
try { | ||
ArrayList<Class> allClass = getAllClass(clazz.getPackage().getName()); | ||
/** | ||
* 循环判断路径下的所有类是否实现了指定的接口 并且排除接口类自己 | ||
*/ | ||
for (int i = 0; i < allClass.size(); i++) { | ||
/** | ||
* 判断是不是同一个接口 | ||
*/ | ||
// isAssignableFrom:判定此 Class 对象所表示的类或接口与指定的 Class | ||
// 参数所表示的类或接口是否相同,或是否是其超类或超接口 | ||
if (clazz.isAssignableFrom(allClass.get(i))) { | ||
if (!clazz.equals(allClass.get(i))) { | ||
// 自身并不加进去 | ||
list.add(allClass.get(i)); | ||
} | ||
} | ||
} | ||
} catch (Exception e) { | ||
Const.LOGGER.error("出现异常{}",e.getMessage()); | ||
throw new RuntimeException("出现异常"+e.getMessage()); | ||
} | ||
} | ||
Const.LOGGER.debug("class list size :"+list.size()); | ||
return list; | ||
} | ||
|
||
|
||
/** | ||
* 从一个指定路径下查找所有的类 | ||
* | ||
* @param packagename | ||
*/ | ||
private static ArrayList<Class> getAllClass(String packagename) { | ||
|
||
List<String> classNameList = getClassName(packagename); | ||
ArrayList<Class> list = new ArrayList<>(); | ||
|
||
for(String className : classNameList){ | ||
try { | ||
list.add(Class.forName(className)); | ||
} catch (ClassNotFoundException e) { | ||
Const.LOGGER.error("load class from name failed:"+className+e.getMessage()); | ||
throw new RuntimeException("load class from name failed:"+className+e.getMessage()); | ||
} | ||
} | ||
Const.LOGGER.debug("find list size :"+list.size()); | ||
return list; | ||
} | ||
|
||
/** | ||
* 获取某包下所有类 | ||
* @param packageName 包名 | ||
* @return 类的完整名称 | ||
*/ | ||
public static List<String> getClassName(String packageName) { | ||
|
||
List<String> fileNames = null; | ||
ClassLoader loader = Thread.currentThread().getContextClassLoader(); | ||
String packagePath = packageName.replace(".", "/"); | ||
URL url = loader.getResource(packagePath); | ||
if (url != null) { | ||
String type = url.getProtocol(); | ||
Const.LOGGER.debug("file type : " + type); | ||
if (type.equals("file")) { | ||
String fileSearchPath = url.getPath(); | ||
Const.LOGGER.debug("fileSearchPath: "+fileSearchPath); | ||
fileSearchPath = fileSearchPath.substring(0,fileSearchPath.indexOf("/classes")); | ||
Const.LOGGER.debug("fileSearchPath: "+fileSearchPath); | ||
fileNames = getClassNameByFile(fileSearchPath); | ||
} else if (type.equals("jar")) { | ||
try{ | ||
JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection(); | ||
JarFile jarFile = jarURLConnection.getJarFile(); | ||
fileNames = getClassNameByJar(jarFile,packagePath); | ||
}catch (java.io.IOException e){ | ||
throw new RuntimeException("open Package URL failed:"+e.getMessage()); | ||
} | ||
|
||
}else{ | ||
throw new RuntimeException("file system not support! cannot load MsgProcessor!"); | ||
} | ||
} | ||
return fileNames; | ||
} | ||
|
||
/** | ||
* 从项目文件获取某包下所有类 | ||
* @param filePath 文件路径 | ||
* @return 类的完整名称 | ||
*/ | ||
private static List<String> getClassNameByFile(String filePath) { | ||
List<String> myClassName = new ArrayList<String>(); | ||
File file = new File(filePath); | ||
File[] childFiles = file.listFiles(); | ||
for (File childFile : childFiles) { | ||
if (childFile.isDirectory()) { | ||
myClassName.addAll(getClassNameByFile(childFile.getPath())); | ||
} else { | ||
String childFilePath = childFile.getPath(); | ||
if (childFilePath.endsWith(".class")) { | ||
childFilePath = childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf(".")); | ||
childFilePath = childFilePath.replace("\\", "."); | ||
myClassName.add(childFilePath); | ||
} | ||
} | ||
} | ||
|
||
return myClassName; | ||
} | ||
|
||
/** | ||
* 从jar获取某包下所有类 | ||
* @return 类的完整名称 | ||
*/ | ||
private static List<String> getClassNameByJar(JarFile jarFile ,String packagePath) { | ||
List<String> myClassName = new ArrayList<String>(); | ||
try { | ||
Enumeration<JarEntry> entrys = jarFile.entries(); | ||
while (entrys.hasMoreElements()) { | ||
JarEntry jarEntry = entrys.nextElement(); | ||
String entryName = jarEntry.getName(); | ||
//LOG.info("entrys jarfile:"+entryName); | ||
if (entryName.endsWith(".class")) { | ||
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf(".")); | ||
myClassName.add(entryName); | ||
//LOG.debug("Find Class :"+entryName); | ||
} | ||
} | ||
} catch (Exception e) { | ||
Const.LOGGER.error("发生异常:"+e.getMessage()); | ||
throw new RuntimeException("发生异常:"+e.getMessage()); | ||
} | ||
return myClassName; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
fabric/src/main/java/cn/evole/mods/mcbot/util/FileUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package cn.evole.mods.mcbot.util; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
/** | ||
* FileUtil | ||
* | ||
* @author cnlimiter | ||
* @version 1.0 | ||
* @description | ||
* @date 2024/3/11 19:18 | ||
*/ | ||
public class FileUtil { | ||
public static void checkFolder(Path folder) { | ||
if (!folder.toFile().isDirectory()) { | ||
try { | ||
Files.createDirectories(folder); | ||
} catch (IOException ignored) { | ||
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
===ALGORITHM SHA-256 | ||
cn.evole.onebot:OneBot-Client:0.4.0 1b4321761f5c3a1b52bbc350b0aabc1571d3c1ef8cd3df3eee09022a25678ee6 | ||
cn.evole.onebot:OneBot-Client:0.4.0 3990bb0791cff13a2329aac6aae8aa18df77d7dac9d673a1961fb6750a4d545e | ||
cn.evole.config:AtomConfig-Toml:0.1.5 53e0c80d6d8fc789c8bdf75764474bf4a106e355d2dd761acb5ae627e14450c1 | ||
|