fix(config): Use JsonReader from GsonHolders
This commit is contained in:
parent
7bb0edbbb8
commit
0f3933a946
|
@ -2,7 +2,7 @@ package io.gitlab.jfronny.libjf.config.impl.dsl;
|
|||
|
||||
import io.gitlab.jfronny.commons.serialize.gson.api.v1.GsonHolders;
|
||||
import io.gitlab.jfronny.gson.*;
|
||||
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||
import io.gitlab.jfronny.gson.stream.*;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.config.api.v1.*;
|
||||
import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe;
|
||||
|
@ -10,17 +10,17 @@ import io.gitlab.jfronny.libjf.config.impl.watch.JfConfigWatchService;
|
|||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DefaultConfigIO {
|
||||
public static Consumer<ConfigInstance> loader(String id) {
|
||||
return c -> c.getFilePath().ifPresent(path -> {
|
||||
// Actions cannot be cached since entries can change
|
||||
if (Files.exists(path)) {
|
||||
try (BufferedReader br = Files.newBufferedReader(path)) {
|
||||
JsonElement element = JsonParser.parseReader(br);
|
||||
if (element.isJsonObject()) loadFrom(element.getAsJsonObject(), c);
|
||||
else LibJf.LOGGER.error("Invalid config: Not a JSON object for " + id);
|
||||
try (BufferedReader br = Files.newBufferedReader(path);
|
||||
JsonReader jr = GsonHolders.CONFIG.getGson().newJsonReader(br)) {
|
||||
runActions(id, createActions(c), jr);
|
||||
} catch (Exception e) {
|
||||
LibJf.LOGGER.error("Could not read config for " + id, e);
|
||||
}
|
||||
|
@ -29,30 +29,63 @@ public class DefaultConfigIO {
|
|||
});
|
||||
}
|
||||
|
||||
private static void loadFrom(JsonObject source, ConfigCategory category) {
|
||||
for (EntryInfo<?> entry : category.getEntries()) {
|
||||
if (source.has(entry.getName())) {
|
||||
try {
|
||||
entry.loadFromJson(source.get(entry.getName()));
|
||||
} catch (IllegalAccessException e) {
|
||||
LibJf.LOGGER.error("Could not set config entry value of " + entry.getName(), e);
|
||||
}
|
||||
} else LibJf.LOGGER.error("Config does not contain entry for " + entry.getName());
|
||||
record Action(Consumer<JsonReader> task, boolean required) {
|
||||
public Action(Consumer<JsonReader> task) {
|
||||
this(task, true);
|
||||
}
|
||||
for (Map.Entry<String, ConfigCategory> entry : category.getCategories().entrySet()) {
|
||||
if (source.has(entry.getKey())) {
|
||||
JsonElement el = source.get(entry.getKey());
|
||||
if (el.isJsonObject()) loadFrom(el.getAsJsonObject(), entry.getValue());
|
||||
else LibJf.LOGGER.error("Config category is not a JSON object, skipping");
|
||||
} else LibJf.LOGGER.error("Config does not contain entry for subcategory " + entry.getKey());
|
||||
}
|
||||
if (category instanceof DslConfigCategory cat) {
|
||||
for (Map.Entry<String, Consumer<JsonElement>> entry : cat.migrations.entrySet()) {
|
||||
if (source.has(entry.getKey())) {
|
||||
entry.getValue().accept(source.get(entry.getKey()));
|
||||
}
|
||||
|
||||
private static void runActions(String id, Map<String, Action> actions, JsonReader reader) {
|
||||
try {
|
||||
if (reader.peek() == JsonToken.BEGIN_OBJECT) {
|
||||
Set<String> appeared = new HashSet<>();
|
||||
reader.beginObject();
|
||||
while (reader.peek() != JsonToken.END_OBJECT) {
|
||||
String name = reader.nextName();
|
||||
if (!actions.containsKey(name)) {
|
||||
LibJf.LOGGER.warn("Unrecognized key in config for " + id + ": " + name);
|
||||
continue;
|
||||
}
|
||||
if (!appeared.add(name)) {
|
||||
LibJf.LOGGER.warn("Duplicate key in config for " + id + ": " + name);
|
||||
continue;
|
||||
}
|
||||
actions.get(name).task.accept(reader);
|
||||
}
|
||||
reader.endObject();
|
||||
actions.forEach((name, action) -> {
|
||||
if (action.required && !appeared.contains(name)) {
|
||||
LibJf.LOGGER.error("Missing entry in config for " + id + ": " + name);
|
||||
}
|
||||
});
|
||||
} LibJf.LOGGER.error("Invalid config: Not a JSON object for " + id);
|
||||
} catch (IOException e) {
|
||||
throw new JsonParseException("Could not read config", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, Action> createActions(ConfigCategory category) {
|
||||
Map<String, Action> actions = new HashMap<>();
|
||||
category.getEntries().forEach(entry -> actions.putIfAbsent(entry.getName(), new Action(reader -> {
|
||||
try {
|
||||
entry.loadFromJson(JsonParser.parseReader(reader));
|
||||
} catch (IllegalAccessException e) {
|
||||
LibJf.LOGGER.error("Could not set config entry value of " + entry.getName(), e);
|
||||
}
|
||||
})));
|
||||
category.getCategories().forEach((id, cat) -> {
|
||||
String innerId = category.getId() + "." + id;
|
||||
var innerActions = createActions(cat);
|
||||
actions.putIfAbsent(id, new Action(reader -> runActions(innerId, innerActions, reader)));
|
||||
});
|
||||
if (category instanceof DslConfigCategory cat) {
|
||||
cat.migrations.forEach((id, migration) -> {
|
||||
actions.putIfAbsent(id, new Action(reader -> {
|
||||
migration.accept(JsonParser.parseReader(reader));
|
||||
}, false));
|
||||
});
|
||||
}
|
||||
return Map.copyOf(actions);
|
||||
}
|
||||
|
||||
public static Consumer<ConfigInstance> writer(String id) {
|
||||
|
|
Loading…
Reference in New Issue