private boolean substitutePlaceholders(final Map<String, String> flat, final Set<String> changedKeys) {
final BoolWrap changed = new BoolWrap();
for (Map.Entry<String, String> e : U.map(flat).entrySet()) {
final String cfgKey = e.getKey();
String val = e.getValue();
if (val.contains("${")) {
val = Str.replace(val, "\\$\\{([^\\}]+)\\}", src -> {
String name = src[1];
Object value = flat.get(name);
if (value == null) {
value = GlobalCfg.get(name);
}
if (value == null) {
value = getSpecialValue(name);
}
U.must(value != null, "Cannot find configuration entry '%s' for key '%s'!", name, cfgKey);
changed.value = true;
changedKeys.add(cfgKey);
return value.toString();
});
flat.put(cfgKey, val);
}
}
return changed.value;
}