Stirling-PDF/src/main/java/stirling/software/SPDF/config/ConfigInitializer.java

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

144 lines
5.5 KiB
Java
Raw Normal View History

2023-08-26 18:30:49 +02:00
package stirling.software.SPDF.config;
2023-09-05 21:58:18 +02:00
import java.io.BufferedReader;
2023-08-26 18:30:49 +02:00
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
2023-09-05 21:58:18 +02:00
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
2023-08-26 18:30:49 +02:00
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
2023-09-05 21:58:18 +02:00
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
2023-09-24 22:09:34 +02:00
import java.util.Set;
import java.util.function.Function;
2023-09-05 21:58:18 +02:00
import java.util.stream.Collectors;
2023-08-26 18:30:49 +02:00
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
public class ConfigInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
try {
ensureConfigExists();
} catch (IOException e) {
throw new RuntimeException("Failed to initialize application configuration", e);
}
}
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
public void ensureConfigExists() throws IOException {
// Define the path to the external config directory
Path destPath = Paths.get("configs", "settings.yml");
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
// Check if the file already exists
if (Files.notExists(destPath)) {
// Ensure the destination directory exists
Files.createDirectories(destPath.getParent());
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
// Copy the resource from classpath to the external directory
try (InputStream in =
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
if (in != null) {
Files.copy(in, destPath);
} else {
throw new FileNotFoundException(
"Resource file not found: settings.yml.template");
}
}
} else {
// If user file exists, we need to merge it with the template from the classpath
List<String> templateLines;
try (InputStream in =
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
templateLines =
new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))
.lines()
.collect(Collectors.toList());
}
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
mergeYamlFiles(templateLines, destPath, destPath);
}
2023-12-30 20:11:27 +01:00
}
2023-09-24 22:09:34 +02:00
public void mergeYamlFiles(List<String> templateLines, Path userFilePath, Path outputPath)
throws IOException {
List<String> userLines = Files.readAllLines(userFilePath);
List<String> mergedLines = new ArrayList<>();
boolean insideAutoGenerated = false;
boolean beforeFirstKey = true;
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
Function<String, Boolean> isCommented = line -> line.trim().startsWith("#");
Function<String, String> extractKey =
line -> {
String[] parts = line.split(":");
return parts.length > 0 ? parts[0].trim().replace("#", "").trim() : "";
};
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
Set<String> userKeys = userLines.stream().map(extractKey).collect(Collectors.toSet());
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
for (String line : templateLines) {
String key = extractKey.apply(line);
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
if (line.trim().equalsIgnoreCase("AutomaticallyGenerated:")) {
insideAutoGenerated = true;
mergedLines.add(line);
continue;
} else if (insideAutoGenerated && line.trim().isEmpty()) {
insideAutoGenerated = false;
mergedLines.add(line);
continue;
}
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
if (beforeFirstKey && (isCommented.apply(line) || line.trim().isEmpty())) {
// Handle top comments and empty lines before the first key.
mergedLines.add(line);
continue;
}
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
if (!key.isEmpty()) beforeFirstKey = false;
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
if (userKeys.contains(key)) {
// If user has any version (commented or uncommented) of this key, skip the
// template line
Optional<String> userValue =
userLines.stream()
.filter(
l ->
extractKey.apply(l).equalsIgnoreCase(key)
&& !isCommented.apply(l))
.findFirst();
if (userValue.isPresent()) mergedLines.add(userValue.get());
continue;
}
2023-12-30 20:11:27 +01:00
2023-09-24 22:09:34 +02:00
if (isCommented.apply(line) || line.trim().isEmpty() || !userKeys.contains(key)) {
mergedLines.add(
line); // If line is commented, empty or key not present in user's file,
// retain the
// template line
continue;
}
2023-12-30 20:11:27 +01:00
}
2023-09-24 22:09:34 +02:00
// Add any additional uncommented user lines that are not present in the
// template
for (String userLine : userLines) {
String userKey = extractKey.apply(userLine);
boolean isPresentInTemplate =
templateLines.stream()
.map(extractKey)
.anyMatch(templateKey -> templateKey.equalsIgnoreCase(userKey));
if (!isPresentInTemplate && !isCommented.apply(userLine)) {
mergedLines.add(userLine);
}
2023-12-30 20:11:27 +01:00
}
2023-09-24 22:09:34 +02:00
Files.write(outputPath, mergedLines, StandardCharsets.UTF_8);
}
2023-09-05 21:58:18 +02:00
}