diff --git a/core/pom.xml b/core/pom.xml
index 62c38e2..8f9e98b 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -5,7 +5,7 @@
easyconfiguration-parent
cc.carm.lib
- 4.0.7
+ 4.0.8
4.0.0
diff --git a/demo/pom.xml b/demo/pom.xml
index bc89f7d..9d84d6a 100644
--- a/demo/pom.xml
+++ b/demo/pom.xml
@@ -5,7 +5,7 @@
easyconfiguration-parent
cc.carm.lib
- 4.0.7
+ 4.0.8
4.0.0
diff --git a/features/commentable/pom.xml b/features/commentable/pom.xml
index 83bdddc..61912b7 100644
--- a/features/commentable/pom.xml
+++ b/features/commentable/pom.xml
@@ -6,7 +6,7 @@
cc.carm.lib
easyconfiguration-parent
- 4.0.7
+ 4.0.8
../../pom.xml
diff --git a/features/file/pom.xml b/features/file/pom.xml
index e899f77..5ac7568 100644
--- a/features/file/pom.xml
+++ b/features/file/pom.xml
@@ -6,7 +6,7 @@
cc.carm.lib
easyconfiguration-parent
- 4.0.7
+ 4.0.8
../../pom.xml
diff --git a/features/section/pom.xml b/features/section/pom.xml
index 79f4e45..c3969b1 100644
--- a/features/section/pom.xml
+++ b/features/section/pom.xml
@@ -6,7 +6,7 @@
cc.carm.lib
easyconfiguration-parent
- 4.0.7
+ 4.0.8
../../pom.xml
diff --git a/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java b/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java
index 63a9083..d225248 100644
--- a/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java
+++ b/features/section/src/main/java/cc/carm/lib/configuration/source/section/AbstractMapSection.java
@@ -98,6 +98,11 @@ public abstract class AbstractMapSection> implem
return Collections.unmodifiableMap(deep ? mappingValues(this, null, true, String.valueOf(pathSeparator())) : data());
}
+ @Override
+ public @NotNull @UnmodifiableView Set getKeys(boolean deep) {
+ return Collections.unmodifiableSet(deep ? mappingKeys(this, null, true, String.valueOf(pathSeparator())) : data().keySet());
+ }
+
@Override
public void set(@NotNull String path, @Nullable Object value) {
if (value instanceof Map) value = createSection(path, (Map, ?>) value);
@@ -157,5 +162,17 @@ public abstract class AbstractMapSection> implem
return output;
}
+ protected static Set mappingKeys(@NotNull AbstractMapSection> section, @Nullable String parent, boolean deep, String pathSeparator) {
+ Set keys = new LinkedHashSet<>();
+ for (Map.Entry entry : section.data().entrySet()) {
+ String path = (parent == null ? "" : parent + pathSeparator) + entry.getKey();
+ keys.add(path);
+ if (deep && entry.getValue() instanceof AbstractMapSection>) {
+ keys.addAll(mappingKeys((AbstractMapSection>) entry.getValue(), path, true, pathSeparator));
+ }
+ }
+ return keys;
+ }
+
}
diff --git a/features/text/pom.xml b/features/text/pom.xml
index 15e94ad..efc9d0e 100644
--- a/features/text/pom.xml
+++ b/features/text/pom.xml
@@ -6,7 +6,7 @@
cc.carm.lib
easyconfiguration-parent
- 4.0.7
+ 4.0.8
../../pom.xml
diff --git a/features/versioned/pom.xml b/features/versioned/pom.xml
index 4a6c9a3..44b4aae 100644
--- a/features/versioned/pom.xml
+++ b/features/versioned/pom.xml
@@ -6,7 +6,7 @@
cc.carm.lib
easyconfiguration-parent
- 4.0.7
+ 4.0.8
../../pom.xml
diff --git a/pom.xml b/pom.xml
index 4077842..282e37e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,7 +15,7 @@
cc.carm.lib
easyconfiguration-parent
pom
- 4.0.7
+ 4.0.8
core
features/section
@@ -28,7 +28,7 @@
providers/gson
-
+ providers/mongodb
demo
diff --git a/providers/gson/pom.xml b/providers/gson/pom.xml
index e2bf4c9..a3c26c0 100644
--- a/providers/gson/pom.xml
+++ b/providers/gson/pom.xml
@@ -5,7 +5,7 @@
easyconfiguration-parent
cc.carm.lib
- 4.0.7
+ 4.0.8
../../pom.xml
4.0.0
diff --git a/providers/mongodb/pom.xml b/providers/mongodb/pom.xml
index c8c2074..2768078 100644
--- a/providers/mongodb/pom.xml
+++ b/providers/mongodb/pom.xml
@@ -5,7 +5,7 @@
easyconfiguration-parent
cc.carm.lib
- 4.0.0
+ 4.0.8
../../pom.xml
4.0.0
@@ -15,6 +15,7 @@
UTF-8
UTF-8
+ 5.3.1
2.24.3
easyconfiguration-mongodb
@@ -30,7 +31,7 @@
${project.parent.groupId}
- easyconfiguration-gson
+ easyconfiguration-feature-section
${project.parent.version}
compile
@@ -38,14 +39,7 @@
org.mongodb
mongodb-driver-sync
- 5.3.1
-
-
-
- ${project.parent.groupId}
- easyconfiguration-demo
- ${project.parent.version}
- test
+ ${deps.mongodb.version}
@@ -69,6 +63,20 @@
test
+
+ ${project.parent.groupId}
+ easyconfiguration-demo
+ ${project.parent.version}
+ test
+
+
+
+ ${project.parent.groupId}
+ easyconfiguration-gson
+ ${project.parent.version}
+ test
+
+
diff --git a/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoConfigFactory.java b/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoConfigFactory.java
new file mode 100644
index 0000000..5fc485e
--- /dev/null
+++ b/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoConfigFactory.java
@@ -0,0 +1,75 @@
+package cc.carm.lib.configuration.source.mongodb;
+
+import cc.carm.lib.configuration.source.ConfigurationFactory;
+import cc.carm.lib.configuration.source.ConfigurationHolder;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.function.Supplier;
+
+public class MongoConfigFactory extends ConfigurationFactory, MongoConfigFactory> {
+
+ public static MongoConfigFactory from(@NotNull Supplier> collectionSupplier) {
+ return new MongoConfigFactory(collectionSupplier);
+ }
+
+ public static MongoConfigFactory from(@NotNull MongoCollection collection) {
+ return from(() -> collection);
+ }
+
+ public static MongoConfigFactory from(@NotNull MongoDatabase database, @NotNull String collectionName) {
+ return from(() -> database.getCollection(collectionName));
+ }
+
+ protected @NotNull Supplier> collectionSupplier;
+ protected @NotNull String namespace = "config";
+
+ public MongoConfigFactory(@NotNull Supplier> collectionSupplier) {
+ super();
+ this.collectionSupplier = collectionSupplier;
+ }
+
+ public MongoConfigFactory collection(@NotNull Supplier> collectionSupplier) {
+ this.collectionSupplier = collectionSupplier;
+ return this;
+ }
+
+ public MongoConfigFactory collection(@NotNull MongoCollection collection) {
+ return collection(() -> collection);
+ }
+
+ public MongoConfigFactory namespace(@NotNull String namespace) {
+ this.namespace = namespace;
+ return this;
+ }
+
+ public MongoConfigFactory namespace(@NotNull Supplier namespace) {
+ return namespace(namespace.get());
+ }
+
+
+ @Override
+ protected MongoConfigFactory self() {
+ return this;
+ }
+
+ @Override
+ public @NotNull ConfigurationHolder build() {
+ MongoCollection collection = this.collectionSupplier.get();
+ if (collection == null) {
+ throw new IllegalStateException("Failed to get MongoCollection from supplier");
+ }
+
+ return new ConfigurationHolder(this.adapters, this.options, this.metadata, this.initializer) {
+ final @NotNull MongoSource source = new MongoSource(this, System.currentTimeMillis(), collection, namespace);
+
+ @Override
+ public @NotNull MongoSource config() {
+ return this.source;
+ }
+ };
+ }
+
+}
diff --git a/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoSource.java b/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoSource.java
index c915857..d7d1866 100644
--- a/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoSource.java
+++ b/providers/mongodb/src/main/java/cc/carm/lib/configuration/source/mongodb/MongoSource.java
@@ -1,4 +1,76 @@
package cc.carm.lib.configuration.source.mongodb;
-public class MongoSource {
+import cc.carm.lib.configuration.source.ConfigurationHolder;
+import cc.carm.lib.configuration.source.section.ConfigureSource;
+import cc.carm.lib.configuration.source.section.SourcedSection;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.ReplaceOptions;
+import org.bson.Document;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+import java.util.Objects;
+
+public class MongoSource extends ConfigureSource, MongoSource> {
+
+ protected final @NotNull MongoCollection collection;
+ protected final @NotNull String namespace;
+
+ protected SourcedSection rootSection;
+
+ protected MongoSource(@NotNull ConfigurationHolder extends MongoSource> holder, long lastUpdateMillis,
+ @NotNull MongoCollection collection, @NotNull String namespace) {
+ super(holder, lastUpdateMillis);
+ this.collection = collection;
+ this.namespace = namespace;
+ try {
+ onReload();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected @NotNull MongoSource self() {
+ return this;
+ }
+
+ @Override
+ public @NotNull Map original() {
+ return section().data();
+ }
+
+ @Override
+ public @NotNull SourcedSection section() {
+ return Objects.requireNonNull(rootSection, "RootSection is not initialized");
+ }
+
+ public @NotNull String namespace() {
+ return this.namespace;
+ }
+
+ public @NotNull MongoCollection collection() {
+ return this.collection;
+ }
+
+ @Override
+ public void save() throws Exception {
+ Map data = this.rootSection.rawMap();
+ if (data.isEmpty()) return; // Skip saving if empty
+ if (data.containsKey("_id") && data.size() == 1) return; // Skip saving if only contains _id
+
+ ReplaceOptions options = new ReplaceOptions().upsert(true);
+ Document storage = new Document(data).append("_id", this.namespace);
+ this.collection.replaceOne(new Document("_id", this.namespace), storage, options);
+ }
+
+ @Override
+ protected void onReload() throws Exception {
+ Document storage = this.collection.find(new Document("_id", this.namespace)).first();
+ if (storage == null) storage = new Document();
+ else storage.remove("_id"); // Remove _id
+ this.rootSection = SourcedSection.root(this, storage);
+ }
+
+
}
diff --git a/providers/mongodb/src/test/java/config/MongoConfig.java b/providers/mongodb/src/test/java/config/MongoConfig.java
new file mode 100644
index 0000000..b831c37
--- /dev/null
+++ b/providers/mongodb/src/test/java/config/MongoConfig.java
@@ -0,0 +1,12 @@
+package config;
+
+import cc.carm.lib.configuration.Configuration;
+import cc.carm.lib.configuration.value.standard.ConfiguredValue;
+
+interface MongoConfig extends Configuration {
+ ConfiguredValue HOST = ConfiguredValue.of("127.0.0.1");
+ ConfiguredValue PORT = ConfiguredValue.of(27017);
+ ConfiguredValue USERNAME = ConfiguredValue.of("minecraft");
+ ConfiguredValue PASSWORD = ConfiguredValue.of("minecraft");
+ ConfiguredValue DATABASE = ConfiguredValue.of("minecraft");
+}
diff --git a/providers/mongodb/src/test/java/config/MongoTest.java b/providers/mongodb/src/test/java/config/MongoTest.java
new file mode 100644
index 0000000..7abdfd1
--- /dev/null
+++ b/providers/mongodb/src/test/java/config/MongoTest.java
@@ -0,0 +1,57 @@
+package config;
+
+import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
+import cc.carm.lib.configuration.source.ConfigurationHolder;
+import cc.carm.lib.configuration.source.json.JSONConfigFactory;
+import cc.carm.lib.configuration.source.mongodb.MongoConfigFactory;
+import com.mongodb.ConnectionString;
+import com.mongodb.MongoClientSettings;
+import com.mongodb.MongoCredential;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.mongodb.client.MongoDatabase;
+import org.bson.UuidRepresentation;
+import org.junit.Test;
+
+import java.io.File;
+
+public class MongoTest {
+
+ boolean local = false;
+
+ @Test
+ public void test() {
+
+ if (!local) return;
+
+ ConfigurationHolder> gsonHolder = JSONConfigFactory.from(new File("target/mongo.json")).build();
+ gsonHolder.initialize(MongoConfig.class);
+
+ MongoClientSettings settings = MongoClientSettings.builder()
+ .applyConnectionString(new ConnectionString(
+ "mongodb://" + MongoConfig.HOST.resolve() + ":" + MongoConfig.PORT.resolve()
+ ))
+ .credential(MongoCredential.createCredential(
+ MongoConfig.USERNAME.resolve(), MongoConfig.DATABASE.resolve(),
+ MongoConfig.PASSWORD.resolve().toCharArray()
+ ))
+ .uuidRepresentation(UuidRepresentation.STANDARD)
+ .build();
+ MongoClient mongoClient = MongoClients.create(settings);
+ MongoDatabase mongoDatabase = mongoClient.getDatabase(MongoConfig.DATABASE.resolve());
+
+ ConfigurationHolder> mongoHolder = MongoConfigFactory
+ .from(mongoDatabase, "configs")
+ .namespace("my_plugin")
+ .build();
+
+ // Test the configuration
+ ConfigurationTest.testDemo(mongoHolder);
+ ConfigurationTest.testInner(mongoHolder);
+
+ ConfigurationTest.save(mongoHolder);
+
+ }
+
+
+}
diff --git a/providers/yaml/pom.xml b/providers/yaml/pom.xml
index d1e2bd1..42e4ace 100644
--- a/providers/yaml/pom.xml
+++ b/providers/yaml/pom.xml
@@ -6,7 +6,7 @@
easyconfiguration-parent
cc.carm.lib
- 4.0.7
+ 4.0.8
../../pom.xml