generate json schemas for intelij

This commit is contained in:
Julian Krings 2025-04-24 16:00:23 +02:00
parent 0a2f35dd8d
commit e72abc8c39
No known key found for this signature in database
GPG Key ID: 208C6E08C3B718D2
6 changed files with 139 additions and 22 deletions

View File

@ -171,6 +171,7 @@ allprojects {
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
compileOnly 'org.apache.commons:commons-lang3:3.12.0'
compileOnly 'com.github.oshi:oshi-core:6.6.5'
compileOnly 'org.dom4j:dom4j:2.1.4'
}
/**

View File

@ -50,6 +50,8 @@ import lombok.Data;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.dom4j.Document;
import org.dom4j.Element;
import org.zeroturnaround.zip.ZipUtil;
import java.awt.*;
@ -275,7 +277,6 @@ public class IrisProject {
PrecisionStopwatch p = PrecisionStopwatch.start();
JSONObject j = createCodeWorkspaceConfig();
IO.writeAll(ws, j.toString(4));
ExecutionEnvironment.createPack(IrisData.get(path)).buildProject();
p.end();
return true;
} catch (Throwable e) {
@ -361,6 +362,73 @@ public class IrisProject {
settings.put("json.schemas", schemas);
ws.put("settings", settings);
ExecutionEnvironment.createSimple().configureProject(path);
File schemasFile = new File(path, ".idea" + File.separator + "jsonSchemas.xml");
Document doc = IO.read(schemasFile);
Element mappings = (Element) doc.selectSingleNode("//component[@name='JsonSchemaMappingsProjectConfiguration']");
if (mappings == null) {
mappings = doc.getRootElement()
.addElement("component")
.addAttribute("name", "JsonSchemaMappingsProjectConfiguration");
}
Element state = (Element) mappings.selectSingleNode("state");
if (state == null) state = mappings.addElement("state");
Element map = (Element) state.selectSingleNode("map");
if (map == null) map = state.addElement("map");
var schemaMap = new KMap<String, String>();
schemas.forEach(element -> {
if (!(element instanceof JSONObject obj))
return;
String url = obj.getString("url");
String dir = obj.getJSONArray("fileMatch").getString(0);
schemaMap.put(url, dir.substring(1, dir.indexOf("/*")));
});
map.selectNodes("entry/value/SchemaInfo/option[@name='relativePathToSchema']")
.stream()
.map(node -> node.valueOf("@value"))
.forEach(schemaMap::remove);
var ideaSchemas = map;
schemaMap.forEach((url, dir) -> {
var genName = UUID.randomUUID().toString();
var info = ideaSchemas.addElement("entry")
.addAttribute("key", genName)
.addElement("value")
.addElement("SchemaInfo");
info.addElement("option")
.addAttribute("name", "generatedName")
.addAttribute("value", genName);
info.addElement("option")
.addAttribute("name", "name")
.addAttribute("value", dir);
info.addElement("option")
.addAttribute("name", "relativePathToSchema")
.addAttribute("value", url);
var item = info.addElement("option")
.addAttribute("name", "patterns")
.addElement("list")
.addElement("Item");
item.addElement("option")
.addAttribute("name", "directory")
.addAttribute("value", "true");
item.addElement("option")
.addAttribute("name", "path")
.addAttribute("value", dir);
item.addElement("option")
.addAttribute("name", "mappingKind")
.addAttribute("value", "Directory");
});
if (!schemaMap.isEmpty()) {
IO.write(schemasFile, doc);
}
return ws;
}

View File

@ -108,7 +108,9 @@ public class SchemaBuilder {
private JSONObject buildProperties(Class<?> c) {
JSONObject o = new JSONObject();
JSONObject properties = new JSONObject();
o.put("description", getDescription(c));
String desc = getDescription(c);
o.put("description", desc);
o.put("x-intellij-html-description", desc.replace("\n", "<br>"));
o.put("type", getType(c));
JSONArray required = new JSONArray();
@ -506,16 +508,18 @@ public class SchemaBuilder {
}
KList<String> d = new KList<>();
d.add(k.getName());
d.add(getFieldDescription(k));
d.add(" ");
d.add(fancyType);
d.add(getDescription(k.getType()));
d.add("<h>" + k.getName() + "</h>");
d.add(getFieldDescription(k) + "<hr></hr>");
d.add("<h>" + fancyType + "</h>");
String typeDesc = getDescription(k.getType());
boolean present = !typeDesc.isBlank();
if (present) d.add(typeDesc);
if (k.getType().isAnnotationPresent(Snippet.class)) {
String sm = k.getType().getDeclaredAnnotation(Snippet.class).value();
d.add(" ");
if (present) d.add(" ");
d.add("You can instead specify \"snippet/" + sm + "/some-name.json\" to use a snippet file instead of specifying it here.");
present = false;
}
try {
@ -523,15 +527,13 @@ public class SchemaBuilder {
Object value = k.get(cl.newInstance());
if (value != null) {
if (present) d.add(" ");
if (value instanceof List) {
d.add(" ");
d.add("* Default Value is an empty list");
d.add(SYMBOL_LIMIT__N + " Default Value is an empty list");
} else if (!cl.isPrimitive() && !(value instanceof Number) && !(value instanceof String) && !(cl.isEnum()) && !OldEnum.isOldEnum(cl)) {
d.add(" ");
d.add("* Default Value is a default object (create this object to see default properties)");
d.add(SYMBOL_LIMIT__N + " Default Value is a default object (create this object to see default properties)");
} else {
d.add(" ");
d.add("* Default Value is " + value);
d.add(SYMBOL_LIMIT__N + " Default Value is " + value);
}
}
} catch (Throwable ignored) {
@ -539,8 +541,14 @@ public class SchemaBuilder {
}
description.forEach((g) -> d.add(g.trim()));
String desc = d.toString("\n")
.replace("<hr></hr>", "\n")
.replace("<h>", "")
.replace("</h>", "");
String hDesc = d.toString("<br>");
prop.put("type", type);
prop.put("description", d.toString("\n"));
prop.put("description", desc);
prop.put("x-intellij-html-description", hDesc);
if (k.getType().isAnnotationPresent(Snippet.class)) {
JSONObject anyOf = new JSONObject();
@ -560,10 +568,13 @@ public class SchemaBuilder {
arr.put(prop);
arr.put(str);
prop.put("description", d.toString("\n"));
str.put("description", d.toString("\n"));
prop.put("description", desc);
prop.put("x-intellij-html-description", hDesc);
str.put("description", desc);
str.put("x-intellij-html-description", hDesc);
anyOf.put("anyOf", arr);
anyOf.put("description", d.toString("\n"));
anyOf.put("description", desc);
anyOf.put("x-intellij-html-description", hDesc);
anyOf.put("!required", k.isAnnotationPresent(Required.class));
return anyOf;
@ -592,7 +603,9 @@ public class SchemaBuilder {
String name = function.apply(gg);
j.put("const", name);
Desc dd = type.getField(name).getAnnotation(Desc.class);
j.put("description", dd == null ? ("No Description for " + name) : dd.value());
String desc = dd == null ? ("No Description for " + name) : dd.value();
j.put("description", desc);
j.put("x-intellij-html-description", desc.replace("\n", "<br>"));
a.put(j);
} catch (Throwable e) {
Iris.reportError(e);

View File

@ -10,6 +10,7 @@ import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.dom4j.Document;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@ -46,7 +47,7 @@ public class ExecutionEnvironment {
@SneakyThrows
private static URLClassLoader buildLoader() {
String version = "46d271c6ce";
String version = "868b3b9910";
String url = BASE_URL.formatted(version, version);
String hash = IO.hash("Iris-Scripts.jar@" + version);
var file = Iris.instance.getDataFile("cache", hash.substring(0, 2), hash.substring(3, 5), hash + ".jar");
@ -124,6 +125,16 @@ public class ExecutionEnvironment {
public interface Simple {
default void configureProject(@NonNull File projectDir) {
var workspaceFile = new File(projectDir, ".idea" + File.separator + "workspace.xml");
var workspaceDoc = IO.read(workspaceFile);
if (configureProject(projectDir, workspaceDoc)) {
IO.write(workspaceFile, workspaceDoc);
}
}
boolean configureProject(@NonNull File projectDir, @NonNull Document workspace);
void execute(@NonNull String script);
void execute(@NonNull String script, @NonNull Class<?> type, @Nullable Map<@NonNull String, Object> vars);
@ -142,8 +153,6 @@ public class ExecutionEnvironment {
public interface Pack extends Simple {
@NonNull
IrisData getData();
void buildProject();
}
public interface Engine extends Pack {

View File

@ -20,6 +20,12 @@ package com.volmit.iris.util.io;
import com.volmit.iris.Iris;
import com.volmit.iris.util.format.Form;
import lombok.SneakyThrows;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.*;
import java.nio.charset.StandardCharsets;
@ -1602,4 +1608,22 @@ public class IO {
int ch2 = input2.read();
return (ch2 == -1);
}
@SneakyThrows
public static void write(File file, Document doc) {
file.getParentFile().mkdirs();
try (var writer = new FileWriter(file)) {
new XMLWriter(writer, OutputFormat.createPrettyPrint())
.write(doc);
}
}
@SneakyThrows
public static Document read(File file) {
if (file.exists()) return new SAXReader().read(file);
var doc = DocumentHelper.createDocument();
doc.addElement("project")
.addAttribute("version", "4");
return doc;
}
}

View File

@ -18,6 +18,8 @@ libraries:
- org.ow2.asm:asm:9.2
- org.lz4:lz4-java:1.8.0
- com.github.oshi:oshi-core:6.6.5
- org.dom4j:dom4j:2.1.4
- jaxen:jaxen:1.1.6
commands:
iris:
aliases: [ ir, irs ]