GUI: ApplicationRunContext beim Datei-Öffnen proaktiv aufbauen
Bisher wurde der ApplicationRunContext nur beim --config-Startpfad erzeugt. Der auto-load-Pfad (letzte Konfiguration aus Preferences) baute keinen Kontext auf, was Scheduler und Batch-Vorinitialisierung blockierte. Neu: GuiApplicationContextInitializer-Callback, den Bootstrap für jeden GUI-Startpfad bereitstellt. openConfigurationFile() ruft ihn im Hintergrund-Thread auf; das Scheduler-Ergebnis wird via Platform.runLater() an GuiSchedulerTab.onSchedulerAvailable() übergeben. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
|||||||
|
package de.gecheckt.pdf.umbenenner.adapter.in.gui;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import de.gecheckt.pdf.umbenenner.application.port.in.SchedulerControlUseCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback invoked by the workspace on a background thread after a configuration file
|
||||||
|
* has been successfully loaded from disk.
|
||||||
|
* <p>
|
||||||
|
* Bootstrap supplies an implementation that builds the application run context
|
||||||
|
* (migrate → load → validate → schema-init sequence) and, on success, also initialises
|
||||||
|
* the automatic scheduler. The workspace calls this initializer inside the same
|
||||||
|
* background submit that loads the editor state, so the JavaFX Application Thread is
|
||||||
|
* never blocked.
|
||||||
|
* <p>
|
||||||
|
* In isolated GUI tests a {@link #noOp() no-op} implementation can be used so that no
|
||||||
|
* Bootstrap wiring is required.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface GuiApplicationContextInitializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to initialise the application run context for the supplied configuration file.
|
||||||
|
* <p>
|
||||||
|
* If context initialisation succeeds and the configuration enables the scheduler, the
|
||||||
|
* scheduler is also wired and its use case is returned in the result. The caller is
|
||||||
|
* responsible for handing the scheduler use case to the scheduler tab on the JavaFX
|
||||||
|
* Application Thread via {@code Platform.runLater}.
|
||||||
|
* <p>
|
||||||
|
* This method must be called on a background worker thread, not on the JavaFX Application
|
||||||
|
* Thread.
|
||||||
|
*
|
||||||
|
* @param configFilePath path to the {@code .properties} configuration file; must exist on disk
|
||||||
|
* @return the result of the initialisation attempt; never {@code null}
|
||||||
|
*/
|
||||||
|
InitResult initialize(Path configFilePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a no-op initializer that always reports success and no scheduler.
|
||||||
|
* <p>
|
||||||
|
* Suitable for GUI tests and startup paths where no Bootstrap wiring is available.
|
||||||
|
*
|
||||||
|
* @return no-op initializer; never {@code null}
|
||||||
|
*/
|
||||||
|
static GuiApplicationContextInitializer noOp() {
|
||||||
|
return configFilePath -> new InitResult(Optional.empty(), Optional.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of a context initialisation attempt.
|
||||||
|
*
|
||||||
|
* @param contextError empty on success; a human-readable German error message
|
||||||
|
* when initialisation failed — the GUI remains functional
|
||||||
|
* but falls back to per-run initialisation for batch runs;
|
||||||
|
* must not be {@code null}
|
||||||
|
* @param schedulerControlUseCase the scheduler use case when the configuration enables the
|
||||||
|
* scheduler and initialisation succeeded; empty otherwise;
|
||||||
|
* must not be {@code null}
|
||||||
|
*/
|
||||||
|
record InitResult(
|
||||||
|
Optional<String> contextError,
|
||||||
|
Optional<SchedulerControlUseCase> schedulerControlUseCase) {
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
-1
@@ -436,6 +436,13 @@ public final class GuiConfigurationEditorWorkspace {
|
|||||||
*/
|
*/
|
||||||
private final GuiCreateNewDatabasePort createNewDatabasePort;
|
private final GuiCreateNewDatabasePort createNewDatabasePort;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback, der nach jedem erfolgreichen Datei-Öffnen auf dem Hintergrund-Thread
|
||||||
|
* aufgerufen wird, um den Bootstrap-seitigen Anwendungskontext und den Scheduler
|
||||||
|
* zu initialisieren.
|
||||||
|
*/
|
||||||
|
private final GuiApplicationContextInitializer applicationContextInitializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktiver DB-Busy-Zustand während einer laufenden Datenbank-Anlage. Solange
|
* Aktiver DB-Busy-Zustand während einer laufenden Datenbank-Anlage. Solange
|
||||||
* dieser Zustand aktiv ist, sind alle DB-lesenden und DB-schreibenden Aktionen
|
* dieser Zustand aktiv ist, sind alle DB-lesenden und DB-schreibenden Aktionen
|
||||||
@@ -561,6 +568,7 @@ public final class GuiConfigurationEditorWorkspace {
|
|||||||
this.historicalDocumentContextPort = effectiveContext.historicalDocumentContextPort();
|
this.historicalDocumentContextPort = effectiveContext.historicalDocumentContextPort();
|
||||||
this.promptEditorPortFactory = effectiveContext.promptEditorPortFactory();
|
this.promptEditorPortFactory = effectiveContext.promptEditorPortFactory();
|
||||||
this.createNewDatabasePort = effectiveContext.createNewDatabasePort();
|
this.createNewDatabasePort = effectiveContext.createNewDatabasePort();
|
||||||
|
this.applicationContextInitializer = effectiveContext.applicationContextInitializer();
|
||||||
this.batchRunTab = new GuiBatchRunTab(
|
this.batchRunTab = new GuiBatchRunTab(
|
||||||
() -> this.batchRunLauncher,
|
() -> this.batchRunLauncher,
|
||||||
() -> this.miniRunLauncher,
|
() -> this.miniRunLauncher,
|
||||||
@@ -1024,7 +1032,13 @@ public final class GuiConfigurationEditorWorkspace {
|
|||||||
GuiConfigurationEditorState loadedState = configurationFileLoader.load(configFilePath);
|
GuiConfigurationEditorState loadedState = configurationFileLoader.load(configFilePath);
|
||||||
// Speichern des Pfads als letzte geladene Konfiguration
|
// Speichern des Pfads als letzte geladene Konfiguration
|
||||||
saveLastConfigurationPath(configFilePath);
|
saveLastConfigurationPath(configFilePath);
|
||||||
Platform.runLater(() -> applyEditorState(loadedState));
|
// Anwendungskontext und Scheduler initialisieren; Ergebnis auf dem FX-Thread auswerten.
|
||||||
|
GuiApplicationContextInitializer.InitResult initResult =
|
||||||
|
applicationContextInitializer.initialize(configFilePath);
|
||||||
|
Platform.runLater(() -> {
|
||||||
|
applyEditorState(loadedState);
|
||||||
|
initResult.schedulerControlUseCase().ifPresent(schedulerTab::onSchedulerAvailable);
|
||||||
|
});
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
Platform.runLater(() -> showError("Konfiguration konnte nicht geladen werden: "
|
Platform.runLater(() -> showError("Konfiguration konnte nicht geladen werden: "
|
||||||
+ safeMessage(exception)));
|
+ safeMessage(exception)));
|
||||||
|
|||||||
+31
-1
@@ -69,7 +69,10 @@ public final class GuiSchedulerTab {
|
|||||||
DateTimeFormatter.ofPattern("HH:mm").withZone(ZoneId.systemDefault());
|
DateTimeFormatter.ofPattern("HH:mm").withZone(ZoneId.systemDefault());
|
||||||
|
|
||||||
private final Tab tab = new Tab(TAB_TITLE);
|
private final Tab tab = new Tab(TAB_TITLE);
|
||||||
private final Optional<SchedulerControlUseCase> schedulerUseCase;
|
// Not final: may be updated via onSchedulerAvailable after the tab was created without a use
|
||||||
|
// case (e.g., when auto-load initialises the scheduler after the workspace was already built).
|
||||||
|
// Declared volatile so worker-thread reads (executeStart/Stop) see the write from the FX thread.
|
||||||
|
private volatile Optional<SchedulerControlUseCase> schedulerUseCase;
|
||||||
private final Supplier<Boolean> isConfigDirty;
|
private final Supplier<Boolean> isConfigDirty;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -134,6 +137,33 @@ public final class GuiSchedulerTab {
|
|||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Macht den Scheduler-Use-Case für diesen Tab verfügbar, nachdem er nach einem
|
||||||
|
* erfolgreichen Datei-Öffnen initialisiert wurde.
|
||||||
|
* <p>
|
||||||
|
* Wird vom Workspace auf dem JavaFX Application Thread aufgerufen, nachdem der
|
||||||
|
* {@link GuiApplicationContextInitializer} auf einem Hintergrund-Thread einen
|
||||||
|
* {@link SchedulerControlUseCase} geliefert hat. Hat keine Wirkung, wenn bereits
|
||||||
|
* ein Use Case vorhanden ist.
|
||||||
|
* <p>
|
||||||
|
* Muss auf dem JavaFX Application Thread aufgerufen werden.
|
||||||
|
*
|
||||||
|
* @param useCase der neu initialisierte Use Case; darf nicht {@code null} sein
|
||||||
|
*/
|
||||||
|
public void onSchedulerAvailable(SchedulerControlUseCase useCase) {
|
||||||
|
if (schedulerUseCase.isPresent()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
schedulerUseCase = Optional.of(useCase);
|
||||||
|
intervalField.setText(String.valueOf(useCase.getIntervalSeconds()));
|
||||||
|
intervalField.setEditable(true);
|
||||||
|
intervalField.setDisable(false);
|
||||||
|
// Buttons werden im nächsten updateStatus-Tick (1 Hz) korrekt gesetzt;
|
||||||
|
// vorab grob aktivieren damit kein misleadender Disabled-Zustand bleibt.
|
||||||
|
startButton.setDisable(false);
|
||||||
|
startButton.setTooltip(null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aktualisiert alle Tab-Elemente anhand des aktuellen Scheduler-Status.
|
* Aktualisiert alle Tab-Elemente anhand des aktuellen Scheduler-Status.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
+12
-3
@@ -70,6 +70,10 @@ import de.gecheckt.pdf.umbenenner.domain.model.DocumentFingerprint;
|
|||||||
* no locking is performed (e.g., no valid configuration was loaded at startup, or locking is
|
* no locking is performed (e.g., no valid configuration was loaded at startup, or locking is
|
||||||
* not required in this context).
|
* not required in this context).
|
||||||
* <p>
|
* <p>
|
||||||
|
* The {@code applicationContextInitializer} is invoked on a background thread each time the
|
||||||
|
* workspace loads a configuration file (auto-load at startup and manual open). Bootstrap
|
||||||
|
* provides an implementation that builds the application run context and wires the scheduler.
|
||||||
|
* <p>
|
||||||
* All ports and services are supplied by Bootstrap so that the GUI adapter does not need to
|
* All ports and services are supplied by Bootstrap so that the GUI adapter does not need to
|
||||||
* know about provider-specific HTTP details or adapter wiring.
|
* know about provider-specific HTTP details or adapter wiring.
|
||||||
*/
|
*/
|
||||||
@@ -100,7 +104,8 @@ public record GuiStartupContext(
|
|||||||
GuiCreateNewDatabasePort createNewDatabasePort,
|
GuiCreateNewDatabasePort createNewDatabasePort,
|
||||||
Optional<String> applicationContextError,
|
Optional<String> applicationContextError,
|
||||||
Optional<SchedulerControlUseCase> schedulerControlUseCase,
|
Optional<SchedulerControlUseCase> schedulerControlUseCase,
|
||||||
Optional<ConfigurationFileLockPort> configurationFileLockPort) {
|
Optional<ConfigurationFileLockPort> configurationFileLockPort,
|
||||||
|
GuiApplicationContextInitializer applicationContextInitializer) {
|
||||||
private static final String NO_PROMPT_PORT_MSG = "Kein Prompt-Editor-Port in diesem Startkontext verfügbar.";
|
private static final String NO_PROMPT_PORT_MSG = "Kein Prompt-Editor-Port in diesem Startkontext verfügbar.";
|
||||||
private static final String NO_PORT_MSG = "Kein Port in diesem Startkontext.";
|
private static final String NO_PORT_MSG = "Kein Port in diesem Startkontext.";
|
||||||
|
|
||||||
@@ -188,6 +193,8 @@ public record GuiStartupContext(
|
|||||||
"createNewDatabasePort must not be null");
|
"createNewDatabasePort must not be null");
|
||||||
schedulerControlUseCase = schedulerControlUseCase == null ? Optional.empty() : schedulerControlUseCase;
|
schedulerControlUseCase = schedulerControlUseCase == null ? Optional.empty() : schedulerControlUseCase;
|
||||||
configurationFileLockPort = configurationFileLockPort == null ? Optional.empty() : configurationFileLockPort;
|
configurationFileLockPort = configurationFileLockPort == null ? Optional.empty() : configurationFileLockPort;
|
||||||
|
applicationContextInitializer = applicationContextInitializer == null
|
||||||
|
? GuiApplicationContextInitializer.noOp() : applicationContextInitializer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -255,7 +262,8 @@ public record GuiStartupContext(
|
|||||||
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
||||||
historyOverviewPort, historyDetailsPort, historyResetDocumentStatusPort,
|
historyOverviewPort, historyDetailsPort, historyResetDocumentStatusPort,
|
||||||
deleteDocumentHistoryPort, promptEditorPortFactory, createNewDatabasePort,
|
deleteDocumentHistoryPort, promptEditorPortFactory, createNewDatabasePort,
|
||||||
applicationContextError, Optional.empty(), Optional.empty());
|
applicationContextError, Optional.empty(), Optional.empty(),
|
||||||
|
GuiApplicationContextInitializer.noOp());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,7 +334,8 @@ public record GuiStartupContext(
|
|||||||
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
||||||
historyOverviewPort, historyDetailsPort, historyResetDocumentStatusPort,
|
historyOverviewPort, historyDetailsPort, historyResetDocumentStatusPort,
|
||||||
deleteDocumentHistoryPort, promptEditorPortFactory, createNewDatabasePort,
|
deleteDocumentHistoryPort, promptEditorPortFactory, createNewDatabasePort,
|
||||||
applicationContextError, schedulerControlUseCase, Optional.empty());
|
applicationContextError, schedulerControlUseCase, Optional.empty(),
|
||||||
|
GuiApplicationContextInitializer.noOp());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+40
-10
@@ -21,6 +21,7 @@ import de.gecheckt.pdf.umbenenner.adapter.in.cli.SchedulerBatchCommand;
|
|||||||
import de.gecheckt.pdf.umbenenner.adapter.in.scheduler.FileChannelConfigurationAccessAdapter;
|
import de.gecheckt.pdf.umbenenner.adapter.in.scheduler.FileChannelConfigurationAccessAdapter;
|
||||||
import de.gecheckt.pdf.umbenenner.adapter.in.scheduler.ScheduledExecutorServiceSchedulerAdapter;
|
import de.gecheckt.pdf.umbenenner.adapter.in.scheduler.ScheduledExecutorServiceSchedulerAdapter;
|
||||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiAdapter;
|
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiAdapter;
|
||||||
|
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiApplicationContextInitializer;
|
||||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationFileLoader;
|
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationFileLoader;
|
||||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationFileWriter;
|
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationFileWriter;
|
||||||
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationLoadException;
|
import de.gecheckt.pdf.umbenenner.adapter.in.gui.GuiConfigurationLoadException;
|
||||||
@@ -255,11 +256,13 @@ public class BootstrapRunner {
|
|||||||
* the resolved JDBC URL, so that batch runs and reset operations can skip the
|
* the resolved JDBC URL, so that batch runs and reset operations can skip the
|
||||||
* migrate → load → validate → schema-init sequence for each call.
|
* migrate → load → validate → schema-init sequence for each call.
|
||||||
* <p>
|
* <p>
|
||||||
* Written by {@link #initializeApplicationRunContext(Path)} during
|
* Written by {@link #initializeApplicationRunContext(Path)} — either directly during
|
||||||
* {@link #buildGuiStartupContext(Optional)} and read by
|
* {@link #buildGuiStartupContext(Optional)} (when {@code --config} is supplied and valid),
|
||||||
|
* or via the {@link GuiApplicationContextInitializer} callback that the workspace invokes
|
||||||
|
* on a background thread after each successful file open. Read by
|
||||||
* {@link #launchGuiBatchRun}, {@link #launchGuiMiniBatchRun}, and
|
* {@link #launchGuiBatchRun}, {@link #launchGuiMiniBatchRun}, and
|
||||||
* {@link #resetDocumentStatusForGui}. {@code volatile} ensures visibility
|
* {@link #resetDocumentStatusForGui}. {@code volatile} ensures visibility across threads
|
||||||
* across threads without explicit synchronisation on the happy path.
|
* without explicit synchronisation on the happy path.
|
||||||
*/
|
*/
|
||||||
private volatile Optional<ApplicationRunContext> guiApplicationRunContext = Optional.empty();
|
private volatile Optional<ApplicationRunContext> guiApplicationRunContext = Optional.empty();
|
||||||
|
|
||||||
@@ -771,8 +774,12 @@ public class BootstrapRunner {
|
|||||||
* during startup is treated as a hard GUI startup failure and mapped to exit code 1.
|
* during startup is treated as a hard GUI startup failure and mapped to exit code 1.
|
||||||
* Normal termination (user closes the window) returns exit code 0.
|
* Normal termination (user closes the window) returns exit code 0.
|
||||||
* <p>
|
* <p>
|
||||||
* The headless batch pipeline is not entered from this method. Configuration loading,
|
* The headless batch pipeline is not entered from this method. When {@code --config} is
|
||||||
* schema initialization, and all batch infrastructure are not initialized in the GUI path.
|
* supplied and the file exists, configuration loading and schema initialisation run
|
||||||
|
* immediately so the application run context is pre-built. For all other startup paths
|
||||||
|
* (no {@code --config}, missing file, load failure) a {@link GuiApplicationContextInitializer}
|
||||||
|
* callback is wired into the startup context; the workspace calls it on a background thread
|
||||||
|
* each time a configuration file is successfully opened.
|
||||||
*
|
*
|
||||||
* @param configPathOverride the optional {@code --config} path string from startup arguments;
|
* @param configPathOverride the optional {@code --config} path string from startup arguments;
|
||||||
* must not be {@code null}
|
* must not be {@code null}
|
||||||
@@ -915,6 +922,20 @@ public class BootstrapRunner {
|
|||||||
// Versionsnummer aus dem MANIFEST.MF des gepackten JARs lesen; Fallback "dev" bei IDE-Start
|
// Versionsnummer aus dem MANIFEST.MF des gepackten JARs lesen; Fallback "dev" bei IDE-Start
|
||||||
String applicationVersion = ApplicationVersionProvider.resolveVersion();
|
String applicationVersion = ApplicationVersionProvider.resolveVersion();
|
||||||
|
|
||||||
|
// Initializer that the workspace calls on a background thread after every successful
|
||||||
|
// file open (auto-load at startup and manual open). Builds the ApplicationRunContext
|
||||||
|
// and wires the scheduler for the newly loaded configuration file.
|
||||||
|
GuiApplicationContextInitializer contextInitializer = configFilePath -> {
|
||||||
|
stopGuiSchedulerIfActive();
|
||||||
|
Optional<String> initError = initializeApplicationRunContext(configFilePath);
|
||||||
|
if (initError.isEmpty()) {
|
||||||
|
tryInitializeScheduler(configFilePath);
|
||||||
|
}
|
||||||
|
return new GuiApplicationContextInitializer.InitResult(
|
||||||
|
initError,
|
||||||
|
guiSchedulerUseCase.map(s -> (SchedulerControlUseCase) s));
|
||||||
|
};
|
||||||
|
|
||||||
if (configPathOverride.isEmpty()) {
|
if (configPathOverride.isEmpty()) {
|
||||||
return new GuiStartupContext(
|
return new GuiStartupContext(
|
||||||
GuiConfigurationEditorStateFactory.createBlankStartState(),
|
GuiConfigurationEditorStateFactory.createBlankStartState(),
|
||||||
@@ -941,7 +962,10 @@ public class BootstrapRunner {
|
|||||||
deleteHistoryPort,
|
deleteHistoryPort,
|
||||||
this::buildGuiPromptEditorPort,
|
this::buildGuiPromptEditorPort,
|
||||||
createNewDatabasePort,
|
createNewDatabasePort,
|
||||||
Optional.empty());
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
contextInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
Path configPath = Paths.get(configPathOverride.get());
|
Path configPath = Paths.get(configPathOverride.get());
|
||||||
@@ -974,7 +998,10 @@ public class BootstrapRunner {
|
|||||||
deleteHistoryPort,
|
deleteHistoryPort,
|
||||||
this::buildGuiPromptEditorPort,
|
this::buildGuiPromptEditorPort,
|
||||||
createNewDatabasePort,
|
createNewDatabasePort,
|
||||||
Optional.empty());
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
contextInitializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("GUI startup: configuration file confirmed at: {}", configPath.toAbsolutePath());
|
LOG.info("GUI startup: configuration file confirmed at: {}", configPath.toAbsolutePath());
|
||||||
@@ -997,7 +1024,7 @@ public class BootstrapRunner {
|
|||||||
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
historicalDocumentContextPort, applicationVersion, promptEditorPort,
|
||||||
historyOverviewPort, historyDetailsPort, historyResetPort, deleteHistoryPort,
|
historyOverviewPort, historyDetailsPort, historyResetPort, deleteHistoryPort,
|
||||||
this::buildGuiPromptEditorPort, createNewDatabasePort, contextError,
|
this::buildGuiPromptEditorPort, createNewDatabasePort, contextError,
|
||||||
schedulerUseCase, guiRunLockPort);
|
schedulerUseCase, guiRunLockPort, contextInitializer);
|
||||||
} catch (GuiConfigurationLoadException e) {
|
} catch (GuiConfigurationLoadException e) {
|
||||||
LOG.error("GUI startup: configuration could not be loaded, starting without it: {}",
|
LOG.error("GUI startup: configuration could not be loaded, starting without it: {}",
|
||||||
e.getMessage(), e);
|
e.getMessage(), e);
|
||||||
@@ -1026,7 +1053,10 @@ public class BootstrapRunner {
|
|||||||
deleteHistoryPort,
|
deleteHistoryPort,
|
||||||
this::buildGuiPromptEditorPort,
|
this::buildGuiPromptEditorPort,
|
||||||
createNewDatabasePort,
|
createNewDatabasePort,
|
||||||
Optional.empty());
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
Optional.empty(),
|
||||||
|
contextInitializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user