Skip to content

Commit 98a6450

Browse files
#356 - Add Footer Comment Support (#511)
* add footer comment support * PR review feedback fixes
1 parent 2ccc783 commit 98a6450

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

src/main/java/ch/jalu/configme/configurationdata/CommentsConfiguration.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ public class CommentsConfiguration {
1818

1919
private final @NotNull Map<String, List<String>> comments;
2020

21+
public static final String FOOTER_KEY = "..FOOTER";
22+
2123
/**
2224
* Constructor.
2325
*/
@@ -59,4 +61,23 @@ public void setComment(@NotNull String path, @NotNull String @NotNull ... commen
5961
public @NotNull @UnmodifiableView Map<String, @UnmodifiableView List<String>> getAllComments() {
6062
return Collections.unmodifiableMap(comments);
6163
}
64+
65+
/**
66+
* Adds the given lines as footer comments. They will be written at the end of the configuration file.
67+
*
68+
* @param commentLines the comment lines to add as footer comments
69+
*/
70+
public void setFooterComments(@NotNull String... commentLines) {
71+
setComment(FOOTER_KEY, commentLines);
72+
}
73+
74+
/**
75+
* Adds the given lines as header comments. They will be written at the start of the configuration file.
76+
*
77+
* @param commentLines the comment lines to add as header comments
78+
*/
79+
public void setHeaderComments(@NotNull String... commentLines) {
80+
setComment("", commentLines);
81+
}
82+
6283
}

src/main/java/ch/jalu/configme/resource/YamlFileResource.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ch.jalu.configme.resource;
22

3+
import ch.jalu.configme.configurationdata.CommentsConfiguration;
34
import ch.jalu.configme.configurationdata.ConfigurationData;
45
import ch.jalu.configme.exception.ConfigMeException;
56
import ch.jalu.configme.internal.StreamUtils;
@@ -14,6 +15,7 @@
1415
import org.jetbrains.annotations.Nullable;
1516
import org.yaml.snakeyaml.DumperOptions;
1617
import org.yaml.snakeyaml.Yaml;
18+
import org.yaml.snakeyaml.comments.CommentLine;
1719
import org.yaml.snakeyaml.nodes.Node;
1820

1921
import java.io.IOException;
@@ -70,6 +72,14 @@ public void exportProperties(@NotNull ConfigurationData configurationData) {
7072
rootNode = root.convertToNode(nodeBuilder);
7173
}
7274

75+
List<String> footerStrings = configurationData.getCommentsForSection(CommentsConfiguration.FOOTER_KEY);
76+
77+
List<CommentLine> footerCommentLines = footerStrings.stream()
78+
.flatMap(nodeBuilder::createCommentLines)
79+
.collect(Collectors.toList());
80+
81+
rootNode.setEndComments(footerCommentLines);
82+
7383
try (OutputStream os = Files.newOutputStream(path);
7484
OutputStreamWriter writer = new OutputStreamWriter(os, options.getCharset())) {
7585
createSnakeYamlInstance().serialize(rootNode, writer);
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package ch.jalu.configme.resource;
2+
3+
import ch.jalu.configme.SettingsHolder;
4+
import ch.jalu.configme.TestUtils;
5+
import ch.jalu.configme.configurationdata.CommentsConfiguration;
6+
import ch.jalu.configme.configurationdata.ConfigurationData;
7+
import ch.jalu.configme.configurationdata.ConfigurationDataBuilder;
8+
import ch.jalu.configme.properties.Property;
9+
import ch.jalu.configme.properties.StringProperty;
10+
import org.jetbrains.annotations.NotNull;
11+
import org.junit.jupiter.api.Test;
12+
import org.junit.jupiter.api.io.TempDir;
13+
14+
import java.io.IOException;
15+
import java.nio.file.Files;
16+
import java.nio.file.Path;
17+
import java.util.*;
18+
19+
import static org.hamcrest.MatcherAssert.assertThat;
20+
import static org.hamcrest.Matchers.contains;
21+
22+
public class YamlFileResourceFooterCommentTest {
23+
24+
@TempDir
25+
public Path tempFolder;
26+
27+
@Test
28+
void shouldIncludeFooterCommentInYamlWithMultipleProperties() throws IOException {
29+
// given
30+
Path file = TestUtils.createTemporaryFile(tempFolder);
31+
32+
YamlFileResource yamlResource = new YamlFileResource(file);
33+
ConfigurationData configurationData =
34+
ConfigurationDataBuilder.createConfiguration(RootPropertyHolderWithFooter.class);
35+
configurationData.setValue(RootPropertyHolderWithFooter.PROPERTY_NAME, "ExampleProperty");
36+
configurationData.setValue(RootPropertyHolderWithFooter.PROPERTY_NAME2, "ExampleProperty2");
37+
38+
// when
39+
yamlResource.exportProperties(configurationData);
40+
41+
// then
42+
List<String> lines = Files.readAllLines(file);
43+
assertThat(lines, contains(
44+
"# Header comment line 1",
45+
"# Header comment line 2",
46+
"PropertyName: ExampleProperty",
47+
"PropertyName2: ExampleProperty2",
48+
"# Footer comment line 1",
49+
"# Footer comment line 2"
50+
));
51+
}
52+
53+
54+
@Test
55+
void shouldIncludeFooterCommentForSingleRootProperty() throws IOException {
56+
// given
57+
Path file = TestUtils.createTemporaryFile(tempFolder);
58+
59+
YamlFileResource yamlResource = new YamlFileResource(file);
60+
ConfigurationData configurationData =
61+
ConfigurationDataBuilder.createConfiguration(RootPropertyHolderSingleRootProperty.class);
62+
configurationData.setValue(RootPropertyHolderSingleRootProperty.ROOT_PROPERTY, "RootValue");
63+
64+
// when
65+
yamlResource.exportProperties(configurationData);
66+
67+
// then
68+
List<String> lines = Files.readAllLines(file);
69+
assertThat(lines, contains(
70+
"# Header comment line 1",
71+
"# Header comment line 2",
72+
"RootValue",
73+
"# Footer comment line 1",
74+
"# Footer comment line 2"
75+
));
76+
}
77+
78+
public static final class RootPropertyHolderSingleRootProperty implements SettingsHolder {
79+
80+
public static final Property<String> ROOT_PROPERTY =
81+
new StringProperty("", "DefaultValue");
82+
83+
private RootPropertyHolderSingleRootProperty() {
84+
}
85+
86+
@Override
87+
public void registerComments(@NotNull CommentsConfiguration conf) {
88+
conf.setComment("", "Header comment line 1", "Header comment line 2");
89+
conf.setFooterComments("Footer comment line 1", "Footer comment line 2");
90+
}
91+
}
92+
93+
public static final class RootPropertyHolderWithFooter implements SettingsHolder {
94+
95+
public static final Property<String> PROPERTY_NAME =
96+
new StringProperty("PropertyName", "DefaultPropertyValue");
97+
98+
public static final Property<String> PROPERTY_NAME2 =
99+
new StringProperty("PropertyName2", "DefaultPropertyValue2");
100+
101+
private RootPropertyHolderWithFooter() {
102+
}
103+
104+
@Override
105+
public void registerComments(@NotNull CommentsConfiguration conf) {
106+
conf.setComment("", "Header comment line 1", "Header comment line 2");
107+
conf.setFooterComments("Footer comment line 1", "Footer comment line 2");
108+
}
109+
}
110+
111+
}

src/test/java/ch/jalu/configme/resource/yaml/SnakeYamlNodeContainerImplTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,6 @@ void shouldThrowIfNoRootValueWasSaved() {
162162
// then
163163
assertThat(ex.getMessage(), equalTo("No value was stored for the root path ''"));
164164
}
165+
166+
165167
}

0 commit comments

Comments
 (0)