diff --git a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java index 4123bbf..87aab0e 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java +++ b/src/main/java/org/saturnclient/saturnclient/config/ConfigManager.java @@ -1,107 +1,86 @@ package org.saturnclient.saturnclient.config; import com.google.gson.*; +import org.saturnclient.saturnclient.SaturnClient; + import java.io.File; import java.io.IOException; import java.nio.file.Files; -import java.util.*; -import org.saturnclient.saturnclient.SaturnClient; +import java.util.LinkedHashMap; +import java.util.Map; public class ConfigManager { - private static final File configFile = new File(SaturnClient.client.runDirectory, "saturn.json"); - private static final Map>> properties = new HashMap<>(); - private static JsonObject cachedThemeJson = null; + + private static final File configFile = + new File(SaturnClient.client.runDirectory, "saturn.json"); + + // SINGLE ROOT TREE + private static final Map> ROOT = new LinkedHashMap<>(); + + private static JsonObject cachedJson = null; private final Map> currentMap; - private final String namespace; + /** + * Creates a root namespace + */ public ConfigManager(String namespace) { - this.namespace = namespace; this.currentMap = new LinkedHashMap<>(); - properties.put(namespace, currentMap); - System.out.println("Created namespace: " + namespace); + ROOT.put(namespace, Property.namespace(currentMap)); } + /** + * Creates a sub-namespace inside a parent + */ public ConfigManager(ConfigManager parent, String namespace) { - this.namespace = namespace; this.currentMap = new LinkedHashMap<>(); - Property>> nsProp = Property.namespace(currentMap); - parent.property(namespace, nsProp); - System.out.println("Created sub-namespace: " + namespace); - } - - public void sub(String name) { - property(name, Property.namespace(new LinkedHashMap<>())); + parent.property(namespace, Property.namespace(currentMap)); } + /** + * Add a property + */ public Property property(String name, Property value) { currentMap.put(name, value); - loadProp(name, value); + loadSingleProperty(name, value); return value; } - private void loadProp(String name, Property prop) { - JsonObject source = cachedThemeJson != null ? cachedThemeJson : loadAndCache(); - if (source == null) - return; - - JsonElement namespaceJson = source.get(namespace); - if (namespaceJson == null || !namespaceJson.isJsonObject()) - return; - - JsonElement value = namespaceJson.getAsJsonObject().get(name); - if (value != null) - prop.loadFromJson(value); - } - - private static JsonObject loadAndCache() { - try { - if (!configFile.exists()) { - Files.writeString(configFile.toPath(), "{}"); - return new JsonObject(); - } - String json = Files.readString(configFile.toPath()); - cachedThemeJson = JsonParser.parseString(json).getAsJsonObject(); - return cachedThemeJson; - } catch (IOException e) { - SaturnClient.LOGGER.error("Error reading config file", e); - return null; - } + /** + * Add empty namespace + */ + public ConfigManager sub(String name) { + return new ConfigManager(this, name); } + /** + * Load entire config + */ public static void load() { SaturnClient.LOGGER.info("Loading config..."); + JsonObject json = loadAndCache(); if (json == null) return; - properties.forEach((namespace, map) -> { - JsonElement nsElement = json.get(namespace); - if (nsElement != null && nsElement.isJsonObject()) { - loadProperties(nsElement.getAsJsonObject(), map); - } - }); - } - - private static void loadProperties(JsonObject json, Map> props) { - props.forEach((name, prop) -> { - JsonElement el = json.get(name); - if (el != null) - prop.loadFromJson(el); - }); + loadRecursive(json, ROOT); } + /** + * Save entire config + */ public static void save() { SaturnClient.LOGGER.info("Saving config..."); - JsonObject root = new JsonObject(); - properties.forEach((namespace, map) -> { - JsonObject nsJson = new JsonObject(); - saveProperties(nsJson, map); - root.add(namespace, nsJson); - }); + + JsonObject rootJson = new JsonObject(); + saveRecursive(rootJson, ROOT); try { - String formatted = new GsonBuilder().setPrettyPrinting().create().toJson(root); + String formatted = new GsonBuilder() + .setPrettyPrinting() + .create() + .toJson(rootJson); + Files.writeString(configFile.toPath(), formatted); SaturnClient.LOGGER.info("Config saved successfully."); } catch (IOException e) { @@ -109,11 +88,72 @@ public class ConfigManager { } } - private static void saveProperties(JsonObject json, Map> props) { - props.forEach((name, prop) -> json.add(name, prop.toJson())); + /** + * Recursive save + */ + private static void saveRecursive(JsonObject json, Map> map) { + map.forEach((name, prop) -> { + if (prop.isNamespace()) { + JsonObject child = new JsonObject(); + saveRecursive(child, prop.getNamespaceMap()); + json.add(name, child); + } else { + json.add(name, prop.toJson()); + } + }); + } + + /** + * Recursive load + */ + private static void loadRecursive(JsonObject json, Map> map) { + map.forEach((name, prop) -> { + JsonElement element = json.get(name); + if (element == null) + return; + + if (prop.isNamespace() && element.isJsonObject()) { + loadRecursive(element.getAsJsonObject(), prop.getNamespaceMap()); + } else { + prop.loadFromJson(element); + } + }); + } + + /** + * Load only a single property immediately after creation + */ + private void loadSingleProperty(String name, Property prop) { + JsonObject source = cachedJson != null ? cachedJson : loadAndCache(); + if (source == null) + return; + + JsonElement element = source.get(name); + if (element != null) + prop.loadFromJson(element); + } + + /** + * Reads file and caches json + */ + private static JsonObject loadAndCache() { + try { + if (!configFile.exists()) { + Files.writeString(configFile.toPath(), "{}"); + return new JsonObject(); + } + + String json = Files.readString(configFile.toPath()); + cachedJson = JsonParser.parseString(json).getAsJsonObject(); + return cachedJson; + + } catch (IOException e) { + SaturnClient.LOGGER.error("Error reading config file", e); + return null; + } } public Map> getProperties() { return currentMap; } -} +} \ No newline at end of file diff --git a/src/main/java/org/saturnclient/saturnclient/config/Property.java b/src/main/java/org/saturnclient/saturnclient/config/Property.java index 6d81da7..2d7dd2e 100644 --- a/src/main/java/org/saturnclient/saturnclient/config/Property.java +++ b/src/main/java/org/saturnclient/saturnclient/config/Property.java @@ -286,4 +286,13 @@ public class Property { if (value != null) this.loadFromJson(value); } + + public boolean isNamespace() { + return type == PropertyType.NAMESPACE; + } + + @SuppressWarnings("unchecked") + public Map> getNamespaceMap() { + return isNamespace() ? (Map>) (Object) value : null; + } }