生成kafka内部请求与响应的接口文档
/**
*/
package com.code260.ss.kafka10demo;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.kafka.common.protocol.types.BoundField;
import org.apache.kafka.common.protocol.types.Schema;
import org.apache.kafka.common.requests.AbstractRequest;
import org.apache.kafka.common.requests.AbstractResponse;
/**
* @since 2019-08-07
*
*/
public class GenKafkaRequestDoc {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
collect(AbstractRequest.class);
System.out.println("=======");
collect(AbstractResponse.class);
}
/**
* @param sedClazz
* @throws IOException
* @throws ClassNotFoundException
*/
public static void collect(Class<?> sedClazz) throws IOException, ClassNotFoundException {
List<Class<?>> children = getAllChildrenClass("org.apache.kafka", sedClazz);
List<Class<?>> childrenOfAbstractRequest = filter(children, sedClazz);
for (Class<?> rquestClazz : childrenOfAbstractRequest) {
System.out.println("
## " + rquestClazz.getSimpleName());
try {
Schema[] schemas = (Schema[]) rquestClazz.getDeclaredMethod("schemaVersions").invoke(null);
for (int i = 0; i < schemas.length; i++) {
Schema schema = schemas[i];
System.out.println("
### version:" + i);
StringBuffer sb = new StringBuffer();
sb.append(
"<table><tr><td style="160px">name</td><td>type</td><td style="80px">defaultValue</td><td>docString</td></tr>");
for (int j = 0; j < schema.fields().length; j++) {
BoundField field = schema.fields()[j];
sb.append("<tr><td>").append(field.def.name).append("</td>");
sb.append("<td>").append(field.def.type).append("</td>");
sb.append("<td>").append(field.def.defaultValue).append("</td>");
sb.append("<td>").append(field.def.docString).append("</td></tr>").append("
");
}
sb.append("</table>
");
System.out.println(sb.toString());
}
// System.out.println(schemas);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
private static List<Class<?>> filter(List<Class<?>> children, Class<?> parentClazz) {
List<Class<?>> result = new ArrayList<Class<?>>();
if (children == null || children.isEmpty()) {
return result;
}
for (Class<?> child : children) {
if (isAssignedFrom(child, parentClazz)) {
result.add(child);
}
}
return result;
}
private static boolean isAssignedFrom(Class<?> currentClazz, Class<?> targetParentClazz) {
if (targetParentClazz == null || currentClazz == null) {
return false;
}
// Class<?>[] parentInterfaces = currentClazz.getInterfaces();
Class<?> parentClazz = currentClazz.getSuperclass();
while (parentClazz != null) {
if (parentClazz.equals(targetParentClazz)) {
return true;
} else {
parentClazz = parentClazz.getSuperclass();
}
}
Class<?>[] parentInterfaces = currentClazz.getInterfaces();
return isAssignedFrom(parentInterfaces, targetParentClazz);
}
private static boolean isAssignedFrom(Class<?>[] parentInterfaces, Class<?> targetParentClazz) {
if (parentInterfaces == null) {
return false;
}
for (Class<?> ppInterface : parentInterfaces) {
if (ppInterface != null && ppInterface.equals(targetParentClazz)) {
return true;
} else {
boolean result = isAssignedFrom(ppInterface.getInterfaces(), targetParentClazz);
if (result) {
return true;
}
}
}
return false;
}
private static List<Class<?>> getAllChildrenClass(String scanPackageStr, Class<?> parentClazz)
throws IOException, ClassNotFoundException {
List<Class<?>> children = new ArrayList<Class<?>>();
Enumeration<URL> packageLocations = parentClazz.getClassLoader().getResources(scanPackageStr.replace(".", "/"));
while (packageLocations.hasMoreElements()) {
URL packageLocation = packageLocations.nextElement();
String protocol = packageLocation.getProtocol();
if ("file".equals(protocol)) {
String filePath = URLDecoder.decode(packageLocation.getFile(), "UTF-8");
findAndAddClassesInPackageByFile(filePath, scanPackageStr, children);
} else if ("jar".equals(protocol)) {
findAndAddClassesInPackageByJar(packageLocation.getPath(), scanPackageStr, children);
}
}
return children;
}
private static void findAndAddClassesInPackageByJar(String packageLocation, String packageName,
List<Class<?>> clazzList) throws IOException, ClassNotFoundException {
String[] segs = packageLocation.split("!");
String jarFilePath = segs[0].substring(segs[0].indexOf("/"));
jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
String packagePath = segs[1].substring(1);
JarFile jarFile = null;
try {
jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
if (entryName.startsWith(packagePath)) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(entryName);
clazzList.add(clazz);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (jarFile != null) {
jarFile.close();
}
}
}
private static void findAndAddClassesInPackageByFile(String filePath, String packageName,
List<Class<?>> clazzList) {
File file = new File(filePath);
File[] children = file.listFiles();
for (File child : children) {
if (child.isDirectory()) {
findAndAddClassesInPackageByFile(child.getAbsolutePath(), packageName + "." + child.getName(),
clazzList);
}
if (child.isFile()) {
if (!child.getName().endsWith(".class")) {
continue;
}
}
String childName = child.getName();
if (!childName.endsWith(".class")) {
continue;
}
String className = packageName + "." + childName.substring(0, childName.length() - ".class".length());
try {
Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
clazzList.add(clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}