diff --git a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java index 1074bbf..d6fcc26 100644 --- a/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java +++ b/pdf-umbenenner-bootstrap/src/main/java/de/gecheckt/pdf/umbenenner/bootstrap/BootstrapRunner.java @@ -1725,9 +1725,7 @@ public class BootstrapRunner { } try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); + StartConfiguration config = resolveStartConfigurationForGui(configFilePath); ManualFileRenameUseCase useCase = buildProductionManualFileRenameUseCase(config); ManualFileRenameResult result = useCase.rename(request); LOG.info("GUI-Umbenennung abgeschlossen: Ergebnis={}.", result.getClass().getSimpleName()); @@ -1789,9 +1787,7 @@ public class BootstrapRunner { } try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); + StartConfiguration config = resolveStartConfigurationForGui(configFilePath); ManualFileCopyUseCase useCase = buildProductionManualFileCopyUseCase(config); ManualFileCopyResult result = useCase.copy(request); LOG.info("GUI-Dateikopie abgeschlossen: Ergebnis={}.", result.getClass().getSimpleName()); @@ -1851,10 +1847,7 @@ public class BootstrapRunner { } try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); - String jdbcUrl = resolveActiveJdbcUrl(config); + String jdbcUrl = resolveJdbcUrlForGui(configFilePath); DocumentRecordRepository documentRecordRepository = new SqliteDocumentRecordRepositoryAdapter(jdbcUrl); ResolveHistoricalDocumentContextUseCase useCase = @@ -1884,10 +1877,7 @@ public class BootstrapRunner { Objects.requireNonNull(configFilePath, CONFIG_FILE_NOT_NULL); Objects.requireNonNull(query, "query must not be null"); try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); - String jdbcUrl = resolveActiveJdbcUrl(config); + String jdbcUrl = resolveJdbcUrlForGui(configFilePath); HistoryQueryPort historyQueryPort = new SqliteHistoryQueryAdapter(jdbcUrl); DefaultHistoryOverviewUseCase useCase = new DefaultHistoryOverviewUseCase(historyQueryPort); return useCase.loadOverview(query); @@ -1914,10 +1904,7 @@ public class BootstrapRunner { Objects.requireNonNull(configFilePath, CONFIG_FILE_NOT_NULL); Objects.requireNonNull(fingerprint, FINGERPRINT_NOT_NULL); try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); - String jdbcUrl = resolveActiveJdbcUrl(config); + String jdbcUrl = resolveJdbcUrlForGui(configFilePath); HistoryQueryPort historyQueryPort = new SqliteHistoryQueryAdapter(jdbcUrl); DefaultHistoryDetailsUseCase useCase = new DefaultHistoryDetailsUseCase(historyQueryPort); return useCase.loadDetails(fingerprint); @@ -1945,10 +1932,7 @@ public class BootstrapRunner { Objects.requireNonNull(fingerprint, FINGERPRINT_NOT_NULL); LOG.info("Historien-Status-Reset für Fingerprint: {}", fingerprint.sha256Hex()); try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); - String jdbcUrl = resolveActiveJdbcUrl(config); + String jdbcUrl = resolveJdbcUrlForGui(configFilePath); UnitOfWorkPort unitOfWorkPort = new SqliteUnitOfWorkAdapter(jdbcUrl); DefaultHistoryResetDocumentStatusUseCase useCase = new DefaultHistoryResetDocumentStatusUseCase(unitOfWorkPort); @@ -1977,10 +1961,7 @@ public class BootstrapRunner { Objects.requireNonNull(fingerprint, FINGERPRINT_NOT_NULL); LOG.info("Historien-Löschen für Fingerprint: {}", fingerprint.sha256Hex()); try { - migrateConfigurationIfNeededForGui(configFilePath); - StartConfiguration config = loadAndValidateConfiguration(configFilePath); - initializeSchema(config); - String jdbcUrl = resolveActiveJdbcUrl(config); + String jdbcUrl = resolveJdbcUrlForGui(configFilePath); UnitOfWorkPort unitOfWorkPort = new SqliteUnitOfWorkAdapter(jdbcUrl); DefaultDeleteDocumentHistoryUseCase useCase = new DefaultDeleteDocumentHistoryUseCase(unitOfWorkPort); @@ -2158,20 +2139,50 @@ public class BootstrapRunner { } /** - * Führt die Legacy-Migration nur durch, wenn der GUI-Anwendungskontext noch nicht steht. + * Liefert die aktive JDBC-URL für GUI-Aufrufe, die keinen vollständigen + * {@link StartConfiguration} benötigen. *
- * Steht der Kontext bereits, wurde die Migration in
- * {@link #initializeApplicationRunContext(Path)} schon einmal abgeschlossen. Ein erneuter
- * Lese-/Schreibzugriff auf die Konfigurationsdatei ist nicht nur redundant, sondern
- * kollidiert auch mit einem aktiven Scheduler-Lock auf derselben Datei und führt
- * dann zu {@code IOException: Datei gesperrt}.
+ * Steht der GUI-Anwendungskontext bereits, wird die JDBC-URL daraus übernommen –
+ * die Konfigurationsdatei wird in diesem Fall nicht erneut gelesen und das Schema
+ * nicht erneut initialisiert. Das vermeidet Kollisionen mit einem aktiven
+ * Scheduler-Lock auf der Konfigurationsdatei. Steht kein Kontext, läuft die
+ * gewohnte Sequenz Migration → Laden → Validieren → Schema-Init durch.
*
- * @param configFilePath Pfad zur Konfigurationsdatei; darf nicht {@code null} sein
+ * @param configFilePath Pfad zur Konfigurationsdatei; nur relevant ohne aktiven Kontext
+ * @return aktive JDBC-URL; nie {@code null}
*/
- private void migrateConfigurationIfNeededForGui(Path configFilePath) {
- if (guiApplicationRunContext.isEmpty()) {
- migrateConfigurationIfNeeded(configFilePath);
+ private String resolveJdbcUrlForGui(Path configFilePath) {
+ Optional
+ * Steht der GUI-Anwendungskontext bereits, wird die Konfiguration daraus übernommen,
+ * ohne die Konfigurationsdatei erneut zu lesen oder das Schema erneut zu initialisieren.
+ * Steht kein Kontext, läuft die gewohnte Sequenz Migration → Laden → Validieren →
+ * Schema-Init durch.
+ *
+ * @param configFilePath Pfad zur Konfigurationsdatei; nur relevant ohne aktiven Kontext
+ * @return validierte Konfiguration; nie {@code null}
+ */
+ private StartConfiguration resolveStartConfigurationForGui(Path configFilePath) {
+ Optional