Start Navigation

This commit is contained in:
skippyall
2026-05-22 18:13:17 +02:00
parent 7db92ffa33
commit 017ca40e3e
6 changed files with 113 additions and 77 deletions
@@ -1,29 +1,18 @@
package io.github.skippyall.ruler.config; package io.github.skippyall.ruler.config;
import com.google.gson.Gson; import com.google.gson.JsonParser;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import io.github.skippyall.ruler.FileUtils; import io.github.skippyall.ruler.FileUtils;
import io.github.skippyall.ruler.Ruler; import io.github.skippyall.ruler.Ruler;
import io.github.skippyall.ruler.config.condition.Condition;
import io.github.skippyall.ruler.config.condition.ConditionTypeAdapter;
import io.github.skippyall.ruler.rule.InvalidRuleException; import io.github.skippyall.ruler.rule.InvalidRuleException;
import io.github.skippyall.ruler.rule.RuleUtils; import io.github.skippyall.ruler.rule.RuleUtils;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.ComponentSerializer; import net.kyori.adventure.text.serializer.ComponentSerializer;
import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
public class ConfigLoader { public class ConfigLoader {
public static final Gson configSerializer = new GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(Condition.class, new ConditionTypeAdapter())
.registerTypeAdapter(Redirect.class, new Redirect.Adapter())
.create();
public static RuleConfig loadConfig(String rulePath) { public static RuleConfig loadConfig(String rulePath) {
Path configPath = RuleUtils.getFilePathWithoutExtension(rulePath); Path configPath = RuleUtils.getFilePathWithoutExtension(rulePath);
return loadConfig(configPath); return loadConfig(configPath);
@@ -36,10 +25,11 @@ public class ConfigLoader {
} }
RuleConfig config = null; RuleConfig config = null;
Path configPath = FileUtils.append(fileWithoutExtension, ".config.json"); Path configPath = FileUtils.append(fileWithoutExtension, ".config.json");
String rulePath = RuleUtils.getRulePathFromWithoutExtension(fileWithoutExtension.toString());
if(Files.isRegularFile(configPath)) { if(Files.isRegularFile(configPath)) {
try { try {
config = configSerializer.fromJson(Files.newBufferedReader(configPath), RuleConfig.class); config = RuleConfig.loadFromJson(JsonParser.parseReader(Files.newBufferedReader(configPath)), rulePath);
} catch (IOException | JsonParseException e) { } catch (Exception e) {
Ruler.getPlatform().getLogger().error("Could not read config {}", configPath, e); Ruler.getPlatform().getLogger().error("Could not read config {}", configPath, e);
return parentConfig; return parentConfig;
} }
@@ -53,10 +43,7 @@ public class ConfigLoader {
return config; return config;
} }
public static String getActualRulePath(String rulePath, Audience audience) { public static String getActualRulePath(String rulePath, Audience audience, RuleConfig config) {
Path fileWithoutExtension = RuleUtils.getFilePathWithoutExtension(rulePath);
RuleConfig config = loadConfig(fileWithoutExtension);
if(config != null) { if(config != null) {
for (Redirect redirect : config.getRedirects()) { for (Redirect redirect : config.getRedirects()) {
if (redirect.getCondition().test(audience)) { if (redirect.getCondition().test(audience)) {
@@ -69,11 +56,12 @@ public class ConfigLoader {
} }
public static Component getRule(String path, Audience player) throws InvalidRuleException { public static Component getRule(String path, Audience player) throws InvalidRuleException {
String actualPath = ConfigLoader.getActualRulePath(path, player); RuleConfig config = loadConfig(path);
String actualPath = ConfigLoader.getActualRulePath(path, player, config);
Ruler.getPlatform().getLogger().error(actualPath); Ruler.getPlatform().getLogger().error(actualPath);
Path filePath = RuleUtils.getFilePath(actualPath); Path filePath = RuleUtils.getFilePath(actualPath);
String extension = FileUtils.getExtension(filePath); String extension = FileUtils.getExtension(filePath);
ComponentSerializer<Component, Component, String> serializer = RuleUtils.getSerializer(extension); ComponentSerializer<Component, Component, String> serializer = RuleUtils.getSerializer(extension);
@@ -82,7 +70,6 @@ public class ConfigLoader {
throw new InvalidRuleException("File doesn't exist"); throw new InvalidRuleException("File doesn't exist");
} }
return RuleUtils.readRuleFromFile(filePath, serializer); return RuleUtils.readRuleFromFile(filePath, serializer);
} }
} }
@@ -0,0 +1,40 @@
package io.github.skippyall.ruler.config;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.List;
public class Navigation {
String root;
List<String> rulePaths;
public Navigation(String root, List<String> rulePaths) {
this.root = root;
this.rulePaths = rulePaths;
}
public static Navigation loadFromJson(JsonElement element, String configPath) {
String root = configPath;
JsonArray array;
if(element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
if(object.has("root")) {
root = object.get("root").getAsString();
}
array = object.getAsJsonArray("paths");
} else {
array = element.getAsJsonArray();
}
List<String> rulePaths = new ArrayList<>();
for(JsonElement rulePathElement : array) {
rulePaths.add(rulePathElement.getAsString());
}
return new Navigation(root, rulePaths);
}
}
@@ -1,18 +1,12 @@
package io.github.skippyall.ruler.config; package io.github.skippyall.ruler.config;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import io.github.skippyall.ruler.config.condition.AlwaysCondition; import io.github.skippyall.ruler.config.condition.AlwaysCondition;
import io.github.skippyall.ruler.config.condition.Condition; import io.github.skippyall.ruler.config.condition.Condition;
import io.github.skippyall.ruler.config.condition.Conditions; import io.github.skippyall.ruler.config.condition.Conditions;
import java.lang.reflect.Type;
public class Redirect { public class Redirect {
Condition condition = AlwaysCondition.ALWAYS_TRUE; Condition condition = AlwaysCondition.ALWAYS_TRUE;
String rulePath; String rulePath;
@@ -42,9 +36,7 @@ public class Redirect {
this.rulePath = rulePath; this.rulePath = rulePath;
} }
public static class Adapter implements JsonDeserializer<Redirect>, JsonSerializer<Redirect> { public static Redirect deserialize(JsonElement json) throws JsonParseException {
@Override
public Redirect deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if(json.isJsonObject()) { if(json.isJsonObject()) {
JsonObject object = json.getAsJsonObject(); JsonObject object = json.getAsJsonObject();
String rulePath = object.get("rulePath").getAsString(); String rulePath = object.get("rulePath").getAsString();
@@ -59,12 +51,10 @@ public class Redirect {
} }
} }
@Override public JsonElement serialize() {
public JsonElement serialize(Redirect src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
object.addProperty("rulePath", src.rulePath); object.addProperty("rulePath", rulePath);
object.add("condition", Conditions.serialize(src.condition)); object.add("condition", Conditions.serialize(condition));
return null; return null;
} }
} }
}
@@ -1,17 +1,32 @@
package io.github.skippyall.ruler.config; package io.github.skippyall.ruler.config;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.skippyall.ruler.Ruler;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class RuleConfig { public class RuleConfig {
private List<Redirect> redirects = new ArrayList<>(); private List<Redirect> redirects = new ArrayList<>();
private Navigation navigation = null;
public RuleConfig() { public RuleConfig() {
} }
public RuleConfig(List<Redirect> redirects, Navigation navigation) {
this.redirects = redirects;
this.navigation = navigation;
}
public void applyParentRules(RuleConfig parent) { public void applyParentRules(RuleConfig parent) {
redirects.addAll(parent.getRedirects()); redirects.addAll(parent.getRedirects());
if(navigation != null) {
navigation = parent.navigation;
}
} }
public List<Redirect> getRedirects() { public List<Redirect> getRedirects() {
@@ -21,4 +36,26 @@ public class RuleConfig {
public void setRedirects(List<Redirect> redirects) { public void setRedirects(List<Redirect> redirects) {
this.redirects = redirects; this.redirects = redirects;
} }
public static RuleConfig loadFromJson(JsonElement element, String rulePath) {
JsonObject object = element.getAsJsonObject();
JsonArray redirectArray = object.getAsJsonArray("redirects");
List<Redirect> redirects = new ArrayList<>();
if(redirectArray != null) {
for (JsonElement redirectElement : redirectArray) {
try {
redirects.add(Redirect.deserialize(redirectElement));
} catch (Exception e) {
Ruler.getPlatform().getLogger().error("Could not read redirect: {}", redirectElement.toString(), e);
}
}
}
Navigation navigation = null;
if(object.has("navigation")) {
navigation = Navigation.loadFromJson(object.get("navigation"), rulePath);
}
return new RuleConfig(redirects, navigation);
}
} }
@@ -1,26 +0,0 @@
package io.github.skippyall.ruler.config.condition;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
public class ConditionTypeAdapter implements JsonSerializer<Condition>, JsonDeserializer<Condition> {
@Override
public Condition deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
return Conditions.deserialize(json);
} catch (Exception e) {
throw new JsonParseException(e);
}
}
@Override
public JsonElement serialize(Condition src, Type typeOfSrc, JsonSerializationContext context) {
return Conditions.serialize(src);
}
}
@@ -46,7 +46,11 @@ public class RuleUtils {
} }
public static boolean isInDirectory(Path path) { public static boolean isInDirectory(Path path) {
return path.toAbsolutePath().startsWith(getRoot()); try {
return path.toRealPath().startsWith(getRoot());
} catch (IOException e) {
return false;
}
} }
public static void checkDirectory(Path path) throws InvalidRulePathException { public static void checkDirectory(Path path) throws InvalidRulePathException {
@@ -88,8 +92,12 @@ public class RuleUtils {
} else { } else {
withoutExtension = FileUtils.removeExtension(relativeString); withoutExtension = FileUtils.removeExtension(relativeString);
} }
String path = withoutExtension.replace(FileSystems.getDefault().getSeparator(), ".");
return getRulePathFromWithoutExtension(withoutExtension);
}
public static String getRulePathFromWithoutExtension(String withoutExtension) throws InvalidRuleException {
String path = withoutExtension.replace(FileSystems.getDefault().getSeparator(), ".");
checkValidRulePath(path); checkValidRulePath(path);
return path; return path;
} }