diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java b/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java index a2721f4d3..34492ce2d 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/Settings.java @@ -30,6 +30,8 @@ public class Settings { public static final int DEFAULT_NUM_TRAY_NOTIFICATIONS = 3; public static final String DEFAULT_GVFS_SCHEME = "dav"; public static final boolean DEFAULT_DEBUG_MODE = false; + public static final String DEFAULT_DEFAULT_MOUNT_DIR = System.getProperty("user.home"); + public static final String DEFAULT_NIO_ADAPTER = "WEBDAV"; private final ObservableList directories = FXCollections.observableArrayList(VaultSettings::observables); private final BooleanProperty checkForUpdates = new SimpleBooleanProperty(DEFAULT_CHECK_FOR_UDPATES); @@ -37,6 +39,9 @@ public class Settings { private final IntegerProperty numTrayNotifications = new SimpleIntegerProperty(DEFAULT_NUM_TRAY_NOTIFICATIONS); private final StringProperty preferredGvfsScheme = new SimpleStringProperty(DEFAULT_GVFS_SCHEME); private final BooleanProperty debugMode = new SimpleBooleanProperty(DEFAULT_DEBUG_MODE); + private final StringProperty nioAdapterImpl = new SimpleStringProperty(DEFAULT_NIO_ADAPTER); + private final StringProperty defaultMountDir = new SimpleStringProperty(DEFAULT_DEFAULT_MOUNT_DIR); + private Consumer saveCmd; /** @@ -49,6 +54,8 @@ public class Settings { numTrayNotifications.addListener(this::somethingChanged); preferredGvfsScheme.addListener(this::somethingChanged); debugMode.addListener(this::somethingChanged); + nioAdapterImpl.addListener(this::somethingChanged); + defaultMountDir.addListener(this::somethingChanged); } void setSaveCmd(Consumer saveCmd) { @@ -91,4 +98,11 @@ public class Settings { return debugMode; } + public StringProperty usedNioAdapterImpl() { + return nioAdapterImpl; + } + + public StringProperty defaultMountDir() { + return defaultMountDir; + } } diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java index e474fcf7c..0a2a13c3f 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsJsonAdapter.java @@ -33,6 +33,8 @@ public class SettingsJsonAdapter extends TypeAdapter { out.name("numTrayNotifications").value(value.numTrayNotifications().get()); out.name("preferredGvfsScheme").value(value.preferredGvfsScheme().get()); out.name("debugMode").value(value.debugMode().get()); + out.name("nioAdapterImpl").value(value.usedNioAdapterImpl().get()); + out.name("defaultMountDir").value(value.defaultMountDir().get()); out.endObject(); } @@ -70,6 +72,12 @@ public class SettingsJsonAdapter extends TypeAdapter { case "debugMode": settings.debugMode().set(in.nextBoolean()); break; + case "nioAdapterImpl": + settings.usedNioAdapterImpl().set(in.nextString()); + break; + case "defaultMountDir": + settings.defaultMountDir().set(in.nextString()); + break; default: LOG.warn("Unsupported vault setting found in JSON: " + name); in.skipValue(); diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java index 8ee82146f..bcaae5587 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettings.java @@ -36,6 +36,7 @@ public class VaultSettings { private final BooleanProperty unlockAfterStartup = new SimpleBooleanProperty(DEFAULT_UNLOCK_AFTER_STARTUP); private final BooleanProperty mountAfterUnlock = new SimpleBooleanProperty(DEFAULT_MOUNT_AFTER_UNLOCK); private final BooleanProperty revealAfterMount = new SimpleBooleanProperty(DEFAULT_REAVEAL_AFTER_MOUNT); + private final StringProperty mountPath = new SimpleStringProperty(Settings.DEFAULT_DEFAULT_MOUNT_DIR); public VaultSettings(String id) { this.id = Objects.requireNonNull(id); @@ -123,6 +124,10 @@ public class VaultSettings { return revealAfterMount; } + public StringProperty mountPath() { + return mountPath; + } + /* Hashcode/Equals */ @Override diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java index d1de6231e..e171ea178 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/VaultSettingsJsonAdapter.java @@ -34,6 +34,7 @@ class VaultSettingsJsonAdapter { String id = null; String path = null; String mountName = null; + String mountPath = null; String winDriveLetter = null; boolean unlockAfterStartup = VaultSettings.DEFAULT_UNLOCK_AFTER_STARTUP; boolean mountAfterUnlock = VaultSettings.DEFAULT_MOUNT_AFTER_UNLOCK; @@ -64,6 +65,8 @@ class VaultSettingsJsonAdapter { case "revealAfterMount": revealAfterMount = in.nextBoolean(); break; + case "mountPath": + mountPath = in.nextString(); default: LOG.warn("Unsupported vault setting found in JSON: " + name); in.skipValue(); @@ -78,6 +81,7 @@ class VaultSettingsJsonAdapter { vaultSettings.unlockAfterStartup().set(unlockAfterStartup); vaultSettings.mountAfterUnlock().set(mountAfterUnlock); vaultSettings.revealAfterMount().set(revealAfterMount); + vaultSettings.mountPath().set(mountPath); return vaultSettings; } diff --git a/main/pom.xml b/main/pom.xml index 6c939e273..e5738b56c 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -28,7 +28,8 @@ 1.4.5 1.0.3 1.0.2 - + 0.1.1-SNAPSHOT + 2.5 3.6 4.5.3 @@ -96,6 +97,11 @@ cryptofs ${cryptomator.cryptofs.version} + + org.cryptomator + fuse-nio-adapter + ${cryptomator.fuse.version} + org.cryptomator webdav-nio-adapter diff --git a/main/ui/pom.xml b/main/ui/pom.xml index c5a0980c9..7172387ab 100644 --- a/main/ui/pom.xml +++ b/main/ui/pom.xml @@ -30,7 +30,11 @@ org.cryptomator keychain - + + org.cryptomator + fuse-nio-adapter + + org.cryptomator diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java index 20ac7cac6..1e01db321 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/SettingsController.java @@ -8,15 +8,22 @@ ******************************************************************************/ package org.cryptomator.ui.controllers; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Optional; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import javafx.beans.Observable; +import javafx.beans.value.ObservableValue; +import javafx.scene.layout.GridPane; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.settings.Settings; import org.cryptomator.ui.l10n.Localization; +import org.cryptomator.ui.model.NioAdapterImpl; import com.google.common.base.CharMatcher; import com.google.common.base.Strings; @@ -52,6 +59,15 @@ public class SettingsController implements ViewController { @FXML private CheckBox checkForUpdatesCheckbox; + @FXML + private GridPane webdavNioAdapter; + + @FXML + private GridPane fuseNioAdapter; + + @FXML + private Label portFieldLabel; + @FXML private TextField portField; @@ -64,9 +80,24 @@ public class SettingsController implements ViewController { @FXML private Label prefGvfsSchemeLabel; + @FXML + private Label defaultMountDirLabel; + + @FXML + private TextField defaultMountDir; + + @FXML + private Button changeDefaultMountDirButton; + @FXML private ChoiceBox prefGvfsScheme; + @FXML + private Label nioAdapterLabel; + + @FXML + private ChoiceBox nioAdapter; + @FXML private CheckBox debugModeCheckbox; @@ -75,25 +106,69 @@ public class SettingsController implements ViewController { @Override public void initialize() { + versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion.orElse("SNAPSHOT"))); checkForUpdatesCheckbox.setDisable(areUpdatesManagedExternally()); checkForUpdatesCheckbox.setSelected(settings.checkForUpdates().get() && !areUpdatesManagedExternally()); + + //NIOADAPTER + nioAdapter.getItems().addAll(getSupportedAdapters()); + nioAdapter.setValue(settings.usedNioAdapterImpl().get()); + nioAdapter.setVisible(true); + nioAdapter.getSelectionModel().selectedItemProperty().addListener( (ObservableValue observable, String oldVal, String newVal) -> changeNioView(newVal) ); + + + //WEBDAV + webdavNioAdapter.managedProperty().bind(webdavNioAdapter.visibleProperty()); + prefGvfsScheme.managedProperty().bind(webdavNioAdapter.visibleProperty()); + prefGvfsSchemeLabel.managedProperty().bind(webdavNioAdapter.visibleProperty()); + portFieldLabel.managedProperty().bind(webdavNioAdapter.visibleProperty()); + changePortButton.managedProperty().bind(webdavNioAdapter.visibleProperty()); + portField.managedProperty().bind(webdavNioAdapter.visibleProperty()); portField.setText(String.valueOf(settings.port().intValue())); portField.addEventFilter(KeyEvent.KEY_TYPED, this::filterNumericKeyEvents); changePortButton.visibleProperty().bind(settings.port().asString().isNotEqualTo(portField.textProperty())); changePortButton.disableProperty().bind(Bindings.createBooleanBinding(this::isPortValid, portField.textProperty()).not()); - versionLabel.setText(String.format(localization.getString("settings.version.label"), applicationVersion.orElse("SNAPSHOT"))); - prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX); - prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX); prefGvfsScheme.getItems().add("dav"); prefGvfsScheme.getItems().add("webdav"); prefGvfsScheme.setValue(settings.preferredGvfsScheme().get()); + prefGvfsSchemeLabel.setVisible(SystemUtils.IS_OS_LINUX); + prefGvfsScheme.setVisible(SystemUtils.IS_OS_LINUX); + + //FUSE + fuseNioAdapter.managedProperty().bind(fuseNioAdapter.visibleProperty()); + defaultMountDirLabel.managedProperty().bind(fuseNioAdapter.visibleProperty()); + defaultMountDir.managedProperty().bind(fuseNioAdapter.visibleProperty()); + defaultMountDirLabel.setVisible(SystemUtils.IS_OS_LINUX); + defaultMountDir.setVisible(SystemUtils.IS_OS_LINUX); + defaultMountDir.setText(String.valueOf(settings.defaultMountDir().get())); + changeDefaultMountDirButton.setVisible(false); + changeDefaultMountDirButton.visibleProperty().bind( + Bindings.createBooleanBinding( + () -> fuseNioAdapter.visibleProperty().get() && settings.defaultMountDir().isNotEqualTo(Strings.nullToEmpty(defaultMountDir.getText())).get() , + fuseNioAdapter.visibleProperty(), + settings.defaultMountDir().isNotEqualTo(defaultMountDir.textProperty()) + ) + ); + changeDefaultMountDirButton.disableProperty().bind(Bindings.createBooleanBinding(this::isDirValid, defaultMountDir.textProperty()).not()); + debugModeCheckbox.setSelected(settings.debugMode().get()); settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty()); settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty()); + settings.usedNioAdapterImpl().bind(nioAdapter.valueProperty()); settings.debugMode().bind(debugModeCheckbox.selectedProperty()); } + //TODO: how to implement this? + private String [] getSupportedAdapters() { + return new String[]{NioAdapterImpl.FUSE.name(), NioAdapterImpl.WEBDAV.name()}; + } + + private void changeNioView(String newVal) { + fuseNioAdapter.setVisible(newVal.equalsIgnoreCase("FUSE")); + webdavNioAdapter.setVisible(newVal.equalsIgnoreCase("WEBDAV")); + } + @Override public Parent getRoot() { return root; @@ -110,6 +185,23 @@ public class SettingsController implements ViewController { } } + @FXML + private void changeDefaultMountDir(ActionEvent event){ + assert isDirValid() : "Error. Not a valid Directory. Does and exist and do you have the needed Rights?"; + settings.defaultMountDir().set(defaultMountDir.getText()); + } + + private boolean isDirValid(){ + if(SystemUtils.IS_OS_WINDOWS){ + //this should never ever happen! + return false; + } + else{ + Path path = Paths.get(defaultMountDir.getText()); + return Files.isDirectory(path) && Files.isReadable(path) && Files.isWritable(path) && Files.isExecutable(path); + } + } + private boolean isPortValid() { try { int port = Integer.parseInt(portField.getText()); diff --git a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java index 6d30a7e2f..c1b2aac68 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/controllers/UnlockController.java @@ -8,7 +8,9 @@ ******************************************************************************/ package org.cryptomator.ui.controllers; +import java.io.File; import java.io.IOException; +import java.nio.file.*; import java.util.Arrays; import java.util.Comparator; import java.util.Objects; @@ -16,6 +18,8 @@ import java.util.Optional; import javax.inject.Inject; +import javafx.beans.Observable; +import javafx.beans.binding.Bindings; import org.apache.commons.lang3.CharUtils; import org.apache.commons.lang3.SystemUtils; import org.cryptomator.common.settings.VaultSettings; @@ -112,6 +116,15 @@ public class UnlockController implements ViewController { @FXML private ChoiceBox winDriveLetter; + @FXML + private Label mountPathLabel; + + @FXML + private TextField mountPath; + + @FXML + private Button changeMountPathButton; + @FXML private ProgressIndicator progressIndicator; @@ -142,12 +155,26 @@ public class UnlockController implements ViewController { unlockAfterStartup.disableProperty().bind(savePassword.disabledProperty().or(savePassword.selectedProperty().not())); if (SystemUtils.IS_OS_WINDOWS) { winDriveLetter.setConverter(new WinDriveLetterLabelConverter()); + mountPathLabel.setVisible(false); + mountPathLabel.setManaged(false); + mountPath.setVisible(false); + mountPath.setManaged(false); + changeMountPathButton.setVisible(false); + changeMountPathButton.setManaged(false); } else { winDriveLetterLabel.setVisible(false); winDriveLetterLabel.setManaged(false); winDriveLetter.setVisible(false); winDriveLetter.setManaged(false); } + changeMountPathButton.disableProperty().bind(Bindings.createBooleanBinding(this::isDirVaild, mountPath.textProperty()).not()); + changeMountPathButton.visibleProperty().bind( + Bindings.createBooleanBinding( + ()-> mountPathLabel.isVisible() && mountPath.textProperty().isEmpty().not().get(), + mountPathLabel.visibleProperty(), + mountPath.textProperty().isEmpty().not() + ) + ); } @Override @@ -208,6 +235,7 @@ public class UnlockController implements ViewController { vaultSubs = vaultSubs.and(EasyBind.subscribe(unlockAfterStartup.selectedProperty(), settings.unlockAfterStartup()::set)); vaultSubs = vaultSubs.and(EasyBind.subscribe(mountAfterUnlock.selectedProperty(), settings.mountAfterUnlock()::set)); vaultSubs = vaultSubs.and(EasyBind.subscribe(revealAfterMount.selectedProperty(), settings.revealAfterMount()::set)); + } // **************************************** @@ -233,6 +261,32 @@ public class UnlockController implements ViewController { } } + @FXML + private void didClickchangeMountPathButton(ActionEvent event){ + assert isDirVaild(); + vault.setMountPath(mountPath.getText()); + } + + private boolean isDirVaild(){ + try{ + if(!mountPath.textProperty().isEmpty().get()){ + Path p = Paths.get(mountPath.textProperty().get()); + return Files.isDirectory(p) && Files.isReadable(p) && Files.isWritable(p) && Files.isExecutable(p); + } + else{ + //default path will be taken + return true; + } + + } + catch (InvalidPathException e){ + LOG.info("Invalid path"); + return false; + } + } + + + private void filterAlphanumericKeyEvents(KeyEvent t) { if (!Strings.isNullOrEmpty(t.getCharacter()) && !ALPHA_NUMERIC_MATCHER.matchesAllOf(t.getCharacter())) { t.consume(); diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/AutoUnlocker.java b/main/ui/src/main/java/org/cryptomator/ui/model/AutoUnlocker.java index 3d5ac4201..ba982c872 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/AutoUnlocker.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/AutoUnlocker.java @@ -18,7 +18,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.cryptomator.cryptolib.api.CryptoException; -import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException; import org.cryptomator.keychain.KeychainAccess; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/FuseNioAdapter.java b/main/ui/src/main/java/org/cryptomator/ui/model/FuseNioAdapter.java new file mode 100644 index 000000000..6abd25955 --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/model/FuseNioAdapter.java @@ -0,0 +1,225 @@ +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 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; + } + + @Override + public void unlock(CryptoFileSystem fs) { + this.cfs = fs; + ffs = AdapterFactory.createReadWriteAdapter(fs.getPath("/")); + } + + /** + * TODO: should createTempDirectory() be used instead of createDirectory()? + * + * @throws CommandFailedException + */ + @Override + public void mount() throws CommandFailedException { + ArrayList 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) { + 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; + } + + @Override + public synchronized void unmount() throws CommandFailedException { + if (!(cfs.getStats().pollBytesRead() > 0 || cfs.getStats().pollBytesWritten() > 0)) { + unmountForced(); + } else { + throw new CommandFailedException("Pending read or write operations."); + } + } + + @Override + public synchronized void unmountForced() throws CommandFailedException { + ffs.umount(); + } + + @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; + } + + } + + @Override + public String getFilesystemRootUrl() { + return mountURL; + } + + /** + * 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; + } + + @Override + public boolean supportsForcedUnmount() { + return true; + } + +} diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java index 1e076c2da..d456d4f1f 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java +++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultModule.java @@ -43,13 +43,13 @@ public class VaultModule { @Provides @PerVault - public NioAdapter provideNioAdpater(Settings settings, WebDavNioAdapter webDavNioAdapter) { + public NioAdapter provideNioAdpater(Settings settings, WebDavNioAdapter webDavNioAdapter, FuseNioAdapter fuseNioAdapter) { NioAdapterImpl impl = NioAdapterImpl.valueOf(settings.usedNioAdapterImpl().get()); switch (impl) { case WEBDAV: return webDavNioAdapter; case FUSE: - throw new NotImplementedException(); + return fuseNioAdapter; default: //this should not happen! throw new IllegalStateException("Unsupported NioAdapter: " + settings.usedNioAdapterImpl().get()); diff --git a/main/ui/src/main/resources/fxml/settings.fxml b/main/ui/src/main/resources/fxml/settings.fxml index d3f9c7c12..f778ba090 100644 --- a/main/ui/src/main/resources/fxml/settings.fxml +++ b/main/ui/src/main/resources/fxml/settings.fxml @@ -35,22 +35,37 @@