Skip to content

Commit 4fa23bf

Browse files
committed
Polish "Add support for List properties in ApplicationProperties"
See gh-1759
1 parent e4d6206 commit 4fa23bf

2 files changed

Lines changed: 57 additions & 49 deletions

File tree

initializr-generator-spring/src/main/java/io/spring/initializr/generator/spring/properties/ApplicationProperties.java

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
package io.spring.initializr.generator.spring.properties;
1818

1919
import java.io.PrintWriter;
20-
import java.util.ArrayList;
20+
import java.util.Collection;
2121
import java.util.HashMap;
22-
import java.util.List;
2322
import java.util.Map;
24-
import java.util.stream.Collectors;
23+
24+
import org.springframework.util.Assert;
25+
import org.springframework.util.StringUtils;
2526

2627
/**
2728
* Application properties.
@@ -70,11 +71,20 @@ public void add(String key, String value) {
7071
add(key, (Object) value);
7172
}
7273

74+
/**
75+
* Adds a new property.
76+
* @param key the key of the property
77+
* @param value the value of the property
78+
*/
79+
public void add(String key, Collection<?> value) {
80+
add(key, (Object) value);
81+
}
82+
7383
void writeProperties(PrintWriter writer) {
7484
for (Map.Entry<String, Object> entry : this.properties.entrySet()) {
75-
writer.printf("%s=%s%n", entry.getKey(), (entry.getValue() instanceof List)
76-
? ((List<?>) entry.getValue()).stream().map(Object::toString).collect(Collectors.joining(", "))
77-
: entry.getValue());
85+
Object value = (entry.getValue() instanceof Collection<?> collection)
86+
? StringUtils.collectionToCommaDelimitedString(collection) : entry.getValue();
87+
writer.printf("%s=%s%n", entry.getKey(), value);
7888
}
7989
}
8090

@@ -120,36 +130,29 @@ private static void writeEntry(Map.Entry<String, Object> entry, PrintWriter writ
120130
writeYamlRecursive((Map<String, Object>) nestedMap, writer, indent + 1);
121131
}
122132
else {
123-
if (value instanceof List) {
124-
writer.printf("%s%s:%n", indentStr, entry.getKey());
125-
writeList((List<?>) value, writer, indent + 1);
133+
if (value instanceof Collection<?> collection) {
134+
if (collection.isEmpty()) {
135+
writer.printf("%s%s: []%n", indentStr, entry.getKey());
136+
}
137+
else {
138+
writer.printf("%s%s:%n", indentStr, entry.getKey());
139+
writeCollection(collection, writer, indent + 1);
140+
}
126141
}
127142
else {
128143
writer.printf("%s%s: %s%n", indentStr, entry.getKey(), value);
129144
}
130145
}
131146
}
132147

133-
private static void writeList(List<?> list, PrintWriter writer, int indent) {
148+
private static void writeCollection(Collection<?> collection, PrintWriter writer, int indent) {
134149
String indentStr = YAML_SPACE.repeat(indent);
135-
list.forEach((element) -> writer.printf("%s- %s%n", indentStr, element));
150+
collection.forEach((element) -> writer.printf("%s- %s%n", indentStr, element));
136151
}
137152

138153
private void add(String key, Object value) {
139-
this.properties.merge(key, value, (oldValue, newValue) -> {
140-
var newValues = new ArrayList<>((oldValue instanceof List) ? ((List<?>) oldValue).size() + 1 : 2);
141-
if (oldValue instanceof List<?>) {
142-
newValues.addAll((List<?>) oldValue);
143-
}
144-
else {
145-
newValues.add(oldValue);
146-
}
147-
if (!newValues.contains(newValue)) {
148-
newValues.add(newValue);
149-
return newValues;
150-
}
151-
return oldValue;
152-
});
154+
Assert.state(!this.properties.containsKey(key), () -> "Property '%s' already exists".formatted(key));
155+
this.properties.put(key, value);
153156
}
154157

155158
}

initializr-generator-spring/src/test/java/io/spring/initializr/generator/spring/properties/ApplicationPropertiesTests.java

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818

1919
import java.io.PrintWriter;
2020
import java.io.StringWriter;
21+
import java.util.Collections;
22+
import java.util.List;
2123

2224
import org.junit.jupiter.api.Test;
2325

2426
import static org.assertj.core.api.Assertions.assertThat;
27+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
2528

2629
/**
2730
* Tests for {@link ApplicationProperties}.
@@ -39,21 +42,20 @@ void stringProperty() {
3942
}
4043

4144
@Test
42-
void stringPropertyDiffValuesWithSameKey() {
45+
void collectionProperty() {
4346
ApplicationProperties properties = new ApplicationProperties();
44-
properties.add("test", "string");
45-
properties.add("test", "string2");
47+
List<String> strings = List.of("string1", "string2");
48+
properties.add("test", strings);
4649
String written = writeProperties(properties);
47-
assertThat(written).isEqualToIgnoringNewLines("test=string, string2");
50+
assertThat(written).isEqualToIgnoringNewLines("test=string1,string2");
4851
}
4952

5053
@Test
51-
void stringPropertySameValuesWithSameKey() {
54+
void emptyCollectionProperty() {
5255
ApplicationProperties properties = new ApplicationProperties();
53-
properties.add("test", "string");
54-
properties.add("test", "string");
56+
properties.add("test", Collections.emptyList());
5557
String written = writeProperties(properties);
56-
assertThat(written).isEqualToIgnoringNewLines("test=string");
58+
assertThat(written).isEqualToIgnoringNewLines("test=");
5759
}
5860

5961
@Test
@@ -80,6 +82,14 @@ void booleanProperty() {
8082
assertThat(written).isEqualToIgnoringNewLines("test=false");
8183
}
8284

85+
@Test
86+
void shouldFailOnExistingProperty() {
87+
ApplicationProperties properties = new ApplicationProperties();
88+
properties.add("test", 1);
89+
assertThatIllegalStateException().isThrownBy(() -> properties.add("test", 2))
90+
.withMessage("Property 'test' already exists");
91+
}
92+
8393
@Test
8494
void writeYaml() {
8595
ApplicationProperties properties = new ApplicationProperties();
@@ -105,32 +115,27 @@ void writeYaml() {
105115
}
106116

107117
@Test
108-
void writeYamlSameKeyDistinctValues() {
118+
void writeYamlCollection() {
109119
ApplicationProperties properties = new ApplicationProperties();
110-
properties.add("spring.docker.compose.file", "./ollama/docker-compose.yml");
111-
properties.add("spring.docker.compose.file", "./qdrant/docker-compose.yml");
120+
List<Integer> ints = List.of(1, 2);
121+
properties.add("test.sub", ints);
112122
String written = writeYaml(properties);
113123
assertThat(written).isEqualToNormalizingNewlines("""
114-
spring:
115-
docker:
116-
compose:
117-
file:
118-
- ./ollama/docker-compose.yml
119-
- ./qdrant/docker-compose.yml
124+
test:
125+
sub:
126+
- 1
127+
- 2
120128
""");
121129
}
122130

123131
@Test
124-
void writeYamlSameKeySameValues() {
132+
void writeEmptyYamlCollection() {
125133
ApplicationProperties properties = new ApplicationProperties();
126-
properties.add("spring.docker.compose.file", "./ollama/docker-compose.yml");
127-
properties.add("spring.docker.compose.file", "./ollama/docker-compose.yml");
134+
properties.add("test.sub", Collections.emptyList());
128135
String written = writeYaml(properties);
129136
assertThat(written).isEqualToNormalizingNewlines("""
130-
spring:
131-
docker:
132-
compose:
133-
file: ./ollama/docker-compose.yml
137+
test:
138+
sub: []
134139
""");
135140
}
136141

0 commit comments

Comments
 (0)