Add auto-trimming support to configtree sources
Update `ConfigTreePropertySource` with an option to automatically trim trailing new-line characters. Closes gh-23826
This commit is contained in:
parent
cf673cee55
commit
2e2b371679
|
|
@ -21,6 +21,7 @@ import java.nio.file.Path;
|
|||
import java.util.Collections;
|
||||
|
||||
import org.springframework.boot.env.ConfigTreePropertySource;
|
||||
import org.springframework.boot.env.ConfigTreePropertySource.Option;
|
||||
|
||||
/**
|
||||
* {@link ConfigDataLoader} for config tree locations.
|
||||
|
|
@ -37,7 +38,7 @@ public class ConfigTreeConfigDataLoader implements ConfigDataLoader<ConfigTreeCo
|
|||
Path path = resource.getPath();
|
||||
ConfigDataResourceNotFoundException.throwIfDoesNotExist(resource, path);
|
||||
String name = "Config tree '" + path + "'";
|
||||
ConfigTreePropertySource source = new ConfigTreePropertySource(name, path);
|
||||
ConfigTreePropertySource source = new ConfigTreePropertySource(name, path, Option.AUTO_TRIM_TRAILING_NEW_LINE);
|
||||
return new ConfigData(Collections.singletonList(source));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,12 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
|||
/**
|
||||
* Convert file and directory names to lowercase.
|
||||
*/
|
||||
USE_LOWERCASE_NAMES
|
||||
USE_LOWERCASE_NAMES,
|
||||
|
||||
/**
|
||||
* Automatically attempt trim trailing new-line characters.
|
||||
*/
|
||||
AUTO_TRIM_TRAILING_NEW_LINE
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -173,17 +178,22 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
|||
|
||||
private final PropertyFileContent cachedContent;
|
||||
|
||||
private final boolean autoTrimTrailingNewLine;
|
||||
|
||||
private PropertyFile(Path path, Set<Option> options) {
|
||||
this.path = path;
|
||||
this.resource = new PathResource(path);
|
||||
this.origin = new TextResourceOrigin(this.resource, START_OF_FILE);
|
||||
this.autoTrimTrailingNewLine = options.contains(Option.AUTO_TRIM_TRAILING_NEW_LINE);
|
||||
this.cachedContent = options.contains(Option.ALWAYS_READ) ? null
|
||||
: new PropertyFileContent(path, this.resource, this.origin, true);
|
||||
: new PropertyFileContent(path, this.resource, this.origin, true, this.autoTrimTrailingNewLine);
|
||||
}
|
||||
|
||||
PropertyFileContent getContent() {
|
||||
return (this.cachedContent != null) ? this.cachedContent
|
||||
: new PropertyFileContent(this.path, this.resource, this.origin, false);
|
||||
if (this.cachedContent != null) {
|
||||
return this.cachedContent;
|
||||
}
|
||||
return new PropertyFileContent(this.path, this.resource, this.origin, false, this.autoTrimTrailingNewLine);
|
||||
}
|
||||
|
||||
Origin getOrigin() {
|
||||
|
|
@ -247,17 +257,21 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
|||
|
||||
private final Resource resource;
|
||||
|
||||
private final Origin origin;
|
||||
|
||||
private final boolean cacheContent;
|
||||
|
||||
private final boolean autoTrimTrailingNewLine;
|
||||
|
||||
private volatile byte[] content;
|
||||
|
||||
private final Origin origin;
|
||||
|
||||
private PropertyFileContent(Path path, Resource resource, Origin origin, boolean cacheContent) {
|
||||
private PropertyFileContent(Path path, Resource resource, Origin origin, boolean cacheContent,
|
||||
boolean autoTrimTrailingNewLine) {
|
||||
this.path = path;
|
||||
this.resource = resource;
|
||||
this.origin = origin;
|
||||
this.cacheContent = cacheContent;
|
||||
this.autoTrimTrailingNewLine = autoTrimTrailingNewLine;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -282,7 +296,28 @@ public class ConfigTreePropertySource extends EnumerablePropertySource<Path> imp
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new String(getBytes());
|
||||
String string = new String(getBytes());
|
||||
if (this.autoTrimTrailingNewLine) {
|
||||
string = autoTrimTrailingNewLine(string);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
private String autoTrimTrailingNewLine(String string) {
|
||||
if (!string.endsWith("\n")) {
|
||||
return string;
|
||||
}
|
||||
int numberOfLines = 0;
|
||||
for (char ch : string.toCharArray()) {
|
||||
if (ch == '\n') {
|
||||
numberOfLines++;
|
||||
}
|
||||
}
|
||||
if (numberOfLines > 1) {
|
||||
return string;
|
||||
}
|
||||
return (string.endsWith("\r\n")) ? string.substring(0, string.length() - 2)
|
||||
: string.substring(0, string.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public class ConfigTreeConfigDataLoaderTests {
|
|||
void loadReturnsConfigDataWithPropertySource() throws IOException {
|
||||
File file = this.directory.resolve("hello").toFile();
|
||||
file.getParentFile().mkdirs();
|
||||
FileCopyUtils.copy("world".getBytes(StandardCharsets.UTF_8), file);
|
||||
FileCopyUtils.copy("world\n".getBytes(StandardCharsets.UTF_8), file);
|
||||
ConfigTreeConfigDataResource location = new ConfigTreeConfigDataResource(this.directory.toString());
|
||||
ConfigData configData = this.loader.load(this.loaderContext, location);
|
||||
assertThat(configData.getPropertySources().size()).isEqualTo(1);
|
||||
|
|
|
|||
|
|
@ -199,6 +199,30 @@ class ConfigTreePropertySourceTests {
|
|||
assertThat(propertySource.getProperty("spring")).hasToString("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyAsStringWhenMultiLinePropertyReturnsNonTrimmed() throws Exception {
|
||||
addProperty("a", "a\nb\n");
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.AUTO_TRIM_TRAILING_NEW_LINE);
|
||||
assertThat(propertySource.getProperty("a").toString()).isEqualTo("a\nb\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyAsStringWhenPropertyEndsWithNewLineReturnsTrimmed() throws Exception {
|
||||
addProperty("a", "a\n");
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.AUTO_TRIM_TRAILING_NEW_LINE);
|
||||
assertThat(propertySource.getProperty("a").toString()).isEqualTo("a");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPropertyAsStringWhenPropertyEndsWithWindowsNewLineReturnsTrimmed() throws Exception {
|
||||
addProperty("a", "a\r\n");
|
||||
ConfigTreePropertySource propertySource = new ConfigTreePropertySource("test", this.directory,
|
||||
Option.AUTO_TRIM_TRAILING_NEW_LINE);
|
||||
assertThat(propertySource.getProperty("a").toString()).isEqualTo("a");
|
||||
}
|
||||
|
||||
private ConfigTreePropertySource getFlatPropertySource() throws IOException {
|
||||
addProperty("a", "A");
|
||||
addProperty("b", "B");
|
||||
|
|
|
|||
Loading…
Reference in New Issue