Простой генератор JSON-RPC клиента для JS
This commit is contained in:
parent
8a2d52b9d2
commit
3ad2f762e0
|
|
@ -18,4 +18,26 @@
|
|||
<version>1.0.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-js-client</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>ru.kirillius.XCP.ApiGenerator.JavascriptClientGenerator</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
package ru.kirillius.XCP.ApiGenerator;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JavascriptClientGenerator {
|
||||
|
||||
private static final String SERVICES_PACKAGE = "ru.kirillius.XCP.RPC.Services";
|
||||
private static final String OUTPUT_DIR = "target/generated-sources/api.js";
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
generateJavascriptClient();
|
||||
System.out.println("JavaScript API client generated successfully at: " + OUTPUT_DIR);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to generate JavaScript client: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void generateJavascriptClient() throws IOException, ClassNotFoundException {
|
||||
StringBuilder jsBuilder = new StringBuilder();
|
||||
jsBuilder.append("API = {\n");
|
||||
|
||||
List<Class<?>> serviceClasses = findServiceClasses();
|
||||
boolean first = true;
|
||||
|
||||
for (Class<?> serviceClass : serviceClasses) {
|
||||
if (!first) {
|
||||
jsBuilder.append(",\n");
|
||||
}
|
||||
first = false;
|
||||
|
||||
String className = serviceClass.getSimpleName();
|
||||
jsBuilder.append(" ").append(className).append(" : {\n");
|
||||
|
||||
Method[] methods = serviceClass.getDeclaredMethods();
|
||||
List<Method> rpcMethods = new ArrayList<>();
|
||||
|
||||
for (Method method : methods) {
|
||||
Annotation[] annotations = method.getAnnotations();
|
||||
for (Annotation annotation : annotations) {
|
||||
if (annotation.annotationType().getSimpleName().equals("JsonRpcMethod")) {
|
||||
rpcMethods.add(method);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < rpcMethods.size(); i++) {
|
||||
Method method = rpcMethods.get(i);
|
||||
Annotation jsonRpcMethod = null;
|
||||
|
||||
for (Annotation annotation : method.getAnnotations()) {
|
||||
if (annotation.annotationType().getSimpleName().equals("JsonRpcMethod")) {
|
||||
jsonRpcMethod = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
generateMethod(jsBuilder, method, jsonRpcMethod, className);
|
||||
|
||||
if (i < rpcMethods.size() - 1) {
|
||||
jsBuilder.append(",\n");
|
||||
} else {
|
||||
jsBuilder.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
jsBuilder.append(" }");
|
||||
}
|
||||
|
||||
jsBuilder.append("\n}\n");
|
||||
|
||||
File outputFile = new File(OUTPUT_DIR);
|
||||
outputFile.getParentFile().mkdirs();
|
||||
|
||||
try (FileWriter writer = new FileWriter(outputFile)) {
|
||||
writer.write(jsBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Class<?>> findServiceClasses() throws ClassNotFoundException {
|
||||
List<Class<?>> serviceClasses = new ArrayList<>();
|
||||
|
||||
serviceClasses.add(Class.forName(SERVICES_PACKAGE + ".Auth"));
|
||||
serviceClasses.add(Class.forName(SERVICES_PACKAGE + ".Profile"));
|
||||
serviceClasses.add(Class.forName(SERVICES_PACKAGE + ".UserManagement"));
|
||||
|
||||
return serviceClasses;
|
||||
}
|
||||
|
||||
private static void generateMethod(StringBuilder builder, Method method, Annotation jsonRpcMethod, String className) {
|
||||
String methodName = method.getName();
|
||||
|
||||
builder.append(" /**\n");
|
||||
|
||||
try {
|
||||
Object description = jsonRpcMethod.annotationType().getMethod("description").invoke(jsonRpcMethod);
|
||||
builder.append(" * ").append(description).append("\n");
|
||||
|
||||
Object parameters = jsonRpcMethod.annotationType().getMethod("parameters").invoke(jsonRpcMethod);
|
||||
if (parameters instanceof Object[]) {
|
||||
Object[] params = (Object[]) parameters;
|
||||
for (Object param : params) {
|
||||
Class<?> paramClass = param.getClass();
|
||||
Object name = paramClass.getMethod("name").invoke(param);
|
||||
Object optional = paramClass.getMethod("optional").invoke(param);
|
||||
|
||||
builder.append(" * @param ").append(name);
|
||||
if (!(Boolean) optional) {
|
||||
builder.append(" (required)");
|
||||
} else {
|
||||
builder.append(" (optional)");
|
||||
}
|
||||
builder.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
Object returnType = jsonRpcMethod.annotationType().getMethod("returnType").invoke(jsonRpcMethod);
|
||||
String returnTypeName = getSimpleTypeName((Class<?>) returnType);
|
||||
builder.append(" * @returns ").append(returnTypeName).append("\n");
|
||||
} catch (Exception e) {
|
||||
builder.append(" * Method: ").append(methodName).append("\n");
|
||||
builder.append(" * @returns unknown\n");
|
||||
}
|
||||
|
||||
builder.append(" */\n");
|
||||
|
||||
builder.append(" ").append(methodName).append(" : async function(");
|
||||
|
||||
List<String> paramNames = new ArrayList<>();
|
||||
try {
|
||||
Object parameters = jsonRpcMethod.annotationType().getMethod("parameters").invoke(jsonRpcMethod);
|
||||
if (parameters instanceof Object[]) {
|
||||
Object[] params = (Object[]) parameters;
|
||||
for (Object param : params) {
|
||||
Object name = param.getClass().getMethod("name").invoke(param);
|
||||
Object optional = param.getClass().getMethod("optional").invoke(param);
|
||||
if (!(Boolean) optional) {
|
||||
paramNames.add(name.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// No parameters available
|
||||
}
|
||||
|
||||
builder.append(String.join(", ", paramNames));
|
||||
builder.append(") {\n");
|
||||
builder.append(" return await JSONRPC.invoke(\"").append(className).append(".").append(methodName).append("\", {");
|
||||
|
||||
List<String> paramPairs = new ArrayList<>();
|
||||
try {
|
||||
Object parameters = jsonRpcMethod.annotationType().getMethod("parameters").invoke(jsonRpcMethod);
|
||||
if (parameters instanceof Object[]) {
|
||||
Object[] params = (Object[]) parameters;
|
||||
for (Object param : params) {
|
||||
Object name = param.getClass().getMethod("name").invoke(param);
|
||||
Object optional = param.getClass().getMethod("optional").invoke(param);
|
||||
if (!(Boolean) optional) {
|
||||
paramPairs.add(name.toString() + ":" + name.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// No parameters available
|
||||
}
|
||||
|
||||
builder.append(String.join(", ", paramPairs));
|
||||
builder.append("});\n");
|
||||
builder.append(" }");
|
||||
}
|
||||
|
||||
private static String getSimpleTypeName(Class<?> type) {
|
||||
if (type == null) return "unknown";
|
||||
if (type == boolean.class) return "boolean";
|
||||
if (type == int.class || type == long.class) return "number";
|
||||
if (type == String.class) return "string";
|
||||
if (type == void.class || type == Void.class) return "void";
|
||||
|
||||
String typeName = type.getSimpleName();
|
||||
if (type.isArray()) {
|
||||
return "Array";
|
||||
}
|
||||
|
||||
if (typeName.contains("Node") || typeName.contains("Object")) {
|
||||
return "Object";
|
||||
}
|
||||
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
1
pom.xml
1
pom.xml
|
|
@ -17,6 +17,7 @@
|
|||
<module>web-server</module>
|
||||
<module>app</module>
|
||||
<module>logging</module>
|
||||
<module>web-ui</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>ru.kirillius</groupId>
|
||||
<artifactId>XCP</artifactId>
|
||||
<version>1.0.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>web-ui</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
Loading…
Reference in New Issue