Merge branch '2.6.x' into 2.7.x

Closes gh-32777
pull/32861/head
Phillip Webb 2 years ago
commit fcaac2b343

@ -495,7 +495,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"]
----
@ -506,7 +506,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.
@ -42,6 +42,7 @@ import org.springframework.util.Assert;
* @author Madhura Bhave
* @author Phillip Webb
* @author Thiago Hirata
* @author Guirong Hu
*/
class OriginTrackedPropertiesLoader {
@ -78,7 +79,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 +91,12 @@ class OriginTrackedPropertiesLoader {
if (document.isEmpty() && !documents.isEmpty()) {
document = documents.remove(documents.size() - 1);
}
reader.setLastLineComment(true);
reader.setLastLineCommentPrefixCharacter(commentPrefixCharacter);
reader.skipComment();
}
}
else {
reader.setLastLineComment(false);
reader.setLastLineCommentPrefixCharacter(-1);
loadKeyAndValue(expandLists, document, reader, buffer);
}
}
@ -161,10 +163,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 +198,7 @@ class OriginTrackedPropertiesLoader {
private int character;
private boolean lastLineComment;
private int lastLineCommentPrefixCharacter;
CharacterReader(Resource resource) throws IOException {
this.reader = new LineNumberReader(
@ -209,20 +211,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 +234,8 @@ class OriginTrackedPropertiesLoader {
}
}
private void setLastLineComment(boolean lastLineComment) {
this.lastLineComment = lastLineComment;
}
private boolean isLastLineComment() {
return this.lastLineComment;
private void setLastLineCommentPrefixCharacter(int lastLineCommentPrefixCharacter) {
this.lastLineCommentPrefixCharacter = lastLineCommentPrefixCharacter;
}
private void skipComment() throws IOException {
@ -264,7 +253,7 @@ class OriginTrackedPropertiesLoader {
}
else if (this.character == '\n') {
this.columnNumber = -1;
read(true);
read();
}
else if (this.character == 'u') {
readUnicode();
@ -318,8 +307,12 @@ class OriginTrackedPropertiesLoader {
return new Location(this.reader.getLineNumber(), this.columnNumber);
}
boolean isPoundCharacter() {
return this.character == '#';
boolean isSameLastLineCommentPrefix() {
return this.lastLineCommentPrefixCharacter == 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…
Cancel
Save