dfkndsfjkdsjjdssdf
This commit is contained in:
136
TODO/ClassFinder.java
Normal file
136
TODO/ClassFinder.java
Normal file
@@ -0,0 +1,136 @@
|
||||
package hdvtdev.telegram.core.objects;
|
||||
|
||||
import hdvtdev.telegram.annotations.handlers.CallbackQueryHandler;
|
||||
import hdvtdev.telegram.annotations.handlers.TextMessageHandler;
|
||||
import hdvtdev.telegram.objects.CallbackQuery;
|
||||
import hdvtdev.telegram.objects.Message;
|
||||
import hdvtdev.telegram.objects.Update;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.CodeSource;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public abstract class ClassFinder {
|
||||
|
||||
private static final Set<Class<? extends Annotation>> annotationsToSearch = Set.of(TextMessageHandler.class, CallbackQueryHandler.class);
|
||||
private static final Set<Class<?>> methodsArgumentType = Set.of(Message.class, Update.class, CallbackQuery.class);
|
||||
|
||||
private static ErrorHandler errorHandler;
|
||||
|
||||
public static Map<Class<?>, Map<String, InvokeMethod>> getClasses() {
|
||||
|
||||
Map<Class<?>, Map<String, InvokeMethod>> allMethods = new HashMap<>();
|
||||
annotationsToSearch.forEach(annotation -> allMethods.put(annotation, new HashMap<>()));
|
||||
|
||||
CodeSource codeSource = ClassFinder.class.getProtectionDomain().getCodeSource();
|
||||
if (codeSource != null) {
|
||||
try {
|
||||
String path = codeSource.getLocation().toURI().getPath();
|
||||
File file = new File(URLDecoder.decode(path, StandardCharsets.UTF_8));
|
||||
|
||||
if (file.isFile() && file.getName().endsWith(".jar")) {
|
||||
processJar(file, allMethods);
|
||||
} else if (file.isDirectory()) {
|
||||
processDirectory(file, "", allMethods);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Map.of();
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableMap(allMethods);
|
||||
}
|
||||
|
||||
private static void processDirectory(File directory, String packageName, Map<Class<?>, Map<String, InvokeMethod>> methods) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) return;
|
||||
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
processDirectory(file, packageName + file.getName() + ".", methods);
|
||||
} else if (file.getName().endsWith(".class")) {
|
||||
|
||||
String className = packageName + file.getName().replace(".class", "");
|
||||
loadClass(className, methods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void processJar(File jarFile, Map<Class<?>, Map<String, InvokeMethod>> methods) {
|
||||
try (JarFile jar = new JarFile(jarFile)) {
|
||||
Enumeration<JarEntry> entries = jar.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
String className = entry.getName()
|
||||
.replace("/", ".")
|
||||
.replace(".class", "");
|
||||
|
||||
loadClass(className, methods);
|
||||
}
|
||||
}
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<Class<?>, Map<String, InvokeMethod>> localScan(Class<?> cls) {
|
||||
Map<Class<?>, Map<String, InvokeMethod>> allMethods = new HashMap<>();
|
||||
annotationsToSearch.forEach(annotation -> allMethods.put(annotation, new HashMap<>()));
|
||||
loadClass(cls.getName(), allMethods);
|
||||
return allMethods;
|
||||
}
|
||||
|
||||
|
||||
private static void loadClass(String className, Map<Class<?>, Map<String, InvokeMethod>> methods) {
|
||||
try {
|
||||
Class<?> c = Class.forName(className);
|
||||
|
||||
for (Method method : c.getDeclaredMethods()) {
|
||||
|
||||
Class<?>[] parameters = method.getParameterTypes();
|
||||
|
||||
if (parameters.length != 0 && !methodsArgumentType.contains(parameters[0])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(CallbackQueryHandler.class)) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
for (String value : method.getAnnotation(CallbackQueryHandler.class).value()) {
|
||||
methods.get(CallbackQueryHandler.class).put(value, new InvokeMethod(method, parameters[0]));
|
||||
}
|
||||
} else
|
||||
System.err.println(method + " is annotated with @CallbackQueryHandler, but it is not static. For the annotation to work, the method must be static.");
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(TextMessageHandler.class)) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
for (String value : method.getAnnotation(TextMessageHandler.class).value()) {
|
||||
methods.get(TextMessageHandler.class).put(value, new InvokeMethod(method, parameters[0]));
|
||||
}
|
||||
} else
|
||||
System.err.println(method + " is annotated with @TextMessageHandler, but it is not static. For the annotation to work, the method must be static.");
|
||||
}
|
||||
|
||||
}
|
||||
} catch (NoClassDefFoundError | UnsupportedClassVersionError | ClassNotFoundException e) {
|
||||
if (errorHandler != null) errorHandler.onError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
ClassFinder.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public interface ErrorHandler {
|
||||
void onError(Throwable throwable);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user