Procházet zdrojové kódy

Refactor mounter class

Armin Schrenk před 2 roky
rodič
revize
47a32893f0

+ 92 - 55
src/main/java/org/cryptomator/common/mount/Mounter.java

@@ -4,7 +4,9 @@ import org.cryptomator.common.Environment;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.common.settings.VaultSettings;
 import org.cryptomator.integrations.mount.Mount;
+import org.cryptomator.integrations.mount.MountBuilder;
 import org.cryptomator.integrations.mount.MountFailedException;
+import org.cryptomator.integrations.mount.MountService;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -26,83 +28,118 @@ public class Mounter {
 	private final Settings settings;
 	private final Environment env;
 	private final WindowsDriveLetters driveLetters;
-	private final ObservableValue<ActualMountService> mountService;
+	private final ObservableValue<ActualMountService> mountServiceObservable;
 
 	@Inject
-	public Mounter(Settings settings, Environment env, WindowsDriveLetters driveLetters, ObservableValue<ActualMountService> mountService) {
+	public Mounter(Settings settings, Environment env, WindowsDriveLetters driveLetters, ObservableValue<ActualMountService> mountServiceObservable) {
 		this.settings = settings;
 		this.env = env;
 		this.driveLetters = driveLetters;
-		this.mountService = mountService;
+		this.mountServiceObservable = mountServiceObservable;
 	}
 
-	public MountHandle mountAndcreateHandle(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
-		var mountService = this.mountService.getValue().service();
-		var builder = mountService.forFileSystem(cryptoFsRoot);
-		boolean mountWithinParent = false;
-
-		for (var capability : mountService.capabilities()) {
-			switch (capability) {
-				case FILE_SYSTEM_NAME -> builder.setFileSystemName("crypto");
-				case LOOPBACK_PORT -> builder.setLoopbackPort(settings.port().get()); //TODO: move port from settings to vaultsettings (see https://github.com/cryptomator/cryptomator/tree/feature/mount-setting-per-vault)
-				case LOOPBACK_HOST_NAME -> env.getLoopbackAlias().ifPresent(builder::setLoopbackHostName);
-				case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode().get());
-				case MOUNT_FLAGS -> builder.setMountFlags(Objects.requireNonNullElse(vaultSettings.mountFlags().getValue(), mountService.getDefaultMountFlags()));
-				case VOLUME_ID -> builder.setVolumeId(vaultSettings.getId());
-				case VOLUME_NAME -> builder.setVolumeName(vaultSettings.mountName().get());
-			}
+	private class SettledMounter {
+
+		private MountService service;
+		private MountBuilder builder;
+		private VaultSettings vaultSettings;
+
+		public SettledMounter(MountService service, MountBuilder builder, VaultSettings vaultSettings) {
+			this.service = service;
+			this.builder = builder;
+			this.vaultSettings = vaultSettings;
 		}
 
-		//TODO: refactor logic to own method
-		var userChosenMountPoint = vaultSettings.getMountPoint();
-		var defaultMountPointBase = env.getMountPointsDir().orElseThrow();
-		var canMountToDriveLetter = mountService.hasCapability(MOUNT_AS_DRIVE_LETTER);
-		var canMountToParent = mountService.hasCapability(MOUNT_WITHIN_EXISTING_PARENT);
-		var canMountToDir = mountService.hasCapability(MOUNT_TO_EXISTING_DIR);
-		if (userChosenMountPoint == null) {
-			if (mountService.hasCapability(MOUNT_TO_SYSTEM_CHOSEN_PATH)) {
-				// no need to set a mount point
-			} else if (canMountToDriveLetter) {
-				builder.setMountpoint(driveLetters.getFirstDesiredAvailable().orElseThrow()); //TODO: catch exception
-			} else if (canMountToParent) {
-				Files.createDirectories(defaultMountPointBase);
-				builder.setMountpoint(defaultMountPointBase);
-			} else if (canMountToDir) {
-				var mountPoint = defaultMountPointBase.resolve(vaultSettings.mountName().get());
-				Files.createDirectories(mountPoint);
-				builder.setMountpoint(mountPoint);
-			}
-		} else {
-			mountWithinParent = canMountToParent && !canMountToDir;
-			if(mountWithinParent) {
-				// TODO: move the mount point away in case of MOUNT_WITHIN_EXISTING_PARENT
+		MadePreparations prepare() throws IOException {
+			for (var capability : service.capabilities()) {
+				switch (capability) {
+					case FILE_SYSTEM_NAME -> builder.setFileSystemName("cryptoFs");
+					case LOOPBACK_PORT ->
+							builder.setLoopbackPort(settings.port().get()); //TODO: move port from settings to vaultsettings (see https://github.com/cryptomator/cryptomator/tree/feature/mount-setting-per-vault)
+					case LOOPBACK_HOST_NAME -> env.getLoopbackAlias().ifPresent(builder::setLoopbackHostName);
+					case READ_ONLY -> builder.setReadOnly(vaultSettings.usesReadOnlyMode().get());
+					case MOUNT_FLAGS -> builder.setMountFlags(Objects.requireNonNullElse(vaultSettings.mountFlags().getValue(), service.getDefaultMountFlags()));
+					case VOLUME_ID -> builder.setVolumeId(vaultSettings.getId());
+					case VOLUME_NAME -> builder.setVolumeName(vaultSettings.mountName().get());
+				}
 			}
-			try {
-				builder.setMountpoint(userChosenMountPoint);
-			} catch (IllegalArgumentException e) {
-				var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\");
-				var configNotSupported = (!canMountToDriveLetter && mpIsDriveLetter) || (!canMountToDir && !mpIsDriveLetter) || (!canMountToParent && !mpIsDriveLetter);
-				if (configNotSupported) {
-					throw new MountPointNotSupportedException(e.getMessage());
-				} else if (canMountToDir && !canMountToParent && !Files.exists(userChosenMountPoint)) {
-					//mountpoint must exist
-					throw new MountPointNotExistsException(e.getMessage());
-				} else {
-					throw new IllegalMountPointException(e.getMessage());
+
+			return prepareMountPoint();
+		}
+
+		private MadePreparations prepareMountPoint() throws IOException {
+			var userChosenMountPoint = vaultSettings.getMountPoint();
+			var defaultMountPointBase = env.getMountPointsDir().orElseThrow();
+			var canMountToDriveLetter = service.hasCapability(MOUNT_AS_DRIVE_LETTER);
+			var canMountToParent = service.hasCapability(MOUNT_WITHIN_EXISTING_PARENT);
+			var canMountToDir = service.hasCapability(MOUNT_TO_EXISTING_DIR);
+			boolean mountWithinCustomParent = false;
+
+			if (userChosenMountPoint == null) {
+				if (service.hasCapability(MOUNT_TO_SYSTEM_CHOSEN_PATH)) {
+					// no need to set a mount point
+				} else if (canMountToDriveLetter) {
+					builder.setMountpoint(driveLetters.getFirstDesiredAvailable().orElseThrow()); //TODO: catch exception and translate
+				} else if (canMountToParent) {
+					Files.createDirectories(defaultMountPointBase);
+					builder.setMountpoint(defaultMountPointBase);
+				} else if (canMountToDir) {
+					var mountPoint = defaultMountPointBase.resolve(vaultSettings.mountName().get());
+					Files.createDirectories(mountPoint);
+					builder.setMountpoint(mountPoint);
+				}
+			} else {
+				mountWithinCustomParent = canMountToParent && !canMountToDir;
+				if (mountWithinCustomParent) {
+					// TODO: move the mount point away in case of MOUNT_WITHIN_EXISTING_PARENT
 				}
+				try {
+					builder.setMountpoint(userChosenMountPoint);
+				} catch (IllegalArgumentException e) {
+					var mpIsDriveLetter = userChosenMountPoint.toString().matches("[A-Z]:\\\\");
+					var configNotSupported = (!canMountToDriveLetter && mpIsDriveLetter) || (!canMountToDir && !mpIsDriveLetter) || (!canMountToParent && !mpIsDriveLetter);
+					if (configNotSupported) {
+						throw new MountPointNotSupportedException(e.getMessage());
+					} else if (canMountToDir && !canMountToParent && !Files.exists(userChosenMountPoint)) {
+						//mountpoint must exist
+						throw new MountPointNotExistsException(e.getMessage());
+					} else {
+						throw new IllegalMountPointException(e.getMessage());
+					}
 				/*
 				//TODO:
 				if (!canMountToDir && canMountToParent && !Files.notExists(userChosenMountPoint)) {
 					//parent must exist, mountpoint must not exist
 				}
 				 */
+				}
 			}
+			return new MadePreparations(mountWithinCustomParent);
 		}
 
-		return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), mountWithinParent);
 	}
 
-	public record MountHandle(Mount mount, boolean supportsUnmountForced, boolean mountWithinParent) {
+	public MountHandle mount(VaultSettings vaultSettings, Path cryptoFsRoot) throws IOException, MountFailedException {
+		var mountService = this.mountServiceObservable.getValue().service();
+		var builder = mountService.forFileSystem(cryptoFsRoot);
+		var internal = new SettledMounter(mountService, builder, vaultSettings);
+		var preps = internal.prepare();
+		return new MountHandle(builder.mount(), mountService.hasCapability(UNMOUNT_FORCED), preps.mountWithinCustomParent);
+	}
 
+	public void cleanup(MountHandle handle) {
+		if(handle.mountWithinCustomParent) {
+			//TODO
+		}
 	}
+
+
+	public record MountHandle(Mount mountObj, boolean supportsUnmountForced, boolean mountWithinCustomParent) {
+
+	}
+
+	private record MadePreparations(boolean mountWithinCustomParent) {
+
+	}
+
 }

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

@@ -8,7 +8,6 @@
  *******************************************************************************/
 package org.cryptomator.common.vaults;
 
-import com.google.common.base.Strings;
 import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.common.Constants;
 import org.cryptomator.common.mount.Mounter;
@@ -150,7 +149,7 @@ public class Vault {
 		try {
 			cryptoFileSystem.set(fs);
 			var rootPath = fs.getRootDirectories().iterator().next();
-			var mountHandle = mounter.mountAndcreateHandle(vaultSettings, rootPath);
+			var mountHandle = mounter.mount(vaultSettings, rootPath);
 			success = this.mountHandle.compareAndSet(null, mountHandle);
 		} finally {
 			if (!success) {
@@ -167,15 +166,15 @@ public class Vault {
 		}
 
 		if (forced && mountHandle.supportsUnmountForced()) {
-			mountHandle.mount().unmountForced();
+			mountHandle.mountObj().unmountForced();
 		} else {
-			mountHandle.mount().unmount();
+			mountHandle.mountObj().unmount();
 		}
 
 		try {
-			mountHandle.mount().close();
-			if(mountHandle.mountWithinParent()) {
-				//TODO: cleanup
+			mountHandle.mountObj().close();
+			if(mountHandle.mountWithinCustomParent()) {
+				mounter.cleanup(mountHandle);
 			}
 		} finally {
 			destroyCryptoFileSystem();
@@ -271,7 +270,7 @@ public class Vault {
 
 	public Mountpoint getMountPoint() {
 		var handle = mountHandle.get();
-		return handle == null ? null : handle.mount().getMountpoint();
+		return handle == null ? null : handle.mountObj().getMountpoint();
 	}
 
 	public StringBinding displayablePathProperty() {