Skip to content

Commit 3c23234

Browse files
authored
Support recursive use of load.properties (#225)
- Recursively load via indirection / via load.properties - Detects and handles case where the property source is already loaded
1 parent 74d4a73 commit 3c23234

File tree

9 files changed

+55
-6
lines changed

9 files changed

+55
-6
lines changed

avaje-config/src/main/java/io/avaje/config/InitialLoadContext.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55

66
import java.io.*;
77
import java.lang.System.Logger.Level;
8-
import java.util.ArrayList;
9-
import java.util.LinkedHashSet;
10-
import java.util.List;
11-
import java.util.Set;
8+
import java.util.*;
129

1310
/**
1411
* Manages the underlying map of properties we are gathering.
@@ -28,6 +25,8 @@ final class InitialLoadContext {
2825
private final Set<String> loadedResources = new LinkedHashSet<>();
2926
private final List<File> loadedFiles = new ArrayList<>();
3027
private final CoreExpressionEval exprEval;
28+
private final Set<String> loadCheck = new HashSet<>();
29+
private int recursiveLoadCount;
3130

3231
InitialLoadContext(ConfigurationLog log, ResourceLoader resourceLoader) {
3332
this.log = log;
@@ -89,13 +88,15 @@ InputStream resource(String resourcePath, InitialLoader.Source source) {
8988
is = resourceStream(resourcePath);
9089
if (is != null) {
9190
loadedResources.add(source.key(resourcePath));
91+
loadCheck.add(resourcePath);
9292
}
9393
} else {
9494
File file = new File(resourcePath);
9595
if (file.exists()) {
9696
try {
9797
is = new FileInputStream(file);
9898
loadedResources.add(source.key(resourcePath));
99+
loadCheck.add(resourcePath);
99100
loadedFiles.add(file);
100101
} catch (FileNotFoundException e) {
101102
throw new UncheckedIOException(e);
@@ -164,4 +165,15 @@ String getAppName() {
164165
final var appName = map.get("app.name");
165166
return (appName != null) ? appName.value() : System.getProperty("app.name");
166167
}
168+
169+
boolean alreadyLoaded(String fileName) {
170+
return !loadCheck.add(fileName);
171+
}
172+
173+
boolean allowRecursiveLoad() {
174+
if (recursiveLoadCount++ > 100) {
175+
throw new IllegalStateException("Recursive loading exceeded 100. Check your load.properties entries");
176+
}
177+
return true;
178+
}
167179
}

avaje-config/src/main/java/io/avaje/config/InitialLoader.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,14 @@ private void loadViaProfiles(Source source) {
221221
}
222222

223223
private void loadViaPaths(String paths) {
224-
for (String path : splitPaths(paths)) {
225-
loadWithExtensionCheck(loadContext.eval(path));
224+
for (String rawPath : splitPaths(paths)) {
225+
String path = loadContext.eval(rawPath);
226+
if (!loadContext.alreadyLoaded(path)) {
227+
if (loadWithExtensionCheck(path) && loadContext.allowRecursiveLoad()) {
228+
// depth first recursively load via load.properties entry
229+
loadViaIndirection();
230+
}
231+
}
226232
}
227233
}
228234

avaje-config/src/test/java/io/avaje/config/InitialLoaderTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,18 @@ void load_withSuppressTestResource() {
138138
System.clearProperty("suppressTestResource");
139139
}
140140
}
141+
142+
@Test
143+
void load_withLoadPropertyChain() {
144+
InitialLoader loader = newInitialLoader();
145+
loader.loadWithExtensionCheck("test-properties/chain/main.properties");
146+
var properties = evalFor(loader.load());
147+
assertThat(properties.get("value.main").value()).isEqualTo("main");
148+
assertThat(properties.get("value.a").value()).isEqualTo("true");
149+
assertThat(properties.get("value.b").value()).isEqualTo("true");
150+
assertThat(properties.get("value.c").value()).isEqualTo("true");
151+
assertThat(properties.get("value.d").value()).isEqualTo("true");
152+
assertThat(properties.get("value.e").value()).isEqualTo("true");
153+
assertThat(properties.get("override").value()).isEqualTo("e");
154+
}
141155
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
value.a=true
2+
override=a
3+
load.properties=test-properties/chain/c.properties
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
value.b=true
2+
override=b
3+
load.properties=test-properties/chain/c.properties
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
value.c=true
2+
override=c
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
value.d=true
2+
override=d
3+
load.properties=test-properties/chain/c.properties
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
value.e=true
2+
override=e
3+
load.properties=test-properties/chain/main.properties
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
load.properties=test-properties/chain/a.properties test-properties/chain/b.properties, test-properties/chain/d.properties test-properties/chain/e.properties
2+
value.main=main
3+
override=main

0 commit comments

Comments
 (0)