diff --git a/build.gradle b/build.gradle index 12a0751b8..02c63f997 100644 --- a/build.gradle +++ b/build.gradle @@ -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' } /** diff --git a/core/src/main/java/com/volmit/iris/core/project/IrisProject.java b/core/src/main/java/com/volmit/iris/core/project/IrisProject.java index aa4ed4900..803057318 100644 --- a/core/src/main/java/com/volmit/iris/core/project/IrisProject.java +++ b/core/src/main/java/com/volmit/iris/core/project/IrisProject.java @@ -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(); + 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; } diff --git a/core/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java b/core/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java index 398d1630b..6f69bf223 100644 --- a/core/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java +++ b/core/src/main/java/com/volmit/iris/core/project/SchemaBuilder.java @@ -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", "
")); o.put("type", getType(c)); JSONArray required = new JSONArray(); @@ -506,16 +508,18 @@ public class SchemaBuilder { } KList d = new KList<>(); - d.add(k.getName()); - d.add(getFieldDescription(k)); - d.add(" "); - d.add(fancyType); - d.add(getDescription(k.getType())); + d.add("" + k.getName() + ""); + d.add(getFieldDescription(k) + "
"); + d.add("" + fancyType + ""); + 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("
", "\n") + .replace("", "") + .replace("", ""); + String hDesc = d.toString("
"); 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", "
")); a.put(j); } catch (Throwable e) { Iris.reportError(e); diff --git a/core/src/main/java/com/volmit/iris/core/scripting/ExecutionEnvironment.java b/core/src/main/java/com/volmit/iris/core/scripting/ExecutionEnvironment.java index c01655449..21ee80219 100644 --- a/core/src/main/java/com/volmit/iris/core/scripting/ExecutionEnvironment.java +++ b/core/src/main/java/com/volmit/iris/core/scripting/ExecutionEnvironment.java @@ -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 { diff --git a/core/src/main/java/com/volmit/iris/util/io/IO.java b/core/src/main/java/com/volmit/iris/util/io/IO.java index a8f718885..f18b157fd 100644 --- a/core/src/main/java/com/volmit/iris/util/io/IO.java +++ b/core/src/main/java/com/volmit/iris/util/io/IO.java @@ -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; + } } diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index cedb75c1e..f3b1cfa8c 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -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 ]