Add route auto-registering (scan package + dependency injection)

This commit is contained in:
jeffcheasey88 2024-06-06 01:43:12 +02:00
parent 600de755ca
commit 2c9897a7c5

View file

@ -1,23 +1,31 @@
package dev.peerat.framework;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jwk.JsonWebKey.OutputControlLevel;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jwk.JsonWebKey.OutputControlLevel;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
@ -28,10 +36,6 @@ import org.jose4j.lang.JoseException;
public class Router<U extends User>{
public static void main(String[] args) {
}
private Locker<Context> logger;
private Locker<Exception> exceptions;
private RouteMapper<U>[] mappers;
@ -106,6 +110,70 @@ public class Router<U extends User>{
return this;
}
public Router<U> registerPackages(Object... injections){
String clazz = Thread.currentThread().getStackTrace()[2].getClassName();
String pack = clazz.substring(0, clazz.lastIndexOf('.'));
return registerPackages(pack, injections);
}
public Router<U> registerPackages(String name, Object... injections){
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/"));
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
Map<Class<?>, Object> cache = new HashMap<>();
while((line = reader.readLine()) != null){
if(line.endsWith(".class")){
Class<?> clazz = Class.forName(name+"."+line.substring(0, line.lastIndexOf('.')));
if(Response.class.isAssignableFrom(clazz)){
if(clazz.equals(Response.class)) continue;
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
if(constructors.length != 1) continue;
injectDependencies(constructors[0], cache, injections);
}
}else{
registerPackages(name+"."+line);
}
}
reader.close();
}catch(Exception e){
e.printStackTrace();
}
return this;
}
private void injectDependencies(Constructor<?> constructor, Map<Class<?>, Object> cache, Object... injections){
Class<?>[] parameterTypes = constructor.getParameterTypes();
Object[] parameters = new Object[parameterTypes.length];
for(int i = 0; i < parameterTypes.length; i++){
Class<?> type = parameterTypes[i];
Object dependency = cache.get(type);
if(dependency != null){
parameters[i] = dependency;
}else{
for(Object injection : injections){
if(type.isAssignableFrom(injection.getClass())){
if(cache.containsKey(type)){
throw new IllegalArgumentException("Double dependency for type "+type);
}else{
cache.put(type, injection);
parameters[i] = injection;
}
}
}
if(parameters[i] == null) throw new IllegalArgumentException("No dependency for type "+type);
}
}
try {
Response response = (Response) constructor.newInstance(parameters);
register(response);
System.out.println("registerd "+response.getClass());
} catch (Exception e){
e.printStackTrace();
}
}
public Router<U> setDefault(Response response){
this.noFileFound = response;
return this;