From 0840695e0a3b4808a6f1f2fe26a78a63ff6a0047 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 8 Apr 2021 17:27:45 +0200 Subject: [PATCH] Refactor lock/unlock convinience methods in FxApplication: * execute vault state transition here * on failed transition show error window * only start worfklow on successful transition --- .../cryptomator/common/vaults/VaultState.java | 9 +++++++- .../cryptomator/ui/fxapp/FxApplication.java | 22 ++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultState.java b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultState.java index 8966e6f65..b9c3cc9b5 100644 --- a/main/commons/src/main/java/org/cryptomator/common/vaults/VaultState.java +++ b/main/commons/src/main/java/org/cryptomator/common/vaults/VaultState.java @@ -1,6 +1,8 @@ package org.cryptomator.common.vaults; import com.google.common.base.Preconditions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Platform; @@ -11,6 +13,8 @@ import java.util.concurrent.atomic.AtomicReference; @PerVault public class VaultState extends ObservableValueBase implements ObservableObjectValue { + private static final Logger LOG = LoggerFactory.getLogger(VaultState.class); + public enum Value { /** * No vault found at the provided path @@ -46,7 +50,7 @@ public class VaultState extends ObservableValueBase implements private final AtomicReference value; @Inject - public VaultState(VaultState.Value initialValue){ + public VaultState(VaultState.Value initialValue) { this.value = new AtomicReference<>(initialValue); } @@ -62,6 +66,7 @@ public class VaultState extends ObservableValueBase implements /** * Transitions from fromState to toState. + * * @param fromState Previous state * @param toState New state * @return true if successful @@ -71,6 +76,8 @@ public class VaultState extends ObservableValueBase implements boolean success = value.compareAndSet(fromState, toState); if (success) { fireValueChangedEvent(); + } else { + LOG.debug("Failed transiting into state {}: Expected state was {}, but actual state is {}.", fromState, toState, value.get()); } return success; } diff --git a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index d33b1171c..b0ea8da47 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -5,11 +5,13 @@ import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.UiTheme; import org.cryptomator.common.vaults.Vault; +import org.cryptomator.common.vaults.VaultState; import org.cryptomator.integrations.tray.TrayIntegrationProvider; import org.cryptomator.integrations.uiappearance.Theme; import org.cryptomator.integrations.uiappearance.UiAppearanceException; import org.cryptomator.integrations.uiappearance.UiAppearanceListener; import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; +import org.cryptomator.ui.common.ErrorComponent; import org.cryptomator.ui.common.VaultService; import org.cryptomator.ui.lock.LockComponent; import org.cryptomator.ui.mainwindow.MainWindowComponent; @@ -46,6 +48,7 @@ public class FxApplication extends Application { private final Lazy quitWindow; private final Provider unlockWorkflowBuilderProvider; private final Provider lockWorkflowBuilderProvider; + private final ErrorComponent.Builder errorWindowBuilder; private final Optional trayIntegration; private final Optional appearanceProvider; private final VaultService vaultService; @@ -55,13 +58,14 @@ public class FxApplication extends Application { private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; @Inject - FxApplication(Settings settings, Lazy mainWindow, Lazy preferencesWindow, Provider unlockWorkflowBuilderProvider, Provider lockWorkflowBuilderProvider, Lazy quitWindow, Optional trayIntegration, Optional appearanceProvider, VaultService vaultService, LicenseHolder licenseHolder) { + FxApplication(Settings settings, Lazy mainWindow, Lazy preferencesWindow, Provider unlockWorkflowBuilderProvider, Provider lockWorkflowBuilderProvider, Lazy quitWindow, ErrorComponent.Builder errorWindowBuilder, Optional trayIntegration, Optional appearanceProvider, VaultService vaultService, LicenseHolder licenseHolder) { this.settings = settings; this.mainWindow = mainWindow; this.preferencesWindow = preferencesWindow; this.unlockWorkflowBuilderProvider = unlockWorkflowBuilderProvider; this.lockWorkflowBuilderProvider = lockWorkflowBuilderProvider; this.quitWindow = quitWindow; + this.errorWindowBuilder = errorWindowBuilder; this.trayIntegration = trayIntegration; this.appearanceProvider = appearanceProvider; this.vaultService = vaultService; @@ -113,15 +117,23 @@ public class FxApplication extends Application { public void startUnlockWorkflow(Vault vault, Optional owner) { Platform.runLater(() -> { - unlockWorkflowBuilderProvider.get().vault(vault).owner(owner).build().startUnlockWorkflow(); - LOG.debug("Showing UnlockWindow for {}", vault.getDisplayName()); + if (vault.stateProperty().transition(VaultState.Value.LOCKED, VaultState.Value.PROCESSING)) { + unlockWorkflowBuilderProvider.get().vault(vault).owner(owner).build().startUnlockWorkflow(); + LOG.debug("Start unlock workflow for {}", vault.getDisplayName()); + } else { + showMainWindow().thenAccept(mainWindow -> errorWindowBuilder.window(mainWindow).cause(new IllegalStateException("Unable to unlock vault in non-locked state."))); + } }); } public void startLockWorkflow(Vault vault, Optional owner) { Platform.runLater(() -> { - lockWorkflowBuilderProvider.get().vault(vault).owner(owner).build().startLockWorkflow(); - LOG.debug("Start lock workflow for {}", vault.getDisplayName()); + if (vault.stateProperty().transition(VaultState.Value.UNLOCKED, VaultState.Value.PROCESSING)) { + lockWorkflowBuilderProvider.get().vault(vault).owner(owner).build().startLockWorkflow(); + LOG.debug("Start lock workflow for {}", vault.getDisplayName()); + } else { + showMainWindow().thenAccept(mainWindow -> errorWindowBuilder.window(mainWindow).cause(new IllegalStateException("Unable to lock vault in non-unlocked state."))); + } }); }