mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Use exclamation character for the document separator prefix
See gh-32521
This commit is contained in:
parent
eaf854bd9c
commit
33e379c4a2
@ -498,7 +498,7 @@ For example, the following file has two logical documents:
|
||||
on-cloud-platform: "kubernetes"
|
||||
----
|
||||
|
||||
For `application.properties` files a special `#---` comment is used to mark the document splits:
|
||||
For `application.properties` files a special `#---` or `!---` comment is used to mark the document splits:
|
||||
|
||||
[source,properties,indent=0,subs="verbatim"]
|
||||
----
|
||||
@ -509,7 +509,7 @@ For `application.properties` files a special `#---` comment is used to mark the
|
||||
----
|
||||
|
||||
NOTE: Property file separators must not have any leading whitespace and must have exactly three hyphen characters.
|
||||
The lines immediately before and after the separator must not be comments.
|
||||
The lines immediately before and after the separator must not be same comment prefix.
|
||||
|
||||
TIP: Multi-document property files are often used in conjunction with activation properties such as `spring.config.activate.on-profile`.
|
||||
See the <<features#features.external-config.files.activation-properties, next section>> for details.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -78,7 +78,8 @@ class OriginTrackedPropertiesLoader {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
try (CharacterReader reader = new CharacterReader(this.resource)) {
|
||||
while (reader.read()) {
|
||||
if (reader.isPoundCharacter()) {
|
||||
if (reader.isCommentPrefixCharacter()) {
|
||||
char commentPrefixCharacter = reader.getCharacter();
|
||||
if (isNewDocument(reader)) {
|
||||
if (!document.isEmpty()) {
|
||||
documents.add(document);
|
||||
@ -89,12 +90,12 @@ class OriginTrackedPropertiesLoader {
|
||||
if (document.isEmpty() && !documents.isEmpty()) {
|
||||
document = documents.remove(documents.size() - 1);
|
||||
}
|
||||
reader.setLastLineComment(true);
|
||||
reader.setLastLineCommentPrefix(commentPrefixCharacter);
|
||||
reader.skipComment();
|
||||
}
|
||||
}
|
||||
else {
|
||||
reader.setLastLineComment(false);
|
||||
reader.setLastLineCommentPrefix(-1);
|
||||
loadKeyAndValue(expandLists, document, reader, buffer);
|
||||
}
|
||||
}
|
||||
@ -161,10 +162,10 @@ class OriginTrackedPropertiesLoader {
|
||||
}
|
||||
|
||||
private boolean isNewDocument(CharacterReader reader) throws IOException {
|
||||
if (reader.isLastLineComment()) {
|
||||
if (reader.isSameLastLineCommentPrefix()) {
|
||||
return false;
|
||||
}
|
||||
boolean result = reader.getLocation().getColumn() == 0 && reader.isPoundCharacter();
|
||||
boolean result = reader.getLocation().getColumn() == 0;
|
||||
result = result && readAndExpect(reader, reader::isHyphenCharacter);
|
||||
result = result && readAndExpect(reader, reader::isHyphenCharacter);
|
||||
result = result && readAndExpect(reader, reader::isHyphenCharacter);
|
||||
@ -196,7 +197,7 @@ class OriginTrackedPropertiesLoader {
|
||||
|
||||
private int character;
|
||||
|
||||
private boolean lastLineComment;
|
||||
private int lastLineCommentPrefix;
|
||||
|
||||
CharacterReader(Resource resource) throws IOException {
|
||||
this.reader = new LineNumberReader(
|
||||
@ -209,20 +210,11 @@ class OriginTrackedPropertiesLoader {
|
||||
}
|
||||
|
||||
boolean read() throws IOException {
|
||||
return read(false);
|
||||
}
|
||||
|
||||
boolean read(boolean wrappedLine) throws IOException {
|
||||
this.escaped = false;
|
||||
this.character = this.reader.read();
|
||||
this.columnNumber++;
|
||||
if (this.columnNumber == 0) {
|
||||
skipWhitespace();
|
||||
if (!wrappedLine) {
|
||||
if (this.character == '!') {
|
||||
skipComment();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.character == '\\') {
|
||||
this.escaped = true;
|
||||
@ -241,12 +233,8 @@ class OriginTrackedPropertiesLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private void setLastLineComment(boolean lastLineComment) {
|
||||
this.lastLineComment = lastLineComment;
|
||||
}
|
||||
|
||||
private boolean isLastLineComment() {
|
||||
return this.lastLineComment;
|
||||
private void setLastLineCommentPrefix(int lastLineCommentPrefix) {
|
||||
this.lastLineCommentPrefix = lastLineCommentPrefix;
|
||||
}
|
||||
|
||||
private void skipComment() throws IOException {
|
||||
@ -264,7 +252,7 @@ class OriginTrackedPropertiesLoader {
|
||||
}
|
||||
else if (this.character == '\n') {
|
||||
this.columnNumber = -1;
|
||||
read(true);
|
||||
read();
|
||||
}
|
||||
else if (this.character == 'u') {
|
||||
readUnicode();
|
||||
@ -318,8 +306,12 @@ class OriginTrackedPropertiesLoader {
|
||||
return new Location(this.reader.getLineNumber(), this.columnNumber);
|
||||
}
|
||||
|
||||
boolean isPoundCharacter() {
|
||||
return this.character == '#';
|
||||
boolean isSameLastLineCommentPrefix() {
|
||||
return this.lastLineCommentPrefix == this.character;
|
||||
}
|
||||
|
||||
boolean isCommentPrefixCharacter() {
|
||||
return this.character == '#' || this.character == '!';
|
||||
}
|
||||
|
||||
boolean isHyphenCharacter() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -183,33 +183,70 @@ class OriginTrackedPropertiesLoaderTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithoutWhitespaceLoadsMultiDoc() throws IOException {
|
||||
void loadWhenMultiDocumentWithPoundPrefixAndWithoutWhitespaceLoadsMultiDoc() throws IOException {
|
||||
String content = "a=a\n#---\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithLeadingWhitespaceLoadsSingleDoc() throws IOException {
|
||||
void loadWhenMultiDocumentWithExclamationPrefixAndWithoutWhitespaceLoadsMultiDoc() throws IOException {
|
||||
String content = "a=a\n!---\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithPoundPrefixAndLeadingWhitespaceLoadsSingleDoc() throws IOException {
|
||||
String content = "a=a\n \t#---\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithTrailingWhitespaceLoadsMultiDoc() throws IOException {
|
||||
void loadWhenMultiDocumentWithExclamationPrefixAndLeadingWhitespaceLoadsSingleDoc() throws IOException {
|
||||
String content = "a=a\n \t!---\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithPoundPrefixAndTrailingWhitespaceLoadsMultiDoc() throws IOException {
|
||||
String content = "a=a\n#--- \t \nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithTrailingCharsLoadsSingleDoc() throws IOException {
|
||||
void loadWhenMultiDocumentWithExclamationPrefixAndTrailingWhitespaceLoadsMultiDoc() throws IOException {
|
||||
String content = "a=a\n!--- \t \nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithPoundPrefixAndTrailingCharsLoadsSingleDoc() throws IOException {
|
||||
String content = "a=a\n#--- \tcomment\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentWithExclamationPrefixAndTrailingCharsLoadsSingleDoc() throws IOException {
|
||||
String content = "a=a\n!--- \tcomment\nb=b";
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenMultiDocumentSeparatorPrefixDifferentFromCommentPrefixLoadsMultiDoc() throws IOException {
|
||||
String[] contents = new String[] { "a=a\n# comment\n!---\nb=b", "a=a\n! comment\n#---\nb=b" };
|
||||
for (String content : contents) {
|
||||
List<Document> loaded = new OriginTrackedPropertiesLoader(new ByteArrayResource(content.getBytes())).load();
|
||||
assertThat(loaded).hasSize(2);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyWithWhitespaceAfterKey() {
|
||||
OriginTrackedValue value = getFromFirst("bar");
|
||||
|
@ -14,3 +14,19 @@ boot=bar
|
||||
#---
|
||||
|
||||
bar=ok
|
||||
|
||||
!---
|
||||
! Test
|
||||
!---
|
||||
|
||||
ok=well
|
||||
|
||||
!---
|
||||
! Test
|
||||
|
||||
well=hello
|
||||
|
||||
! Test
|
||||
!---
|
||||
|
||||
hello=world
|
||||
|
Loading…
Reference in New Issue
Block a user