From aed35c17c84346668f9a7fe4217b7f02ea42b1ea Mon Sep 17 00:00:00 2001 From: Sebastian Stenzel Date: Sun, 17 Jun 2018 13:59:28 +0200 Subject: [PATCH] Added Dokany Support fixes #207 --- .../cryptomator/common/settings/Settings.java | 10 ++-- .../common/settings/SettingsJsonAdapter.java | 10 ++-- .../common/settings/VolumeImpl.java | 3 +- .../settings/SettingsJsonAdapterTest.java | 4 +- main/pom.xml | 8 ++- main/ui/pom.xml | 17 ++++--- .../ui/controllers/SettingsController.java | 4 +- .../ui/controllers/UnlockController.java | 2 +- .../cryptomator/ui/model/DokanyVolume.java | 51 +++++++++++++++++++ .../org/cryptomator/ui/model/VaultModule.java | 23 ++++----- 10 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java 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 25ed6021a..7f57122a3 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 @@ -26,7 +26,7 @@ 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 VolumeImpl DEFAULT_VOLUME_IMPL = VolumeImpl.FUSE; + public static final VolumeImpl DEFAULT_PREFERRED_VOLUME_IMPL = System.getProperty("os.name").toLowerCase().contains("windows") ? VolumeImpl.DOKANY : VolumeImpl.FUSE; private final ObservableList directories = FXCollections.observableArrayList(VaultSettings::observables); private final BooleanProperty askedForUpdateCheck = new SimpleBooleanProperty(DEFAULT_ASKED_FOR_UPDATE_CHECK); @@ -35,7 +35,7 @@ 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 ObjectProperty volumeImpl = new SimpleObjectProperty<>(DEFAULT_VOLUME_IMPL); + private final ObjectProperty preferredVolumeImpl = new SimpleObjectProperty<>(DEFAULT_PREFERRED_VOLUME_IMPL); private Consumer saveCmd; @@ -50,7 +50,7 @@ public class Settings { numTrayNotifications.addListener(this::somethingChanged); preferredGvfsScheme.addListener(this::somethingChanged); debugMode.addListener(this::somethingChanged); - volumeImpl.addListener(this::somethingChanged); + preferredVolumeImpl.addListener(this::somethingChanged); } void setSaveCmd(Consumer saveCmd) { @@ -97,8 +97,8 @@ public class Settings { return debugMode; } - public ObjectProperty volumeImpl() { - return volumeImpl; + public ObjectProperty preferredVolumeImpl() { + return preferredVolumeImpl; } } 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 e02b901a0..2ece80909 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,7 +33,7 @@ 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("volumeImpl").value(value.volumeImpl().get().name()); + out.name("preferredVolumeImpl").value(value.preferredVolumeImpl().get().name()); out.endObject(); } @@ -74,8 +74,8 @@ public class SettingsJsonAdapter extends TypeAdapter { case "debugMode": settings.debugMode().set(in.nextBoolean()); break; - case "volumeImpl": - settings.volumeImpl().set(parseNioAdapterName(in.nextString())); + case "preferredVolumeImpl": + settings.preferredVolumeImpl().set(parsePreferredVolumeImplName(in.nextString())); break; default: LOG.warn("Unsupported vault setting found in JSON: " + name); @@ -87,11 +87,11 @@ public class SettingsJsonAdapter extends TypeAdapter { return settings; } - private VolumeImpl parseNioAdapterName(String nioAdapterName) { + private VolumeImpl parsePreferredVolumeImplName(String nioAdapterName) { try { return VolumeImpl.valueOf(nioAdapterName); } catch (IllegalArgumentException e) { - return Settings.DEFAULT_VOLUME_IMPL; + return Settings.DEFAULT_PREFERRED_VOLUME_IMPL; } } diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/VolumeImpl.java b/main/commons/src/main/java/org/cryptomator/common/settings/VolumeImpl.java index 0862c499b..634f528f4 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/VolumeImpl.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/VolumeImpl.java @@ -4,7 +4,8 @@ import java.util.Arrays; public enum VolumeImpl { WEBDAV("WebDAV"), - FUSE("FUSE"); + FUSE("FUSE"), + DOKANY("DOKANY"); private String displayName; diff --git a/main/commons/src/test/java/org/cryptomator/common/settings/SettingsJsonAdapterTest.java b/main/commons/src/test/java/org/cryptomator/common/settings/SettingsJsonAdapterTest.java index 511197d29..cee09295a 100644 --- a/main/commons/src/test/java/org/cryptomator/common/settings/SettingsJsonAdapterTest.java +++ b/main/commons/src/test/java/org/cryptomator/common/settings/SettingsJsonAdapterTest.java @@ -22,7 +22,7 @@ public class SettingsJsonAdapterTest { + "\"checkForUpdatesEnabled\": true,"// + "\"port\": 8080,"// + "\"numTrayNotifications\": 42,"// - + "\"volumeImpl\": \"FUSE\"}"; + + "\"preferredVolumeImpl\": \"FUSE\"}"; Settings settings = adapter.fromJson(json); @@ -31,7 +31,7 @@ public class SettingsJsonAdapterTest { Assert.assertEquals(8080, settings.port().get()); Assert.assertEquals(42, settings.numTrayNotifications().get()); Assert.assertEquals("dav", settings.preferredGvfsScheme().get()); - Assert.assertEquals(VolumeImpl.FUSE, settings.volumeImpl().get()); + Assert.assertEquals(VolumeImpl.FUSE, settings.preferredVolumeImpl().get()); } } diff --git a/main/pom.xml b/main/pom.xml index 79b6c1548..06ce495ee 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -26,9 +26,10 @@ 1.2.0 1.5.2 - 1.0.4 2.0.0 0.1.5 + 0.1.0 + 1.0.4 2.5 3.6 @@ -105,6 +106,11 @@ fuse-nio-adapter ${cryptomator.fuse.version} + + org.cryptomator + dokany-nio-adapter + ${cryptomator.dokany.version} + org.cryptomator webdav-nio-adapter diff --git a/main/ui/pom.xml b/main/ui/pom.xml index 6c26bc1a0..2421329e6 100644 --- a/main/ui/pom.xml +++ b/main/ui/pom.xml @@ -10,29 +10,34 @@ Cryptomator GUI + + org.cryptomator + keychain + org.cryptomator commons + org.cryptomator cryptofs - - org.cryptomator - webdav-nio-adapter - org.cryptomator jni org.cryptomator - keychain + fuse-nio-adapter org.cryptomator - fuse-nio-adapter + dokany-nio-adapter + + + org.cryptomator + webdav-nio-adapter 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 f4b997314..8b96f80a6 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 @@ -97,7 +97,7 @@ public class SettingsController implements ViewController { //NIOADAPTER volume.getItems().addAll(getSupportedAdapters()); - volume.setValue(settings.volumeImpl().get()); + volume.setValue(settings.preferredVolumeImpl().get()); volume.setVisible(true); volume.setConverter(new NioAdapterImplStringConverter()); @@ -127,7 +127,7 @@ public class SettingsController implements ViewController { settings.checkForUpdates().bind(checkForUpdatesCheckbox.selectedProperty()); settings.preferredGvfsScheme().bind(prefGvfsScheme.valueProperty()); - settings.volumeImpl().bind(volume.valueProperty()); + settings.preferredVolumeImpl().bind(volume.valueProperty()); settings.debugMode().bind(debugModeCheckbox.selectedProperty()); } 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 9b39c96fc..b6588be5c 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 @@ -181,7 +181,7 @@ public class UnlockController implements ViewController { winDriveLetterLabel.setManaged(false); winDriveLetter.setVisible(false); winDriveLetter.setManaged(false); - if (VolumeImpl.WEBDAV.equals(settings.volumeImpl().get())) { + if (VolumeImpl.WEBDAV.equals(settings.preferredVolumeImpl().get())) { useOwnMountPath.setVisible(false); useOwnMountPath.setManaged(false); mountPathLabel.setManaged(false); diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java b/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java new file mode 100644 index 000000000..38b5166de --- /dev/null +++ b/main/ui/src/main/java/org/cryptomator/ui/model/DokanyVolume.java @@ -0,0 +1,51 @@ +package org.cryptomator.ui.model; + +import javax.inject.Inject; +import java.util.concurrent.ExecutorService; + +import org.cryptomator.common.settings.VaultSettings; +import org.cryptomator.cryptofs.CryptoFileSystem; +import org.cryptomator.frontend.dokany.Mount; +import org.cryptomator.frontend.dokany.MountFactory; + +@VaultModule.PerVault +public class DokanyVolume implements Volume { + + private static final String FS_TYPE_NAME = "Cryptomator File System"; + + private final VaultSettings vaultSettings; + private final MountFactory mountFactory; + private Mount mount; + + @Inject + public DokanyVolume(VaultSettings vaultSettings, ExecutorService executorService) { + this.vaultSettings = vaultSettings; + this.mountFactory = new MountFactory(executorService); + } + + + @Override + public boolean isSupported() { + return MountFactory.isApplicable(); + } + + @Override + public void mount(CryptoFileSystem fs) { + char driveLetter = vaultSettings.winDriveLetter().get().charAt(0); + String mountName = vaultSettings.mountName().get(); + this.mount = mountFactory.mount(fs.getPath("/"), driveLetter, mountName, FS_TYPE_NAME); + } + + @Override + public void reveal() throws VolumeException { + boolean success = mount.reveal(); + if (!success) { + throw new VolumeException("Reveal failed."); + } + } + + @Override + public void unmount() { + mount.close(); + } +} 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 93c130522..18b7dec05 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,20 +43,15 @@ public class VaultModule { @Provides @PerVault - public Volume provideNioAdpater(Settings settings, WebDavVolume webDavVolume, FuseVolume fuseVolume) { - VolumeImpl impl = settings.volumeImpl().get(); - switch (impl) { - case FUSE: - if (fuseVolume.isSupported()) { - return fuseVolume; - } else { - settings.volumeImpl().set(VolumeImpl.WEBDAV); - // fallthrough to WEBDAV - } - case WEBDAV: - return webDavVolume; - default: - throw new IllegalStateException("Unsupported NioAdapter: " + impl); + public Volume provideVolume(Settings settings, WebDavVolume webDavVolume, FuseVolume fuseVolume, DokanyVolume dokanyVolume) { + VolumeImpl impl = settings.preferredVolumeImpl().get(); + if (VolumeImpl.DOKANY == impl && dokanyVolume.isSupported()) { + return dokanyVolume; + } else if (VolumeImpl.FUSE == impl && fuseVolume.isSupported()) { + return fuseVolume; + } else { + assert webDavVolume.isSupported(); + return webDavVolume; } }