From 4dade43f82028b50a35554dd65a6082438392395 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 29 Apr 2019 12:53:26 +0200 Subject: [PATCH] Added support for config map gen #59 Hopefully Also added support for setting the path automatically --- .../lib/architecture/ButtonPlugin.java | 2 +- .../lib/architecture/Component.java | 2 +- .../lib/architecture/ConfigData.java | 23 +++++--- .../lib/architecture/IHaveConfig.java | 52 +++++++++++++------ 4 files changed, 54 insertions(+), 25 deletions(-) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java index 10e5c49..8d30120 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ButtonPlugin.java @@ -42,7 +42,7 @@ public abstract class ButtonPlugin extends JavaPlugin { @Override public final void onEnable() { loadConfig(); - IHaveConfig.pregenConfig(this, iConfig); + IHaveConfig.pregenConfig(this, null); try { pluginEnable(); } catch (Exception e) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java index 435c71d..2385195 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/Component.java @@ -85,7 +85,7 @@ public abstract class Component { } component.plugin = plugin; updateConfig(plugin, component); - IHaveConfig.pregenConfig(component, component.config); + IHaveConfig.pregenConfig(component, null); component.register(plugin); components.put(component.getClass(), component); if (plugin instanceof ButtonPlugin) diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java index f4d2285..bc758ef 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/ConfigData.java @@ -5,7 +5,7 @@ import buttondevteam.lib.ThorpeUtils; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.Setter; import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; import org.bukkit.configuration.ConfigurationSection; @@ -20,9 +20,8 @@ import java.util.function.Function; /** * Use the getter/setter constructor if {@link T} isn't a primitive type or String.
- * Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance. + * Use {@link Component#getConfig()} or {@link ButtonPlugin#getIConfig()} then {@link IHaveConfig#getData(String, Object)} to get an instance. */ -@RequiredArgsConstructor(access = AccessLevel.PACKAGE) //@AllArgsConstructor(access = AccessLevel.PACKAGE) public class ConfigData { private static final HashMap saveTasks = new HashMap<>(); @@ -31,7 +30,8 @@ public class ConfigData { */ private final ConfigurationSection config; @Getter - private final String path; + @Setter(AccessLevel.PACKAGE) + private String path; private final T def; private final Object primitiveDef; private final Runnable saveAction; @@ -54,14 +54,23 @@ public class ConfigData { private boolean saved = false; //This constructor is needed because it sets the getter and setter - public ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function getter, Function setter, Runnable saveAction) { + ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Function getter, Function setter, Runnable saveAction) { this.config = config; this.path = path; this.def = def; this.primitiveDef = primitiveDef; this.getter = getter; this.setter = setter; - this.saveAction=saveAction; + this.saveAction = saveAction; + } + + @java.beans.ConstructorProperties({"config", "path", "def", "primitiveDef", "saveAction"}) + ConfigData(ConfigurationSection config, String path, T def, Object primitiveDef, Runnable saveAction) { + this.config = config; + this.path = path; + this.def = def; + this.primitiveDef = primitiveDef; + this.saveAction = saveAction; } @Override @@ -106,7 +115,7 @@ public class ConfigData { else val = value; if (config != null) { config.set(path, val); - if(!saveTasks.containsKey(config.getRoot())) { + if (!saveTasks.containsKey(config.getRoot())) { synchronized (saveTasks) { saveTasks.put(config.getRoot(), new SaveTask(Bukkit.getScheduler().runTaskLaterAsynchronously(MainPlugin.Instance, () -> { synchronized (saveTasks) { diff --git a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java index 15a5d24..2b7ce8f 100644 --- a/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java +++ b/ButtonCore/src/main/java/buttondevteam/lib/architecture/IHaveConfig.java @@ -6,9 +6,12 @@ import lombok.Getter; import lombok.val; import org.bukkit.configuration.ConfigurationSection; -import java.util.HashMap; +import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.util.*; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Collectors; /** * A config system @@ -26,7 +29,7 @@ public final class IHaveConfig { */ IHaveConfig(ConfigurationSection section, Runnable saveAction) { config = section; - this.saveAction=saveAction; + this.saveAction = saveAction; } /** @@ -65,11 +68,11 @@ public final class IHaveConfig { /** * This method overload may be used with any class. The given default value will be run through the getter. * - * @param path The path in config to use - * @param primitiveDef The primitive value to use by default - * @param getter A function that converts a primitive representation to the correct value - * @param setter A function that converts a value to a primitive representation - * @param The type of this variable (can be any class) + * @param path The path in config to use + * @param primitiveDef The primitive value to use by default + * @param getter A function that converts a primitive representation to the correct value + * @param setter A function that converts a value to a primitive representation + * @param The type of this variable (can be any class) * @return The data object that can be used to get or set the value */ @SuppressWarnings("unchecked") @@ -121,22 +124,39 @@ public final class IHaveConfig { /** * Generates the config YAML. * - * @param obj The object which has config methods - * @param config The config that holds the values + * @param obj The object which has config methods + * @param configMap The result from {@link Component#getConfigMap(String, Map)}. May be null. */ - public static void pregenConfig(Object obj, IHaveConfig config) { + public static void pregenConfig(Object obj, @Nullable Map configMap) { val ms = obj.getClass().getDeclaredMethods(); for (val m : ms) { if (!m.getReturnType().getName().equals(ConfigData.class.getName())) continue; try { + m.setAccessible(true); + List> configList; if (m.getParameterCount() == 0) { - m.setAccessible(true); - ConfigData c = (ConfigData) m.invoke(obj); - if (!c.getPath().equals(m.getName())) - MainPlugin.Instance.getLogger().warning("Config name does not match: " + c.getPath() + " instead of " + m.getName()); //TODO: Set it here + configList = Collections.singletonList((ConfigData) m.invoke(obj)); + } else if (m.getParameterCount() == 1 && m.getParameterTypes()[0] == IHaveConfig.class) { + if (configMap == null) continue; //Hope it will get called with the param later + configList = configMap.entrySet().stream().map(kv -> + { + try { + return (ConfigData) m.invoke(obj, kv.getValue()); + } catch (IllegalAccessException | InvocationTargetException e) { + TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + " using config " + kv.getKey() + "!", e); + return null; + } + }).filter(Objects::nonNull).collect(Collectors.toList()); + } else { + MainPlugin.Instance.getLogger().warning("Method " + m.getName() + " returns a config but its parameters are unknown: " + Arrays.toString(m.getParameterTypes())); + continue; + } + for (val c : configList) { + if (c.getPath().length() == 0) + c.setPath(m.getName()); + else if (!c.getPath().equals(m.getName())) + MainPlugin.Instance.getLogger().warning("Config name does not match: " + c.getPath() + " instead of " + m.getName()); c.get(); //Saves the default value if needed - also checks validity - } else if (m.getParameterCount() == 1) { - //TODO: Config map } } catch (Exception e) { TBMCCoreAPI.SendException("Failed to pregenerate " + m.getName() + " for " + obj + "!", e);