Bugfix: GUI-Methoden nutzen ApplicationRunContext statt erneuten Reload
Die GUI-Methoden fuer Historie und manuelle Datei-Aktionen haben Konfig und Schema bei jedem Aufruf neu geladen. Bei aktivem Scheduler-Lock schlug der Properties-Lesezugriff in loadAndValidateConfiguration mit einer IOException fehl. Zwei neue Helper bevorzugen den bereits stehenden ApplicationRunContext und fallen nur ohne Kontext auf das alte Migrate-Load-Validate- Schema-Init-Schema zurueck: - resolveJdbcUrlForGui (nur JDBC-URL benoetigt) - resolveStartConfigurationForGui (volle StartConfiguration benoetigt) Refactoring betrifft: - resolveHistoricalDocumentContextForGui - loadHistoryOverviewForGui - loadHistoryDetailsForGui - resetHistoryDocumentStatusForGui - deleteDocumentHistoryForGui - performGuiManualFileRename - performGuiManualFileCopy Der kurzlebige Helper migrateConfigurationIfNeededForGui wurde durch die beiden neuen Helper ueberfluessig und entfernt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+47
-36
@@ -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.
|
||||
* <p>
|
||||
* 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<ApplicationRunContext> ctx = guiApplicationRunContext;
|
||||
if (ctx.isPresent()) {
|
||||
return ctx.get().jdbcUrl();
|
||||
}
|
||||
migrateConfigurationIfNeeded(configFilePath);
|
||||
StartConfiguration config = loadAndValidateConfiguration(configFilePath);
|
||||
initializeSchema(config);
|
||||
return resolveActiveJdbcUrl(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die {@link StartConfiguration} für GUI-Aufrufe, die zusätzlich zur
|
||||
* JDBC-URL die volle Konfiguration benötigen (z. B. manuelle Umbenennung/Kopie).
|
||||
* <p>
|
||||
* 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<ApplicationRunContext> ctx = guiApplicationRunContext;
|
||||
if (ctx.isPresent()) {
|
||||
return ctx.get().startConfiguration();
|
||||
}
|
||||
migrateConfigurationIfNeeded(configFilePath);
|
||||
StartConfiguration config = loadAndValidateConfiguration(configFilePath);
|
||||
initializeSchema(config);
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user