Browse Source

introduce new FuseEnvironment Interface such that the fuseNioAdapter gets os-dependent information from it

infeo 7 years ago
parent
commit
b069a16f0c

+ 28 - 0
main/ui/src/main/java/org/cryptomator/ui/model/FuseEnvironment.java

@@ -0,0 +1,28 @@
+package org.cryptomator.ui.model;
+
+import java.nio.file.Path;
+
+public interface FuseEnvironment {
+
+	void prepare() throws CommandFailedException;
+
+	String[] getMountParameters() throws CommandFailedException;
+
+	Path getFsRootPath();
+
+	/**
+	 * TODO: implement it in subclasses!
+	 * @throws CommandFailedException
+	 */
+	default void revealFsRootInFilesystemManager() throws CommandFailedException {
+		throw new CommandFailedException("Not implemented.");
+	}
+
+	void cleanUp();
+
+	default boolean supportsFuse(){
+		return false;
+	}
+
+
+}

+ 19 - 155
main/ui/src/main/java/org/cryptomator/ui/model/FuseNioAdapter.java

@@ -1,62 +1,25 @@
 package org.cryptomator.ui.model;
 
-import org.cryptomator.common.settings.Settings;
-import org.cryptomator.common.settings.VaultSettings;
 import org.cryptomator.cryptofs.CryptoFileSystem;
 import org.cryptomator.frontend.fuse.AdapterFactory;
 
-import org.apache.commons.lang3.SystemUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.inject.Inject;
-import java.io.IOException;
-import java.nio.file.DirectoryNotEmptyException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Scanner;
-import java.util.concurrent.TimeUnit;
 
 @VaultModule.PerVault
 public class FuseNioAdapter implements NioAdapter {
 
 	private static final Logger LOG = LoggerFactory.getLogger(FuseNioAdapter.class);
-	private static final String AUTOASSIGN_DRRIVE_LETTER = "*";
-
-	private enum OS {
-		WINDOWS,
-		LINUX,
-		MAC;
-
-		public static OS getCurrentOS() {
-			if (SystemUtils.IS_OS_WINDOWS) {
-				return WINDOWS;
-			} else if (SystemUtils.IS_OS_MAC) {
-				return MAC;
-			} else {
-				return LINUX;
-			}
-		}
-
-	}
+	private final FuseEnvironment fuseEnv;
 
-
-	private final VaultSettings vaultSettings;
-	private final Settings settings;
-	private final WindowsDriveLetters windowsDriveLetters;
-	private final OS os = OS.getCurrentOS();
 	private org.cryptomator.frontend.fuse.FuseNioAdapter ffs;
-	private String mountNameAndId;
-	private String mountURL;
 	private CryptoFileSystem cfs;
 
 	@Inject
-	public FuseNioAdapter(VaultSettings vaultSettings, Settings settings, WindowsDriveLetters windowsDriveLetters) {
-		this.vaultSettings = vaultSettings;
-		this.settings = settings;
-		this.windowsDriveLetters = windowsDriveLetters;
+	public FuseNioAdapter(FuseEnvironment fuseEnv) {
+		this.fuseEnv = fuseEnv;
 	}
 
 	@Override
@@ -72,97 +35,26 @@ public class FuseNioAdapter implements NioAdapter {
 	 */
 	@Override
 	public void mount() throws CommandFailedException {
-		ArrayList<String> mountOptions = new ArrayList<>(8);
-		mountOptions.add(("-oatomic_o_trunc"));
-		Path path;
-		try {
-			switch (os) {
-				case MAC:
-					path = Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get());
-					createVaultDirIfNotExist(path);
-					mountOptions.add("-ouid=" + getUIdOrGID("uid"));
-					mountOptions.add("-ogid=" + getUIdOrGID("gid"));
-					mountOptions.add("-ovolname=" + vaultSettings.mountName().get());
-					mountOptions.add("-oauto_xattr");
-					break;
-				case WINDOWS:
-					if (vaultSettings.winDriveLetter().get().equals(AUTOASSIGN_DRRIVE_LETTER)) {
-						if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
-							path = Paths.get(windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\");
-						} else {
-							throw new CommandFailedException("No free drive letter to mount.");
-						}
-					} else {
-						path = Paths.get(vaultSettings.winDriveLetter().get() + ":\\");
-					}
-					mountOptions.add("-ouid=-1");
-					mountOptions.add("-ogid=-1");
-					mountOptions.add("-ovolname=" + vaultSettings.mountName().get());
-					mountOptions.add("-oFileInfoTimeout=-1");
-					break;
-				case LINUX:
-					path = Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get());
-					createVaultDirIfNotExist(path);
-					mountOptions.add("-ouid=" + getUIdOrGID("uid"));
-					mountOptions.add("-ogid=" + getUIdOrGID("gid"));
-					mountOptions.add("-oauto_unmount");
-					mountOptions.add("-ofsname=CryptoFs");
-					break;
-				default:
-					throw new IllegalStateException("Not Supported OS.");
-			}
-			ffs.mount(path, false, false, mountOptions.toArray(new String[mountOptions.size()]));
-			mountURL = path.toAbsolutePath().toUri().toURL().toString();
-		} catch (Exception e) {
+	try {
+		fuseEnv.prepare();
+		ffs.mount(fuseEnv.getFsRootPath(), false, false, fuseEnv.getMountParameters());
+	} catch (Exception e) {
 			throw new CommandFailedException("Unable to mount Filesystem", e);
 		}
 	}
 
-	private void createVaultDirIfNotExist(Path p) throws IOException {
-		try {
-			if (Files.exists(p)) {
-				if (Files.isDirectory(p)) {
-					if (Files.newDirectoryStream(p).iterator().hasNext()) {
-						return;
-					} else {
-						throw new DirectoryNotEmptyException("Directory not empty.");
-					}
-				}
-			} else {
-				Files.createDirectory(p);
-			}
-		} catch (IOException e) {
-			throw e;
-		}
-	}
-
-	private String getUIdOrGID(String idtype) throws IOException {
-		String id;
-		String parameter;
-		switch (idtype) {
-			case "uid":
-				parameter = "-u";
-				break;
-			case "gid":
-				parameter = "-g";
-				break;
-			default:
-				throw new IllegalArgumentException("Unkown ID type");
-		}
-		Process getId = new ProcessBuilder("sh", "-c", "id " + parameter).start();
-		Scanner s = new Scanner(getId.getInputStream()).useDelimiter("\\A");
-		try {
-			getId.waitFor(1000, TimeUnit.MILLISECONDS);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-		id = s.nextLine();
-		return id;
+	/**
+	 * TODO: implement it!
+	 * @throws CommandFailedException
+	 */
+	@Override
+	public void reveal() throws CommandFailedException{
+		//fuseEnv.revealFsRootUrlInFilesystemManager(SOMETHING);
 	}
 
 	@Override
 	public synchronized void unmount() throws CommandFailedException {
-		if (!(cfs.getStats().pollBytesRead() > 0 || cfs.getStats().pollBytesWritten() > 0)) {
+		if (cfs.getStats().pollBytesRead() == 0 && cfs.getStats().pollBytesWritten() == 0) {
 			unmountForced();
 		} else {
 			throw new CommandFailedException("Pending read or write operations.");
@@ -176,45 +68,17 @@ public class FuseNioAdapter implements NioAdapter {
 
 	@Override
 	public void stop() {
-		switch (os) {
-			case WINDOWS:
-				return;
-			case MAC:
-			case LINUX:
-				try {
-					Files.deleteIfExists(Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get()));
-				} catch (IOException e) {
-					LOG.warn("Could not delete mount directory of vault " + vaultSettings.mountName());
-					e.printStackTrace();
-				}
-				return;
-			default:
-				return;
-		}
-
+		fuseEnv.cleanUp();
 	}
 
 	@Override
-	public String getFilesystemRootUrl() {
-		return mountURL;
+	public String getFsRootUrlString() {
+		return fuseEnv.getFsRootPath().toUri().toString();
 	}
 
-	/**
-	 * TODO: what should i check here?
-	 */
 	@Override
 	public boolean isSupported() {
-		switch (os) {
-			case LINUX:
-				return true;
-			case WINDOWS:
-				break;
-			case MAC:
-				break;
-			default:
-				return false;
-		}
-		return true;
+		return fuseEnv.supportsFuse();
 	}
 
 	@Override

+ 118 - 0
main/ui/src/main/java/org/cryptomator/ui/model/LinuxFuseEnvironment.java

@@ -0,0 +1,118 @@
+package org.cryptomator.ui.model;
+
+import org.cryptomator.common.settings.VaultSettings;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.nio.file.DirectoryNotEmptyException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+public class LinuxFuseEnvironment implements FuseEnvironment{
+
+	private final VaultSettings vaultSettings;
+	private Path root;
+
+	@Inject
+	public LinuxFuseEnvironment(VaultSettings vaultSettings){
+		this.vaultSettings = vaultSettings;
+	}
+
+	@Override
+	public void prepare() throws CommandFailedException {
+		this.root = Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get()).toAbsolutePath();
+		try {
+			createVaultDirIfNotExist(root);
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new CommandFailedException(e);
+		}
+	}
+
+	private void createVaultDirIfNotExist(Path p) throws IOException {
+		try {
+			if (Files.exists(p)) {
+				if (Files.isDirectory(p)) {
+					if (Files.newDirectoryStream(p).iterator().hasNext()) {
+						return;
+					} else {
+						throw new DirectoryNotEmptyException("Directory not empty.");
+					}
+				}
+			} else {
+				Files.createDirectory(p);
+			}
+		} catch (IOException e) {
+			throw e;
+		}
+	}
+
+	@Override
+	public String[] getMountParameters() throws CommandFailedException {
+		ArrayList<String> mountOptions = new ArrayList<>(8);
+		mountOptions.add(("-oatomic_o_trunc"));
+		try {
+			mountOptions.add("-ouid=" + getUIdOrGID("uid"));
+			mountOptions.add("-ogid=" + getUIdOrGID("gid"));
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new CommandFailedException(e);
+		}
+		mountOptions.add("-oauto_unmount");
+		mountOptions.add("-ofsname=CryptoFs");
+		return mountOptions.toArray(new String [mountOptions.size()]);
+	}
+
+	private String getUIdOrGID(String idtype) throws IOException {
+		String id;
+		String parameter;
+		switch (idtype) {
+			case "uid":
+				parameter = "-u";
+				break;
+			case "gid":
+				parameter = "-g";
+				break;
+			default:
+				throw new IllegalArgumentException("Unkown ID type");
+		}
+		Process getId = new ProcessBuilder("sh", "-c", "id " + parameter).start();
+		Scanner s = new Scanner(getId.getInputStream()).useDelimiter("\\A");
+		try {
+			getId.waitFor(1000, TimeUnit.MILLISECONDS);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		id = s.nextLine();
+		return id;
+	}
+
+	@Override
+	public Path getFsRootPath() {
+		return this.root;
+	}
+
+	@Override
+	public void revealFsRootInFilesystemManager() throws CommandFailedException {
+		throw new CommandFailedException("Not implemented.");
+	}
+
+	@Override
+	public void cleanUp() {
+		try {
+			Files.deleteIfExists(Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get()));
+		} catch (IOException e) {
+			//LOG.warn("Could not delete mount directory of vault " + vaultSettings.mountName().get());
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public boolean supportsFuse() {
+		return true;
+	}
+}

+ 118 - 0
main/ui/src/main/java/org/cryptomator/ui/model/MacFuseEnvironment.java

@@ -0,0 +1,118 @@
+package org.cryptomator.ui.model;
+
+import org.cryptomator.common.settings.VaultSettings;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.nio.file.DirectoryNotEmptyException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.concurrent.TimeUnit;
+
+public class MacFuseEnvironment implements FuseEnvironment {
+
+	private final VaultSettings vaultSettings;
+	private Path root;
+
+	@Inject
+	public MacFuseEnvironment(VaultSettings vaultSettings){
+		this.vaultSettings = vaultSettings;
+	}
+
+	@Override
+	public void prepare() throws CommandFailedException {
+		this.root = Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get()).toAbsolutePath();
+		try {
+			createVaultDirIfNotExist(root);
+		} catch (IOException e) {
+			throw new CommandFailedException(e);
+		}
+	}
+
+	private void createVaultDirIfNotExist(Path p) throws IOException {
+		try {
+			if (Files.exists(p)) {
+				if (Files.isDirectory(p)) {
+					if (Files.newDirectoryStream(p).iterator().hasNext()) {
+						return;
+					} else {
+						throw new DirectoryNotEmptyException("Directory not empty.");
+					}
+				}
+			} else {
+				Files.createDirectory(p);
+			}
+		} catch (IOException e) {
+			throw e;
+		}
+	}
+
+	@Override
+	public String[] getMountParameters() throws CommandFailedException {
+		ArrayList<String> mountOptions = new ArrayList<>(8);
+		mountOptions.add(("-oatomic_o_trunc"));
+		try {
+			mountOptions.add("-ouid=" + getUIdOrGID("uid"));
+			mountOptions.add("-ogid=" + getUIdOrGID("gid"));
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new CommandFailedException(e);
+		}
+			mountOptions.add("-ovolname=" + vaultSettings.mountName().get());
+			mountOptions.add("-oauto_xattr");
+		return mountOptions.toArray(new String [mountOptions.size()]);
+	}
+
+	private String getUIdOrGID(String idtype) throws IOException {
+		String id;
+		String parameter;
+		switch (idtype) {
+			case "uid":
+				parameter = "-u";
+				break;
+			case "gid":
+				parameter = "-g";
+				break;
+			default:
+				throw new IllegalArgumentException("Unkown ID type");
+		}
+		Process getId = new ProcessBuilder("sh", "-c", "id " + parameter).start();
+		Scanner s = new Scanner(getId.getInputStream()).useDelimiter("\\A");
+		try {
+			getId.waitFor(1000, TimeUnit.MILLISECONDS);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		id = s.nextLine();
+		return id;
+	}
+
+	@Override
+	public Path getFsRootPath() {
+		return root;
+	}
+
+	@Override
+	public void revealFsRootInFilesystemManager() throws CommandFailedException {
+		throw new CommandFailedException("Not implemented.");
+	}
+
+
+	@Override
+	public void cleanUp() {
+		try {
+			Files.deleteIfExists(Paths.get(vaultSettings.mountPath().get() + vaultSettings.mountName().get()));
+		} catch (IOException e) {
+			//LOG.warn("Could not delete mount directory of vault " + vaultSettings.mountName().get());
+			e.printStackTrace();
+		}
+	}
+
+	@Override
+	public boolean supportsFuse() {
+		return false;
+	}
+}

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/model/NioAdapter.java

@@ -20,7 +20,7 @@ public interface NioAdapter {
 
 	void stop();
 
-	String getFilesystemRootUrl();
+	String getFsRootUrlString();
 
 	default boolean isSupported() {
 		return false;

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/model/Vault.java

@@ -299,7 +299,7 @@ public class Vault {
 	}
 
 	public String getFilesystemRootUrl() {
-		return nioAdapter.getFilesystemRootUrl();
+		return nioAdapter.getFsRootUrlString();
 	}
 
 	public String getId() {

+ 38 - 0
main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java

@@ -12,6 +12,7 @@ import java.util.Objects;
 
 import javax.inject.Scope;
 
+import org.apache.commons.lang3.SystemUtils;
 import org.cryptomator.common.settings.Settings;
 import org.cryptomator.common.settings.VaultSettings;
 
@@ -55,4 +56,41 @@ public class VaultModule {
 				throw new IllegalStateException("Unsupported NioAdapter: " + settings.usedNioAdapterImpl().get());
 		}
 	}
+
+	//TODO: ask sebi if this should be here
+
+	private final OS os = OS.getCurrentOS();
+
+	private enum OS {
+		WINDOWS,
+		LINUX,
+		MAC;
+
+		public static OS getCurrentOS() {
+			if (SystemUtils.IS_OS_WINDOWS) {
+				return WINDOWS;
+			} else if (SystemUtils.IS_OS_MAC) {
+				return MAC;
+			} else {
+				return LINUX;
+			}
+		}
+
+	}
+
+	@Provides
+	@VaultModule.PerVault
+	FuseEnvironment providesFuseEnvironment(WindowsFuseEnvironment windowsFuseEnvironment, LinuxFuseEnvironment linuxFuseEnvironment, MacFuseEnvironment macFuseEnvironment){
+		switch (os){
+			case LINUX:
+				return linuxFuseEnvironment;
+			case WINDOWS:
+				return windowsFuseEnvironment;
+			case MAC:
+				return macFuseEnvironment;
+			default:
+				//TODO: should be better something else returned?
+				return null;
+		}
+	}
 }

+ 1 - 1
main/ui/src/main/java/org/cryptomator/ui/model/WebDavNioAdapter.java

@@ -104,7 +104,7 @@ public class WebDavNioAdapter implements NioAdapter {
 
 	}
 
-	public synchronized String getFilesystemRootUrl() {
+	public synchronized String getFsRootUrlString() {
 		return servlet.getServletRootUri().toString();
 	}
 

+ 69 - 0
main/ui/src/main/java/org/cryptomator/ui/model/WindowsFuseEnvironment.java

@@ -0,0 +1,69 @@
+package org.cryptomator.ui.model;
+
+import org.cryptomator.common.settings.VaultSettings;
+
+import javax.inject.Inject;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+
+@VaultModule.PerVault
+public class WindowsFuseEnvironment implements FuseEnvironment{
+
+	private static final String AUTOASSIGN_DRRIVE_LETTER = "*";
+
+	private final VaultSettings vaultSettings;
+	private final WindowsDriveLetters windowsDriveLetters;
+
+	private Path root;
+
+	@Inject
+	public WindowsFuseEnvironment(VaultSettings vaultSettings, WindowsDriveLetters windowsDriveLetters){
+		this.vaultSettings = vaultSettings;
+		this.windowsDriveLetters = windowsDriveLetters;
+	}
+
+	@Override
+	public void prepare() throws CommandFailedException {
+		if (vaultSettings.winDriveLetter().get().equals(AUTOASSIGN_DRRIVE_LETTER)) {
+			if (!windowsDriveLetters.getAvailableDriveLetters().isEmpty()) {
+				root= Paths.get(windowsDriveLetters.getAvailableDriveLetters().iterator().next() + ":\\").toAbsolutePath();
+			} else {
+				throw new CommandFailedException("No free drive letter to mount.");
+			}
+		} else {
+			root = Paths.get(vaultSettings.winDriveLetter().get() + ":\\").toAbsolutePath();
+		}
+	}
+
+	@Override
+	public String[] getMountParameters() throws CommandFailedException {
+		ArrayList<String> mountOptions = new ArrayList<>(8);
+		mountOptions.add(("-oatomic_o_trunc"));
+		mountOptions.add("-ouid=-1");
+		mountOptions.add("-ogid=-1");
+		mountOptions.add("-ovolname=" + vaultSettings.mountName().get());
+		mountOptions.add("-oFileInfoTimeout=-1");
+		return mountOptions.toArray(new String [mountOptions.size()]);
+	}
+
+	@Override
+	public Path getFsRootPath() {
+		return root;
+	}
+
+	@Override
+	public void revealFsRootInFilesystemManager() throws CommandFailedException {
+		throw new CommandFailedException("Not Implemented");
+	}
+
+	@Override
+	public void cleanUp() {
+
+	}
+
+	@Override
+	public boolean supportsFuse() {
+		return false;
+	}
+}