package hunternif.mc.atlas.util; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.io.File; /** * Basic JSON config that handles format versions and empty or malformed files. * @author Hunternif */ public abstract class AbstractJSONConfig<T extends SaveData> implements Config<T> { private final File file; protected AbstractJSONConfig(File file) { this.file = file; } @Override public void load(T data) { JsonElement root = FileUtil.readJson(file); if (root == null) { Log.info("Config %s not found; creating new", file.getName()); save(data); return; } try { JsonElement versionElem = root.getAsJsonObject().get("version"); JsonObject jsonData; int version; boolean outdated = false; if (versionElem == null) { Log.warn("Outdated config %s", file.getName()); version = 0; // Non-existent version means the whole file is just data: jsonData = root.getAsJsonObject(); outdated = true; } else { version = versionElem.getAsInt(); if (currentVersion() > version) { Log.warn("Outdated config %s: version was %d, but current is %d", file.getName(), version, currentVersion()); outdated = true; } JsonElement jsonElem = root.getAsJsonObject().get("data"); if (jsonElem == null) { Log.error("Malformed config " + file.getName()); return; } jsonData = jsonElem.getAsJsonObject(); } loadData(jsonData, data, version); if (outdated) { save(data); } } catch (IllegalStateException | NumberFormatException e) { Log.error(e, "Malformed config %s", file.getName()); } } @Override public void save(T data) { JsonObject root = new JsonObject(); root.addProperty("version", currentVersion()); JsonObject jsonData = new JsonObject(); saveData(jsonData, data); root.add("data", jsonData); FileUtil.writeJson(root, file); } /** * Read data from a JsonObject using the appropriate version parser. * @param json JsonObject to load from * @param data data instance to load into * @param version version of the json file */ protected abstract void loadData(JsonObject json, T data, int version); /** * Write data to a JsonObject (using the latest version). * @param json JsonObject to write to * @param data data to save */ protected abstract void saveData(JsonObject json, T data); /** Latest version of the config format. This version is what is going to * get written into file, but previous versions may still be read. */ protected abstract int currentVersion(); }