diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java new file mode 100644 index 000000000..20b26be7f --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfig.java @@ -0,0 +1,96 @@ +package net.mamoe.mirai.utils.config; + +import org.ini4j.Config; +import org.ini4j.Ini; +import org.ini4j.Profile; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Mirai Config + * Only support {INI} format + * Support MAP and LIST + * Thread safe + */ +public class MiraiConfig { + + private File file; + + private Ini ini; + + private volatile Map cacheSection = new ConcurrentHashMap<>(); + + public MiraiConfig(File file){ + if(!file.getName().contains(".")){ + file = new File(file.getParent() + file.getName() + ".ini"); + } + this.file = file; + try { + if(file.exists()){ + file.createNewFile(); + } + Config config = new Config(); + config.setMultiSection(true); + ini = new Ini(); + ini.setConfig(config); + ini.load(this.file.toURI().toURL()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void setSection(String key, MiraiConfigSection section){ + cacheSection.put(key, section); + } + + + public MiraiMapSection getMapSection(String key){ + if(!cacheSection.containsKey(key)) { + MiraiMapSection section = new MiraiMapSection(); + if(ini.containsKey(key)){ + section.putAll(ini.get(key)); + } + cacheSection.put(key, section); + } + return (MiraiMapSection) cacheSection.get(key); + } + + public MiraiListSection getListSection(String key){ + if(!cacheSection.containsKey(key)) { + MiraiListSection section = new MiraiListSection(); + if(ini.containsKey(key)){ + section.addAll(ini.get(key).values()); + } + cacheSection.put(key, section); + } + return (MiraiListSection) cacheSection.get(key); + } + + + public synchronized void save(){ + cacheSection.forEach((k,a) -> { + if(!ini.containsKey(k)) { + ini.put(k,"",new HashMap<>()); + } + a.saveAsSection(ini.get(k)); + }); + this.clearCache(); + try { + ini.store(file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void clearCache(){ + cacheSection.clear(); + } +} + diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfigSection.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfigSection.java new file mode 100644 index 000000000..1103901fa --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiConfigSection.java @@ -0,0 +1,12 @@ +package net.mamoe.mirai.utils.config; + +import org.ini4j.Profile; + +import java.io.Closeable; +import java.util.Map; + +public interface MiraiConfigSection extends Closeable { + void saveAsSection(Profile.Section section); +} + + diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiListSection.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiListSection.java new file mode 100644 index 000000000..c974a545b --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiListSection.java @@ -0,0 +1,52 @@ +package net.mamoe.mirai.utils.config; + + +import org.ini4j.Profile; + +import java.io.IOException; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + + +public class MiraiListSection extends Vector implements MiraiConfigSection{ + private Lock lock = new ReentrantLock(); + + @SuppressWarnings("unchecked") + public T getAs(int index){ + return (T)super.get(index); + } + + public int getInt(int index){ + return this.getAs(index); + } + + public int getDouble(int index){ + return this.getAs(index); + } + + public int getString(int index){ + return this.getAs(index); + } + + public int getFloat(int index) { + return this.getAs(index); + } + + @Override + public synchronized void saveAsSection(Profile.Section section) { + section.clear(); + AtomicInteger integer = new AtomicInteger(0); + this.forEach(a -> { + section.put(String.valueOf(integer.getAndAdd(1)),a); + }); + } + + @Override + public void close() throws IOException { + + } + +} diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiMapSection.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiMapSection.java new file mode 100644 index 000000000..f2ee89ddf --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/config/MiraiMapSection.java @@ -0,0 +1,88 @@ +package net.mamoe.mirai.utils.config; + + +import org.ini4j.Profile; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + + +public class MiraiMapSection extends ConcurrentHashMap implements MiraiConfigSection { + + public Object get(String key){ + return this.get(key,null); + } + + @SuppressWarnings("unchecked") + public T get(String key, T defaultValue) { + if (key == null || key.isEmpty()){ + return defaultValue; + } + if (super.containsKey(key)){ + return (T) super.get(key); + } + return defaultValue; + } + + public void set(String key, Object value){ + this.put(key,value); + } + + public void remove(String key){ + super.remove(key); + } + + public int getInt(String key) { + return this.getInt(key, 0); + } + + public int getInt(String key, int defaultValue) { + return Integer.parseInt(String.valueOf(this.get(key, defaultValue))); + } + + public double getDouble(String key) { + return this.getDouble(key, 0D); + } + + public double getDouble(String key, double defaultValue) { + return Double.parseDouble(String.valueOf(this.get(key, defaultValue))); + } + + public float getFloat(String key) { + return this.getFloat(key, 0F); + } + + public float getFloat(String key, float defaultValue) { + return Float.parseFloat(String.valueOf(this.get(key, defaultValue))); + } + + public String getString(String key) { + return this.getString(key, ""); + } + + public String getString(String key, String defaultValue) { + return String.valueOf(this.get(key, defaultValue)); + } + + @SuppressWarnings("unchecked") + public List asList(){ + return this.values().stream().map(a -> (T)(a)).collect(Collectors.toList()); + } + + @Override + public synchronized void saveAsSection(Profile.Section section) { + section.clear(); + this.forEach(section::put); + } + + @Override + public void close() throws IOException { + + } + +} +