瀏覽代碼

Refactor lock/unlock convinience methods in FxApplication:
* execute vault state transition here
* on failed transition show error window
* only start worfklow on successful transition

Armin Schrenk 4 年之前
父節點
當前提交
0840695e0a

+ 8 - 1
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<VaultState.Value> implements ObservableObjectValue<VaultState.Value> {
 
+	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<VaultState.Value> implements
 	private final AtomicReference<Value> 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<VaultState.Value> implements
 
 	/**
 	 * Transitions from <code>fromState</code> to <code>toState</code>.
+	 *
 	 * @param fromState Previous state
 	 * @param toState New state
 	 * @return <code>true</code> if successful
@@ -71,6 +76,8 @@ public class VaultState extends ObservableValueBase<VaultState.Value> 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;
 	}

+ 17 - 5
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<QuitComponent> quitWindow;
 	private final Provider<UnlockComponent.Builder> unlockWorkflowBuilderProvider;
 	private final Provider<LockComponent.Builder> lockWorkflowBuilderProvider;
+	private final ErrorComponent.Builder errorWindowBuilder;
 	private final Optional<TrayIntegrationProvider> trayIntegration;
 	private final Optional<UiAppearanceProvider> 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<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, Provider<UnlockComponent.Builder> unlockWorkflowBuilderProvider, Provider<LockComponent.Builder> lockWorkflowBuilderProvider, Lazy<QuitComponent> quitWindow, Optional<TrayIntegrationProvider> trayIntegration, Optional<UiAppearanceProvider> appearanceProvider, VaultService vaultService, LicenseHolder licenseHolder) {
+	FxApplication(Settings settings, Lazy<MainWindowComponent> mainWindow, Lazy<PreferencesComponent> preferencesWindow, Provider<UnlockComponent.Builder> unlockWorkflowBuilderProvider, Provider<LockComponent.Builder> lockWorkflowBuilderProvider, Lazy<QuitComponent> quitWindow, ErrorComponent.Builder errorWindowBuilder, Optional<TrayIntegrationProvider> trayIntegration, Optional<UiAppearanceProvider> 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<Stage> 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<Stage> 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.")));
+			}
 		});
 	}