package dev.peerat.backend.bonus.extract; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import dev.peerat.backend.model.PeerAtUser; import dev.peerat.framework.RequestType; import dev.peerat.framework.Response; import dev.peerat.framework.Route; import dev.peerat.framework.RouteMapper; import dev.peerat.framework.Router; import dev.peerat.framework.utils.json.JsonArray; import dev.peerat.framework.utils.json.JsonMap; public class RouteExtracter { private Router router; public RouteExtracter(Router router){ this.router = router; } public void extract() throws Exception{ RouteMapper[] mappers = getField(Router.class, router, "mappers"); for(RequestType type : RequestType.values()){ RouteMapper mapper = mappers[type.ordinal()]; Response[] responses = getField(RouteMapper.class, mapper, "responses"); Route[] routes = getField(RouteMapper.class, mapper, "routes"); synchronized (responses){ for(int i = 0; i < responses.length; i++){ Route route = routes[i]; System.out.println("["+type+"] ("+route.needLogin()+") "+route.path()); } } } } public void extractDoc() throws Exception{ RouteMapper[] mappers = getField(Router.class, router, "mappers"); for(RequestType type : RequestType.values()){ RouteMapper mapper = mappers[type.ordinal()]; Response[] responses = getField(RouteMapper.class, mapper, "responses"); synchronized (responses){ for(int i = 0; i < responses.length; i++){ Response response = responses[i]; Method method = response.getClass().getDeclaredMethod("exec", Response.class.getDeclaredMethods()[0].getParameterTypes()); for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){ System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription()); } } } } } public JsonMap swagger(String host) throws Exception{ JsonMap result = new JsonMap(); result.set("swagger","2.0"); JsonMap info = new JsonMap(); info.set("title", "Peer-at-code backend api routes"); info.set("description", "Using Peer-at Code Framework"); result.set("info", info); result.set("host", host); result.set("basePath","/"); List routes = new ArrayList<>(); RouteMapper[] mappers = getField(Router.class, router, "mappers"); for(RequestType type : RequestType.values()){ RouteMapper mapper = mappers[type.ordinal()]; Response[] responses = getField(RouteMapper.class, mapper, "responses"); synchronized (responses){ routes.addAll(Arrays.asList(responses)); } } Set packages = new HashSet<>(); for(Response response : routes){ String name = response.getClass().getPackage().getName(); name = name.substring(name.lastIndexOf('.')+1, name.length()); packages.add(name); } JsonArray tags = new JsonArray(); for(String tag : packages){ JsonMap current = new JsonMap(); current.set("name", tag); tags.add(current); } result.set("tags", tags); JsonArray schemes = new JsonArray(); schemes.add("https"); result.set("schemes", schemes); JsonMap paths = new JsonMap(); for(Response response : routes){ Method method = response.getClass().getDeclaredMethod("exec", Response.class.getDeclaredMethods()[0].getParameterTypes()); Route route = method.getDeclaredAnnotation(Route.class); RouteDoc[] docs = method.getDeclaredAnnotationsByType(RouteDoc.class); if(docs.length < 1) continue; RouteDoc base = docs[0]; JsonMap current = new JsonMap(); JsonMap data = new JsonMap(); JsonArray tag = new JsonArray(); String pack = response.getClass().getPackage().getName(); pack = pack.substring(pack.lastIndexOf('.')+1, pack.length()); tag.add(pack); data.set("tags", tag); current.set(route.type().toString().toLowerCase(), data); paths.set(base.path(), current); } result.set("paths", paths); return result; } private E getField(Class clazz, Object instance, String name) throws Exception{ Field field = clazz.getDeclaredField(name); field.setAccessible(true); return (E) field.get(instance); } }