Skip to content

Commit 9fa21dd

Browse files
committed
Merge pull request #1682 from YangSiJun528
* pr/1682: Polish "Add support for YAML configuration file format" Add support for YAML configuration file format Closes gh-1682
2 parents 6cb81a8 + de8d39c commit 9fa21dd

File tree

51 files changed

+1228
-18
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1228
-18
lines changed

initializr-actuator/src/main/java/io/spring/initializr/actuate/stat/ProjectRequestDocument.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class ProjectRequestDocument {
4848

4949
private String language;
5050

51+
private String configurationFileFormat;
52+
5153
private String packaging;
5254

5355
private String packageName;
@@ -116,6 +118,14 @@ public void setLanguage(String language) {
116118
this.language = language;
117119
}
118120

121+
public String getConfigurationFileFormat() {
122+
return this.configurationFileFormat;
123+
}
124+
125+
public void setConfigurationFileFormat(String configurationFileFormat) {
126+
this.configurationFileFormat = configurationFileFormat;
127+
}
128+
119129
public String getPackaging() {
120130
return this.packaging;
121131
}
@@ -177,6 +187,7 @@ public String toString() {
177187
.add("artifactId='" + this.artifactId + "'")
178188
.add("javaVersion='" + this.javaVersion + "'")
179189
.add("language='" + this.language + "'")
190+
.add("configurationFileFormat='" + this.configurationFileFormat + "'")
180191
.add("packaging='" + this.packaging + "'")
181192
.add("packageName='" + this.packageName + "'")
182193
.add("version=" + this.version)
@@ -331,6 +342,8 @@ public static class ErrorStateInformation {
331342

332343
private Boolean language;
333344

345+
private Boolean configurationFileFormat;
346+
334347
private Boolean packaging;
335348

336349
private Boolean type;
@@ -359,6 +372,14 @@ public void setLanguage(Boolean language) {
359372
this.language = language;
360373
}
361374

375+
public Boolean getConfigurationFileFormat() {
376+
return this.configurationFileFormat;
377+
}
378+
379+
public void setConfigurationFileFormat(Boolean configurationFileFormat) {
380+
this.configurationFileFormat = configurationFileFormat;
381+
}
382+
362383
public Boolean getPackaging() {
363384
return this.packaging;
364385
}
@@ -396,6 +417,7 @@ public String toString() {
396417
return new StringJoiner(", ", "{", "}").add("invalid=" + this.invalid)
397418
.add("javaVersion=" + this.javaVersion)
398419
.add("language=" + this.language)
420+
.add("configurationFileFormat=" + this.configurationFileFormat)
399421
.add("packaging=" + this.packaging)
400422
.add("type=" + this.type)
401423
.add("dependencies=" + this.dependencies)

initializr-actuator/src/main/java/io/spring/initializr/actuate/stat/ProjectRequestDocumentFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ public ProjectRequestDocument createDocument(ProjectRequestEvent event) {
6868
document.triggerError().setLanguage(true);
6969
}
7070

71+
document.setConfigurationFileFormat(request.getConfigurationFileFormat());
72+
if (StringUtils.hasText(request.getConfigurationFileFormat())
73+
&& metadata.getConfigurationFileFormats().get(request.getConfigurationFileFormat()) == null) {
74+
document.triggerError().setConfigurationFileFormat(true);
75+
}
76+
7177
document.setPackaging(request.getPackaging());
7278
if (StringUtils.hasText(request.getPackaging())
7379
&& metadata.getPackagings().get(request.getPackaging()) == null) {

initializr-actuator/src/test/resources/stat/request-invalid-dependencies.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"artifactId": "test",
77
"javaVersion": "1.8",
88
"language": "java",
9+
"configurationFileFormat": "properties",
910
"packaging": "jar",
1011
"packageName": "com.example.acme.test",
1112
"version": {

initializr-actuator/src/test/resources/stat/request-invalid-java-version.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"artifactId": "test",
77
"javaVersion": "1.2",
88
"language": "java",
9+
"configurationFileFormat": "properties",
910
"packaging": "jar",
1011
"packageName": "com.example.acme.test",
1112
"version": {

initializr-actuator/src/test/resources/stat/request-invalid-language.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"artifactId": "test",
77
"javaVersion": "1.8",
88
"language": "c",
9+
"configurationFileFormat": "properties",
910
"packaging": "jar",
1011
"packageName": "com.example.acme.test",
1112
"version": {

initializr-actuator/src/test/resources/stat/request-invalid-type.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"artifactId": "test",
66
"javaVersion": "1.8",
77
"language": "java",
8+
"configurationFileFormat": "properties",
89
"packaging": "jar",
910
"packageName": "com.example.acme.test",
1011
"version": {

initializr-actuator/src/test/resources/stat/request-no-client.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"artifactId": "test",
77
"javaVersion": "1.8",
88
"language": "java",
9+
"configurationFileFormat": "properties",
910
"packaging": "jar",
1011
"packageName": "com.example.acme.test",
1112
"version": {

initializr-actuator/src/test/resources/stat/request-simple.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"artifactId": "project",
77
"javaVersion": "1.8",
88
"language": "java",
9+
"configurationFileFormat": "properties",
910
"packaging": "jar",
1011
"packageName": "com.example.acme.project",
1112
"version": {

initializr-docs/src/main/asciidoc/configuration-guide.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ will have values. In the rest of this section, we will configure those basic set
286286
Most of the settings are configured via `application.properties` using the `initializr`
287287
namespace. Because the configuration is highly hierarchical, we recommend using the yaml
288288
format that is more readable for such structure. If you agree, go ahead and create an
289-
`application.yml` in `src/main/resources`.
289+
`application.yaml` in `src/main/resources`.
290290
====
291291

292292

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

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
*/
3030
public class ApplicationProperties {
3131

32+
private static final String YAML_SPACE = " ";
33+
3234
private final Map<String, Object> properties = new HashMap<>();
3335

3436
/**
@@ -67,12 +69,58 @@ public void add(String key, String value) {
6769
add(key, (Object) value);
6870
}
6971

70-
void writeTo(PrintWriter writer) {
72+
void writeProperties(PrintWriter writer) {
7173
for (Map.Entry<String, Object> entry : this.properties.entrySet()) {
7274
writer.printf("%s=%s%n", entry.getKey(), entry.getValue());
7375
}
7476
}
7577

78+
void writeYaml(PrintWriter writer) {
79+
Map<String, Object> nested = flattenToNestedMap(this.properties);
80+
writeYamlRecursive(nested, writer, 0);
81+
}
82+
83+
private static Map<String, Object> flattenToNestedMap(Map<String, Object> flatMap) {
84+
Map<String, Object> nested = new HashMap<>();
85+
flatMap.forEach((key, value) -> {
86+
String[] path = parseKeyPath(key);
87+
insertValueAtPath(nested, path, value);
88+
});
89+
return nested;
90+
}
91+
92+
private static String[] parseKeyPath(String key) {
93+
return key.split("\\.");
94+
}
95+
96+
@SuppressWarnings("unchecked")
97+
private static void insertValueAtPath(Map<String, Object> map, String[] path, Object value) {
98+
Map<String, Object> current = map;
99+
for (int i = 0; i < path.length - 1; i++) {
100+
String segment = path[i];
101+
current = (Map<String, Object>) current.computeIfAbsent(segment, (k) -> new HashMap<>());
102+
}
103+
current.put(path[path.length - 1], value);
104+
}
105+
106+
private static void writeYamlRecursive(Map<String, Object> map, PrintWriter writer, int indent) {
107+
map.entrySet().forEach((entry) -> writeEntry(entry, writer, indent));
108+
}
109+
110+
@SuppressWarnings("unchecked")
111+
private static void writeEntry(Map.Entry<String, Object> entry, PrintWriter writer, int indent) {
112+
String indentStr = YAML_SPACE.repeat(indent);
113+
Object value = entry.getValue();
114+
115+
if (value instanceof Map<?, ?> nestedMap) {
116+
writer.printf("%s%s:%n", indentStr, entry.getKey());
117+
writeYamlRecursive((Map<String, Object>) nestedMap, writer, indent + 1);
118+
}
119+
else {
120+
writer.printf("%s%s: %s%n", indentStr, entry.getKey(), value);
121+
}
122+
}
123+
76124
private void add(String key, Object value) {
77125
Assert.state(!this.properties.containsKey(key), () -> "Property '%s' already exists".formatted(key));
78126
this.properties.put(key, value);

0 commit comments

Comments
 (0)