From 2bbc3e5834284214c57d6862daa8613ae726bb44 Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Thu, 12 Sep 2019 17:01:50 +0200 Subject: [PATCH] Refactored adding vaults --- .../org/cryptomator/common/CommonsModule.java | 15 ++---- .../vaults/VaultListChangeListener.java | 2 +- ...aultFactory.java => VaultListManager.java} | 48 ++++++++++++++++--- .../ChooseExistingVaultController.java | 34 ++++++------- .../CreateNewVaultPasswordController.java | 37 +++++++------- .../ui/controllers/MainController.java | 17 ++++--- .../ui/launcher/AppLaunchEventHandler.java | 31 ++++++------ .../ui/mainwindow/MainWindowController.java | 45 ++++++++--------- .../ui/mainwindow/VaultListController.java | 2 +- 9 files changed, 130 insertions(+), 101 deletions(-) rename main/commons/src/main/java/org/cryptomator/common/vaults/{VaultFactory.java => VaultListManager.java} (51%) diff --git a/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java index 7742cd90b..5d86ca6ce 100644 --- a/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java +++ b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java @@ -10,16 +10,13 @@ import dagger.Module; import dagger.Provides; import javafx.beans.binding.Binding; import javafx.beans.binding.Bindings; -import javafx.collections.FXCollections; import javafx.collections.ObservableList; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.SettingsProvider; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultComponent; -import org.cryptomator.common.vaults.VaultFactory; -import org.cryptomator.common.vaults.VaultListChangeListener; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.frontend.webdav.WebDavServer; import org.fxmisc.easybind.EasyBind; @@ -53,14 +50,8 @@ public abstract class CommonsModule { @Provides @Singleton - static ObservableList provideVaultList(Settings settings, VaultFactory vaultFactory) { - ObservableList list = FXCollections.observableArrayList(Vault::observables); - for (VaultSettings s : settings.getDirectories()) { - Vault v = vaultFactory.get(s); - list.add(v); - } - list.addListener(new VaultListChangeListener(settings.getDirectories())); - return list; + static ObservableList provideVaultList(VaultListManager vaultListManager) { + return vaultListManager.getVaultList(); } @Provides diff --git a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListChangeListener.java b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListChangeListener.java index 674615d34..147d6cc45 100644 --- a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListChangeListener.java +++ b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListChangeListener.java @@ -10,7 +10,7 @@ import java.util.stream.Collectors; /** * This listener makes sure to reflect any changes to the vault list back to the settings. */ -public class VaultListChangeListener implements ListChangeListener { +class VaultListChangeListener implements ListChangeListener { private final ObservableList vaultSettingsList; diff --git a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultFactory.java b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListManager.java similarity index 51% rename from main/commons/src/main/java/org/cryptomator/common/vaults/VaultFactory.java rename to main/commons/src/main/java/org/cryptomator/common/vaults/VaultListManager.java index da8361723..3bb3496b8 100644 --- a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultFactory.java +++ b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultListManager.java @@ -8,6 +8,9 @@ *******************************************************************************/ package org.cryptomator.common.vaults; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.cryptofs.migration.Migrators; @@ -15,25 +18,56 @@ import org.cryptomator.cryptofs.migration.Migrators; import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Collectors; @Singleton -public class VaultFactory { +public class VaultListManager { private static final String MASTERKEY_FILENAME = "masterkey.cryptomator"; // TODO: deduplicate constant declared in multiple classes private final VaultComponent.Builder vaultComponentBuilder; - private final ConcurrentMap vaults = new ConcurrentHashMap<>(); + private final ObservableList vaultList; @Inject - public VaultFactory(VaultComponent.Builder vaultComponentBuilder) { + public VaultListManager(VaultComponent.Builder vaultComponentBuilder, Settings settings) { this.vaultComponentBuilder = vaultComponentBuilder; + this.vaultList = FXCollections.observableArrayList(Vault::observables); + + addAll(settings.getDirectories()); + vaultList.addListener(new VaultListChangeListener(settings.getDirectories())); } - public Vault get(VaultSettings vaultSettings) { - return vaults.computeIfAbsent(vaultSettings, this::create); + public ObservableList getVaultList() { + return vaultList; + } + + public Vault add(Path pathToVault) throws NoSuchFileException { + if (!CryptoFileSystemProvider.containsVault(pathToVault, MASTERKEY_FILENAME)) { + throw new NoSuchFileException(pathToVault.toString(), null, "Not a vault directory"); + } + Optional alreadyExistingVault = get(pathToVault); + if (alreadyExistingVault.isPresent()) { + return alreadyExistingVault.get(); + } else { + VaultSettings vaultSettings = VaultSettings.withRandomId(); + vaultSettings.path().set(pathToVault); + Vault newVault = create(vaultSettings); + vaultList.add(newVault); + return newVault; + } + } + + private void addAll(Collection vaultSettings) { + Collection vaults = vaultSettings.stream().map(this::create).collect(Collectors.toList()); + vaultList.addAll(vaults); + } + + private Optional get(Path vaultPath) { + return vaultList.stream().filter(v -> v.getPath().equals(vaultPath)).findAny(); } private Vault create(VaultSettings vaultSettings) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 7a11ee303..38776d308 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,44 +2,45 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import javafx.beans.property.ObjectProperty; -import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.stage.FileChooser; import javafx.stage.Stage; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultFactory; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.io.File; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.ResourceBundle; @AddVaultWizardScoped public class ChooseExistingVaultController implements FxController { + private static final Logger LOG = LoggerFactory.getLogger(ChooseExistingVaultController.class); + private final Stage window; private final Lazy welcomeScene; private final Lazy successScene; private final ObjectProperty vaultPath; - private final ObservableList vaults; private final ObjectProperty vault; - private final VaultFactory vaultFactory; + private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; @Inject - ChooseExistingVaultController(@AddVaultWizard Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, ObjectProperty vaultPath, ObservableList vaults, @AddVaultWizard ObjectProperty vault, VaultFactory vaultFactory, ResourceBundle resourceBundle) { + ChooseExistingVaultController(@AddVaultWizard Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, ObjectProperty vaultPath, @AddVaultWizard ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle) { this.window = window; this.welcomeScene = welcomeScene; this.successScene = successScene; this.vaultPath = vaultPath; - this.vaults = vaults; this.vault = vault; - this.vaultFactory = vaultFactory; + this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; } @@ -54,16 +55,17 @@ public class ChooseExistingVaultController implements FxController { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle(resourceBundle.getString("addvaultwizard.existing.filePickerTitle")); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("Cryptomator Masterkey", "*.cryptomator")); - final File file = fileChooser.showOpenDialog(window); + File file = fileChooser.showOpenDialog(window); if (file != null) { vaultPath.setValue(file.toPath().toAbsolutePath().getParent()); - VaultSettings vaultSettings = VaultSettings.withRandomId(); - vaultSettings.path().setValue(vaultPath.get()); - Vault newVault = vaultFactory.get(vaultSettings); - vaults.add(newVault); - vault.set(newVault); - //TODO: error handling? - window.setScene(successScene.get()); + try { + Vault newVault = vaultListManager.add(vaultPath.get()); + vault.set(newVault); + window.setScene(successScene.get()); + } catch (NoSuchFileException e) { + LOG.error("Nope", e); + // TODO + } } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java b/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java index e0bde4514..0a3a77b3a 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/addvaultwizard/CreateNewVaultPasswordController.java @@ -10,7 +10,6 @@ import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.StringProperty; -import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.control.CheckBox; @@ -18,9 +17,8 @@ import javafx.scene.control.ContentDisplay; import javafx.scene.control.Label; import javafx.scene.layout.HBox; import javafx.stage.Stage; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultFactory; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.cryptofs.CryptoFileSystemProperties; import org.cryptomator.cryptofs.CryptoFileSystemProvider; import org.cryptomator.ui.common.FxController; @@ -36,10 +34,12 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.channels.WritableByteChannel; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileSystem; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.Collections; @@ -60,9 +60,8 @@ public class CreateNewVaultPasswordController implements FxController { private final ExecutorService executor; private final StringProperty vaultName; private final ObjectProperty vaultPath; - private final ObservableList vaults; private final ObjectProperty vault; - private final VaultFactory vaultFactory; + private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; private final PasswordStrengthUtil strengthRater; private final ReadmeGenerator readmeGenerator; @@ -81,16 +80,15 @@ public class CreateNewVaultPasswordController implements FxController { public CheckBox finalConfirmationCheckbox; @Inject - CreateNewVaultPasswordController(@AddVaultWizard Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, ExecutorService executor, StringProperty vaultName, ObjectProperty vaultPath, ObservableList vaults, @AddVaultWizard ObjectProperty vault, VaultFactory vaultFactory, ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, ReadmeGenerator readmeGenerator) { + CreateNewVaultPasswordController(@AddVaultWizard Stage window, @FxmlScene(FxmlFile.ADDVAULT_NEW_LOCATION) Lazy chooseLocationScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, ExecutorService executor, StringProperty vaultName, ObjectProperty vaultPath, @AddVaultWizard ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, PasswordStrengthUtil strengthRater, ReadmeGenerator readmeGenerator) { this.window = window; this.chooseLocationScene = chooseLocationScene; this.successScene = successScene; this.executor = executor; this.vaultName = vaultName; this.vaultPath = vaultPath; - this.vaults = vaults; this.vault = vault; - this.vaultFactory = vaultFactory; + this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; this.strengthRater = strengthRater; this.readmeGenerator = readmeGenerator; @@ -127,8 +125,10 @@ public class CreateNewVaultPasswordController implements FxController { @FXML public void next() { + Path pathToVault = vaultPath.get(); + try { - Files.createDirectory(vaultPath.get()); + Files.createDirectory(pathToVault); } catch (FileAlreadyExistsException e) { LOG.error("Vault dir already exists.", e); window.setScene(chooseLocationScene.get()); @@ -139,14 +139,9 @@ public class CreateNewVaultPasswordController implements FxController { processing.set(true); Tasks.create(() -> { - initializeVault(vaultPath.get(), passwordField.getCharacters()); + initializeVault(pathToVault, passwordField.getCharacters()); }).onSuccess(() -> { - VaultSettings vaultSettings = VaultSettings.withRandomId(); - vaultSettings.path().setValue(vaultPath.get()); - Vault newVault = vaultFactory.get(vaultSettings); - vault.set(newVault); - vaults.add(newVault); - window.setScene(successScene.get()); + initializationSucceeded(pathToVault); }).onError(IOException.class, e -> { // TODO show generic error screen LOG.error("", e); @@ -175,6 +170,16 @@ public class CreateNewVaultPasswordController implements FxController { } LOG.info("Created vault at {}", path); } + + private void initializationSucceeded(Path pathToVault) { + try { + Vault newVault = vaultListManager.add(pathToVault); + vault.set(newVault); + window.setScene(successScene.get()); + } catch (NoSuchFileException e) { + throw new UncheckedIOException(e); + } + } /* Getter/Setter */ diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java index 864c17648..1430127ae 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/MainController.java @@ -46,14 +46,13 @@ import javafx.util.Duration; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.vaults.VaultState; import org.cryptomator.ui.fxapp.FxApplicationScoped; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.ui.ExitUtil; import org.cryptomator.ui.controls.DirectoryListCell; import org.cryptomator.ui.l10n.Localization; import org.cryptomator.ui.launcher.AppLaunchEvent; import org.cryptomator.ui.model.AutoUnlocker; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultFactory; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.model.upgrade.UpgradeStrategies; import org.cryptomator.ui.model.upgrade.UpgradeStrategy; import org.cryptomator.ui.util.DialogBuilderUtil; @@ -70,7 +69,9 @@ import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.UncheckedIOException; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.HashMap; import java.util.List; @@ -94,7 +95,7 @@ public class MainController implements ViewController { private final Localization localization; private final ExecutorService executorService; private final BlockingQueue launchEventQueue; - private final VaultFactory vaultFactoy; + private final VaultListManager vaultFactoy; private final ViewControllerLoader viewControllerLoader; private final ObjectProperty activeController = new SimpleObjectProperty<>(); private final ObservableList vaults; @@ -111,7 +112,7 @@ public class MainController implements ViewController { @Inject public MainController(@Named("mainWindow") Stage mainWindow, ExecutorService executorService, @Named("launchEventQueue") BlockingQueue launchEventQueue, ExitUtil exitUtil, Localization localization, - VaultFactory vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, ObservableList vaults, AutoUnlocker autoUnlocker) { + VaultListManager vaultFactoy, ViewControllerLoader viewControllerLoader, UpgradeStrategies upgradeStrategies, ObservableList vaults, AutoUnlocker autoUnlocker) { this.mainWindow = mainWindow; this.executorService = executorService; this.launchEventQueue = launchEventQueue; @@ -344,9 +345,11 @@ public class MainController implements ViewController { } final Vault vault = vaults.stream().filter(v -> v.getPath().equals(vaultPath)).findAny().orElseGet(() -> { - VaultSettings vaultSettings = VaultSettings.withRandomId(); - vaultSettings.path().set(vaultPath); - return vaultFactoy.get(vaultSettings); + try { + return vaultFactoy.add(vaultPath); + } catch (NoSuchFileException e) { + throw new UncheckedIOException(e); + } }); if (!vaults.contains(vault)) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java b/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java index 43486c096..7847940cc 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java +++ b/main/ui/src/main/java/org/cryptomator/ui/launcher/AppLaunchEventHandler.java @@ -1,10 +1,7 @@ package org.cryptomator.ui.launcher; import javafx.application.Platform; -import javafx.collections.ObservableList; -import org.cryptomator.common.settings.VaultSettings; -import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultFactory; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.fxapp.FxApplication; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,6 +9,7 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; @@ -20,20 +18,19 @@ import java.util.concurrent.ExecutorService; class AppLaunchEventHandler { private static final Logger LOG = LoggerFactory.getLogger(AppLaunchEventHandler.class); + private static final String MASTERKEY_FILENAME = "masterkey.cryptomator"; // TODO: deduplicate constant declared in multiple classes private final BlockingQueue launchEventQueue; private final ExecutorService executorService; private final FxApplicationStarter fxApplicationStarter; - private final VaultFactory vaultFactory; - private final ObservableList vaults; + private final VaultListManager vaultListManager; @Inject - public AppLaunchEventHandler(@Named("launchEventQueue") BlockingQueue launchEventQueue, ExecutorService executorService, FxApplicationStarter fxApplicationStarter, VaultFactory vaultFactory, ObservableList vaults) { + public AppLaunchEventHandler(@Named("launchEventQueue") BlockingQueue launchEventQueue, ExecutorService executorService, FxApplicationStarter fxApplicationStarter, VaultListManager vaultListManager) { this.launchEventQueue = launchEventQueue; this.executorService = executorService; this.fxApplicationStarter = fxApplicationStarter; - this.vaultFactory = vaultFactory; - this.vaults = vaults; + this.vaultListManager = vaultListManager; } public void startHandlingLaunchEvents(boolean hasTrayIcon) { @@ -73,12 +70,16 @@ class AppLaunchEventHandler { // TODO dedup MainWindowController... private void addVault(Path potentialVaultPath) { assert Platform.isFxApplicationThread(); - // TODO CryptoFileSystemProvider.containsVault(potentialVaultPath, "masterkey.cryptomator"); - VaultSettings settings = VaultSettings.withRandomId(); - settings.path().set(potentialVaultPath); - Vault vault = vaultFactory.get(settings); - vaults.add(vault); - LOG.debug("Added vault {}", potentialVaultPath); + try { + if (potentialVaultPath.getFileName().toString().equals(MASTERKEY_FILENAME)) { + vaultListManager.add(potentialVaultPath.getParent()); + } else { + vaultListManager.add(potentialVaultPath); + } + LOG.debug("Added vault {}", potentialVaultPath); + } catch (NoSuchFileException e) { + LOG.error("Failed to add vault " + potentialVaultPath, e); + } } } diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java index 622b933ea..175de798e 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java @@ -1,7 +1,6 @@ package org.cryptomator.ui.mainwindow; import javafx.beans.binding.BooleanBinding; -import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.input.TransferMode; import javafx.scene.layout.HBox; @@ -9,9 +8,8 @@ import javafx.scene.layout.Pane; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.stage.Stage; -import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Vault; -import org.cryptomator.common.vaults.VaultFactory; +import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.common.FontLoader; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.fxapp.FxApplication; @@ -24,23 +22,26 @@ import javax.inject.Inject; import javax.inject.Named; import java.io.File; import java.nio.file.Files; +import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.util.Collection; +import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; @MainWindowScoped public class MainWindowController implements FxController { private static final String TITLE_FONT = "/css/dosis-bold.ttf"; private static final Logger LOG = LoggerFactory.getLogger(MainWindowController.class); + private static final String MASTERKEY_FILENAME = "masterkey.cryptomator"; // TODO: deduplicate constant declared in multiple classes private final Stage window; private final FxApplication application; private final boolean minimizeToSysTray; private final UpdateChecker updateChecker; private final BooleanBinding updateAvailable; - private final ObservableList vaults; - private final VaultFactory vaultFactory; + private final VaultListManager vaultListManager; private final WrongFileAlertComponent.Builder wrongFileAlert; public HBox titleBar; public VBox root; @@ -50,14 +51,13 @@ public class MainWindowController implements FxController { private double yOffset; @Inject - public MainWindowController(@MainWindow Stage window, FxApplication application, @Named("trayMenuSupported") boolean minimizeToSysTray, UpdateChecker updateChecker, ObservableList vaults, VaultFactory vaultFactory, WrongFileAlertComponent.Builder wrongFileAlert) { + public MainWindowController(@MainWindow Stage window, FxApplication application, @Named("trayMenuSupported") boolean minimizeToSysTray, UpdateChecker updateChecker, VaultListManager vaultListManager, WrongFileAlertComponent.Builder wrongFileAlert) { this.window = window; this.application = application; this.minimizeToSysTray = minimizeToSysTray; this.updateChecker = updateChecker; this.updateAvailable = updateChecker.latestVersionProperty().isNotNull(); - this.vaults = vaults; - this.vaultFactory = vaultFactory; + this.vaultListManager = vaultListManager; this.wrongFileAlert = wrongFileAlert; } @@ -93,33 +93,26 @@ public class MainWindowController implements FxController { if (event.getGestureSource() != root && event.getDragboard().hasFiles()) { /* allow for both copying and moving, whatever user chooses */ event.acceptTransferModes(TransferMode.COPY_OR_MOVE); - Collection vaultPaths = event.getDragboard().getFiles().stream().map(File::toPath).filter(this::isVaultPath).collect(Collectors.toSet()); + Collection vaultPaths = event.getDragboard().getFiles().stream().map(File::toPath).flatMap(this::addVault).collect(Collectors.toSet()); if (vaultPaths.isEmpty()) { wrongFileAlert.build().showWrongFileAlertWindow(); - } else { - vaultPaths.forEach(this::addVault); } } event.consume(); }); } - private boolean isVaultPath(Path path) { - if (path.getFileName().toString().endsWith(".cryptomator")) { - return true; - } else if (Files.exists(path.resolve("masterkey.cryptomator"))) { - return true; - } else { - return false; + private Stream addVault(Path pathToVault) { + try { + if (pathToVault.getFileName().toString().equals(MASTERKEY_FILENAME)) { + return Stream.of(vaultListManager.add(pathToVault.getParent())); + } else { + return Stream.of(vaultListManager.add(pathToVault)); + } + } catch (NoSuchFileException e) { + LOG.debug("Not a vault: {}", pathToVault); } - } - - private void addVault(Path pathToVault) { - VaultSettings vaultSettings = VaultSettings.withRandomId(); - vaultSettings.path().setValue(pathToVault); - Vault newVault = vaultFactory.get(vaultSettings); - vaults.add(newVault); - //TODO: error handling? + return Stream.empty(); } private void loadFont(String resourcePath) { diff --git a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 12d63a025..0f9a7454d 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -56,7 +56,7 @@ public class VaultListController implements FxController { window.setIconified(false); window.show(); window.toFront(); - window.requestFocus(); + window.requestFocus(); // TODO: this beeps on macOS if there is a modal child window... } } });