mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-04-22 23:08:53 +02:00
settings menu reworks (#5864)
This commit is contained in:
@@ -873,6 +873,36 @@ public class GeneralUtils {
|
||||
settingsYaml.saveOverride(settingsPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates multiple settings in a single transaction. This ensures that nested settings (e.g.,
|
||||
* oauth2.client.google.*) don't lose sibling values when partial updates are made.
|
||||
*
|
||||
* <p>Instead of multiple read-update-write cycles (which could cause race conditions), this
|
||||
* method loads the YAML once, applies all updates, and saves once.
|
||||
*
|
||||
* @param settingsMap Map of dotted-notation keys to values to update
|
||||
* @throws IOException if file read/write fails
|
||||
*/
|
||||
public void updateSettingsTransactional(Map<String, Object> settingsMap) throws IOException {
|
||||
if (settingsMap == null || settingsMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Path settingsPath = Paths.get(InstallationPathConfig.getSettingsPath());
|
||||
YamlHelper settingsYaml = new YamlHelper(settingsPath);
|
||||
|
||||
// Apply all updates to the same YamlHelper instance
|
||||
for (Map.Entry<String, Object> entry : settingsMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
String[] keyArray = key.split("\\.");
|
||||
settingsYaml.updateValue(Arrays.asList(keyArray), value);
|
||||
}
|
||||
|
||||
// Save only once after all updates are applied
|
||||
settingsYaml.saveOverride(settingsPath);
|
||||
}
|
||||
|
||||
/*
|
||||
* Machine fingerprint generation with better error logging and fallbacks.
|
||||
*
|
||||
|
||||
@@ -172,7 +172,7 @@ public class AdminSettingsController {
|
||||
.body(Map.of("error", "No settings provided to update"));
|
||||
}
|
||||
|
||||
int updatedCount = 0;
|
||||
// Validate all settings first before applying any changes
|
||||
for (Map.Entry<String, Object> entry : settings.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
@@ -192,15 +192,18 @@ public class AdminSettingsController {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("error", HtmlUtils.htmlEscape(validationError)));
|
||||
}
|
||||
}
|
||||
|
||||
// Apply all updates in a single transaction (load once, update all, save once)
|
||||
// This ensures nested settings like oauth2.client.* don't lose sibling values
|
||||
GeneralUtils.updateSettingsTransactional(settings);
|
||||
|
||||
// Track all as pending changes
|
||||
for (Map.Entry<String, Object> entry : settings.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
log.info("Admin updating setting: {} = {}", key, value);
|
||||
GeneralUtils.saveKeyToSettings(key, value);
|
||||
|
||||
// Track this as a pending change (convert null to empty string for
|
||||
// ConcurrentHashMap)
|
||||
pendingChanges.put(key, value != null ? value : "");
|
||||
|
||||
updatedCount++;
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(
|
||||
@@ -209,7 +212,7 @@ public class AdminSettingsController {
|
||||
String.format(
|
||||
"Successfully updated %d setting(s). Changes will take effect on"
|
||||
+ " application restart.",
|
||||
updatedCount)));
|
||||
settings.size())));
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to save settings to file: {}", e.getMessage(), e);
|
||||
|
||||
Reference in New Issue
Block a user