Переглянути джерело

Use first available mount provider if none is selected or selected is not present

Armin Schrenk 2 роки тому
батько
коміт
d07b1b96dd

+ 18 - 0
src/main/java/org/cryptomator/common/ObservableUtil.java

@@ -0,0 +1,18 @@
+package org.cryptomator.common;
+
+import javafx.beans.binding.Bindings;
+import javafx.beans.value.ObservableValue;
+import java.util.function.Function;
+
+public class ObservableUtil {
+
+	public static <T, U> ObservableValue<U> mapWithDefault(ObservableValue<T> observable, Function<? super T, ? extends U> mapper, U defaultValue) {
+		return Bindings.createObjectBinding(() -> {
+			if (observable.getValue() == null) {
+				return defaultValue;
+			} else {
+				return mapper.apply(observable.getValue());
+			}
+		}, observable);
+	}
+}

+ 6 - 0
src/main/java/org/cryptomator/common/mount/ActualMountService.java

@@ -0,0 +1,6 @@
+package org.cryptomator.common.mount;
+
+import org.cryptomator.integrations.mount.MountService;
+
+public record ActualMountService(MountService service, boolean isDesired) {
+}

+ 9 - 5
src/main/java/org/cryptomator/common/mount/MountModule.java

@@ -2,6 +2,7 @@ package org.cryptomator.common.mount;
 
 import dagger.Module;
 import dagger.Provides;
+import org.cryptomator.common.ObservableUtil;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.integrations.mount.MountService;
 
@@ -20,11 +21,14 @@ public class MountModule {
 
 	@Provides
 	@Singleton
-	static ObservableValue<MountService> provideMountService(Settings settings, List<MountService> serviceImpls) {
-		return settings.mountService().map(desiredServiceImpl -> {
-			var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
-			return serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny().orElse(fallbackProvider);
-		});
+	static ObservableValue<ActualMountService> provideMountService(Settings settings, List<MountService> serviceImpls) {
+		var fallbackProvider = serviceImpls.stream().findFirst().orElse(null);
+		return ObservableUtil.mapWithDefault(settings.mountService(), //
+				desiredServiceImpl -> { //
+					var desiredService = serviceImpls.stream().filter(serviceImpl -> serviceImpl.getClass().getName().equals(desiredServiceImpl)).findAny(); //
+					return new ActualMountService(desiredService.orElse(fallbackProvider), desiredService.isPresent()); //
+				}, //
+				new ActualMountService(fallbackProvider, true));
 	}
 
 }

+ 10 - 7
src/main/java/org/cryptomator/common/vaults/Vault.java

@@ -12,6 +12,8 @@ import com.google.common.base.Strings;
 import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.common.Constants;
 import org.cryptomator.common.Environment;
+import org.cryptomator.common.mount.ActualMountService;
+import org.cryptomator.common.mount.MountModule;
 import org.cryptomator.common.mount.WindowsDriveLetters;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.common.settings.VaultSettings;
@@ -72,7 +74,7 @@ public class Vault {
 	private final AtomicReference<CryptoFileSystem> cryptoFileSystem;
 	private final VaultState state;
 	private final ObjectProperty<Exception> lastKnownException;
-	private final ObservableValue<MountService> mountService;
+	private final ObservableValue<ActualMountService> mountService;
 	private final ObservableValue<String> defaultMountFlags;
 	private final VaultConfigCache configCache;
 	private final VaultStats stats;
@@ -90,7 +92,7 @@ public class Vault {
 	private AtomicReference<MountHandle> mountHandle = new AtomicReference<>(null);
 
 	@Inject
-	Vault(Environment env, Settings settings, VaultSettings vaultSettings, VaultConfigCache configCache, AtomicReference<CryptoFileSystem> cryptoFileSystem, VaultState state, @Named("lastKnownException") ObjectProperty<Exception> lastKnownException, ObservableValue<MountService> mountService, VaultStats stats, WindowsDriveLetters windowsDriveLetters) {
+	Vault(Environment env, Settings settings, VaultSettings vaultSettings, VaultConfigCache configCache, AtomicReference<CryptoFileSystem> cryptoFileSystem, VaultState state, @Named("lastKnownException") ObjectProperty<Exception> lastKnownException, ObservableValue<ActualMountService> mountService, VaultStats stats, WindowsDriveLetters windowsDriveLetters) {
 		this.env = env;
 		this.settings = settings;
 		this.vaultSettings = vaultSettings;
@@ -99,7 +101,7 @@ public class Vault {
 		this.state = state;
 		this.lastKnownException = lastKnownException;
 		this.mountService = mountService;
-		this.defaultMountFlags = mountService.map(MountService::getDefaultMountFlags);
+		this.defaultMountFlags = mountService.map(s -> s.service().getDefaultMountFlags());
 		this.stats = stats;
 		this.displayablePath = Bindings.createStringBinding(this::getDisplayablePath, vaultSettings.path());
 		this.locked = Bindings.createBooleanBinding(this::isLocked, state);
@@ -159,8 +161,8 @@ public class Vault {
 		}
 	}
 
-	private MountBuilder prepareMount(Path cryptoRoot) throws IOException {
-		var mountProvider = mountService.getValue();
+	private MountBuilder prepareMount(MountService actualMountService, Path cryptoRoot) throws IOException {
+		var mountProvider = mountService.getValue().service();
 		var builder = mountProvider.forFileSystem(cryptoRoot);
 
 		for (var capability : mountProvider.capabilities()) {
@@ -207,8 +209,9 @@ public class Vault {
 		try {
 			cryptoFileSystem.set(fs);
 			var rootPath = fs.getRootDirectories().iterator().next();
-			var supportsForcedUnmount = mountService.getValue().hasCapability(MountCapability.UNMOUNT_FORCED);
-			var mountHandle = new MountHandle(prepareMount(rootPath).mount(), supportsForcedUnmount);
+			var actualMountService = mountService.getValue().service();
+			var supportsForcedUnmount = actualMountService.hasCapability(MountCapability.UNMOUNT_FORCED);
+			var mountHandle = new MountHandle(prepareMount(actualMountService, rootPath).mount(), supportsForcedUnmount);
 			success = this.mountHandle.compareAndSet(null, mountHandle);
 		} finally {
 			if (!success) {

+ 7 - 6
src/main/java/org/cryptomator/ui/preferences/VolumePreferencesController.java

@@ -1,5 +1,6 @@
 package org.cryptomator.ui.preferences;
 
+import org.cryptomator.common.mount.ActualMountService;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.integrations.mount.MountCapability;
 import org.cryptomator.integrations.mount.MountService;
@@ -22,7 +23,7 @@ import java.util.List;
 public class VolumePreferencesController implements FxController {
 
 	private final Settings settings;
-	private final ObservableValue<MountService> selectedMountService;
+	private final ObservableValue<ActualMountService> selectedMountService;
 	private final BooleanExpression loopbackPortSupported;
 	private final List<MountService> mountProviders;
 	public ChoiceBox<MountService> volumeTypeChoiceBox;
@@ -30,17 +31,17 @@ public class VolumePreferencesController implements FxController {
 	public Button loopbackPortApplyButton;
 
 	@Inject
-	VolumePreferencesController(Settings settings, List<MountService> mountProviders, ObservableValue<MountService> selectedMountService) {
+	VolumePreferencesController(Settings settings, List<MountService> mountProviders, ObservableValue<ActualMountService> actualMountService) {
 		this.settings = settings;
 		this.mountProviders = mountProviders;
-		this.selectedMountService = selectedMountService;
-		this.loopbackPortSupported = BooleanExpression.booleanExpression(selectedMountService.map(s -> s.hasCapability(MountCapability.LOOPBACK_PORT)));
+		this.selectedMountService = actualMountService;
+		this.loopbackPortSupported = BooleanExpression.booleanExpression(selectedMountService.map(as -> as.service().hasCapability(MountCapability.LOOPBACK_PORT)));
 	}
 
 	public void initialize() {
 		volumeTypeChoiceBox.getItems().addAll(mountProviders);
 		volumeTypeChoiceBox.setConverter(new MountServiceConverter());
-		volumeTypeChoiceBox.getSelectionModel().select(selectedMountService.getValue());
+		volumeTypeChoiceBox.getSelectionModel().select(selectedMountService.getValue().service());
 		volumeTypeChoiceBox.valueProperty().addListener((observableValue, oldProvide, newProvider) -> settings.mountService().set(newProvider.getClass().getName()));
 
 		loopbackPortField.setText(String.valueOf(settings.port().get()));
@@ -81,7 +82,7 @@ public class VolumePreferencesController implements FxController {
 
 		@Override
 		public String toString(MountService provider) {
-			return provider== null? "None" : provider.displayName(); //TODO: adjust message
+			return provider== null? "Automatic" : provider.displayName(); //TODO: adjust message
 		}
 
 		@Override

+ 6 - 6
src/main/java/org/cryptomator/ui/vaultoptions/MountOptionsController.java

@@ -1,10 +1,10 @@
 package org.cryptomator.ui.vaultoptions;
 
 import org.cryptomator.common.Environment;
+import org.cryptomator.common.mount.ActualMountService;
 import org.cryptomator.common.mount.WindowsDriveLetters;
 import org.cryptomator.common.vaults.Vault;
 import org.cryptomator.integrations.mount.MountCapability;
-import org.cryptomator.integrations.mount.MountService;
 import org.cryptomator.ui.common.FxController;
 
 import javax.inject.Inject;
@@ -54,15 +54,15 @@ public class MountOptionsController implements FxController {
 	public ChoiceBox<Path> driveLetterSelection;
 
 	@Inject
-	MountOptionsController(@VaultOptionsWindow Stage window, @VaultOptionsWindow Vault vault, ObservableValue<MountService> mountService, WindowsDriveLetters windowsDriveLetters, ResourceBundle resourceBundle, Environment environment) {
+	MountOptionsController(@VaultOptionsWindow Stage window, @VaultOptionsWindow Vault vault, ObservableValue<ActualMountService> mountService, WindowsDriveLetters windowsDriveLetters, ResourceBundle resourceBundle, Environment environment) {
 		this.window = window;
 		this.vault = vault;
 		this.windowsDriveLetters = windowsDriveLetters;
 		this.resourceBundle = resourceBundle;
-		this.mountpointDirSupported = mountService.map(s -> s.hasCapability(MountCapability.MOUNT_TO_EXISTING_DIR) || s.hasCapability(MountCapability.MOUNT_WITHIN_EXISTING_PARENT));
-		this.mountpointDriveLetterSupported = mountService.map(s -> s.hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
-		this.mountFlagsSupported = mountService.map(s -> s.hasCapability(MountCapability.MOUNT_FLAGS));
-		this.readOnlySupported = mountService.map(s -> s.hasCapability(MountCapability.READ_ONLY));
+		this.mountpointDirSupported = mountService.map(as -> as.service().hasCapability(MountCapability.MOUNT_TO_EXISTING_DIR) || as.service().hasCapability(MountCapability.MOUNT_WITHIN_EXISTING_PARENT));
+		this.mountpointDriveLetterSupported = mountService.map(as -> as.service().hasCapability(MountCapability.MOUNT_AS_DRIVE_LETTER));
+		this.mountFlagsSupported = mountService.map(as -> as.service().hasCapability(MountCapability.MOUNT_FLAGS));
+		this.readOnlySupported = mountService.map(as -> as.service().hasCapability(MountCapability.READ_ONLY));
 		this.driveLetter = vault.getVaultSettings().mountPoint().map(p -> isDriveLetter(p) ? p : null);
 		this.directoryPath = vault.getVaultSettings().mountPoint().map(p -> isDriveLetter(p) ? null : p.toString());
 	}