From 74a30837573e966f64ddcdcbbe6dece9eda953be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20B=C3=BChlmann?= Date: Thu, 18 Jan 2024 14:22:48 +0100 Subject: [PATCH] WIP --- .../ch/admin/bar/siardsuite/Controller.java | 72 ++------------ .../database/DatabaseConnectionFactory.java | 95 +++++++----------- .../database/DatabaseInteractionService.java | 96 ++++++++++++++++++ .../siardsuite/database/DatabaseLoadTask.java | 26 ++--- .../database/DatabaseUploadTask.java | 6 +- .../database/model/DbmsConnectionData.java | 36 +++++-- .../model/DbmsConnectionProperties.java | 5 - .../model/LoadDatabaseInstruction.java | 10 +- .../ServerBasedDbmsConnectionProperties.java | 15 --- .../model/UploadDatabaseInstruction.java | 36 +++++++ .../presenter/StepperPresenter.java | 17 ++-- .../archive/ArchiveAbortDialogPresenter.java | 12 +++ .../archive/ArchiveChooseDbmsPresenter.java | 6 +- .../archive/ArchiveConnectionPresenter.java | 43 ++++---- .../archive/ArchiveDownloadPresenter.java | 43 ++++---- ...chiveRecentConnectionsDialogPresenter.java | 11 ++- .../open/OpenSiardArchiveDialogPresenter.java | 10 +- .../option/OptionDialogPresenter.java | 8 +- .../upload/UploadConnectionPresenter.java | 16 +-- .../upload/UploadDbDialogPresenter.java | 10 +- .../presenter/upload/UploadingPresenter.java | 28 ++++-- .../admin/bar/siardsuite/util/SiardEvent.java | 17 +++- .../util/preferences/DbConnection.java | 86 ++++++++++++++++ .../siardsuite/util/preferences/Options.java | 12 +++ .../{ => preferences}/UserPreferences.java | 97 ++++--------------- .../admin/bar/siardsuite/view/RootStage.java | 8 ++ 26 files changed, 472 insertions(+), 349 deletions(-) create mode 100644 src/main/java/ch/admin/bar/siardsuite/database/DatabaseInteractionService.java create mode 100644 src/main/java/ch/admin/bar/siardsuite/database/model/UploadDatabaseInstruction.java create mode 100644 src/main/java/ch/admin/bar/siardsuite/util/preferences/DbConnection.java create mode 100644 src/main/java/ch/admin/bar/siardsuite/util/preferences/Options.java rename src/main/java/ch/admin/bar/siardsuite/util/{ => preferences}/UserPreferences.java (67%) diff --git a/src/main/java/ch/admin/bar/siardsuite/Controller.java b/src/main/java/ch/admin/bar/siardsuite/Controller.java index 003c42ce..6c415bcf 100644 --- a/src/main/java/ch/admin/bar/siardsuite/Controller.java +++ b/src/main/java/ch/admin/bar/siardsuite/Controller.java @@ -2,11 +2,13 @@ import ch.admin.bar.siard2.api.Archive; import ch.admin.bar.siardsuite.database.DatabaseConnectionFactory; +import ch.admin.bar.siardsuite.database.DatabaseInteractionService; import ch.admin.bar.siardsuite.database.DatabaseLoadService; import ch.admin.bar.siardsuite.database.DatabaseProperties; import ch.admin.bar.siardsuite.database.DatabaseUploadService; import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; import ch.admin.bar.siardsuite.database.model.LoadDatabaseInstruction; +import ch.admin.bar.siardsuite.database.model.UploadDatabaseInstruction; import ch.admin.bar.siardsuite.model.Failure; import ch.admin.bar.siardsuite.model.Model; import ch.admin.bar.siardsuite.model.View; @@ -15,11 +17,6 @@ import ch.admin.bar.siardsuite.view.RootStage; import ch.admin.bar.siardsuite.visitor.ArchiveVisitor; import javafx.beans.property.StringProperty; -import javafx.beans.value.ChangeListener; -import javafx.collections.ObservableList; -import javafx.concurrent.WorkerStateEvent; -import javafx.event.EventHandler; -import javafx.util.Pair; import lombok.Getter; import lombok.Setter; import lombok.val; @@ -28,7 +25,6 @@ import java.io.IOException; import java.net.URI; import java.nio.file.Paths; -import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.Optional; @@ -42,43 +38,23 @@ public class Controller { private Workflow workflow; public String recentDatabaseConnection; + private final DatabaseInteractionService databaseInteractionService; + @Setter @Getter private Optional tempConnectionData = Optional.empty(); - public Optional popTempConnectionData() { - val tempReturnValue = tempConnectionData; - tempConnectionData = Optional.empty(); - return tempReturnValue; - } - public Controller(Model model) { this.model = model; + this.databaseInteractionService = new DatabaseInteractionService(new DatabaseConnectionFactory(), model); } - public void loadDatabase(final LoadDatabaseInstruction instruction) throws SQLException { - tmpArchive = model.initArchive(); - - val connection = instruction.getConnectionData().createConnection(); - - val dbLoadService = new DatabaseLoadService( - connection, - model, - tmpArchive, - instruction.isLoadOnlyMetadata(), - instruction.isViewsAsTables()); - - dbLoadService.setOnSucceeded(instruction.getOnSuccess()); - dbLoadService.setOnFailed(instruction.getOnFailure()); - - dbLoadService.start(); - - dbLoadService.valueProperty().addListener(instruction.getOnSingleValueCompleted()); - dbLoadService.progressProperty().addListener(instruction.getOnProgress()); + public void loadDatabase(final LoadDatabaseInstruction instruction) { + databaseInteractionService.execute(instruction); } - public void closeDbConnection() { - DatabaseConnectionFactory.disconnect(); + public void uploadDatabase(final UploadDatabaseInstruction instruction) { + databaseInteractionService.execute(instruction); } public void updateConnectionData(String connectionUrl, String username, String databaseName, String password) { @@ -92,35 +68,10 @@ public void updateSchemaMap(Map schemaMap) { this.model.setSchemaMap(schemaMap); } - public void onDatabaseUploadSuccess(EventHandler workerStateEventEventHandler) { - this.databaseUploadService.setOnSucceeded(workerStateEventEventHandler); - } - - public void onDatabaseUploadFailed(EventHandler workerStateEventEventHandler) { - this.databaseUploadService.setOnFailed(workerStateEventEventHandler); - } - - public void addDatabaseUploadingValuePropertyListener(ChangeListener listener) { - this.databaseUploadService.valueProperty().addListener(listener); - } - - public void addDatabaseUploadingProgressPropertyListener(ChangeListener listener) { - this.databaseUploadService.progressProperty().addListener(listener); - } - public Workflow getWorkflow() { return workflow; } - - public void uploadArchive(EventHandler onSuccess, - EventHandler onFailure) throws SQLException { - this.databaseUploadService = DatabaseConnectionFactory.getInstance(model).createDatabaseUploader(); - this.onDatabaseUploadSuccess(onSuccess); - this.onDatabaseUploadFailed(onFailure); - this.databaseUploadService.start(); - } - public void cancelDownload() { if (databaseLoadService != null && databaseLoadService.isRunning()) { this.databaseLoadService.cancel(); @@ -136,7 +87,6 @@ public void cancelUpload() { } public void releaseResources() { - closeDbConnection(); removeTmpArchive(); } @@ -231,10 +181,6 @@ public DatabaseProperties getDatabaseProps() { return this.model.getDatabaseProps(); } - public StringProperty getDatabaseProduct() { - return this.model.getDatabaseProduct(); - } - public List getDatabaseTypes() { return this.model.getDatabaseTypes(); } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseConnectionFactory.java b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseConnectionFactory.java index 25caadaa..52f41a40 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseConnectionFactory.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseConnectionFactory.java @@ -1,75 +1,50 @@ package ch.admin.bar.siardsuite.database; -import ch.admin.bar.siard2.api.Archive; -import ch.admin.bar.siardsuite.model.Model; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; +import lombok.extern.slf4j.Slf4j; +import lombok.val; -import java.io.IOException; -import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; -import java.util.Properties; - -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.LOGIN_TIMEOUT; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.OPTIONS; +@Slf4j public class DatabaseConnectionFactory { - private static DatabaseConnectionFactory instance; - private static Connection connection; - private static Model model; - - private DatabaseConnectionFactory(Model model) throws SQLException { - DatabaseConnectionFactory.model = model; - loadDriver(DatabaseConnectionFactory.model.getDatabaseProps().product()); - DriverManager.setLoginTimeout(Integer.parseInt(UserPreferences.node(OPTIONS).get(LOGIN_TIMEOUT.name(), "0"))); - connection = DriverManager.getConnection(model.getConnectionUrl().get(), - model.getDatabaseUsername().get(), model.getDatabasePassword()); - } - - public static DatabaseConnectionFactory getInstance(Model model) throws SQLException { - if (instance == null || connection.isClosed()) { - instance = new DatabaseConnectionFactory(model); - } - return instance; - } - public DatabaseLoadService createDatabaseLoader(final Archive archive, boolean onlyMetaData, boolean viewsAsTables) { - return new DatabaseLoadService(connection, model, archive, onlyMetaData, viewsAsTables); - } - - public DatabaseUploadService createDatabaseUploader() { - return new DatabaseUploadService(connection, model); - } - - public static void disconnect() { - if (connection != null) { - try { - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } + public Connection createConnection(final DbmsConnectionData dbmsConnectionData) { + val options = UserPreferences.getStoredOptions(); + + loadDriverByClassName(dbmsConnectionData.getDbms().getDriverClassName()); + DriverManager.setLoginTimeout(options.getLoginTimeout()); + + try { + return DriverManager.getConnection( + dbmsConnectionData.getJdbcConnectionString(), + dbmsConnectionData.getUser(), + dbmsConnectionData.getPassword()); + } catch (SQLException e) { + throw new DatabaseConnectionException( + String.format("Failed to create connection '%s'", dbmsConnectionData), + e); + } } - } - private void loadDriver(String product) { - Properties properties = new Properties(); - try (InputStream is = getClass().getResourceAsStream("driver.properties")) { - properties.load(is); - } catch (IOException e) { - throw new RuntimeException(e); - } - String jdbcDriverClass = properties.getProperty(product); - if (jdbcDriverClass != null) { - try { - Class.forName(jdbcDriverClass); - } catch (ClassNotFoundException var7) { - throw new RuntimeException("Driver " + jdbcDriverClass + " could not be loaded!"); - } - } else { - throw new RuntimeException("No driver found for sub scheme \"" + product + "\"!"); + private static void loadDriverByClassName(String jdbcDriverClass) { + try { + Class.forName(jdbcDriverClass); + } catch (ClassNotFoundException var7) { + throw new DatabaseConnectionException("Driver " + jdbcDriverClass + " could not be loaded!"); + } } - } + private static class DatabaseConnectionException extends RuntimeException { + public DatabaseConnectionException(String message) { + super(message); + } + public DatabaseConnectionException(String message, Throwable cause) { + super(message, cause); + } + } } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseInteractionService.java b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseInteractionService.java new file mode 100644 index 00000000..5e9db90f --- /dev/null +++ b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseInteractionService.java @@ -0,0 +1,96 @@ +package ch.admin.bar.siardsuite.database; + +import ch.admin.bar.siardsuite.database.model.LoadDatabaseInstruction; +import ch.admin.bar.siardsuite.database.model.UploadDatabaseInstruction; +import ch.admin.bar.siardsuite.model.Model; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import lombok.val; + +import java.sql.Connection; +import java.sql.SQLException; + +@Slf4j +@RequiredArgsConstructor +public class DatabaseInteractionService { + + private final DatabaseConnectionFactory connectionFactory; + + @Deprecated // TODO remove model + private final Model model; + + public InstructionExecutionHandle execute(final LoadDatabaseInstruction instruction) { + val tempArchive = model.initArchive(); + val connection = connectionFactory.createConnection(instruction.getConnectionData()); + + val dbLoadService = new DatabaseLoadService( + connection, + model, + tempArchive, + instruction.isLoadOnlyMetadata(), + instruction.isViewsAsTables()); + + dbLoadService.setOnSucceeded(event -> { + instruction.getOnSuccess().handle(event); + close(connection); + }); + dbLoadService.setOnFailed(event -> { + instruction.getOnFailure().handle(event); + close(connection); + }); + + dbLoadService.start(); + + dbLoadService.valueProperty().addListener((observable, oldValue, newValue) -> { + instruction.getOnStepCompleted().changed(observable, oldValue, newValue); + }); + + dbLoadService.progressProperty().addListener((observable, oldValue, newValue) -> { + instruction.getOnProgress().changed(observable, oldValue, newValue); + }); + + return () -> { + dbLoadService.cancel(); + close(connection); + }; + } + + public InstructionExecutionHandle execute(final UploadDatabaseInstruction instruction) { + val connection = connectionFactory.createConnection(instruction.getConnectionData()); + + val dbUploadService = new DatabaseUploadService( + connection, + model); + + dbUploadService.setOnSucceeded(event -> { + instruction.getOnSuccess().handle(event); + close(connection); + }); + dbUploadService.setOnFailed(event -> { + instruction.getOnFailure().handle(event); + close(connection); + }); + + dbUploadService.start(); + + dbUploadService.valueProperty().addListener(instruction.getOnStepCompleted()); + dbUploadService.progressProperty().addListener(instruction.getOnProgress()); + + return () -> { + dbUploadService.cancel(); + close(connection); + }; + } + + public interface InstructionExecutionHandle { + void cancel(); + } + + private static void close(final Connection connection) { + try { + connection.close(); + } catch (SQLException e) { + log.error("Failed to close connection {} because: {}", connection, e); + } + } +} diff --git a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseLoadTask.java b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseLoadTask.java index 22cbe218..2d652db9 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseLoadTask.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseLoadTask.java @@ -6,8 +6,7 @@ import ch.admin.bar.siard2.cmd.PrimaryDataFromDb; import ch.admin.bar.siardsuite.model.Model; import ch.admin.bar.siardsuite.model.database.SiardArchiveMetaData; -import ch.admin.bar.siardsuite.presenter.tree.SiardArchiveMetaDataDetailsVisitor; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.visitor.SiardArchiveMetaDataVisitor; import ch.enterag.utils.background.Progress; import javafx.collections.FXCollections; @@ -15,15 +14,12 @@ import javafx.concurrent.Task; import javafx.util.Pair; -import java.io.File; -import java.net.URI; import java.sql.Connection; -import java.time.LocalDate; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.QUERY_TIMEOUT; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.OPTIONS; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.QUERY_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.OPTIONS; -public class DatabaseLoadTask extends Task>> implements Progress, SiardArchiveMetaDataVisitor, SiardArchiveMetaDataDetailsVisitor { +public class DatabaseLoadTask extends Task>> implements Progress, SiardArchiveMetaDataVisitor { private final Connection connection; private final Model model; @@ -48,14 +44,16 @@ protected ObservableList> call() throws Exception { ObservableList> progressData = FXCollections.observableArrayList(); connection.setAutoCommit(false); int timeout = Integer.parseInt(UserPreferences.node(OPTIONS).get(QUERY_TIMEOUT.name(), "0")); + archive.getMetaData().setDbName(model.getDatabaseName().getValue()); + MetaDataFromDb metadata = MetaDataFromDb.newInstance(connection.getMetaData(), archive.getMetaData()); metadata.setQueryTimeout(timeout); updateValue(FXCollections.observableArrayList(new Pair<>("Metadata", -1L))); updateProgress(0, 100); metadata.download(viewsAsTables, false, this); - model.provideDatabaseArchiveMetaDataObject(this); + model.provideDatabaseArchiveMetaDataObject(this); // very complicated getter for the SiardArchiveMetaData if (metaData != null) { metaData.write(archive); } @@ -96,16 +94,6 @@ public void notifyProgress(int i) { updateProgress(i, 100); } - @Override - public void visit(String siardFormatVersion, String databaseName, String databaseProduct, - String databaseConnectionURL, - String databaseUsername, String databaseDescription, String databaseOwner, - String databaseCreationDate, - LocalDate archivingDate, String archiverName, String archiverContact, File targetArchive, - URI lobFolder, boolean viewsAsTables) { - this.name = targetArchive.getName(); - } - @Override public void visit(SiardArchiveMetaData metaData) { this.metaData = metaData; diff --git a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseUploadTask.java b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseUploadTask.java index b19a09bd..530792d1 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/DatabaseUploadTask.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/DatabaseUploadTask.java @@ -5,15 +5,15 @@ import ch.admin.bar.siard2.cmd.MetaDataToDb; import ch.admin.bar.siard2.cmd.PrimaryDataToDb; import ch.admin.bar.siardsuite.model.Model; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.visitor.ArchiveVisitor; import ch.enterag.utils.background.Progress; import javafx.concurrent.Task; import java.sql.Connection; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.QUERY_TIMEOUT; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.OPTIONS; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.QUERY_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.OPTIONS; public class DatabaseUploadTask extends Task implements Progress, ArchiveVisitor { diff --git a/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionData.java b/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionData.java index 50034dee..6aaeb1e0 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionData.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionData.java @@ -1,16 +1,24 @@ package ch.admin.bar.siardsuite.database.model; import lombok.Builder; +import lombok.Getter; import lombok.NonNull; import lombok.Value; +import lombok.val; import java.sql.Connection; import java.sql.SQLException; +import java.util.function.Supplier; -@Value public class DbmsConnectionData { - Dbms dbms; - DbmsConnectionProperties properties; + @Getter + private final Dbms dbms; + @Getter + private final DbmsConnectionProperties properties; + + private final Supplier jdbsConnectionStringSupplier; + private final Supplier userSupplier; + private final Supplier passwordSupplier; public DbmsConnectionData( @NonNull ServerBasedDbms dbms, @@ -18,6 +26,10 @@ public DbmsConnectionData( ) { this.dbms = dbms; this.properties = properties; + + jdbsConnectionStringSupplier = () -> dbms.getJdbcConnectionStringEncoder().apply(properties); + userSupplier = properties::getUser; + passwordSupplier = properties::getPassword; } public DbmsConnectionData( @@ -26,15 +38,21 @@ public DbmsConnectionData( ) { this.dbms = dbms; this.properties = properties; + + jdbsConnectionStringSupplier = () -> dbms.getJdbcConnectionStringEncoder().apply(properties); + userSupplier = () -> null; + passwordSupplier = () -> null; } + public String getUser() { + return userSupplier.get(); + } - public Connection createConnection() throws SQLException { // TODO: Move to connection factory + public String getPassword() { + return passwordSupplier.get(); + } - throw new UnsupportedOperationException(); -// DriverManager.setLoginTimeout(Integer.parseInt(UserPreferences.node(OPTIONS).get(LOGIN_TIMEOUT.name(), "0"))); -// val connection = config.createConnection(dbms.getJdbcConnectionStringEncoder()); -// -// return connection; + public String getJdbcConnectionString() { + return jdbsConnectionStringSupplier.get(); } } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionProperties.java b/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionProperties.java index 1f356db6..e2bdf83b 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionProperties.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/model/DbmsConnectionProperties.java @@ -1,9 +1,4 @@ package ch.admin.bar.siardsuite.database.model; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.function.Function; - public interface DbmsConnectionProperties { - Connection createConnection(final Function jdbcConnectionStringEncoder) throws SQLException; } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/model/LoadDatabaseInstruction.java b/src/main/java/ch/admin/bar/siardsuite/database/model/LoadDatabaseInstruction.java index cc10ac43..52c12668 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/model/LoadDatabaseInstruction.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/model/LoadDatabaseInstruction.java @@ -20,7 +20,7 @@ public class LoadDatabaseInstruction { EventHandler onSuccess; EventHandler onFailure; ChangeListener onProgress; - ChangeListener>> onSingleValueCompleted; // TODO: Naming + ChangeListener>> onStepCompleted; @Builder public LoadDatabaseInstruction( @@ -34,10 +34,12 @@ public LoadDatabaseInstruction( ) { this.connectionData = connectionData; this.loadOnlyMetadata = Optional.ofNullable(loadOnlyMetadata).orElse(false); - this.viewsAsTables = Optional.ofNullable(viewsAsTables).orElse(false);; + this.viewsAsTables = Optional.ofNullable(viewsAsTables).orElse(false); this.onSuccess = Optional.ofNullable(onSuccess).orElse(event -> {}); this.onFailure = Optional.ofNullable(onFailure).orElse(event -> {}); - this.onProgress = Optional.ofNullable(onProgress).orElse((observable, oldValue, newValue) -> {}); - this.onSingleValueCompleted = Optional.ofNullable(onSingleValueCompleted).orElse((observable, oldValue, newValue) -> {}); + this.onProgress = Optional.ofNullable(onProgress) + .orElse((observable, oldValue, newValue) -> {}); + this.onStepCompleted = Optional.ofNullable(onSingleValueCompleted) + .orElse((observable, oldValue, newValue) -> {}); } } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/model/ServerBasedDbmsConnectionProperties.java b/src/main/java/ch/admin/bar/siardsuite/database/model/ServerBasedDbmsConnectionProperties.java index 28dab565..a3fb91de 100644 --- a/src/main/java/ch/admin/bar/siardsuite/database/model/ServerBasedDbmsConnectionProperties.java +++ b/src/main/java/ch/admin/bar/siardsuite/database/model/ServerBasedDbmsConnectionProperties.java @@ -3,12 +3,6 @@ import lombok.Builder; import lombok.NonNull; import lombok.Value; -import lombok.val; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.function.Function; @Value @Builder @@ -18,13 +12,4 @@ public class ServerBasedDbmsConnectionProperties implements DbmsConnectionProper @NonNull String dbName; @NonNull String user; @NonNull String password; - - @Override - public Connection createConnection(final Function jdbcConnectionStringEncoder) throws SQLException { - val jdbcConnectionString = jdbcConnectionStringEncoder.apply(this); - return DriverManager.getConnection( - jdbcConnectionString, - user, - password); - } } diff --git a/src/main/java/ch/admin/bar/siardsuite/database/model/UploadDatabaseInstruction.java b/src/main/java/ch/admin/bar/siardsuite/database/model/UploadDatabaseInstruction.java new file mode 100644 index 00000000..e1aa7c37 --- /dev/null +++ b/src/main/java/ch/admin/bar/siardsuite/database/model/UploadDatabaseInstruction.java @@ -0,0 +1,36 @@ +package ch.admin.bar.siardsuite.database.model; + +import javafx.beans.value.ChangeListener; +import javafx.concurrent.WorkerStateEvent; +import javafx.event.EventHandler; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +@Value +public class UploadDatabaseInstruction { + DbmsConnectionData connectionData; + EventHandler onSuccess; + EventHandler onFailure; + ChangeListener onProgress; + ChangeListener onStepCompleted; + + @Builder + public UploadDatabaseInstruction( + @NonNull DbmsConnectionData connectionData, + @Nullable EventHandler onSuccess, + @Nullable EventHandler onFailure, + @Nullable ChangeListener onProgress, + @Nullable ChangeListener onStepCompleted + ) { + this.connectionData = connectionData; + + this.onSuccess = Optional.ofNullable(onSuccess).orElse(event -> {}); + this.onFailure = Optional.ofNullable(onFailure).orElse(event -> {}); + this.onProgress = Optional.ofNullable(onProgress).orElse((observable, oldValue, newValue) -> {}); + this.onStepCompleted = Optional.ofNullable(onStepCompleted).orElse((observable, oldValue, newValue) -> {}); + } +} diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/StepperPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/StepperPresenter.java index 50147aac..fe4a3986 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/StepperPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/StepperPresenter.java @@ -4,6 +4,7 @@ import ch.admin.bar.siardsuite.model.Step; import ch.admin.bar.siardsuite.model.View; import ch.admin.bar.siardsuite.util.CastHelper; +import ch.admin.bar.siardsuite.util.SiardEvent; import ch.admin.bar.siardsuite.view.RootStage; import ch.admin.bar.siardsuite.view.skins.CustomStepperSkin; import ch.admin.bar.siardsuite.view.skins.CustomStepperToggleSkin; @@ -18,6 +19,7 @@ import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -37,7 +39,6 @@ public void injectStepper(MFXStepper stepper) { } protected void createStepper(List steps, MFXStepper stepper) { - boolean recentConnection = controller.getTempConnectionData().isPresent(); List stepperToggles = createSteps(steps, stepper); stepper.getStepperToggles().addAll(stepperToggles); @@ -47,11 +48,15 @@ protected void createStepper(List steps, MFXStepper stepper) { stepper.next(); } - if (recentConnection) { - stepper.getStepperToggles().get(0).setState(StepperToggleState.COMPLETED); - stepper.updateProgress(); - stepper.next(); - } + controller.getTempConnectionData() + .ifPresent(dbmsConnectionData -> { + stepper.getStepperToggles().get(0).setState(StepperToggleState.COMPLETED); + stepper.updateProgress(); + stepper.next(); + stepper.fireEvent(new SiardEvent.DbmsSelectedEvent( + dbmsConnectionData.getDbms(), + Optional.of(dbmsConnectionData.getProperties()))); + }); } private List createSteps(List steps, MFXStepper stepper) { diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveAbortDialogPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveAbortDialogPresenter.java index 16c2a923..5afbeca7 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveAbortDialogPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveAbortDialogPresenter.java @@ -4,13 +4,19 @@ import ch.admin.bar.siardsuite.component.CloseDialogButton; import ch.admin.bar.siardsuite.model.View; import ch.admin.bar.siardsuite.presenter.DialogPresenter; +import ch.admin.bar.siardsuite.presenter.archive.browser.dialogues.UnsavedChangesDialogPresenter; import ch.admin.bar.siardsuite.util.I18n; +import ch.admin.bar.siardsuite.util.fxml.FXMLLoadHelper; +import ch.admin.bar.siardsuite.util.fxml.LoadedFxml; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import javafx.fxml.FXML; import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.scene.text.Text; +import lombok.val; + +import java.util.function.Consumer; import static ch.admin.bar.siardsuite.util.I18n.bind; @@ -57,4 +63,10 @@ private void addDialogButtons(Controller controller, RootStage stage) { buttonBox.getChildren().addAll(proceedArchiveButton, cancelArchiveButton); } + public static LoadedFxml load(final Controller controller, final RootStage stage) { + val loaded = FXMLLoadHelper.load("ch/admin/bar/siardsuite/fxml/archive/archive-abort-dialog.fxml"); + loaded.getController().init(controller, stage); + + return loaded; + } } diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveChooseDbmsPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveChooseDbmsPresenter.java index ed8904ec..37379130 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveChooseDbmsPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveChooseDbmsPresenter.java @@ -19,6 +19,8 @@ import javafx.scene.text.Text; import lombok.val; +import java.util.Optional; + import static ch.admin.bar.siardsuite.component.ButtonBox.Type.DEFAULT; public class ArchiveChooseDbmsPresenter extends StepperPresenter { @@ -81,13 +83,13 @@ private void setListeners(MFXStepper stepper) { this.errorMessage.setVisible(false); stepper.next(); - stepper.fireEvent(new SiardEvent.DbmsSelectedEvent(selectedDbms)); + stepper.fireEvent(new SiardEvent.DbmsSelectedEvent(selectedDbms, Optional.empty())); } else { this.errorMessage.setVisible(true); } }); this.buttonsBox.previous().setOnAction((event) -> stage.openDialog(View.ARCHIVE_DB_DIALOG)); - this.buttonsBox.cancel().setOnAction((event) -> stage.openDialog(View.ARCHIVE_ABORT_DIALOG)); + this.buttonsBox.cancel().setOnAction((event) -> stage.openAbortArchivingDialog()); } } diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveConnectionPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveConnectionPresenter.java index 0d27ae07..7c13914b 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveConnectionPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveConnectionPresenter.java @@ -18,7 +18,10 @@ import ch.admin.bar.siardsuite.util.CastHelper; import ch.admin.bar.siardsuite.util.I18n; import ch.admin.bar.siardsuite.util.SiardEvent; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.DbConnection; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; +import ch.admin.bar.siardsuite.util.i18n.DisplayableText; +import ch.admin.bar.siardsuite.util.i18n.keys.I18nKey; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import io.github.palexdev.materialfx.controls.MFXStepper; @@ -39,6 +42,12 @@ public class ArchiveConnectionPresenter extends StepperPresenter { + private static final I18nKey TITLE = I18nKey.of("connection.view.title"); + private static final I18nKey SUBTITLE_LEFT = I18nKey.of("connection.view.subtitleLeft"); + private static final I18nKey SUBTITLE_RIGHT = I18nKey.of("connection.view.subtitleRight"); + private static final I18nKey TEXT_LEFT = I18nKey.of("connection.view.textLeft"); + private static final I18nKey TEXT_RIGHT = I18nKey.of("connection.view.textRight"); + @FXML public Text title; @FXML @@ -105,11 +114,11 @@ public void init(Controller controller, RootStage stage, MFXStepper stepper) { } private void addTextWithStyles() { - I18n.bind(title.textProperty(), "connection.view.title"); - I18n.bind(subtitleLeft.textProperty(), "connection.view.subtitleLeft"); - I18n.bind(subtitleRight.textProperty(), "connection.view.subtitleRight"); - I18n.bind(textLeft.textProperty(), "connection.view.textLeft"); - I18n.bind(textRight.textProperty(), "connection.view.textRight"); + title.textProperty().bind(DisplayableText.of(TITLE).bindable()); + subtitleLeft.textProperty().bind(DisplayableText.of(SUBTITLE_LEFT).bindable()); + subtitleRight.textProperty().bind(DisplayableText.of(SUBTITLE_RIGHT).bindable()); + textLeft.textProperty().bind(DisplayableText.of(TEXT_LEFT).bindable()); + textRight.textProperty().bind(DisplayableText.of(TEXT_RIGHT).bindable()); for (int i = 0; i < textFlow.getChildren().size(); i++) { Text text = (Text) textFlow.getChildren().get(i); @@ -125,9 +134,9 @@ private void addFormText() { I18n.bind(connectionLabel.textProperty(), "archiveConnection.view.connectionName.label"); } - private ConnectionPropertiesForm getConnectionPropertiesForm( - final Dbms dbms, - final Optional> initialValue + private ConnectionPropertiesForm getConnectionPropertiesForm( + final Dbms dbms, + final Optional> initialValue ) { if (dbms instanceof ServerBasedDbms) { return new ServerBasedDbmsConnectionPropertiesForm( @@ -144,19 +153,13 @@ private ConnectionPropertiesForm getConnectionPropertiesForm( throw new IllegalArgumentException("Unsupported DBMS: " + dbms); } - private void handleConnectionPropertiesForm() { - connectionPropertiesForm = controller.popTempConnectionData() - .map(dbmsConnectionData -> getConnectionPropertiesForm(dbmsConnectionData.getDbms(), Optional.of(dbmsConnectionData.getProperties()))) - .orElseGet(() -> getConnectionPropertiesForm(event.getSelectedDbms(), Optional.empty())); - - HBox.setHgrow(connectionPropertiesForm, Priority.ALWAYS); - formContainer.getChildren().clear(); - formContainer.getChildren().add(connectionPropertiesForm); - } - private void setListeners(MFXStepper stepper) { stepper.addEventHandler(SiardEvent.UPDATE_STEPPER_DBTYPE_EVENT, event -> { + connectionPropertiesForm = this.getConnectionPropertiesForm(event.getSelectedDbms(), event.getProperties()); + HBox.setHgrow(connectionPropertiesForm, Priority.ALWAYS); + formContainer.getChildren().clear(); + formContainer.getChildren().add(connectionPropertiesForm); }); toggleSave.setOnAction(event -> { @@ -170,7 +173,7 @@ private void setListeners(MFXStepper stepper) { connectionPropertiesForm.tryGetValidConnectionData() .ifPresent(connectionData -> { if (toggleSave.isSelected()) { - UserPreferences.push(UserPreferences.DbConnection.from( + UserPreferences.push(DbConnection.from( connectionData, connectionName.getText(), urlField.getText() diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveDownloadPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveDownloadPresenter.java index 3af3e5e0..a68e38c4 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveDownloadPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveDownloadPresenter.java @@ -3,7 +3,12 @@ import ch.admin.bar.siard2.api.Archive; import ch.admin.bar.siard2.api.primary.ArchiveImpl; import ch.admin.bar.siardsuite.Controller; -import ch.admin.bar.siardsuite.component.*; +import ch.admin.bar.siardsuite.component.ButtonBox; +import ch.admin.bar.siardsuite.component.Icon; +import ch.admin.bar.siardsuite.component.IconView; +import ch.admin.bar.siardsuite.component.LabelIcon; +import ch.admin.bar.siardsuite.component.Spinner; +import ch.admin.bar.siardsuite.component.SystemFileBrowser; import ch.admin.bar.siardsuite.database.model.LoadDatabaseInstruction; import ch.admin.bar.siardsuite.model.Failure; import ch.admin.bar.siardsuite.model.View; @@ -30,11 +35,12 @@ import java.io.File; import java.io.IOException; import java.net.URI; -import java.sql.SQLException; import java.time.LocalDate; import java.util.concurrent.atomic.AtomicInteger; -import static ch.admin.bar.siardsuite.component.ButtonBox.Type.*; +import static ch.admin.bar.siardsuite.component.ButtonBox.Type.CANCEL; +import static ch.admin.bar.siardsuite.component.ButtonBox.Type.DOWNLOAD_FINISHED; +import static ch.admin.bar.siardsuite.component.ButtonBox.Type.TO_START; import static ch.admin.bar.siardsuite.model.View.START; import static ch.admin.bar.siardsuite.util.SiardEvent.DATABASE_DOWNLOADED; import static ch.admin.bar.siardsuite.util.SiardEvent.ERROR_OCCURED; @@ -131,23 +137,20 @@ private EventHandler downloadAndArchiveDatabase(MFXStepper stepper) this.openLink.setOnMouseClicked(openArchiveDirectory(targetArchive)); this.archivePath.setText(targetArchive.getAbsolutePath()); this.subtitle1.setText(this.databaseName); - try { - controller.loadDatabase(LoadDatabaseInstruction.builder() - .connectionData(null) // TODO FIXME - .loadOnlyMetadata(true) - .onSuccess(successEvent -> handleDownloadSuccess(stepper).handle(successEvent)) - .onFailure(failureEvent -> handleDownloadFailure(stepper).handle(failureEvent)) - .onProgress((observable, oldValue, newValue) -> progressBar.progressProperty().set(newValue.doubleValue())) - .onSingleValueCompleted((observable, oldValue, newValue) -> { - AtomicInteger pos = new AtomicInteger(); - newValue.forEach(p -> addLoadingData(p.getKey(), p.getValue(), pos.getAndIncrement())); - }) - .build()); - event.consume(); - } catch (SQLException e) { - fail(stepper, e, ERROR_OCCURED); - } + controller.loadDatabase(LoadDatabaseInstruction.builder() + .connectionData(null) // TODO FIXME + .loadOnlyMetadata(true) + .onSuccess(successEvent -> handleDownloadSuccess(stepper).handle(successEvent)) + .onFailure(failureEvent -> handleDownloadFailure(stepper).handle(failureEvent)) + .onProgress((observable, oldValue, newValue) -> progressBar.progressProperty().set(newValue.doubleValue())) + .onSingleValueCompleted((observable, oldValue, newValue) -> { + AtomicInteger pos = new AtomicInteger(); + newValue.forEach(p -> addLoadingData(p.getKey(), p.getValue(), pos.getAndIncrement())); + }) + .build()); + + event.consume(); } }; } @@ -171,7 +174,6 @@ private EventHandler handleDownloadSuccess(MFXStepper stepper) I18n.bind(resultTitle.textProperty(), "archiveDownload.view.title.success"); resultTitle.getStyleClass().setAll("ok-circle-icon", "h2", "label-icon-left"); setResultData(); - controller.closeDbConnection(); stepper.fireEvent(new SiardEvent(DATABASE_DOWNLOADED)); this.buttonsBox = new ButtonBox().make(DOWNLOAD_FINISHED); addButtons(stepper); @@ -193,7 +195,6 @@ private EventHandler handleDownloadFailure(MFXStepper stepper) I18n.bind(resultTitle.textProperty(), "archiveDownload.view.title.failed"); I18n.bind(recordsLoaded.textProperty(), "archiveDownload.view.message.failed"); resultTitle.getStyleClass().setAll("x-circle-icon", "h2", "label-icon-left"); - controller.closeDbConnection(); this.buttonsBox = new ButtonBox().make(TO_START); fail(stepper, e.getSource().getException(), ERROR_OCCURED); addButtons(stepper); diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveRecentConnectionsDialogPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveRecentConnectionsDialogPresenter.java index 21c2b420..6c2791b5 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveRecentConnectionsDialogPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/archive/ArchiveRecentConnectionsDialogPresenter.java @@ -5,7 +5,8 @@ import ch.admin.bar.siardsuite.model.View; import ch.admin.bar.siardsuite.presenter.DialogPresenter; import ch.admin.bar.siardsuite.util.I18n; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.DbConnection; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import javafx.fxml.FXML; @@ -19,8 +20,8 @@ import java.util.prefs.Preferences; import java.util.stream.Collectors; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.STORAGE_DATE; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.DATABASE_CONNECTION; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.STORAGE_DATE; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.DATABASE_CONNECTION; public class ArchiveRecentConnectionsDialogPresenter extends DialogPresenter { @@ -83,7 +84,7 @@ private void showNoRecentConnections() { label.setStyle("-fx-text-fill: #2a2a2a82"); } - private HBox getRecentConnectionsBox(final UserPreferences.StorageData storedConnection) { + private HBox getRecentConnectionsBox(final UserPreferences.StorageData storedConnection) { val imageLabel = new Label(); imageLabel.getStyleClass().add("link-icon"); @@ -127,7 +128,7 @@ private HBox getRecentConnectionsBox(String connectionName) { return recentConnectionsBox; } - private void showRecentConnection(final UserPreferences.StorageData storedConnection) { + private void showRecentConnection(final UserPreferences.StorageData storedConnection) { controller.setTempConnectionData(storedConnection.getStoredData().tryMapToDbmsConnectionData()); stage.closeDialog(); stage.navigate(View.ARCHIVE_STEPPER); diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/open/OpenSiardArchiveDialogPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/open/OpenSiardArchiveDialogPresenter.java index d42b5468..c94895a2 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/open/OpenSiardArchiveDialogPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/open/OpenSiardArchiveDialogPresenter.java @@ -10,7 +10,7 @@ import ch.admin.bar.siardsuite.presenter.DialogPresenter; import ch.admin.bar.siardsuite.util.I18n; import ch.admin.bar.siardsuite.util.SiardEvent; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import javafx.event.ActionEvent; @@ -35,10 +35,10 @@ import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.ABSOLUTE_PATH; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.TIMESTAMP; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.RECENT_FILES; -import static ch.admin.bar.siardsuite.util.UserPreferences.sortedChildrenNames; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.ABSOLUTE_PATH; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.TIMESTAMP; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.RECENT_FILES; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.sortedChildrenNames; public class OpenSiardArchiveDialogPresenter extends DialogPresenter { diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/option/OptionDialogPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/option/OptionDialogPresenter.java index 29dc3415..60ecccc1 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/option/OptionDialogPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/option/OptionDialogPresenter.java @@ -5,7 +5,7 @@ import ch.admin.bar.siardsuite.component.DialogButton; import ch.admin.bar.siardsuite.presenter.DialogPresenter; import ch.admin.bar.siardsuite.util.I18n; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import javafx.fxml.FXML; @@ -15,9 +15,9 @@ import java.util.prefs.Preferences; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.LOGIN_TIMEOUT; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.QUERY_TIMEOUT; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.OPTIONS; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.LOGIN_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.QUERY_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.OPTIONS; public class OptionDialogPresenter extends DialogPresenter { diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadConnectionPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadConnectionPresenter.java index 2acc7522..89fc2e73 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadConnectionPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadConnectionPresenter.java @@ -12,7 +12,7 @@ import ch.admin.bar.siardsuite.presenter.ValidationProperty; import ch.admin.bar.siardsuite.util.I18n; import ch.admin.bar.siardsuite.util.SiardEvent; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import io.github.palexdev.materialfx.controls.MFXStepper; @@ -39,13 +39,13 @@ import java.util.prefs.Preferences; import static ch.admin.bar.siardsuite.component.ButtonBox.Type.DEFAULT; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.CONNECTION_URL; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.DATABASE_NAME; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.DATABASE_SERVER; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.DATABASE_SYSTEM; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.PORT_NUMBER; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.USER_NAME; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.DATABASE_CONNECTION; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.CONNECTION_URL; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.DATABASE_NAME; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.DATABASE_SERVER; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.DATABASE_SYSTEM; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.PORT_NUMBER; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.USER_NAME; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.DATABASE_CONNECTION; public class UploadConnectionPresenter extends StepperPresenter { diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadDbDialogPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadDbDialogPresenter.java index d3f3509f..f5590e8f 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadDbDialogPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadDbDialogPresenter.java @@ -5,7 +5,7 @@ import ch.admin.bar.siardsuite.model.View; import ch.admin.bar.siardsuite.presenter.DialogPresenter; import ch.admin.bar.siardsuite.util.I18n; -import ch.admin.bar.siardsuite.util.UserPreferences; +import ch.admin.bar.siardsuite.util.preferences.UserPreferences; import ch.admin.bar.siardsuite.view.RootStage; import io.github.palexdev.materialfx.controls.MFXButton; import javafx.fxml.FXML; @@ -20,10 +20,10 @@ import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.STORAGE_DATE; -import static ch.admin.bar.siardsuite.util.UserPreferences.KeyIndex.TIMESTAMP; -import static ch.admin.bar.siardsuite.util.UserPreferences.NodePath.DATABASE_CONNECTION; -import static ch.admin.bar.siardsuite.util.UserPreferences.sortedChildrenNames; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.STORAGE_DATE; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.TIMESTAMP; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.DATABASE_CONNECTION; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.sortedChildrenNames; public class UploadDbDialogPresenter extends DialogPresenter { diff --git a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadingPresenter.java b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadingPresenter.java index 8e54c892..736a3a89 100644 --- a/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadingPresenter.java +++ b/src/main/java/ch/admin/bar/siardsuite/presenter/upload/UploadingPresenter.java @@ -5,6 +5,7 @@ import ch.admin.bar.siardsuite.component.IconView; import ch.admin.bar.siardsuite.component.LabelIcon; import ch.admin.bar.siardsuite.component.Spinner; +import ch.admin.bar.siardsuite.database.model.UploadDatabaseInstruction; import ch.admin.bar.siardsuite.model.Failure; import ch.admin.bar.siardsuite.presenter.StepperPresenter; import ch.admin.bar.siardsuite.util.I18n; @@ -13,6 +14,7 @@ import io.github.palexdev.materialfx.controls.MFXButton; import io.github.palexdev.materialfx.controls.MFXProgressBar; import io.github.palexdev.materialfx.controls.MFXStepper; +import javafx.beans.value.ChangeListener; import javafx.concurrent.WorkerStateEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; @@ -81,20 +83,26 @@ private EventHandler uploadDatabase(MFXStepper stepper) { stepper.fireEvent(new SiardEvent(UPLOAD_FAILED)); }; - try { - controller.uploadArchive(onSuccess, onFailure); - } catch (Exception e) { - fail(e, stepper); - } - - controller.addDatabaseUploadingValuePropertyListener((o, oldValue, newValue) -> { + ChangeListener onStepCompleted = (o, oldValue, newValue) -> { AtomicInteger pos1 = new AtomicInteger(); addLoadingData(newValue, pos1.getAndIncrement()); - }); - controller.addDatabaseUploadingProgressPropertyListener((o, oldValue, newValue) -> { + }; + + ChangeListener onProgress = (o, oldValue, newValue) -> { double pos = newValue.doubleValue(); progressBar.progressProperty().set(pos); - }); + }; + + controller.uploadDatabase(UploadDatabaseInstruction.builder() + // TODO FIXME connection data should be delivered by SiardEvent.class + .connectionData(controller.getTempConnectionData() + .orElseThrow(() -> new IllegalStateException("No required connection data found"))) + .onSuccess(onSuccess) + .onFailure(onFailure) + .onProgress(onProgress) + .onStepCompleted(onStepCompleted) + .build()); + event.consume(); } }; diff --git a/src/main/java/ch/admin/bar/siardsuite/util/SiardEvent.java b/src/main/java/ch/admin/bar/siardsuite/util/SiardEvent.java index 1db59827..e3fdaae3 100644 --- a/src/main/java/ch/admin/bar/siardsuite/util/SiardEvent.java +++ b/src/main/java/ch/admin/bar/siardsuite/util/SiardEvent.java @@ -1,13 +1,16 @@ package ch.admin.bar.siardsuite.util; -import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; import ch.admin.bar.siardsuite.database.model.Dbms; +import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; +import ch.admin.bar.siardsuite.database.model.DbmsConnectionProperties; import javafx.event.Event; import javafx.event.EventType; import lombok.Getter; +import java.util.Optional; + public class SiardEvent extends Event { - public static final EventType UPDATE_STEPPER_DBTYPE_EVENT; + public static final EventType> UPDATE_STEPPER_DBTYPE_EVENT; public static final EventType UPDATE_STEPPER_DBLOAD_EVENT; public static final EventType UPDATE_LANGUAGE_EVENT; public static final EventType ARCHIVE_LOADED; @@ -39,14 +42,18 @@ public SiardEvent(EventType eventType) { ERROR_OCCURED = new EventType<>("DATABASE_DOWNLOAD_FAILED"); } - public static class DbmsSelectedEvent extends Event { + public static class DbmsSelectedEvent extends Event { + + @Getter + private final Dbms selectedDbms; @Getter - private final Dbms selectedDbms; + private final Optional> properties; - public DbmsSelectedEvent(final Dbms selectedDbms) { + public DbmsSelectedEvent(final Dbms selectedDbms, Optional> properties) { super(UPDATE_STEPPER_DBTYPE_EVENT); this.selectedDbms = selectedDbms; + this.properties = properties; } } diff --git a/src/main/java/ch/admin/bar/siardsuite/util/preferences/DbConnection.java b/src/main/java/ch/admin/bar/siardsuite/util/preferences/DbConnection.java new file mode 100644 index 00000000..052c5d9a --- /dev/null +++ b/src/main/java/ch/admin/bar/siardsuite/util/preferences/DbConnection.java @@ -0,0 +1,86 @@ +package ch.admin.bar.siardsuite.util.preferences; + +import ch.admin.bar.siardsuite.database.DbmsRegistry; +import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; +import ch.admin.bar.siardsuite.database.model.DbmsId; +import ch.admin.bar.siardsuite.database.model.FileBasedDbms; +import ch.admin.bar.siardsuite.database.model.FileBasedDbmsConnectionProperties; +import ch.admin.bar.siardsuite.database.model.ServerBasedDbms; +import ch.admin.bar.siardsuite.database.model.ServerBasedDbmsConnectionProperties; +import ch.admin.bar.siardsuite.util.CastHelper; +import ch.admin.bar.siardsuite.util.OptionalHelper; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.val; + +import java.io.File; +import java.util.Optional; + +@Value +@Builder +public class DbConnection { + @NonNull String name; + + @NonNull DbmsId dbmsProduct; + @NonNull String jdbcUrl; + + @NonNull String host; + @NonNull String port; + @NonNull String dbName; + @NonNull String user; + + @NonNull String file; + + public Optional tryMapToDbmsConnectionData() { + val dbms = DbmsRegistry.findDbmsById(dbmsProduct); + + return OptionalHelper.firstPresent( + () -> CastHelper.tryCast(dbms, ServerBasedDbms.class) + .map(serverBasedDbms -> new DbmsConnectionData( + serverBasedDbms, + ServerBasedDbmsConnectionProperties.builder() + .host(host) + .port(port) + .dbName(dbName) + .user(user) + .password("") + .build() + )), + () -> CastHelper.tryCast(dbms, FileBasedDbms.class) + .map(fileBasedDbms -> new DbmsConnectionData( + fileBasedDbms, + new FileBasedDbmsConnectionProperties(new File(file)) + )) + ); + } + + public static DbConnection from( + final DbmsConnectionData connectionData, + final String name, + final String jdbcUrl + ) { + + val serverBasedProp = CastHelper.tryCast( + connectionData.getProperties(), + ServerBasedDbmsConnectionProperties.class); + + val fileBasedProp = CastHelper.tryCast( + connectionData.getProperties(), + FileBasedDbmsConnectionProperties.class); + + return DbConnection.builder() + .name(name) + .dbmsProduct(connectionData.getDbms().getId()) + .jdbcUrl(jdbcUrl) + + .host(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getHost).orElse("")) + .port(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getPort).orElse("")) + .dbName(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getDbName).orElse("")) + .user(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getUser).orElse("")) + + .file(fileBasedProp.map(prop -> prop.getFile().getAbsolutePath()).orElse("")) + + .build(); + } +} diff --git a/src/main/java/ch/admin/bar/siardsuite/util/preferences/Options.java b/src/main/java/ch/admin/bar/siardsuite/util/preferences/Options.java new file mode 100644 index 00000000..71f6b255 --- /dev/null +++ b/src/main/java/ch/admin/bar/siardsuite/util/preferences/Options.java @@ -0,0 +1,12 @@ +package ch.admin.bar.siardsuite.util.preferences; + +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; + +@Value +@Builder +public class Options { + @NonNull Integer loginTimeout; + @NonNull Integer queryTimeout; +} diff --git a/src/main/java/ch/admin/bar/siardsuite/util/UserPreferences.java b/src/main/java/ch/admin/bar/siardsuite/util/preferences/UserPreferences.java similarity index 67% rename from src/main/java/ch/admin/bar/siardsuite/util/UserPreferences.java rename to src/main/java/ch/admin/bar/siardsuite/util/preferences/UserPreferences.java index c4026ad7..1a8863c5 100644 --- a/src/main/java/ch/admin/bar/siardsuite/util/UserPreferences.java +++ b/src/main/java/ch/admin/bar/siardsuite/util/preferences/UserPreferences.java @@ -1,31 +1,27 @@ -package ch.admin.bar.siardsuite.util; +package ch.admin.bar.siardsuite.util.preferences; -import ch.admin.bar.siardsuite.database.DbmsRegistry; -import ch.admin.bar.siardsuite.database.model.DbmsConnectionData; import ch.admin.bar.siardsuite.database.model.DbmsId; -import ch.admin.bar.siardsuite.database.model.FileBasedDbms; -import ch.admin.bar.siardsuite.database.model.FileBasedDbmsConnectionProperties; -import ch.admin.bar.siardsuite.database.model.ServerBasedDbms; -import ch.admin.bar.siardsuite.database.model.ServerBasedDbmsConnectionProperties; +import ch.admin.bar.siardsuite.util.I18n; import lombok.Builder; -import lombok.NonNull; import lombok.Value; import lombok.extern.slf4j.Slf4j; import lombok.val; -import java.io.File; import java.time.Clock; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; -import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; import java.util.stream.Collectors; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.LOGIN_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.KeyIndex.QUERY_TIMEOUT; +import static ch.admin.bar.siardsuite.util.preferences.UserPreferences.NodePath.OPTIONS; + @Slf4j public class UserPreferences { @@ -91,6 +87,15 @@ public static List> getStoredConnections() { } } + public static Options getStoredOptions() { + val optionsNode = node(OPTIONS); + + return Options.builder() + .queryTimeout(Integer.parseInt(optionsNode.get(QUERY_TIMEOUT.name(), "0"))) + .loginTimeout(Integer.parseInt(optionsNode.get(LOGIN_TIMEOUT.name(), "0"))) + .build(); + } + @Value @Builder public static class StorageData { @@ -99,74 +104,6 @@ public static class StorageData { T storedData; } - @Value - @Builder - public static class DbConnection { - @NonNull String name; - - @NonNull DbmsId dbmsProduct; - @NonNull String jdbcUrl; - - @NonNull String host; - @NonNull String port; - @NonNull String dbName; - @NonNull String user; - - @NonNull String file; - - public Optional tryMapToDbmsConnectionData() { - val dbms = DbmsRegistry.findDbmsById(dbmsProduct); - - return OptionalHelper.firstPresent( - () -> CastHelper.tryCast(dbms, ServerBasedDbms.class) - .map(serverBasedDbms -> new DbmsConnectionData( - serverBasedDbms, - ServerBasedDbmsConnectionProperties.builder() - .host(host) - .port(port) - .dbName(dbName) - .user(user) - .password("") - .build() - )), - () -> CastHelper.tryCast(dbms, FileBasedDbms.class) - .map(fileBasedDbms -> new DbmsConnectionData( - fileBasedDbms, - new FileBasedDbmsConnectionProperties(new File(file)) - )) - ); - } - - public static DbConnection from( - final DbmsConnectionData connectionData, - final String name, - final String jdbcUrl - ) { - - val serverBasedProp = CastHelper.tryCast( - connectionData.getProperties(), - ServerBasedDbmsConnectionProperties.class); - - val fileBasedProp = CastHelper.tryCast( - connectionData.getProperties(), - FileBasedDbmsConnectionProperties.class); - - return DbConnection.builder() - .name(name) - .dbmsProduct(connectionData.getDbms().getId()) - .jdbcUrl(jdbcUrl) - - .host(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getHost).orElse("")) - .port(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getPort).orElse("")) - .dbName(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getDbName).orElse("")) - .user(serverBasedProp.map(ServerBasedDbmsConnectionProperties::getUser).orElse("")) - - .file(fileBasedProp.map(prop -> prop.getFile().getAbsolutePath()).orElse("")) - - .build(); - } - } - public static Preferences push(NodePath nodePath, KeyIndex comparisonKeyIndex, Comparator comparator, String path) throws BackingStoreException { final List childrenNames = sortedChildrenNames(nodePath, comparisonKeyIndex, comparator); List list = new ArrayList<>(); @@ -219,7 +156,7 @@ public static List childrenNodeNamesOldestToNewest(NodePath nodePath) th val parentNode = node(nodePath); return Arrays.stream(parentNode.childrenNames()) .sorted(Comparator.comparing( - name -> Long.parseLong(parentNode.node(name).get(KeyIndex.TIMESTAMP.name(), "0")), + name -> Long.parseLong(parentNode.node(name).get(KeyIndex.TIMESTAMP.name(), "0")), Comparator.naturalOrder() )) .collect(Collectors.toList()); @@ -229,7 +166,7 @@ public static List childrenNodeNamesNewestToOldest(NodePath nodePath) th val parentNode = node(nodePath); return Arrays.stream(parentNode.childrenNames()) .sorted(Comparator.comparing( - name -> Long.parseLong(parentNode.node(name).get(KeyIndex.TIMESTAMP.name(), "0")), + name -> Long.parseLong(parentNode.node(name).get(KeyIndex.TIMESTAMP.name(), "0")), Comparator.reverseOrder() )) .collect(Collectors.toList()); diff --git a/src/main/java/ch/admin/bar/siardsuite/view/RootStage.java b/src/main/java/ch/admin/bar/siardsuite/view/RootStage.java index 6a5adbf0..db4bcb4f 100644 --- a/src/main/java/ch/admin/bar/siardsuite/view/RootStage.java +++ b/src/main/java/ch/admin/bar/siardsuite/view/RootStage.java @@ -5,6 +5,7 @@ import ch.admin.bar.siardsuite.component.rendering.TreeItemsExplorer; import ch.admin.bar.siardsuite.model.Failure; import ch.admin.bar.siardsuite.presenter.ErrorDialogPresenter; +import ch.admin.bar.siardsuite.presenter.archive.ArchiveAbortDialogPresenter; import ch.admin.bar.siardsuite.presenter.archive.browser.dialogues.UnsavedChangesDialogPresenter; import ch.admin.bar.siardsuite.model.TreeAttributeWrapper; import ch.admin.bar.siardsuite.model.View; @@ -71,6 +72,13 @@ public void openDialog(View view) { dialogPane.setVisible(true); } + public void openAbortArchivingDialog() { + val loaded = ArchiveAbortDialogPresenter.load(controller, this); + + dialogPane.setCenter(loaded.getNode()); + dialogPane.setVisible(true); + } + @Override public void openErrorDialog(final Throwable e) { val loaded = ErrorDialogPresenter.load(new Failure(e), this::closeDialog);