mirror of
https://github.com/filoghost/ChestCommands.git
synced 2024-11-22 18:16:14 +01:00
Large configuration refactoring
This commit is contained in:
parent
dfc060fdcd
commit
58bdf388bf
@ -17,12 +17,11 @@ package me.filoghost.chestcommands;
|
|||||||
import me.filoghost.chestcommands.api.internal.BackendAPI;
|
import me.filoghost.chestcommands.api.internal.BackendAPI;
|
||||||
import me.filoghost.chestcommands.command.CommandHandler;
|
import me.filoghost.chestcommands.command.CommandHandler;
|
||||||
import me.filoghost.chestcommands.command.framework.CommandFramework;
|
import me.filoghost.chestcommands.command.framework.CommandFramework;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
import me.filoghost.chestcommands.config.ConfigManager;
|
import me.filoghost.chestcommands.config.ConfigManager;
|
||||||
import me.filoghost.chestcommands.config.files.CustomPlaceholders;
|
import me.filoghost.chestcommands.config.CustomPlaceholders;
|
||||||
import me.filoghost.chestcommands.config.files.Lang;
|
import me.filoghost.chestcommands.config.Lang;
|
||||||
import me.filoghost.chestcommands.parsing.menu.LoadedMenu;
|
import me.filoghost.chestcommands.config.Settings;
|
||||||
import me.filoghost.chestcommands.config.files.Settings;
|
|
||||||
import me.filoghost.chestcommands.hook.BarAPIHook;
|
import me.filoghost.chestcommands.hook.BarAPIHook;
|
||||||
import me.filoghost.chestcommands.hook.BungeeCordHook;
|
import me.filoghost.chestcommands.hook.BungeeCordHook;
|
||||||
import me.filoghost.chestcommands.hook.PlaceholderAPIHook;
|
import me.filoghost.chestcommands.hook.PlaceholderAPIHook;
|
||||||
@ -34,10 +33,11 @@ import me.filoghost.chestcommands.listener.InventoryListener;
|
|||||||
import me.filoghost.chestcommands.listener.JoinListener;
|
import me.filoghost.chestcommands.listener.JoinListener;
|
||||||
import me.filoghost.chestcommands.listener.SignListener;
|
import me.filoghost.chestcommands.listener.SignListener;
|
||||||
import me.filoghost.chestcommands.menu.MenuManager;
|
import me.filoghost.chestcommands.menu.MenuManager;
|
||||||
|
import me.filoghost.chestcommands.parsing.menu.LoadedMenu;
|
||||||
import me.filoghost.chestcommands.task.RefreshMenusTask;
|
import me.filoghost.chestcommands.task.RefreshMenusTask;
|
||||||
|
import me.filoghost.chestcommands.util.Log;
|
||||||
import me.filoghost.chestcommands.util.Utils;
|
import me.filoghost.chestcommands.util.Utils;
|
||||||
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
||||||
import me.filoghost.chestcommands.util.Log;
|
|
||||||
import me.filoghost.updatechecker.UpdateChecker;
|
import me.filoghost.updatechecker.UpdateChecker;
|
||||||
import org.bstats.bukkit.MetricsLite;
|
import org.bstats.bukkit.MetricsLite;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -152,9 +152,9 @@ public class ChestCommands extends JavaPlugin {
|
|||||||
public ErrorCollector load() {
|
public ErrorCollector load() {
|
||||||
ErrorCollector errors = new ErrorCollector();
|
ErrorCollector errors = new ErrorCollector();
|
||||||
menuManager.clear();
|
menuManager.clear();
|
||||||
boolean isFreshInstall = !Files.isDirectory(configManager.getBaseDataPath());
|
boolean isFreshInstall = !Files.isDirectory(configManager.getRootDataFolder());
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(configManager.getBaseDataPath());
|
Files.createDirectories(configManager.getRootDataFolder());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
errors.addError("Plugin failed to load, couldn't create data folder.");
|
errors.addError("Plugin failed to load, couldn't create data folder.");
|
||||||
return errors;
|
return errors;
|
||||||
@ -172,7 +172,7 @@ public class ChestCommands extends JavaPlugin {
|
|||||||
|
|
||||||
// Create the menu folder with the example menu
|
// Create the menu folder with the example menu
|
||||||
if (!Files.isDirectory(configManager.getMenusFolder())) {
|
if (!Files.isDirectory(configManager.getMenusFolder())) {
|
||||||
ConfigLoader exampleMenuLoader = new ConfigLoader(configManager.getMenusFolder().resolve("example.yml"));
|
ConfigLoader exampleMenuLoader = configManager.getConfigLoader(configManager.getMenusFolder().resolve("example.yml"));
|
||||||
configManager.tryCreateDefault(exampleMenuLoader);
|
configManager.tryCreateDefault(exampleMenuLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package me.filoghost.chestcommands.config;
|
|
||||||
|
|
||||||
import me.filoghost.chestcommands.util.Preconditions;
|
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
public class ConfigLoader {
|
|
||||||
|
|
||||||
private final Path path;
|
|
||||||
|
|
||||||
public ConfigLoader(Path path) {
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Path getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createDefault(Path baseDataPath) throws IOException {
|
|
||||||
if (!path.startsWith(baseDataPath)) {
|
|
||||||
throw new IOException("Config file " + path + " must be inside " + baseDataPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Files.exists(path)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path.getParent() != null) {
|
|
||||||
Files.createDirectories(path.getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
Path absoluteDataPath = baseDataPath.toAbsolutePath();
|
|
||||||
Path absoluteConfigPath = path.toAbsolutePath();
|
|
||||||
|
|
||||||
if (absoluteConfigPath.startsWith(absoluteDataPath)) {
|
|
||||||
Path relativeConfigPath = absoluteDataPath.relativize(absoluteConfigPath);
|
|
||||||
String internalJarPath = toInternalJarPath(relativeConfigPath);
|
|
||||||
|
|
||||||
try (InputStream defaultFile = getResource(internalJarPath)) {
|
|
||||||
if (defaultFile != null) {
|
|
||||||
Files.copy(defaultFile, path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Files.createFile(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toInternalJarPath(Path path) {
|
|
||||||
return StreamSupport.stream(path.spliterator(), false)
|
|
||||||
.map(Path::toString)
|
|
||||||
.collect(Collectors.joining("/", "/", ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private InputStream getResource(String internalJarPath) throws IOException {
|
|
||||||
Preconditions.notNull(internalJarPath, "internalJarPath");
|
|
||||||
|
|
||||||
URL resourceURL = getClass().getResource(internalJarPath);
|
|
||||||
if (resourceURL == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
URLConnection connection = resourceURL.openConnection();
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
return connection.getInputStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Config load() throws IOException, InvalidConfigurationException {
|
|
||||||
YamlConfiguration yaml = new YamlConfiguration();
|
|
||||||
|
|
||||||
try (BufferedReader reader = Files.newBufferedReader(path)) {
|
|
||||||
yaml.load(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Config(yaml, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Config loadEmpty() {
|
|
||||||
return new Config(new YamlConfiguration(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(Config config) throws IOException {
|
|
||||||
if (path.getParent() != null) {
|
|
||||||
Files.createDirectories(path.getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
String data = config.saveToString();
|
|
||||||
|
|
||||||
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
|
|
||||||
writer.write(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFileName() {
|
|
||||||
return path.getFileName().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -14,14 +14,17 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.config;
|
package me.filoghost.chestcommands.config;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.files.CustomPlaceholders;
|
import me.filoghost.chestcommands.config.framework.BaseConfigManager;
|
||||||
import me.filoghost.chestcommands.config.files.Lang;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSyntaxException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.MappedConfigLoader;
|
||||||
import me.filoghost.chestcommands.parsing.menu.LoadedMenu;
|
import me.filoghost.chestcommands.parsing.menu.LoadedMenu;
|
||||||
import me.filoghost.chestcommands.config.files.Settings;
|
|
||||||
import me.filoghost.chestcommands.parsing.menu.MenuParser;
|
import me.filoghost.chestcommands.parsing.menu.MenuParser;
|
||||||
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
|
||||||
import me.filoghost.chestcommands.util.Log;
|
import me.filoghost.chestcommands.util.Log;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
|
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.FileVisitOption;
|
import java.nio.file.FileVisitOption;
|
||||||
@ -33,55 +36,46 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager extends BaseConfigManager {
|
||||||
|
|
||||||
private final Path baseDataPath;
|
private final MappedConfigLoader<Settings> settingsConfigLoader;
|
||||||
private final ConfigLoader settingsConfigLoader;
|
|
||||||
private final ConfigLoader placeholdersConfigLoader;
|
private final ConfigLoader placeholdersConfigLoader;
|
||||||
private final ConfigLoader langConfigLoader;
|
private final MappedConfigLoader<Lang> langConfigLoader;
|
||||||
|
|
||||||
public ConfigManager(Path baseDataPath) {
|
public ConfigManager(Path rootDataFolder) {
|
||||||
this.baseDataPath = baseDataPath;
|
super(rootDataFolder);
|
||||||
settingsConfigLoader = new ConfigLoader(baseDataPath.resolve("config.yml"));
|
|
||||||
placeholdersConfigLoader = new ConfigLoader(baseDataPath.resolve("custom-placeholders.yml"));
|
settingsConfigLoader = getMappedConfigLoader("config.yml", Settings::new);
|
||||||
langConfigLoader = new ConfigLoader(baseDataPath.resolve("lang.yml"));
|
placeholdersConfigLoader = getConfigLoader("custom-placeholders.yml");
|
||||||
|
langConfigLoader = getMappedConfigLoader("lang.yml", Lang::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Settings tryLoadSettings() {
|
public Settings tryLoadSettings() {
|
||||||
Settings settings = new Settings();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
settingsConfigLoader.createDefault(baseDataPath);
|
return settingsConfigLoader.init();
|
||||||
settings.load(settingsConfigLoader);
|
} catch (ConfigException e) {
|
||||||
} catch (Throwable t) {
|
logConfigInitException(settingsConfigLoader.getFileName(), e);
|
||||||
logConfigLoadException(settingsConfigLoader, t);
|
return new Settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lang tryLoadLang() {
|
public Lang tryLoadLang() {
|
||||||
Lang lang = new Lang();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
langConfigLoader.createDefault(baseDataPath);
|
return langConfigLoader.init();
|
||||||
lang.load(langConfigLoader);
|
} catch (ConfigException e) {
|
||||||
} catch (Throwable t) {
|
logConfigInitException(langConfigLoader.getFileName(), e);
|
||||||
logConfigLoadException(langConfigLoader, t);
|
return new Lang();
|
||||||
}
|
}
|
||||||
|
|
||||||
return lang;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomPlaceholders tryLoadCustomPlaceholders(ErrorCollector errorCollector) {
|
public CustomPlaceholders tryLoadCustomPlaceholders(ErrorCollector errorCollector) {
|
||||||
CustomPlaceholders placeholders = new CustomPlaceholders();
|
CustomPlaceholders placeholders = new CustomPlaceholders();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
placeholdersConfigLoader.createDefault(baseDataPath);
|
Config placeholdersConfig = placeholdersConfigLoader.init();
|
||||||
Config placeholdersConfig = placeholdersConfigLoader.load();
|
|
||||||
placeholders.load(placeholdersConfig, errorCollector);
|
placeholders.load(placeholdersConfig, errorCollector);
|
||||||
} catch (Throwable t) {
|
} catch (ConfigException t) {
|
||||||
logConfigLoadException(placeholdersConfigLoader, t);
|
logConfigInitException(placeholdersConfigLoader.getFileName(), t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return placeholders;
|
return placeholders;
|
||||||
@ -89,20 +83,22 @@ public class ConfigManager {
|
|||||||
|
|
||||||
public void tryCreateDefault(ConfigLoader configLoader) {
|
public void tryCreateDefault(ConfigLoader configLoader) {
|
||||||
try {
|
try {
|
||||||
configLoader.createDefault(baseDataPath);
|
configLoader.createDefault();
|
||||||
} catch (Throwable t) {
|
} catch (ConfigException e) {
|
||||||
logConfigLoadException(configLoader, t);
|
logConfigInitException(configLoader.getFileName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getMenusFolder() {
|
public Path getMenusFolder() {
|
||||||
return baseDataPath.resolve("menu");
|
return rootDataFolder.resolve("menu");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of YML menu files.
|
* Returns a list of YML menu files.
|
||||||
*/
|
*/
|
||||||
public List<Path> getMenuPaths() throws IOException {
|
public List<Path> getMenuPaths() throws IOException {
|
||||||
|
Preconditions.checkState(Files.isDirectory(getMenusFolder()), "menus folder doesn't exist");
|
||||||
|
|
||||||
try (Stream<Path> paths = Files.walk(getMenusFolder(), FileVisitOption.FOLLOW_LINKS)) {
|
try (Stream<Path> paths = Files.walk(getMenusFolder(), FileVisitOption.FOLLOW_LINKS)) {
|
||||||
return paths.filter(Files::isRegularFile)
|
return paths.filter(Files::isRegularFile)
|
||||||
.filter(this::isYmlPath)
|
.filter(this::isYmlPath)
|
||||||
@ -110,39 +106,15 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void logConfigInitException(String fileName, ConfigException e) {
|
||||||
private boolean isYmlPath(Path path) {
|
if (e instanceof ConfigSyntaxException) {
|
||||||
return path.getFileName().toString().toLowerCase().endsWith(".yml");
|
Log.warning("Invalid YAML syntax in config file \"" + fileName + "\": " + e.getMessage());
|
||||||
}
|
|
||||||
|
|
||||||
private void logConfigLoadException(ConfigLoader configLoader, Throwable t) {
|
|
||||||
t.printStackTrace();
|
|
||||||
|
|
||||||
if (t instanceof IOException) {
|
|
||||||
Log.warning("Error while reading the file \"" + configLoader.getFileName() + "\". Default values will be used.");
|
|
||||||
} else if (t instanceof InvalidConfigurationException) {
|
|
||||||
Log.warning("Invalid YAML syntax in the file \"" + configLoader.getFileName() + "\", please look at the error above. Default values will be used.");
|
|
||||||
} else {
|
} else {
|
||||||
Log.warning("Unhandled error while parsing the file \"" + configLoader.getFileName() + "\". Please inform the developer.");
|
e.printStackTrace();
|
||||||
|
Log.warning("Error while reading config file \"" + fileName + "\": " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Path getBaseDataPath() {
|
|
||||||
return baseDataPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigLoader getSettingsConfigLoader() {
|
|
||||||
return settingsConfigLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigLoader getPlaceholdersConfigLoader() {
|
|
||||||
return placeholdersConfigLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigLoader getLangConfigLoader() {
|
|
||||||
return langConfigLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<LoadedMenu> tryLoadMenus(ErrorCollector errorCollector) {
|
public List<LoadedMenu> tryLoadMenus(ErrorCollector errorCollector) {
|
||||||
List<LoadedMenu> loadedMenus = new ArrayList<>();
|
List<LoadedMenu> loadedMenus = new ArrayList<>();
|
||||||
List<Path> menuPaths;
|
List<Path> menuPaths;
|
||||||
@ -155,16 +127,21 @@ public class ConfigManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Path menuFile : menuPaths) {
|
for (Path menuFile : menuPaths) {
|
||||||
ConfigLoader menuConfigLoader = new ConfigLoader(menuFile);
|
ConfigLoader menuConfigLoader = new ConfigLoader(rootDataFolder, menuFile);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Config menuConfig = menuConfigLoader.load();
|
Config menuConfig = menuConfigLoader.load();
|
||||||
loadedMenus.add(MenuParser.loadMenu(menuConfig, errorCollector));
|
loadedMenus.add(MenuParser.loadMenu(menuConfig, errorCollector));
|
||||||
} catch (Throwable t) {
|
} catch (ConfigException e) {
|
||||||
logConfigLoadException(menuConfigLoader, t);
|
logConfigInitException(menuConfigLoader.getFileName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return loadedMenus;
|
return loadedMenus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isYmlPath(Path path) {
|
||||||
|
return path.getFileName().toString().toLowerCase().endsWith(".yml");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package me.filoghost.chestcommands.config;
|
|
||||||
|
|
||||||
public class ConfigValueException extends Exception {
|
|
||||||
|
|
||||||
public ConfigValueException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -12,12 +12,12 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.config.files;
|
package me.filoghost.chestcommands.config;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
|
||||||
import me.filoghost.chestcommands.util.Colors;
|
import me.filoghost.chestcommands.util.Colors;
|
||||||
import me.filoghost.chestcommands.util.collection.CollectionUtils;
|
import me.filoghost.chestcommands.util.collection.CollectionUtils;
|
||||||
|
import me.filoghost.chestcommands.util.collection.ErrorCollector;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -36,12 +36,12 @@ public class CustomPlaceholders {
|
|||||||
String replacement = Colors.addColors(config.getString(key));
|
String replacement = Colors.addColors(config.getString(key));
|
||||||
|
|
||||||
if (placeholder.length() == 0) {
|
if (placeholder.length() == 0) {
|
||||||
errorCollector.addError("Error in " + config.getFileName() + ": placeholder cannot be empty (skipped).");
|
errorCollector.addError("Error in " + config.getSourceFileName() + ": placeholder cannot be empty (skipped).");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (placeholder.length() > 100) {
|
if (placeholder.length() > 100) {
|
||||||
errorCollector.addError("Error in " + config.getFileName() + ": placeholder cannot be longer than 100 character (" + placeholder + ").");
|
errorCollector.addError("Error in " + config.getSourceFileName() + ": placeholder cannot be longer than 100 character (" + placeholder + ").");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -12,11 +12,13 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.config.files;
|
package me.filoghost.chestcommands.config;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.SpecialConfig;
|
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.modifier.ChatColors;
|
||||||
|
|
||||||
public class Lang extends SpecialConfig {
|
@ChatColors
|
||||||
|
public class Lang extends MappedConfig {
|
||||||
|
|
||||||
public String no_open_permission = "&cYou don't have permission &e{permission} &cto use this menu.";
|
public String no_open_permission = "&cYou don't have permission &e{permission} &cto use this menu.";
|
||||||
public String default_no_icon_permission = "&cYou don't have permission for this icon.";
|
public String default_no_icon_permission = "&cYou don't have permission for this icon.";
|
@ -12,11 +12,13 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.config.files;
|
package me.filoghost.chestcommands.config;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.SpecialConfig;
|
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.modifier.ChatColors;
|
||||||
|
|
||||||
public class Settings extends SpecialConfig {
|
@ChatColors
|
||||||
|
public class Settings extends MappedConfig {
|
||||||
|
|
||||||
public String default_color__name = "&f";
|
public String default_color__name = "&f";
|
||||||
public String default_color__lore = "&7";
|
public String default_color__lore = "&7";
|
||||||
@ -25,8 +27,8 @@ public class Settings extends SpecialConfig {
|
|||||||
|
|
||||||
public Settings() {
|
public Settings() {
|
||||||
setHeader(
|
setHeader(
|
||||||
"ChestCommands main configuration file.\n" +
|
"ChestCommands main configuration file.",
|
||||||
"Documentation: https://filoghost.me/docs/chest-commands\n");
|
"Documentation: https://filoghost.me/docs/chest-commands");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package me.filoghost.chestcommands.config;
|
|
||||||
|
|
||||||
import me.filoghost.chestcommands.util.Colors;
|
|
||||||
import me.filoghost.chestcommands.util.Log;
|
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A special configuration wrapper that reads the values using reflection.
|
|
||||||
* It will also save default values if not set.
|
|
||||||
*/
|
|
||||||
public abstract class SpecialConfig {
|
|
||||||
|
|
||||||
private transient String header;
|
|
||||||
private transient Map<String, Object> defaultValuesMap;
|
|
||||||
|
|
||||||
public void setHeader(String header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void load(ConfigLoader loader) throws IOException, IllegalAccessException, InvalidConfigurationException {
|
|
||||||
Config config = loader.load();
|
|
||||||
|
|
||||||
// Check if the configuration was initialized
|
|
||||||
if (defaultValuesMap == null) {
|
|
||||||
defaultValuesMap = new HashMap<>();
|
|
||||||
|
|
||||||
// Put the values in the default values map
|
|
||||||
for (Field field : getClass().getDeclaredFields()) {
|
|
||||||
if (skipField(field)) continue;
|
|
||||||
|
|
||||||
field.setAccessible(true);
|
|
||||||
String configKey = getConfigNode(field);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Object defaultValue = field.get(this);
|
|
||||||
if (defaultValue != null) {
|
|
||||||
defaultValuesMap.put(configKey, defaultValue);
|
|
||||||
} else {
|
|
||||||
Log.warning("The field " + field.getName() + " was not provided with a default value, please inform the developer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean needsSave = false;
|
|
||||||
|
|
||||||
// Save default values not set
|
|
||||||
for (Entry<String, Object> entry : defaultValuesMap.entrySet()) {
|
|
||||||
if (!config.isSet(entry.getKey())) {
|
|
||||||
needsSave = true;
|
|
||||||
config.set(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsSave) {
|
|
||||||
config.setHeader(header);
|
|
||||||
loader.save(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now read change the fields
|
|
||||||
for (Field field : getClass().getDeclaredFields()) {
|
|
||||||
if (skipField(field)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
field.setAccessible(true);
|
|
||||||
String configNode = getConfigNode(field);
|
|
||||||
|
|
||||||
if (config.isSet(configNode)) {
|
|
||||||
Class<?> type = field.getType();
|
|
||||||
|
|
||||||
if (type == boolean.class || type == Boolean.class) {
|
|
||||||
field.set(this, config.getBoolean(configNode));
|
|
||||||
|
|
||||||
} else if (type == int.class || type == Integer.class) {
|
|
||||||
field.set(this, config.getInt(configNode));
|
|
||||||
|
|
||||||
} else if (type == double.class || type == Double.class) {
|
|
||||||
field.set(this, config.getDouble(configNode));
|
|
||||||
|
|
||||||
} else if (type == String.class) {
|
|
||||||
field.set(this, Colors.addColors(config.getString(configNode))); // Always add colors
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Log.warning("Unknown field type: " + field.getType().getName() + " (" + field.getName() + "). Please inform the developer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
field.set(this, defaultValuesMap.get(configNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean skipField(Field field) {
|
|
||||||
int modifiers = field.getModifiers();
|
|
||||||
return Modifier.isTransient(modifiers) || Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getConfigNode(Field field) {
|
|
||||||
return field.getName().replace("__", ".").replace("_", "-");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.MappedConfigLoader;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class BaseConfigManager {
|
||||||
|
|
||||||
|
protected final Path rootDataFolder;
|
||||||
|
|
||||||
|
public BaseConfigManager(Path rootDataFolder) {
|
||||||
|
this.rootDataFolder = rootDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getRootDataFolder() {
|
||||||
|
return rootDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigLoader getConfigLoader(String fileName) {
|
||||||
|
return getConfigLoader(rootDataFolder.resolve(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigLoader getConfigLoader(Path configPath) {
|
||||||
|
return new ConfigLoader(rootDataFolder, configPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends MappedConfig> MappedConfigLoader<T> getMappedConfigLoader(String fileName, Supplier<T> mappedObjectConstructor) {
|
||||||
|
return getMappedConfigLoader(rootDataFolder.resolve(fileName), mappedObjectConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends MappedConfig> MappedConfigLoader<T> getMappedConfigLoader(Path configPath, Supplier<T> mappedObjectConstructor) {
|
||||||
|
return new MappedConfigLoader<>(rootDataFolder, configPath, mappedObjectConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.config;
|
package me.filoghost.chestcommands.config.framework;
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
@ -21,16 +21,20 @@ import java.nio.file.Path;
|
|||||||
public class Config extends ConfigSection {
|
public class Config extends ConfigSection {
|
||||||
|
|
||||||
private final YamlConfiguration yaml;
|
private final YamlConfiguration yaml;
|
||||||
private final Path filePath;
|
private final Path sourceFilePath;
|
||||||
|
|
||||||
public Config(YamlConfiguration yaml, Path filePath) {
|
public Config(Path sourceFilePath) {
|
||||||
super(yaml);
|
this(new YamlConfiguration(), sourceFilePath);
|
||||||
this.yaml = yaml;
|
|
||||||
this.filePath = filePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public Config(YamlConfiguration yaml, Path sourceFilePath) {
|
||||||
return filePath.getFileName().toString();
|
super(yaml);
|
||||||
|
this.yaml = yaml;
|
||||||
|
this.sourceFilePath = sourceFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSourceFileName() {
|
||||||
|
return sourceFilePath.getFileName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String saveToString() {
|
public String saveToString() {
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSyntaxException;
|
||||||
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
public class ConfigLoader {
|
||||||
|
|
||||||
|
private final Path rootDataFolder;
|
||||||
|
private final Path configPath;
|
||||||
|
|
||||||
|
public ConfigLoader(Path rootDataFolder, Path configPath) {
|
||||||
|
Preconditions.checkArgument(configPath.startsWith(rootDataFolder), "config file " + configPath + " cannot be outside " + rootDataFolder);
|
||||||
|
|
||||||
|
this.rootDataFolder = rootDataFolder;
|
||||||
|
this.configPath = configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Config init() throws ConfigSaveException, ConfigLoadException {
|
||||||
|
createDefault();
|
||||||
|
return load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createDefault() throws ConfigSaveException {
|
||||||
|
if (fileExists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
createParentDirectory();
|
||||||
|
|
||||||
|
Path relativeConfigPath = rootDataFolder.relativize(configPath);
|
||||||
|
String internalJarPath = toInternalJarPath(relativeConfigPath);
|
||||||
|
|
||||||
|
try (InputStream defaultFile = getInternalResource(internalJarPath)) {
|
||||||
|
if (defaultFile != null) {
|
||||||
|
Files.copy(defaultFile, configPath);
|
||||||
|
} else {
|
||||||
|
Files.createFile(configPath);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ConfigSaveException("couldn't create default config file " + configPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toInternalJarPath(Path path) {
|
||||||
|
return StreamSupport.stream(path.spliterator(), false)
|
||||||
|
.map(Path::toString)
|
||||||
|
.collect(Collectors.joining("/", "/", ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private InputStream getInternalResource(String internalJarPath) throws IOException {
|
||||||
|
Preconditions.notNull(internalJarPath, "internalJarPath");
|
||||||
|
|
||||||
|
URL resourceURL = getClass().getResource(internalJarPath);
|
||||||
|
if (resourceURL == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
URLConnection connection = resourceURL.openConnection();
|
||||||
|
connection.setUseCaches(false);
|
||||||
|
return connection.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fileExists() {
|
||||||
|
return (Files.isRegularFile(configPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Config load() throws ConfigLoadException {
|
||||||
|
Preconditions.checkState(fileExists(), configPath.getFileName() + " doesn't exist or is not a regular file");
|
||||||
|
|
||||||
|
YamlConfiguration yaml = new YamlConfiguration();
|
||||||
|
|
||||||
|
try (BufferedReader reader = Files.newBufferedReader(configPath)) {
|
||||||
|
yaml.load(reader);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ConfigLoadException("couldn't read config file " + configPath, e);
|
||||||
|
} catch (InvalidConfigurationException e) {
|
||||||
|
throw new ConfigSyntaxException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Config(yaml, configPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(Config config) throws ConfigSaveException {
|
||||||
|
createParentDirectory();
|
||||||
|
|
||||||
|
String data = config.saveToString();
|
||||||
|
|
||||||
|
try (BufferedWriter writer = Files.newBufferedWriter(configPath)) {
|
||||||
|
writer.write(data);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ConfigSaveException("couldn't write config data to " + configPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createParentDirectory() throws ConfigSaveException {
|
||||||
|
if (configPath.getParent() != null) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(configPath.getParent());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ConfigSaveException("couldn't create directory " + configPath.getParent(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Path getConfigPath() {
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return configPath.getFileName().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package me.filoghost.chestcommands.config;
|
package me.filoghost.chestcommands.config.framework;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigValueException;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -75,10 +76,6 @@ public class ConfigSection {
|
|||||||
return yamlSection.getKeys(deep);
|
return yamlSection.getKeys(deep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(String path) {
|
|
||||||
return yamlSection.contains(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSet(String path) {
|
public boolean isSet(String path) {
|
||||||
return yamlSection.isSet(path);
|
return yamlSection.isSet(path);
|
||||||
}
|
}
|
||||||
@ -91,10 +88,6 @@ public class ConfigSection {
|
|||||||
return yamlSection.getString(path);
|
return yamlSection.getString(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String path, String def) {
|
|
||||||
return yamlSection.getString(path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt(String path) {
|
public int getInt(String path) {
|
||||||
return yamlSection.getInt(path);
|
return yamlSection.getInt(path);
|
||||||
}
|
}
|
||||||
@ -107,10 +100,6 @@ public class ConfigSection {
|
|||||||
return yamlSection.getDouble(path);
|
return yamlSection.getDouble(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLong(String path) {
|
|
||||||
return yamlSection.getLong(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getStringList(String path) {
|
public List<String> getStringList(String path) {
|
||||||
return yamlSection.getStringList(path);
|
return yamlSection.getStringList(path);
|
||||||
}
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package me.filoghost.chestcommands.config.framework.exception;
|
||||||
|
|
||||||
|
public class ConfigException extends Exception {
|
||||||
|
|
||||||
|
public ConfigException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfigException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package me.filoghost.chestcommands.config.framework.exception;
|
||||||
|
|
||||||
|
public class ConfigLoadException extends ConfigException {
|
||||||
|
|
||||||
|
public ConfigLoadException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package me.filoghost.chestcommands.config.framework.exception;
|
||||||
|
|
||||||
|
public class ConfigSaveException extends ConfigException {
|
||||||
|
|
||||||
|
public ConfigSaveException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package me.filoghost.chestcommands.config.framework.exception;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
|
||||||
|
public class ConfigSyntaxException extends ConfigLoadException {
|
||||||
|
|
||||||
|
public ConfigSyntaxException(String message, InvalidConfigurationException cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package me.filoghost.chestcommands.config.framework.exception;
|
||||||
|
|
||||||
|
public class ConfigValueException extends ConfigException {
|
||||||
|
|
||||||
|
public ConfigValueException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.BooleanConverter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.Converter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.DoubleConverter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.IntegerConverter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.ListConverter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.converter.StringConverter;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.modifier.ChatColorsModifier;
|
||||||
|
import me.filoghost.chestcommands.config.framework.mapped.modifier.ValueModifier;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ConfigMapper {
|
||||||
|
|
||||||
|
private static final List<Converter> CONVERTERS = ImmutableList.of(
|
||||||
|
new DoubleConverter(),
|
||||||
|
new IntegerConverter(),
|
||||||
|
new BooleanConverter(),
|
||||||
|
new StringConverter(),
|
||||||
|
new ListConverter()
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final List<ValueModifier<?, ?>> VALUE_MODIFIERS = ImmutableList.of(
|
||||||
|
new ChatColorsModifier()
|
||||||
|
);
|
||||||
|
|
||||||
|
private final MappedConfig mappedObject;
|
||||||
|
private final ConfigSection config;
|
||||||
|
private final List<MappedField> mappedFields;
|
||||||
|
|
||||||
|
public ConfigMapper(MappedConfig mappedObject, ConfigSection config) throws ReflectiveOperationException {
|
||||||
|
this.mappedObject = mappedObject;
|
||||||
|
this.config = config;
|
||||||
|
this.mappedFields = getMappableFields(mappedObject.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MappedField> getMappableFields(Class<?> type) throws ReflectiveOperationException {
|
||||||
|
Field[] declaredFields;
|
||||||
|
|
||||||
|
try {
|
||||||
|
declaredFields = type.getDeclaredFields();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new ReflectiveOperationException(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.stream(declaredFields)
|
||||||
|
.filter(this::isMappable)
|
||||||
|
.map(MappedField::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<MappedField, Object> getFieldValues() throws ReflectiveOperationException {
|
||||||
|
Map<MappedField, Object> mappedFieldValues = new HashMap<>();
|
||||||
|
|
||||||
|
for (MappedField mappedField : mappedFields) {
|
||||||
|
Object defaultValue = mappedField.getFromObject(mappedObject);
|
||||||
|
|
||||||
|
if (defaultValue == null) {
|
||||||
|
throw new IllegalArgumentException("mapped field \"" + mappedField.getFieldName() + "\" cannot be null by default");
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedFieldValues.put(mappedField, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedFieldValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addMissingConfigValues(Map<MappedField, Object> defaultValues) {
|
||||||
|
boolean modified = false;
|
||||||
|
|
||||||
|
// Add missing values from defaults
|
||||||
|
for (Entry<MappedField, Object> entry : defaultValues.entrySet()) {
|
||||||
|
MappedField mappedField = entry.getKey();
|
||||||
|
Object defaultValue = entry.getValue();
|
||||||
|
|
||||||
|
if (!config.isSet(mappedField.getConfigPath())) {
|
||||||
|
modified = true;
|
||||||
|
Converter converter = findConverter(mappedField.getFieldType());
|
||||||
|
converter.setConfigValue(config, mappedField.getConfigPath(), defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void injectObjectFields() throws ReflectiveOperationException {
|
||||||
|
for (MappedField mappedField : mappedFields) {
|
||||||
|
injectObjectField(mappedField);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void injectObjectField(MappedField mappedField) throws ReflectiveOperationException {
|
||||||
|
Type[] genericTypes = mappedField.getGenericTypes();
|
||||||
|
Converter converter = findConverter(mappedField.getFieldType());
|
||||||
|
|
||||||
|
Object fieldValue = converter.getFieldValue(config, mappedField.getConfigPath(), genericTypes);
|
||||||
|
|
||||||
|
for (Annotation annotation : mappedField.getAnnotations()) {
|
||||||
|
fieldValue = applyValueModifiers(fieldValue, annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
mappedField.setToObject(mappedObject, fieldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object applyValueModifiers(Object fieldValue, Annotation annotation) {
|
||||||
|
for (ValueModifier<?, ?> modifier : VALUE_MODIFIERS) {
|
||||||
|
if (modifier.isApplicable(annotation, fieldValue)) {
|
||||||
|
fieldValue = modifier.transform(annotation, fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fieldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Converter findConverter(Class<?> type) {
|
||||||
|
return CONVERTERS.stream()
|
||||||
|
.filter(converter -> converter.matches(type))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new IllegalStateException("cannot find converter for type " + type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMappable(Field field) {
|
||||||
|
int modifiers = field.getModifiers();
|
||||||
|
boolean includeStatic = field.isAnnotationPresent(IncludeStatic.class)
|
||||||
|
|| field.getDeclaringClass().isAnnotationPresent(IncludeStatic.class);
|
||||||
|
|
||||||
|
return (!Modifier.isStatic(modifiers) || includeStatic)
|
||||||
|
|| !Modifier.isTransient(modifiers)
|
||||||
|
|| !Modifier.isFinal(modifiers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||||
|
public @interface IncludeStatic {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
|
||||||
|
public class MappedConfig {
|
||||||
|
|
||||||
|
private String header;
|
||||||
|
|
||||||
|
protected void setHeader(String... header) {
|
||||||
|
this.header = String.join("\n", header) + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postLoad() throws ConfigLoadException {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class MappedConfigLoader<T extends MappedConfig> {
|
||||||
|
|
||||||
|
private final ConfigLoader configLoader;
|
||||||
|
private final Supplier<T> mappedObjectConstructor;
|
||||||
|
private Map<MappedField, Object> defaultValues;
|
||||||
|
|
||||||
|
public MappedConfigLoader(Path rootDataFolder, Path configPath, Supplier<T> mappedObjectConstructor) {
|
||||||
|
this.configLoader = new ConfigLoader(rootDataFolder, configPath);
|
||||||
|
this.mappedObjectConstructor = mappedObjectConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T init() throws ConfigLoadException, ConfigSaveException {
|
||||||
|
Config config = configLoader.init();
|
||||||
|
T mappedObject = mappedObjectConstructor.get();
|
||||||
|
|
||||||
|
ConfigMapper mapper;
|
||||||
|
try {
|
||||||
|
mapper = new ConfigMapper(mappedObject, config);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new ConfigLoadException("couldn't initialize config mapper for class " + mappedObject.getClass(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract default values from fields
|
||||||
|
if (defaultValues == null) {
|
||||||
|
try {
|
||||||
|
defaultValues = mapper.getFieldValues();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new ConfigLoadException("couldn't read field values in class " + mappedObject.getClass(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing values and save if necessary
|
||||||
|
boolean modified = mapper.addMissingConfigValues(defaultValues);
|
||||||
|
if (modified) {
|
||||||
|
config.setHeader(mappedObject.getHeader());
|
||||||
|
configLoader.save(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the mapped object with the contents from the config
|
||||||
|
try {
|
||||||
|
mapper.injectObjectFields();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new ConfigLoadException("couldn't inject fields values in class " + mappedObject.getClass(), e);
|
||||||
|
}
|
||||||
|
mappedObject.postLoad();
|
||||||
|
return mappedObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFileName() {
|
||||||
|
return configLoader.getFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class MappedField {
|
||||||
|
|
||||||
|
private final Field field;
|
||||||
|
private final String configPath;
|
||||||
|
|
||||||
|
public MappedField(Field field) {
|
||||||
|
this.field = field;
|
||||||
|
|
||||||
|
this.configPath = field.getName()
|
||||||
|
.replace("__", ".")
|
||||||
|
.replace("_", "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getFromObject(MappedConfig mappedObject) throws ReflectiveOperationException {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
return field.get(mappedObject);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new ReflectiveOperationException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToObject(MappedConfig mappedObject, Object fieldValue) throws ReflectiveOperationException {
|
||||||
|
try {
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(mappedObject, fieldValue);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new ReflectiveOperationException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type[] getGenericTypes() throws ReflectiveOperationException {
|
||||||
|
try {
|
||||||
|
Type genericType = field.getGenericType();
|
||||||
|
if (genericType instanceof ParameterizedType) {
|
||||||
|
return ((ParameterizedType) genericType).getActualTypeArguments();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new ReflectiveOperationException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Annotation> getAnnotations() {
|
||||||
|
return Stream.concat(
|
||||||
|
Arrays.stream(field.getDeclaredAnnotations()),
|
||||||
|
Arrays.stream(field.getDeclaringClass().getDeclaredAnnotations()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFieldName() {
|
||||||
|
return field.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> getFieldType() {
|
||||||
|
return field.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfigPath() {
|
||||||
|
return configPath;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class BooleanConverter implements Converter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfigValue(ConfigSection config, String path, Object value) {
|
||||||
|
config.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getFieldValue(ConfigSection config, String path, Type[] parameterizedTypes) {
|
||||||
|
return config.getBoolean(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class<?> type) {
|
||||||
|
return type == Boolean.class || type == boolean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public interface Converter {
|
||||||
|
|
||||||
|
void setConfigValue(ConfigSection config, String path, Object value);
|
||||||
|
|
||||||
|
Object getFieldValue(ConfigSection config, String path, Type[] genericTypes);
|
||||||
|
|
||||||
|
boolean matches(Class<?> type);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class DoubleConverter implements Converter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfigValue(ConfigSection config, String path, Object value) {
|
||||||
|
config.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double getFieldValue(ConfigSection config, String path, Type[] parameterizedTypes) {
|
||||||
|
return config.getDouble(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class<?> type) {
|
||||||
|
return type == Double.class || type == double.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class IntegerConverter implements Converter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfigValue(ConfigSection config, String path, Object value) {
|
||||||
|
config.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getFieldValue(ConfigSection config, String path, Type[] parameterizedTypes) {
|
||||||
|
return config.getInt(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class<?> type) {
|
||||||
|
return type == Integer.class || type == int.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ListConverter implements Converter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfigValue(ConfigSection config, String path, Object value) {
|
||||||
|
config.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<?> getFieldValue(ConfigSection config, String path, Type[] genericTypes) {
|
||||||
|
Preconditions.notNull(genericTypes, "genericTypes");
|
||||||
|
Preconditions.checkArgument(genericTypes.length == 1, "genericTypes length must be 1");
|
||||||
|
|
||||||
|
Type listType = genericTypes[0];
|
||||||
|
|
||||||
|
if (listType == Integer.class) {
|
||||||
|
return config.getIntegerList(path);
|
||||||
|
} else if (listType == String.class) {
|
||||||
|
return config.getStringList(path);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("unsupported list type: " + listType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class<?> type) {
|
||||||
|
return type == List.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.converter;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class StringConverter implements Converter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setConfigValue(ConfigSection config, String path, Object value) {
|
||||||
|
config.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldValue(ConfigSection config, String path, Type[] parameterizedTypes) {
|
||||||
|
return config.getString(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(Class<?> type) {
|
||||||
|
return type == String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.modifier;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||||
|
public @interface ChatColors {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.modifier;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.util.Colors;
|
||||||
|
|
||||||
|
public class ChatColorsModifier implements ValueModifier<String, ChatColors> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String transformChecked(ChatColors annotation, String value) {
|
||||||
|
return Colors.addColors(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<ChatColors> getAnnotationType() {
|
||||||
|
return ChatColors.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<String> getValueType() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package me.filoghost.chestcommands.config.framework.mapped.modifier;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
|
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
|
public interface ValueModifier<V, A extends Annotation> {
|
||||||
|
|
||||||
|
V transformChecked(A annotation, V value);
|
||||||
|
|
||||||
|
Class<A> getAnnotationType();
|
||||||
|
|
||||||
|
Class<V> getValueType();
|
||||||
|
|
||||||
|
default boolean isApplicable(Annotation annotation, Object value) {
|
||||||
|
return getAnnotationType().isInstance(annotation) && getValueType().isInstance(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Object transform(Annotation annotation, Object fieldValue) {
|
||||||
|
Preconditions.checkArgument(isApplicable(annotation, fieldValue), "modifier doesn't match given types");
|
||||||
|
|
||||||
|
return transformChecked(getAnnotationType().cast(annotation), getValueType().cast(fieldValue));
|
||||||
|
}
|
||||||
|
}
|
@ -14,10 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.legacy;
|
package me.filoghost.chestcommands.legacy;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
import me.filoghost.chestcommands.util.Preconditions;
|
import me.filoghost.chestcommands.util.Preconditions;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -40,7 +39,11 @@ public abstract class Upgrade {
|
|||||||
Preconditions.checkState(!hasRun, "Upgrade can only be run once");
|
Preconditions.checkState(!hasRun, "Upgrade can only be run once");
|
||||||
hasRun = true;
|
hasRun = true;
|
||||||
|
|
||||||
|
try {
|
||||||
computeChanges();
|
computeChanges();
|
||||||
|
} catch (ConfigLoadException e) {
|
||||||
|
throw new UpgradeException("couldn't load file to upgrade \"" + getOriginalFile().getFileName() + "\"", e);
|
||||||
|
}
|
||||||
|
|
||||||
if (modified) {
|
if (modified) {
|
||||||
try {
|
try {
|
||||||
@ -51,7 +54,7 @@ public abstract class Upgrade {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
saveChanges();
|
saveChanges();
|
||||||
} catch (IOException e) {
|
} catch (ConfigSaveException e) {
|
||||||
throw new UpgradeException("couldn't save upgraded file \"" + getUpgradedFile().getFileName() + "\"", e);
|
throw new UpgradeException("couldn't save upgraded file \"" + getUpgradedFile().getFileName() + "\"", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,16 +62,6 @@ public abstract class Upgrade {
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Config loadConfig(ConfigLoader configLoader) throws UpgradeException {
|
|
||||||
try {
|
|
||||||
return configLoader.load();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UpgradeException("couldn't read configuration file \"" + configLoader.getFileName() + "\"", e);
|
|
||||||
} catch (InvalidConfigurationException e) {
|
|
||||||
throw new UpgradeException("couldn't parse YAML syntax of file \"" + configLoader.getFileName() + "\"", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createBackupFile(Path path) throws IOException {
|
private void createBackupFile(Path path) throws IOException {
|
||||||
String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd-HH.mm"));
|
String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd-HH.mm"));
|
||||||
String backupName = path.getFileName() + "_" + date + ".backup";
|
String backupName = path.getFileName() + "_" + date + ".backup";
|
||||||
@ -80,8 +73,8 @@ public abstract class Upgrade {
|
|||||||
|
|
||||||
public abstract Path getUpgradedFile();
|
public abstract Path getUpgradedFile();
|
||||||
|
|
||||||
protected abstract void computeChanges() throws UpgradeException;
|
protected abstract void computeChanges() throws ConfigLoadException;
|
||||||
|
|
||||||
protected abstract void saveChanges() throws IOException;
|
protected abstract void saveChanges() throws ConfigSaveException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
package me.filoghost.chestcommands.legacy;
|
package me.filoghost.chestcommands.legacy;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.ConfigManager;
|
import me.filoghost.chestcommands.config.ConfigManager;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradesDoneRegistry.UpgradeID;
|
import me.filoghost.chestcommands.legacy.UpgradesDoneRegistry.UpgradeID;
|
||||||
import me.filoghost.chestcommands.legacy.upgrades.MenuUpgrade;
|
import me.filoghost.chestcommands.legacy.upgrades.MenuUpgrade;
|
||||||
import me.filoghost.chestcommands.legacy.upgrades.PlaceholdersUpgrade;
|
import me.filoghost.chestcommands.legacy.upgrades.PlaceholdersUpgrade;
|
||||||
@ -42,7 +42,7 @@ public class UpgradesExecutor {
|
|||||||
|
|
||||||
public void run(boolean isFreshInstall) throws UpgradeExecutorException {
|
public void run(boolean isFreshInstall) throws UpgradeExecutorException {
|
||||||
this.failedUpgrades = new ArrayList<>();
|
this.failedUpgrades = new ArrayList<>();
|
||||||
Path upgradesDoneFile = configManager.getBaseDataPath().resolve(".upgrades-done");
|
Path upgradesDoneFile = configManager.getRootDataFolder().resolve(".upgrades-done");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
upgradesDoneRegistry = new UpgradesDoneRegistry(upgradesDoneFile);
|
upgradesDoneRegistry = new UpgradesDoneRegistry(upgradesDoneFile);
|
||||||
@ -56,18 +56,23 @@ public class UpgradesExecutor {
|
|||||||
upgradesDoneRegistry.setAllDone();
|
upgradesDoneRegistry.setAllDone();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
String legacyCommandSeparator = readLegacyCommandSeparator();
|
String legacyCommandSeparator;
|
||||||
|
if (!upgradesDoneRegistry.isDone(UpgradeID.V4_MENUS)) {
|
||||||
|
legacyCommandSeparator = readLegacyCommandSeparator();
|
||||||
|
} else {
|
||||||
|
legacyCommandSeparator = null;
|
||||||
|
}
|
||||||
|
|
||||||
SettingsUpgrade settingsUpgrade = new SettingsUpgrade(configManager.getSettingsConfigLoader());
|
SettingsUpgrade settingsUpgrade = new SettingsUpgrade(configManager);
|
||||||
runIfNecessary(UpgradeID.V4_CONFIG, settingsUpgrade);
|
runIfNecessary(UpgradeID.V4_CONFIG, settingsUpgrade);
|
||||||
|
|
||||||
PlaceholdersUpgrade placeholdersUpgrade = new PlaceholdersUpgrade(configManager.getPlaceholdersConfigLoader(), configManager.getBaseDataPath());
|
PlaceholdersUpgrade placeholdersUpgrade = new PlaceholdersUpgrade(configManager);
|
||||||
runIfNecessary(UpgradeID.V4_PLACEHOLDERS, placeholdersUpgrade);
|
runIfNecessary(UpgradeID.V4_PLACEHOLDERS, placeholdersUpgrade);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<MenuUpgrade> menuUpgrades = CollectionUtils.transform(
|
List<MenuUpgrade> menuUpgrades = CollectionUtils.transform(
|
||||||
configManager.getMenuPaths(),
|
configManager.getMenuPaths(),
|
||||||
menuPath -> new MenuUpgrade(new ConfigLoader(menuPath), legacyCommandSeparator));
|
menuPath -> new MenuUpgrade(configManager.getConfigLoader(menuPath), legacyCommandSeparator));
|
||||||
runIfNecessary(UpgradeID.V4_MENUS, menuUpgrades);
|
runIfNecessary(UpgradeID.V4_MENUS, menuUpgrades);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
failedUpgrades.add(configManager.getMenusFolder());
|
failedUpgrades.add(configManager.getMenusFolder());
|
||||||
@ -91,18 +96,18 @@ public class UpgradesExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String readLegacyCommandSeparator() {
|
private String readLegacyCommandSeparator() {
|
||||||
String legacyCommandSeparator;
|
ConfigLoader settingsConfigLoader = configManager.getConfigLoader("config.yml");
|
||||||
ConfigLoader settingsConfigLoader = configManager.getSettingsConfigLoader();
|
|
||||||
|
|
||||||
try {
|
if (!settingsConfigLoader.fileExists()) {
|
||||||
legacyCommandSeparator = settingsConfigLoader.load().getString("multiple-commands-separator", ";");
|
return null;
|
||||||
} catch (Exception e) {
|
|
||||||
legacyCommandSeparator = ";";
|
|
||||||
Log.severe("Failed to load " + settingsConfigLoader.getFileName()
|
|
||||||
+ ", assuming default command separator \"" + legacyCommandSeparator + "\".");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return legacyCommandSeparator;
|
try {
|
||||||
|
return settingsConfigLoader.load().getString("multiple-commands-separator");
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Log.severe("Failed to load " + settingsConfigLoader.getFileName() + ", assuming default command separator \";\".");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,8 +148,7 @@ public class UpgradesExecutor {
|
|||||||
|
|
||||||
private void logUpgradeException(Upgrade upgrade, UpgradeException upgradeException) {
|
private void logUpgradeException(Upgrade upgrade, UpgradeException upgradeException) {
|
||||||
Log.severe(
|
Log.severe(
|
||||||
"Error while trying to automatically upgrade "
|
"Error while trying to automatically upgrade " + upgrade.getOriginalFile() + ": " + upgradeException.getMessage(),
|
||||||
+ upgrade.getOriginalFile() + ": " + upgradeException.getMessage(),
|
|
||||||
upgradeException.getCause());
|
upgradeException.getCause());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,16 +14,16 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.legacy.upgrades;
|
package me.filoghost.chestcommands.legacy.upgrades;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
import me.filoghost.chestcommands.config.ConfigSection;
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
import me.filoghost.chestcommands.legacy.Upgrade;
|
import me.filoghost.chestcommands.legacy.Upgrade;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradeException;
|
|
||||||
import me.filoghost.chestcommands.parsing.menu.MenuSettingsNode;
|
|
||||||
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
|
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
|
||||||
|
import me.filoghost.chestcommands.parsing.menu.MenuSettingsNode;
|
||||||
import me.filoghost.chestcommands.util.Strings;
|
import me.filoghost.chestcommands.util.Strings;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -43,17 +43,17 @@ public class MenuUpgrade extends Upgrade {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getOriginalFile() {
|
public Path getOriginalFile() {
|
||||||
return menuConfigLoader.getPath();
|
return menuConfigLoader.getConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getUpgradedFile() {
|
public Path getUpgradedFile() {
|
||||||
return menuConfigLoader.getPath();
|
return menuConfigLoader.getConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws UpgradeException {
|
protected void computeChanges() throws ConfigLoadException {
|
||||||
Config menuConfig = loadConfig(menuConfigLoader);
|
Config menuConfig = menuConfigLoader.load();
|
||||||
menuConfig.setHeader(null);
|
menuConfig.setHeader(null);
|
||||||
|
|
||||||
for (String key : menuConfig.getKeys(true)) {
|
for (String key : menuConfig.getKeys(true)) {
|
||||||
@ -74,7 +74,7 @@ public class MenuUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws IOException {
|
protected void saveChanges() throws ConfigSaveException {
|
||||||
menuConfigLoader.save(updatedConfig);
|
menuConfigLoader.save(updatedConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.legacy.upgrades;
|
package me.filoghost.chestcommands.legacy.upgrades;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.ConfigManager;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
import me.filoghost.chestcommands.legacy.Upgrade;
|
import me.filoghost.chestcommands.legacy.Upgrade;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradeException;
|
|
||||||
import me.filoghost.chestcommands.util.Strings;
|
import me.filoghost.chestcommands.util.Strings;
|
||||||
import org.apache.commons.lang.StringEscapeUtils;
|
import org.apache.commons.lang.StringEscapeUtils;
|
||||||
|
|
||||||
@ -28,13 +30,13 @@ import java.util.List;
|
|||||||
|
|
||||||
public class PlaceholdersUpgrade extends Upgrade {
|
public class PlaceholdersUpgrade extends Upgrade {
|
||||||
|
|
||||||
private final ConfigLoader newPlaceholdersConfigLoader;
|
|
||||||
private final Path oldPlaceholdersFile;
|
private final Path oldPlaceholdersFile;
|
||||||
|
private final ConfigLoader newPlaceholdersConfigLoader;
|
||||||
private Config updatedConfig;
|
private Config updatedConfig;
|
||||||
|
|
||||||
public PlaceholdersUpgrade(ConfigLoader placeholdersConfigLoader, Path dataPath) {
|
public PlaceholdersUpgrade(ConfigManager configManager) {
|
||||||
this.newPlaceholdersConfigLoader = placeholdersConfigLoader;
|
this.oldPlaceholdersFile = configManager.getRootDataFolder().resolve("placeholders.yml");
|
||||||
this.oldPlaceholdersFile = dataPath.resolve("placeholders.yml");
|
this.newPlaceholdersConfigLoader = configManager.getConfigLoader("custom-placeholders.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -44,22 +46,22 @@ public class PlaceholdersUpgrade extends Upgrade {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getUpgradedFile() {
|
public Path getUpgradedFile() {
|
||||||
return newPlaceholdersConfigLoader.getPath();
|
return newPlaceholdersConfigLoader.getConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws UpgradeException {
|
protected void computeChanges() throws ConfigLoadException {
|
||||||
if (!Files.isRegularFile(oldPlaceholdersFile)) {
|
if (!Files.isRegularFile(oldPlaceholdersFile)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do NOT load the new placeholder configuration from disk, as it should only contain placeholders imported from the old file
|
// Do NOT load the new placeholder configuration from disk, as it should only contain placeholders imported from the old file
|
||||||
Config newPlaceholdersConfig = newPlaceholdersConfigLoader.loadEmpty();
|
Config newPlaceholdersConfig = new Config(newPlaceholdersConfigLoader.getConfigPath());
|
||||||
List<String> lines;
|
List<String> lines;
|
||||||
try {
|
try {
|
||||||
lines = Files.readAllLines(oldPlaceholdersFile);
|
lines = Files.readAllLines(oldPlaceholdersFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new UpgradeException("couldn't read file \"" + oldPlaceholdersFile.getFileName() + "\"", e);
|
throw new ConfigLoadException("couldn't read file \"" + oldPlaceholdersFile.getFileName() + "\"", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String line : lines) {
|
for (String line : lines) {
|
||||||
@ -85,7 +87,7 @@ public class PlaceholdersUpgrade extends Upgrade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws IOException {
|
protected void saveChanges() throws ConfigSaveException {
|
||||||
try {
|
try {
|
||||||
Files.deleteIfExists(oldPlaceholdersFile);
|
Files.deleteIfExists(oldPlaceholdersFile);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
@ -14,12 +14,13 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.legacy.upgrades;
|
package me.filoghost.chestcommands.legacy.upgrades;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.ConfigManager;
|
||||||
import me.filoghost.chestcommands.config.ConfigLoader;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
|
import me.filoghost.chestcommands.config.framework.ConfigLoader;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
|
||||||
|
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
|
||||||
import me.filoghost.chestcommands.legacy.Upgrade;
|
import me.filoghost.chestcommands.legacy.Upgrade;
|
||||||
import me.filoghost.chestcommands.legacy.UpgradeException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
public class SettingsUpgrade extends Upgrade {
|
public class SettingsUpgrade extends Upgrade {
|
||||||
@ -27,23 +28,23 @@ public class SettingsUpgrade extends Upgrade {
|
|||||||
private final ConfigLoader settingsConfigLoader;
|
private final ConfigLoader settingsConfigLoader;
|
||||||
private Config updatedConfig;
|
private Config updatedConfig;
|
||||||
|
|
||||||
public SettingsUpgrade(ConfigLoader settingsConfigLoader) {
|
public SettingsUpgrade(ConfigManager configManager) {
|
||||||
this.settingsConfigLoader = settingsConfigLoader;
|
this.settingsConfigLoader = configManager.getConfigLoader("config.yml");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getOriginalFile() {
|
public Path getOriginalFile() {
|
||||||
return settingsConfigLoader.getPath();
|
return settingsConfigLoader.getConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path getUpgradedFile() {
|
public Path getUpgradedFile() {
|
||||||
return settingsConfigLoader.getPath();
|
return settingsConfigLoader.getConfigPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void computeChanges() throws UpgradeException {
|
protected void computeChanges() throws ConfigLoadException {
|
||||||
Config settingsConfig = loadConfig(settingsConfigLoader);
|
Config settingsConfig = settingsConfigLoader.load();
|
||||||
|
|
||||||
removeNode(settingsConfig, "use-only-commands-without-args");
|
removeNode(settingsConfig, "use-only-commands-without-args");
|
||||||
removeNode(settingsConfig, "use-console-colors");
|
removeNode(settingsConfig, "use-console-colors");
|
||||||
@ -61,7 +62,7 @@ public class SettingsUpgrade extends Upgrade {
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveChanges() throws IOException {
|
protected void saveChanges() throws ConfigSaveException {
|
||||||
settingsConfigLoader.save(updatedConfig);
|
settingsConfigLoader.save(updatedConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
package me.filoghost.chestcommands.parsing;
|
package me.filoghost.chestcommands.parsing;
|
||||||
|
|
||||||
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
import me.filoghost.chestcommands.parsing.icon.IconSettings;
|
import me.filoghost.chestcommands.parsing.icon.IconSettings;
|
||||||
|
|
||||||
public class ErrorFormat {
|
public class ErrorFormat {
|
||||||
|
|
||||||
public static String invalidMenuSetting(String menuName, String invalidSetting, String errorMessage) {
|
public static String invalidMenuSetting(Config menuConfig, String invalidSetting, String errorMessage) {
|
||||||
return menuError(menuName, "has an invalid menu setting \"" + invalidSetting + "\": " + errorMessage);
|
return menuError(menuConfig, "has an invalid menu setting \"" + invalidSetting + "\": " + errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String missingMenuSetting(String menuName, String missingSetting) {
|
public static String missingMenuSetting(Config menuConfig, String missingSetting) {
|
||||||
return menuError(menuName, "is missing the menu setting \"" + missingSetting + "\"");
|
return menuError(menuConfig, "is missing the menu setting \"" + missingSetting + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String menuError(String menuName, String errorMessage) {
|
private static String menuError(Config menuConfig, String errorMessage) {
|
||||||
return "The menu \"" + menuName + "\" " + errorMessage + ".";
|
return "The menu \"" + menuConfig.getSourceFileName() + "\" " + errorMessage + ".";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String invalidAttribute(IconSettings iconSettings, String attributeName, String errorMessage) {
|
public static String invalidAttribute(IconSettings iconSettings, String attributeName, String errorMessage) {
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.parsing.icon;
|
package me.filoghost.chestcommands.parsing.icon;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.config.ConfigSection;
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
import me.filoghost.chestcommands.config.ConfigValueException;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigValueException;
|
||||||
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
|
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
|
||||||
import me.filoghost.chestcommands.parsing.ParseException;
|
import me.filoghost.chestcommands.parsing.ParseException;
|
||||||
import me.filoghost.chestcommands.parsing.icon.attributes.ActionsAttribute;
|
import me.filoghost.chestcommands.parsing.icon.attributes.ActionsAttribute;
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
package me.filoghost.chestcommands.parsing.menu;
|
package me.filoghost.chestcommands.parsing.menu;
|
||||||
|
|
||||||
import me.filoghost.chestcommands.action.Action;
|
import me.filoghost.chestcommands.action.Action;
|
||||||
import me.filoghost.chestcommands.config.Config;
|
import me.filoghost.chestcommands.config.framework.Config;
|
||||||
import me.filoghost.chestcommands.config.ConfigSection;
|
import me.filoghost.chestcommands.config.framework.ConfigSection;
|
||||||
import me.filoghost.chestcommands.config.ConfigValueException;
|
import me.filoghost.chestcommands.config.framework.exception.ConfigValueException;
|
||||||
import me.filoghost.chestcommands.menu.InternalIconMenu;
|
|
||||||
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
|
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
|
||||||
|
import me.filoghost.chestcommands.menu.InternalIconMenu;
|
||||||
import me.filoghost.chestcommands.parsing.ActionParser;
|
import me.filoghost.chestcommands.parsing.ActionParser;
|
||||||
import me.filoghost.chestcommands.parsing.ErrorFormat;
|
import me.filoghost.chestcommands.parsing.ErrorFormat;
|
||||||
import me.filoghost.chestcommands.parsing.ItemStackParser;
|
import me.filoghost.chestcommands.parsing.ItemStackParser;
|
||||||
@ -41,7 +41,7 @@ public class MenuParser {
|
|||||||
MenuSettings menuSettings = loadMenuSettings(menuConfig, errorCollector);
|
MenuSettings menuSettings = loadMenuSettings(menuConfig, errorCollector);
|
||||||
List<IconSettings> iconSettingsList = loadIconSettingsList(menuConfig, errorCollector);
|
List<IconSettings> iconSettingsList = loadIconSettingsList(menuConfig, errorCollector);
|
||||||
|
|
||||||
InternalIconMenu iconMenu = new InternalIconMenu(menuSettings.getTitle(), menuSettings.getRows(), menuConfig.getFileName());
|
InternalIconMenu iconMenu = new InternalIconMenu(menuSettings.getTitle(), menuSettings.getRows(), menuConfig.getSourceFileName());
|
||||||
|
|
||||||
for (IconSettings iconSettings : iconSettingsList) {
|
for (IconSettings iconSettings : iconSettingsList) {
|
||||||
try {
|
try {
|
||||||
@ -54,7 +54,7 @@ public class MenuParser {
|
|||||||
iconMenu.setRefreshTicks(menuSettings.getRefreshTicks());
|
iconMenu.setRefreshTicks(menuSettings.getRefreshTicks());
|
||||||
iconMenu.setOpenActions(menuSettings.getOpenActions());
|
iconMenu.setOpenActions(menuSettings.getOpenActions());
|
||||||
|
|
||||||
return new LoadedMenu(iconMenu, menuConfig.getFileName(), menuSettings.getCommands(), menuSettings.getOpenTrigger());
|
return new LoadedMenu(iconMenu, menuConfig.getSourceFileName(), menuSettings.getCommands(), menuSettings.getOpenTrigger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ public class MenuParser {
|
|||||||
}
|
}
|
||||||
} catch (ConfigValueException e) {
|
} catch (ConfigValueException e) {
|
||||||
title = ChatColor.DARK_RED + "No name set";
|
title = ChatColor.DARK_RED + "No name set";
|
||||||
errorCollector.addError(ErrorFormat.missingMenuSetting(config.getFileName(), MenuSettingsNode.NAME));
|
errorCollector.addError(ErrorFormat.missingMenuSetting(config, MenuSettingsNode.NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
int rows;
|
int rows;
|
||||||
@ -116,7 +116,7 @@ public class MenuParser {
|
|||||||
}
|
}
|
||||||
} catch (ConfigValueException e) {
|
} catch (ConfigValueException e) {
|
||||||
rows = 6; // Defaults to 6 rows
|
rows = 6; // Defaults to 6 rows
|
||||||
errorCollector.addError(ErrorFormat.missingMenuSetting(config.getFileName(), MenuSettingsNode.ROWS));
|
errorCollector.addError(ErrorFormat.missingMenuSetting(config, MenuSettingsNode.ROWS));
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuSettings menuSettings = new MenuSettings(title, rows);
|
MenuSettings menuSettings = new MenuSettings(title, rows);
|
||||||
@ -157,7 +157,7 @@ public class MenuParser {
|
|||||||
menuSettings.setOpenTrigger(openTrigger);
|
menuSettings.setOpenTrigger(openTrigger);
|
||||||
|
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
errorCollector.addError(ErrorFormat.invalidMenuSetting(config.getFileName(), MenuSettingsNode.OPEN_ITEM_MATERIAL, e.getMessage()));
|
errorCollector.addError(ErrorFormat.invalidMenuSetting(config, MenuSettingsNode.OPEN_ITEM_MATERIAL, e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ public class MenuParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConfigSection iconSection = config.getConfigSection(iconSectionName);
|
ConfigSection iconSection = config.getConfigSection(iconSectionName);
|
||||||
IconSettings iconSettings = new IconSettings(config.getFileName(), iconSectionName);
|
IconSettings iconSettings = new IconSettings(config.getSourceFileName(), iconSectionName);
|
||||||
iconSettings.loadFrom(iconSection, errorCollector);
|
iconSettings.loadFrom(iconSection, errorCollector);
|
||||||
iconSettingsList.add(iconSettings);
|
iconSettingsList.add(iconSettings);
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
package me.filoghost.chestcommands.util;
|
package me.filoghost.chestcommands.util;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public final class Preconditions {
|
public final class Preconditions {
|
||||||
|
|
||||||
private Preconditions() {}
|
private Preconditions() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user