Skip to content

Commit a182cc6

Browse files
committed
Merge pull request #32521 from terminux
* pr/32521: Polish 'Use exclamation character for the document separator prefix' Use exclamation character for the document separator prefix Closes gh-32521
2 parents eaf854b + 2c7114f commit a182cc6

File tree

4 files changed

+78
-32
lines changed

4 files changed

+78
-32
lines changed

spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/external-config.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ For example, the following file has two logical documents:
498498
on-cloud-platform: "kubernetes"
499499
----
500500

501-
For `application.properties` files a special `#---` comment is used to mark the document splits:
501+
For `application.properties` files a special `#---` or `!---` comment is used to mark the document splits:
502502

503503
[source,properties,indent=0,subs="verbatim"]
504504
----
@@ -509,7 +509,7 @@ For `application.properties` files a special `#---` comment is used to mark the
509509
----
510510

511511
NOTE: Property file separators must not have any leading whitespace and must have exactly three hyphen characters.
512-
The lines immediately before and after the separator must not be comments.
512+
The lines immediately before and after the separator must not be same comment prefix.
513513

514514
TIP: Multi-document property files are often used in conjunction with activation properties such as `spring.config.activate.on-profile`.
515515
See the <<features#features.external-config.files.activation-properties, next section>> for details.

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/OriginTrackedPropertiesLoader.java

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@
4242
* @author Madhura Bhave
4343
* @author Phillip Webb
4444
* @author Thiago Hirata
45+
* @author Guirong Hu
4546
*/
4647
class OriginTrackedPropertiesLoader {
4748

@@ -78,7 +79,8 @@ List<Document> load(boolean expandLists) throws IOException {
7879
StringBuilder buffer = new StringBuilder();
7980
try (CharacterReader reader = new CharacterReader(this.resource)) {
8081
while (reader.read()) {
81-
if (reader.isPoundCharacter()) {
82+
if (reader.isCommentPrefixCharacter()) {
83+
char commentPrefixCharacter = reader.getCharacter();
8284
if (isNewDocument(reader)) {
8385
if (!document.isEmpty()) {
8486
documents.add(document);
@@ -89,12 +91,12 @@ List<Document> load(boolean expandLists) throws IOException {
8991
if (document.isEmpty() && !documents.isEmpty()) {
9092
document = documents.remove(documents.size() - 1);
9193
}
92-
reader.setLastLineComment(true);
94+
reader.setLastLineCommentPrefixCharacter(commentPrefixCharacter);
9395
reader.skipComment();
9496
}
9597
}
9698
else {
97-
reader.setLastLineComment(false);
99+
reader.setLastLineCommentPrefixCharacter(-1);
98100
loadKeyAndValue(expandLists, document, reader, buffer);
99101
}
100102
}
@@ -161,10 +163,10 @@ private OriginTrackedValue loadValue(StringBuilder buffer, CharacterReader reade
161163
}
162164

163165
private boolean isNewDocument(CharacterReader reader) throws IOException {
164-
if (reader.isLastLineComment()) {
166+
if (reader.isSameLastLineCommentPrefix()) {
165167
return false;
166168
}
167-
boolean result = reader.getLocation().getColumn() == 0 && reader.isPoundCharacter();
169+
boolean result = reader.getLocation().getColumn() == 0;
168170
result = result && readAndExpect(reader, reader::isHyphenCharacter);
169171
result = result && readAndExpect(reader, reader::isHyphenCharacter);
170172
result = result && readAndExpect(reader, reader::isHyphenCharacter);
@@ -196,7 +198,7 @@ private static class CharacterReader implements Closeable {
196198

197199
private int character;
198200

199-
private boolean lastLineComment;
201+
private int lastLineCommentPrefixCharacter;
200202

201203
CharacterReader(Resource resource) throws IOException {
202204
this.reader = new LineNumberReader(
@@ -209,20 +211,11 @@ public void close() throws IOException {
209211
}
210212

211213
boolean read() throws IOException {
212-
return read(false);
213-
}
214-
215-
boolean read(boolean wrappedLine) throws IOException {
216214
this.escaped = false;
217215
this.character = this.reader.read();
218216
this.columnNumber++;
219217
if (this.columnNumber == 0) {
220218
skipWhitespace();
221-
if (!wrappedLine) {
222-
if (this.character == '!') {
223-
skipComment();
224-
}
225-
}
226219
}
227220
if (this.character == '\\') {
228221
this.escaped = true;
@@ -241,12 +234,8 @@ private void skipWhitespace() throws IOException {
241234
}
242235
}
243236

244-
private void setLastLineComment(boolean lastLineComment) {
245-
this.lastLineComment = lastLineComment;
246-
}
247-
248-
private boolean isLastLineComment() {
249-
return this.lastLineComment;
237+
private void setLastLineCommentPrefixCharacter(int lastLineCommentPrefixCharacter) {
238+
this.lastLineCommentPrefixCharacter = lastLineCommentPrefixCharacter;
250239
}
251240

252241
private void skipComment() throws IOException {
@@ -264,7 +253,7 @@ private void readEscaped() throws IOException {
264253
}
265254
else if (this.character == '\n') {
266255
this.columnNumber = -1;
267-
read(true);
256+
read();
268257
}
269258
else if (this.character == 'u') {
270259
readUnicode();
@@ -318,8 +307,12 @@ Location getLocation() {
318307
return new Location(this.reader.getLineNumber(), this.columnNumber);
319308
}
320309

321-
boolean isPoundCharacter() {
322-
return this.character == '#';
310+
boolean isSameLastLineCommentPrefix() {
311+
return this.lastLineCommentPrefixCharacter == this.character;
312+
}
313+
314+
boolean isCommentPrefixCharacter() {
315+
return this.character == '#' || this.character == '!';
323316
}
324317

325318
boolean isHyphenCharacter() {

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/env/OriginTrackedPropertiesLoaderTests.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2021 the original author or authors.
2+
* Copyright 2012-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -183,33 +183,70 @@ void getImmediateMultiline() {
183183
}
184184

185185
@Test
186-
void loadWhenMultiDocumentWithoutWhitespaceLoadsMultiDoc() throws IOException {
186+
void loadWhenMultiDocumentWithPoundPrefixAndWithoutWhitespaceLoadsMultiDoc() throws IOException {
187187
String content = "a=a\n#---\nb=b";
188188
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
189189
assertThat(loaded).hasSize(2);
190190
}
191191

192192
@Test
193-
void loadWhenMultiDocumentWithLeadingWhitespaceLoadsSingleDoc() throws IOException {
193+
void loadWhenMultiDocumentWithExclamationPrefixAndWithoutWhitespaceLoadsMultiDoc() throws IOException {
194+
String content = "a=a\n!---\nb=b";
195+
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
196+
assertThat(loaded).hasSize(2);
197+
}
198+
199+
@Test
200+
void loadWhenMultiDocumentWithPoundPrefixAndLeadingWhitespaceLoadsSingleDoc() throws IOException {
194201
String content = "a=a\n \t#---\nb=b";
195202
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
196203
assertThat(loaded).hasSize(1);
197204
}
198205

199206
@Test
200-
void loadWhenMultiDocumentWithTrailingWhitespaceLoadsMultiDoc() throws IOException {
207+
void loadWhenMultiDocumentWithExclamationPrefixAndLeadingWhitespaceLoadsSingleDoc() throws IOException {
208+
String content = "a=a\n \t!---\nb=b";
209+
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
210+
assertThat(loaded).hasSize(1);
211+
}
212+
213+
@Test
214+
void loadWhenMultiDocumentWithPoundPrefixAndTrailingWhitespaceLoadsMultiDoc() throws IOException {
201215
String content = "a=a\n#--- \t \nb=b";
202216
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
203217
assertThat(loaded).hasSize(2);
204218
}
205219

206220
@Test
207-
void loadWhenMultiDocumentWithTrailingCharsLoadsSingleDoc() throws IOException {
221+
void loadWhenMultiDocumentWithExclamationPrefixAndTrailingWhitespaceLoadsMultiDoc() throws IOException {
222+
String content = "a=a\n!--- \t \nb=b";
223+
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
224+
assertThat(loaded).hasSize(2);
225+
}
226+
227+
@Test
228+
void loadWhenMultiDocumentWithPoundPrefixAndTrailingCharsLoadsSingleDoc() throws IOException {
208229
String content = "a=a\n#--- \tcomment\nb=b";
209230
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
210231
assertThat(loaded).hasSize(1);
211232
}
212233

234+
@Test
235+
void loadWhenMultiDocumentWithExclamationPrefixAndTrailingCharsLoadsSingleDoc() throws IOException {
236+
String content = "a=a\n!--- \tcomment\nb=b";
237+
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
238+
assertThat(loaded).hasSize(1);
239+
}
240+
241+
@Test
242+
void loadWhenMultiDocumentSeparatorPrefixDifferentFromCommentPrefixLoadsMultiDoc() throws IOException {
243+
String[] contents = new String[] { "a=a\n# comment\n!---\nb=b", "a=a\n! comment\n#---\nb=b" };
244+
for (String content : contents) {
245+
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
246+
assertThat(loaded).hasSize(2);
247+
}
248+
}
249+
213250
@Test
214251
void getPropertyWithWhitespaceAfterKey() {
215252
OriginTrackedValue value = getFromFirst("bar");

spring-boot-project/spring-boot/src/test/resources/org/springframework/boot/env/existing-non-multi-document.properties

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,19 @@ boot=bar
1414
#---
1515

1616
bar=ok
17+
18+
!---
19+
! Test
20+
!---
21+
22+
ok=well
23+
24+
!---
25+
! Test
26+
27+
well=hello
28+
29+
! Test
30+
!---
31+
32+
hello=world

0 commit comments

Comments
 (0)