Skip to content

Commit

Permalink
Merge pull request #182 from TheElectronWill/async-fileconfig-fixes
Browse files Browse the repository at this point in the history
Fix some AsyncFileConfig issues, resolve #181, resolve #180
  • Loading branch information
TheElectronWill authored Jul 31, 2024
2 parents d474dc7 + b6e3825 commit 511114e
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -605,9 +605,12 @@ private Object convertValue(Object v) {
return v;
} else if (v instanceof Config) {
Config c = (Config) v;
Config converted = createSubConfig();
StampedConfig converted = createSubConfig();
convertSubConfigs(c);
converted.putAll(c);
if (c instanceof CommentedConfig) {
converted.putAllComments((CommentedConfig)c);
}
return converted;
} else if (v instanceof List) {
List<Object> l = (List<Object>) v;
Expand Down Expand Up @@ -811,8 +814,8 @@ public void putAllComments(UnmodifiableCommentedConfig other) {
Object value = entry.getRawValue();
if (value instanceof StampedConfig) {
// all subconfigs are StampedConfig
Object config = values.get(entry.getKey());
if (config instanceof StampedConfig) {
Object config = this.values.get(entry.getKey());
if (config instanceof StampedConfig && config != value) {
((StampedConfig) config).putAllComments((StampedConfig) value);
}
}
Expand All @@ -830,8 +833,8 @@ public void putAllComments(UnmodifiableCommentedConfig other) {
for (UnmodifiableCommentedConfig.Entry entry : other.entrySet()) {
Object value = entry.getRawValue();
if (value instanceof UnmodifiableCommentedConfig) {
Object config = values.get(entry.getKey());
if (config instanceof StampedConfig) {
Object config = this.values.get(entry.getKey());
if (config instanceof StampedConfig && config != value) {
((StampedConfig) config)
.putAllComments((UnmodifiableCommentedConfig) value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,6 @@ private static final class LazyExecutorHolder {
/** Debounced saving task. It runs on the shared executor. */
private final DebouncedRunnable saveTask;

/** Writes to the file (must be called from a task submitted to the executor). */
private BufferedWriter fileWriter;

// Serializing
private final ConfigWriter configWriter;
private final WritingMode writingMode;
Expand Down Expand Up @@ -148,16 +145,12 @@ private void saveNow() {
throw new WritingException(msg, e);
}
} else {
if (fileWriter == null) {
OpenOption lastOption = (writingMode == WritingMode.APPEND) ? APPEND
: TRUNCATE_EXISTING;
try {
fileWriter = Files.newBufferedWriter(nioPath, charset, WRITE, CREATE,
lastOption);
} catch (IOException e) {
throw new WritingException("Failed to open a BufferedWriter on: " + nioPath,
e);
}
BufferedWriter fileWriter;
OpenOption lastOption = (writingMode == WritingMode.APPEND) ? APPEND : TRUNCATE_EXISTING;
try {
fileWriter = Files.newBufferedWriter(nioPath, charset, WRITE, CREATE, lastOption);
} catch (IOException e) {
throw new WritingException("Failed to open a BufferedWriter on: " + nioPath, e);
}
configWriter.write(copy, fileWriter);
try {
Expand Down Expand Up @@ -201,6 +194,7 @@ private void loadNow() {
case REPLACE:
StampedConfig newSafeContent = config.createSubConfig(); // this is actually an independant config
newSafeContent.putAll(newCC);
newSafeContent.putAllComments(newCC);
config.replaceContentBy(newSafeContent);
// It could work with SynchronizedConfig too:
// if (config instanceof SynchronizedConfig) {
Expand All @@ -226,6 +220,9 @@ static void putWithParsingMode(ParsingMode parsingMode, CommentedConfig newCC, C
// convert the subconfig to a proper type
ConcurrentCommentedConfig newSafeContent = config.createSubConfig();
newSafeContent.putAll((UnmodifiableConfig)value);
if (value instanceof UnmodifiableCommentedConfig) {
newSafeContent.putAllComments((UnmodifiableCommentedConfig)value);
}
value = newSafeContent;
}
parsingMode.put(view, key, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,19 @@ public void testWriteDelay() throws IOException, InterruptedException {
assertTrue(Files.exists(file));
assertEquals("a = b", Files.readString(file).trim());

// write again and check
config.set("a", "b2");
Thread.sleep(AsyncFileConfig.DEFAULT_WRITE_DEBOUNCE_TIME.toMillis() *3/2);
assertNotEquals(-1, format.writeTime);
assertEquals(501, autosaveCounter.get());
assertEquals(2, saveCounter.get());
assertTrue(Files.exists(file));
assertEquals("a = b2", Files.readString(file).trim());

config.close();
assertNotEquals(-1, format.writeTime);
assertTrue(Files.exists(file));
assertEquals("a = b", Files.readString(file).trim());
assertEquals("a = b2", Files.readString(file).trim());
}

@Test
Expand Down
48 changes: 48 additions & 0 deletions test-multiple/src/test/java/FileConfigTests.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import org.junit.jupiter.api.Test;

import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.Config;
import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.file.FileConfig;

import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -103,4 +105,50 @@ void checkForgeTestContent(FileConfig fileConfig) {
assertEquals("NONE", dep0.get("ordering"));
assertEquals("BOTH", dep0.get("side"));
}

@Test
public void asyncTomlCommentsTest() throws Exception {
Path forgeTestResource = Path.of(getClass().getResource("/comments_test.toml").toURI());
CommentedFileConfig fileConfig = CommentedFileConfig.builder(forgeTestResource).async().build();
fileConfig.load(); // initial load
System.out.println("loaded: " + fileConfig);

checkCommentsTestContent(fileConfig);
fileConfig.load(); // reload (should have the same content)
checkCommentsTestContent(fileConfig);
fileConfig.close(); // close (should not modify the config)
checkCommentsTestContent(fileConfig);
}

@Test
public void syncTomlCommentsTest() throws Exception {
Path forgeTestResource = Path.of(getClass().getResource("/comments_test.toml").toURI());
CommentedFileConfig fileConfig = CommentedFileConfig.builder(forgeTestResource).sync().build();
fileConfig.load(); // initial load
System.out.println("loaded: " + fileConfig);

checkCommentsTestContent(fileConfig);
fileConfig.load(); // reload (should have the same content)
checkCommentsTestContent(fileConfig);
fileConfig.close(); // close (should not modify the config)
checkCommentsTestContent(fileConfig);
}

void checkCommentsTestContent(CommentedFileConfig config) {
assertEquals(1, config.getInt("v"));
assertEquals(" comment on v", config.getComment("v"));

List<CommentedConfig> abbc = config.get(List.of("a.b", "b.c"));
assertNotNull(abbc);
assertEquals("value", abbc.get(0).get("key"));
assertEquals(" sub1", abbc.get(0).getComment("key"));

assertEquals(" comment on table", config.getComment("table"));
assertEquals("v", config.get(List.of("table", "k")));
assertEquals(" sub2", config.getComment(List.of("table", "k")));

assertEquals(" comment on subtable", config.getComment(List.of("table", "subtable")));
assertEquals("b", config.get(List.of("table", "subtable", "a")));
assertEquals(" sub3", config.getComment(List.of("table", "subtable", "a")));
}
}
17 changes: 17 additions & 0 deletions test-multiple/src/test/resources/comments_test.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# comment on v
v = 1

# comment on array of tables
[["a.b"."b.c"]]
# sub1
key = "value"

# comment on table
[table]
# sub2
k = "v"

# comment on subtable
[table.subtable]
# sub3
a = "b"

0 comments on commit 511114e

Please sign in to comment.