diff --git a/main/commons/pom.xml b/main/commons/pom.xml
index 5d7b53e9f..5603f36b5 100644
--- a/main/commons/pom.xml
+++ b/main/commons/pom.xml
@@ -17,11 +17,28 @@
Shared utilities
+
com.google.guava
guava
-
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+ com.google.dagger
+ dagger
+
+
+ com.google.dagger
+ dagger-compiler
+ provided
+
+
+
junit
junit
diff --git a/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java
new file mode 100644
index 000000000..d56d22f80
--- /dev/null
+++ b/main/commons/src/main/java/org/cryptomator/common/CommonsModule.java
@@ -0,0 +1,21 @@
+package org.cryptomator.common;
+
+import java.util.Comparator;
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public class CommonsModule {
+
+ @Provides
+ @Singleton
+ @Named("SemVer")
+ Comparator providesSemVerComparator() {
+ return new SemVerComparator();
+ }
+
+}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/util/SemVerComparator.java b/main/commons/src/main/java/org/cryptomator/common/SemVerComparator.java
similarity index 97%
rename from main/ui/src/main/java/org/cryptomator/ui/util/SemVerComparator.java
rename to main/commons/src/main/java/org/cryptomator/common/SemVerComparator.java
index b9031b471..930e2e93d 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/util/SemVerComparator.java
+++ b/main/commons/src/main/java/org/cryptomator/common/SemVerComparator.java
@@ -6,7 +6,7 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
-package org.cryptomator.ui.util;
+package org.cryptomator.common;
import java.util.Comparator;
diff --git a/main/ui/src/test/java/org/cryptomator/ui/util/SemVerComparatorTest.java b/main/commons/src/test/java/org/cryptomator/common/SemVerComparatorTest.java
similarity index 95%
rename from main/ui/src/test/java/org/cryptomator/ui/util/SemVerComparatorTest.java
rename to main/commons/src/test/java/org/cryptomator/common/SemVerComparatorTest.java
index a505d0af4..859eb9471 100644
--- a/main/ui/src/test/java/org/cryptomator/ui/util/SemVerComparatorTest.java
+++ b/main/commons/src/test/java/org/cryptomator/common/SemVerComparatorTest.java
@@ -6,10 +6,11 @@
* Contributors:
* Sebastian Stenzel - initial API and implementation
*******************************************************************************/
-package org.cryptomator.ui.util;
+package org.cryptomator.common;
import java.util.Comparator;
+import org.cryptomator.common.SemVerComparator;
import org.junit.Assert;
import org.junit.Test;
diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java
index 9f6c5dbff..68f1a43e7 100644
--- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java
+++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/WebDavComponent.java
@@ -10,10 +10,12 @@ package org.cryptomator.frontend.webdav;
import javax.inject.Singleton;
+import org.cryptomator.common.CommonsModule;
+
import dagger.Component;
@Singleton
-@Component
+@Component(modules = {CommonsModule.class})
public interface WebDavComponent {
WebDavServer server();
diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java
similarity index 91%
rename from main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXWebDavMounter.java
rename to main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java
index 0acf2ddee..f381e2e6f 100644
--- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXWebDavMounter.java
+++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXAppleScriptWebDavMounter.java
@@ -12,11 +12,13 @@ package org.cryptomator.frontend.webdav.mount;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
+import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
+import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.commons.io.IOUtils;
@@ -26,15 +28,18 @@ import org.cryptomator.frontend.CommandFailedException;
import org.cryptomator.frontend.Frontend.MountParam;
@Singleton
-final class MacOsXWebDavMounter implements WebDavMounterStrategy {
+final class MacOsXAppleScriptWebDavMounter implements WebDavMounterStrategy {
+
+ private final Comparator semVerComparator;
@Inject
- MacOsXWebDavMounter() {
+ MacOsXAppleScriptWebDavMounter(@Named("SemVer") Comparator semVerComparator) {
+ this.semVerComparator = semVerComparator;
}
@Override
public boolean shouldWork() {
- return SystemUtils.IS_OS_MAC_OSX;
+ return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") >= 0;
}
@Override
diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java
new file mode 100644
index 000000000..89e8a86a2
--- /dev/null
+++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MacOsXShellScriptWebDavMounter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2014, 2016 Sebastian Stenzel, Markus Kreusch
+ * This file is licensed under the terms of the MIT license.
+ * See the LICENSE.txt file for more info.
+ *
+ * Contributors:
+ * Sebastian Stenzel - initial API and implementation, strategy fine tuning
+ * Markus Kreusch - Refactored WebDavMounter to use strategy pattern
+ ******************************************************************************/
+package org.cryptomator.frontend.webdav.mount;
+
+import java.net.URI;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.cryptomator.frontend.CommandFailedException;
+import org.cryptomator.frontend.Frontend.MountParam;
+import org.cryptomator.frontend.webdav.mount.command.Script;
+
+@Singleton
+final class MacOsXShellScriptWebDavMounter implements WebDavMounterStrategy {
+
+ private final Comparator semVerComparator;
+
+ @Inject
+ MacOsXShellScriptWebDavMounter(@Named("SemVer") Comparator semVerComparator) {
+ this.semVerComparator = semVerComparator;
+ }
+
+ @Override
+ public boolean shouldWork() {
+ return SystemUtils.IS_OS_MAC_OSX && semVerComparator.compare(SystemUtils.OS_VERSION, "10.10") < 0;
+ }
+
+ @Override
+ public void warmUp(int serverPort) {
+ // no-op
+ }
+
+ @Override
+ public WebDavMount mount(URI uri, Map> mountParams) throws CommandFailedException {
+ final String mountName = mountParams.getOrDefault(MountParam.MOUNT_NAME, Optional.empty()).orElseThrow(() -> {
+ return new IllegalArgumentException("Missing mount parameter MOUNT_NAME.");
+ });
+
+ // we don't use the uri to derive a path, as it *could* be longer than 255 chars.
+ final String path = "/Volumes/Cryptomator_" + UUID.randomUUID().toString();
+ final Script mountScript = Script.fromLines("mkdir \"$MOUNT_PATH\"", "mount_webdav -S -v $MOUNT_NAME \"$DAV_AUTHORITY$DAV_PATH\" \"$MOUNT_PATH\"").addEnv("DAV_AUTHORITY", uri.getRawAuthority())
+ .addEnv("DAV_PATH", uri.getRawPath()).addEnv("MOUNT_PATH", path).addEnv("MOUNT_NAME", mountName);
+ mountScript.execute();
+ return new MacWebDavMount(path);
+ }
+
+ private static class MacWebDavMount extends AbstractWebDavMount {
+ private final String mountPath;
+ private final Script revealScript;
+ private final Script unmountScript;
+
+ private MacWebDavMount(String mountPath) {
+ this.mountPath = mountPath;
+ this.revealScript = Script.fromLines("open \"$MOUNT_PATH\"").addEnv("MOUNT_PATH", mountPath);
+ this.unmountScript = Script.fromLines("diskutil umount $MOUNT_PATH").addEnv("MOUNT_PATH", mountPath);
+ }
+
+ @Override
+ public void unmount() throws CommandFailedException {
+ // only attempt unmount if user didn't unmount manually:
+ if (Files.exists(FileSystems.getDefault().getPath(mountPath))) {
+ unmountScript.execute();
+ }
+ }
+
+ @Override
+ public void reveal() throws CommandFailedException {
+ revealScript.execute();
+ }
+
+ }
+
+}
diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java
index edb5645fa..3cd1b2a08 100644
--- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java
+++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/MountStrategies.java
@@ -19,74 +19,87 @@ import javax.inject.Singleton;
@Singleton
class MountStrategies implements Collection {
-
+
private final Collection delegate;
-
+
@Inject
- MountStrategies(LinuxGvfsWebDavMounter linuxMounter, MacOsXWebDavMounter osxMounter, WindowsWebDavMounter winMounter) {
- delegate = unmodifiableList(asList(linuxMounter, osxMounter, winMounter));
+ MountStrategies(LinuxGvfsWebDavMounter linuxMounter, MacOsXAppleScriptWebDavMounter osxAppleScriptMounter, MacOsXShellScriptWebDavMounter osxShellScriptMounter, WindowsWebDavMounter winMounter) {
+ delegate = unmodifiableList(asList(linuxMounter, osxAppleScriptMounter, osxShellScriptMounter, winMounter));
}
+ @Override
public int size() {
return delegate.size();
}
+ @Override
public boolean isEmpty() {
return delegate.isEmpty();
}
+ @Override
public boolean contains(Object o) {
return delegate.contains(o);
}
+ @Override
public Iterator iterator() {
return delegate.iterator();
}
+ @Override
public Object[] toArray() {
return delegate.toArray();
}
+ @Override
public T[] toArray(T[] a) {
return delegate.toArray(a);
}
+ @Override
public boolean add(WebDavMounterStrategy e) {
return delegate.add(e);
}
+ @Override
public boolean remove(Object o) {
return delegate.remove(o);
}
+ @Override
public boolean containsAll(Collection> c) {
return delegate.containsAll(c);
}
+ @Override
public boolean addAll(Collection extends WebDavMounterStrategy> c) {
return delegate.addAll(c);
}
+ @Override
public boolean removeAll(Collection> c) {
return delegate.removeAll(c);
}
+ @Override
public boolean retainAll(Collection> c) {
return delegate.retainAll(c);
}
+ @Override
public void clear() {
delegate.clear();
}
+ @Override
public boolean equals(Object o) {
return delegate.equals(o);
}
+ @Override
public int hashCode() {
return delegate.hashCode();
}
-
-
}
diff --git a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java
index a2a257a61..4136fd2bf 100644
--- a/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java
+++ b/main/frontend-webdav/src/main/java/org/cryptomator/frontend/webdav/mount/WindowsWebDavMounter.java
@@ -60,12 +60,12 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy {
@Override
public WebDavMount mount(URI uri, Map> mountParams) throws CommandFailedException {
- final String driveLetter = mountParams.getOrDefault(MountParam.WIN_DRIVE_LETTER, Optional.of(AUTO_ASSIGN_DRIVE_LETTER)).orElse(AUTO_ASSIGN_DRIVE_LETTER);
+ final String driveLetter = mountParams.getOrDefault(MountParam.WIN_DRIVE_LETTER, Optional.empty()).orElse(AUTO_ASSIGN_DRIVE_LETTER);
if (driveLetters.getOccupiedDriveLetters().contains(CharUtils.toChar(driveLetter))) {
throw new CommandFailedException("Drive letter occupied.");
}
-
- final String hostname = mountParams.getOrDefault(MountParam.HOSTNAME, Optional.of(LOCALHOST)).orElse(LOCALHOST);
+
+ final String hostname = mountParams.getOrDefault(MountParam.HOSTNAME, Optional.empty()).orElse(LOCALHOST);
try {
final URI adjustedUri = new URI(uri.getScheme(), uri.getUserInfo(), hostname, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
CommandResult mountResult = mount(adjustedUri, driveLetter);
@@ -74,14 +74,13 @@ final class WindowsWebDavMounter implements WebDavMounterStrategy {
throw new IllegalArgumentException("Invalid host: " + hostname);
}
}
-
+
private CommandResult mount(URI uri, String driveLetter) throws CommandFailedException {
- final Script proxyBypassScript = fromLines(
- "reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v \"ProxyOverride\" /d \";%DAV_HOST%;%DAV_HOST%:%DAV_PORT%\" /f");
+ final Script proxyBypassScript = fromLines("reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" /v \"ProxyOverride\" /d \";%DAV_HOST%;%DAV_HOST%:%DAV_PORT%\" /f");
proxyBypassScript.addEnv("DAV_HOST", uri.getHost());
proxyBypassScript.addEnv("DAV_PORT", String.valueOf(uri.getPort()));
proxyBypassScript.execute();
-
+
final String driveLetterStr = AUTO_ASSIGN_DRIVE_LETTER.equals(driveLetter) ? AUTO_ASSIGN_DRIVE_LETTER : driveLetter + ":";
final Script mountScript = fromLines("net use %DRIVE_LETTER% \\\\%DAV_HOST%@%DAV_PORT%\\DavWWWRoot%DAV_UNC_PATH% /persistent:no");
mountScript.addEnv("DRIVE_LETTER", driveLetterStr);
diff --git a/main/pom.xml b/main/pom.xml
index 12de27cb6..1aac82079 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -35,12 +35,12 @@
1.3
2.4
4.0
- 3.3.2
+ 3.4
1.10
3.1
2.4.4
1.10.19
- 2.0.2
+ 2.4
diff --git a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java
index fa432cc9d..3740b566d 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java
@@ -8,13 +8,13 @@
*******************************************************************************/
package org.cryptomator.ui;
-import java.util.Comparator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.inject.Named;
import javax.inject.Singleton;
+import org.cryptomator.common.CommonsModule;
import org.cryptomator.crypto.engine.impl.CryptoEngineModule;
import org.cryptomator.frontend.FrontendFactory;
import org.cryptomator.frontend.webdav.WebDavServer;
@@ -24,7 +24,6 @@ import org.cryptomator.ui.model.VaultObjectMapperProvider;
import org.cryptomator.ui.settings.Settings;
import org.cryptomator.ui.settings.SettingsProvider;
import org.cryptomator.ui.util.DeferredCloser;
-import org.cryptomator.ui.util.SemVerComparator;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -33,7 +32,7 @@ import dagger.Provides;
import javafx.application.Application;
import javafx.stage.Stage;
-@Module(includes = CryptoEngineModule.class)
+@Module(includes = {CryptoEngineModule.class, CommonsModule.class})
class CryptomatorModule {
private final Application application;
@@ -65,13 +64,6 @@ class CryptomatorModule {
return closer;
}
- @Provides
- @Singleton
- @Named("SemVer")
- Comparator provideSemVerComparator() {
- return new SemVerComparator();
- }
-
@Provides
@Singleton
@Named("VaultJsonMapper")