1 package com.irtimaled.bbor.client.config;
3 import com.google.common.io.Files;
6 import java.nio.charset.StandardCharsets;
7 import java.util.HashMap;
12 private static final String FALLBACK_CATEGORY = "features";
13 private final File file;
15 Configuration(File file) {
20 try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
21 writer.write("# Configuration file\n");
22 for (String category : settingsGroup.keySet()) {
24 writer.write(String.format("%s {\n", category));
25 Map<String, Setting<?>> settings = settingsGroup.get(category);
27 for (String settingName : settings.keySet()) {
31 Setting setting = settings.get(settingName);
32 writer.write(String.format(" # %s\n", setting.comment));
33 writer.write(String.format(" %s:%s=%s\n", setting.getType(), settingName, setting.getValue()));
37 } catch (IOException ignored) {
41 private final Map<String, Map<String, Setting<?>>> settingsGroup = new HashMap<>();
45 List<String> lines = Files.readLines(file, StandardCharsets.UTF_8);
46 String category = null;
47 String lastCommentLine = null;
48 for (String line : lines) {
49 String trimmedLine = line.trim();
50 if (trimmedLine.isEmpty()) {
53 if (trimmedLine.startsWith("#")) {
54 lastCommentLine = trimmedLine.substring(1).trim();
57 if (trimmedLine.equals("}")) {
61 if (category == null && trimmedLine.endsWith("{")) {
62 category = trimmedLine.substring(0, trimmedLine.length() - 1).trim();
63 settingsGroup.put(category, new HashMap<>());
66 if (category != null) {
67 String[] items = trimmedLine.split("[:=]");
68 char type = items[0].charAt(0);
69 String name = items[1];
70 String stringValue = items[2];
71 Setting setting = getTypedSetting(type, stringValue);
72 setting.comment = lastCommentLine;
73 settingsGroup.get(category).put(name, setting);
76 } catch (IOException ignored) {
80 private Setting<?> getTypedSetting(char type, String value) {
83 return new Setting<>(type, Integer.parseInt(value));
85 return new Setting<>(type, value.equals("1") || value.toLowerCase().equals("true"));
87 return new Setting<>(type, value);
90 <T> Setting<T> get(String category, String settingName, T defaultValue) {
91 char type = getType(defaultValue);
92 if (!settingsGroup.containsKey(category)) {
93 settingsGroup.put(category, new HashMap<>());
95 Map<String, Setting<?>> settings = settingsGroup.get(category);
96 Setting<?> setting = settings.get(settingName);
97 if (setting == null && !category.equals(FALLBACK_CATEGORY))
98 setting = getFallbackSetting(settingName, settings);
99 if (setting != null && setting.getType() != type) {
102 if (setting == null) {
103 settings.put(settingName, setting = new Setting<>(type, defaultValue));
105 return (Setting<T>) setting;
108 private Setting<?> getFallbackSetting(String settingName, Map<String, Setting<?>> settings) {
109 Map<String, Setting<?>> fallbackSettings = settingsGroup.get(FALLBACK_CATEGORY);
110 if (fallbackSettings == null) return null;
112 Setting<?> setting = fallbackSettings.get(settingName);
113 if (setting != null) {
114 fallbackSettings.remove(settingName);
115 settings.put(settingName, setting);
120 private <T> char getType(T defaultValue) {
121 String[] typeNames = defaultValue.getClass().getName().split("[.]");
122 return typeNames[typeNames.length - 1].charAt(0);
125 void put(Setting<?> setting) {
126 String category = setting.category;
127 if (!settingsGroup.containsKey(category)) {
128 settingsGroup.put(category, new HashMap<>());
130 Map<String, Setting<?>> settings = settingsGroup.get(category);
131 settings.put(setting.name, setting);