kerosene/src/main/java/pm/j4/kerosene/util/config/ConfigManager.java

259 lines
6.9 KiB
Java

package pm.j4.kerosene.util.config;
import com.google.common.reflect.TypeToken;
import com.google.gson.*;
import java.io.*;
import java.lang.reflect.Type;
import java.util.*;
import net.fabricmc.loader.api.FabricLoader;
import pm.j4.kerosene.KeroseneMod;
import pm.j4.kerosene.modules.bindings.BindingInfo;
import pm.j4.kerosene.util.data.ModuleConfig;
import pm.j4.kerosene.util.data.OptionSerializiable;
import pm.j4.kerosene.util.module.ModuleBase;
/**
* The type Config manager.
*/
public class ConfigManager {
/**
* The constant GSON.
*/
public static final Gson GSON = new GsonBuilder()
.registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalSerializer())
.registerTypeAdapter(GlobalConfig.class, SerializationHelper.getGlobalDeserializer())
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).setPrettyPrinting().create();
/**
* The constant config.
*/
private static Map<String, ConfigHolder> configs = new HashMap<>();
/**
* Prepare config file.
*
* @param path the path
* @param filename the filename
* @return the file
*/
private static File prepareConfigFile(String path, String filename) {
if (path != "") {
File directory = new File(FabricLoader.getInstance().getConfigDir().toString(), path);
if (!directory.exists()) directory.mkdir();
}
return new File(FabricLoader.getInstance().getConfigDir().toString(), path + filename);
}
/**
* Init config.
*/
public static void initConfig(String moduleName) {
if (configs.containsKey(moduleName)) {
return;
}
ConfigHolder config = new ConfigHolder();
config.globalConfig = new DefaultConfig();
config.serverConfigs = new HashMap<>();
config = load(moduleName + "/", moduleName +".json", ConfigHolder.class);
initModules(moduleName);
}
/**
* Init modules.
*/
public static void initModules(String moduleName) {
KeroseneMod.getRegisteredMods().forEach(module -> {
ModuleConfig options = load(moduleName + "/modules/", module.getModuleName() + ".json", ModuleConfig.class);
if (options != null && options.options != null) {
options.options.forEach((key, option) -> {
if (module.hasOption(option.key)) {
module.setConfigOption(option.key, option.value);
}
});
}
});
}
/**
* Load.
*
* @param <T> the type parameter
* @param path the path
* @param filename the filename
* @param tClass the t class
* @return the t
*/
private static <T> T load(String path, String filename, Class<T> tClass) {
File file = prepareConfigFile(path, filename);
try {
if (!file.exists()) {
save(path, filename, tClass.newInstance());
}
if (file.exists()) {
BufferedReader reader = new BufferedReader(new FileReader(file));
T parsedConfig = null;
try {
parsedConfig = GSON.fromJson(reader, tClass);
} catch (Exception e) {
System.out.println("Couldn't parse config file");
e.printStackTrace();
}
if (parsedConfig != null) {
return parsedConfig;
}
}
} catch (FileNotFoundException | InstantiationException | IllegalAccessException e) {
System.out.println("Couldn't load configuration file at " + path);
e.printStackTrace();
}
return null;
}
/**
* Deserialize element t.
*
* @param <T> the type parameter
* @param element the element
* @param tClass the t class
* @return the t
*/
public static <T> T deserializeElement(JsonElement element, Class<T> tClass) {
return GSON.fromJson(element, tClass);
}
/**
* Save.
*
* @param <T> the type parameter
* @param path the path
* @param filename the filename
* @param data the data
*/
private static <T> void save(String path, String filename, T data) {
File file = prepareConfigFile(path, filename);
String json = GSON.toJson(data);
try (FileWriter fileWriter = new FileWriter(file)) {
fileWriter.write(json);
} catch (IOException e) {
System.out.println("Couldn't save configuration file at " + path);
e.printStackTrace();
}
}
/**
* Save module.
*
* @param b the b
*/
public static void saveModule(String modName, ModuleBase b) {
ModuleConfig c = new ModuleConfig();
c.options = GlobalConfig.serializeModuleConfiguration(b);
save(modName + "/modules/", b.getModuleName() + ".json", c);
}
/**
* Save all modules.
*/
public static void saveAllModules() {
List<ModuleBase> mods = KeroseneMod.getRegisteredMods();
mods.forEach((module) -> {
ConfigManager.saveModule(module.getParent(), module);
});
}
/**
* Save global config.
*/
public static void saveGlobalConfig(String modName) {
if(configs.containsKey(modName)) {
save(modName + "/", modName + ".json", configs.get(modName));
}
}
/**
* Gets config.
*
* @return the config
*/
public static Optional<ConfigHolder> getConfig(String modName) {
if (configs.containsKey(modName)) {
return Optional.of(configs.get(modName));
}
return Optional.empty();
}
}
/**
* The type Serialization helper.
*/
class SerializationHelper {
/**
* The constant s.
*/
private static final JsonSerializer<GlobalConfig> GLOBAL_CONFIG_JSON_SERIALIZER = (src, typeOfSrc, ctx) -> {
JsonObject jsonConfig = new JsonObject();
JsonArray bindings = ctx.serialize(src.serializeBindings()).getAsJsonArray();
jsonConfig.add("bindings", bindings);
JsonArray modules = ctx.serialize(src.enabledModules).getAsJsonArray();
jsonConfig.add("enabled_modules", modules);
return jsonConfig;
};
/**
* The constant ds.
*/
private static final JsonDeserializer<GlobalConfig> GLOBAL_CONFIG_JSON_DESERIALIZER = ((json, typeOfT, ctx) -> {
JsonObject obj = json.getAsJsonObject();
List<BindingInfo> bindings = new ArrayList<>();
if (obj.has("bindings")) {
obj.get("bindings").getAsJsonArray().forEach(b -> bindings.add(ctx.deserialize(b, BindingInfo.class)));
}
List<String> modules = new ArrayList<>();
if (obj.has("enabled_modules")) {
obj.get("enabled_modules").getAsJsonArray().forEach(m -> modules.add(m.getAsString()));
}
GlobalConfig cfg = new GlobalConfig();
Map<String, List<OptionSerializiable>> options;
Type type = new TypeToken<Map<String, List<OptionSerializiable>>>() {
}.getType();
if (obj.has("module_configuration")) {
options = ctx.deserialize(obj.get("module_configuration"), type);
} else {
options = new HashMap<>();
}
KeroseneMod.getRegisteredMods().forEach(module -> {
if (options.containsKey(module.getModuleName())) {
cfg.deserializeModuleConfiguration(options.get(module.getModuleName()), module);
}
});
cfg.deserializeBindings(bindings);
cfg.enabledModules = modules;
return cfg;
});
/**
* Gets serializer.
*
* @return the serializer
*/
public static JsonSerializer<GlobalConfig> getGlobalSerializer() {
return GLOBAL_CONFIG_JSON_SERIALIZER;
}
/**
* Gets deserializer.
*
* @return the deserializer
*/
public static JsonDeserializer<GlobalConfig> getGlobalDeserializer() {
return GLOBAL_CONFIG_JSON_DESERIALIZER;
}
}