first attempt of building Cryptomator with jdk9

This commit is contained in:
Sebastian Stenzel
2017-12-20 18:42:16 +01:00
parent 8e1bb121bb
commit 4be842aff5
17 changed files with 113 additions and 272 deletions
+4
View File
@@ -76,6 +76,10 @@
<groupId>com.google.dagger</groupId>
<artifactId>dagger-compiler</artifactId>
</dependency>
<dependency>
<groupId>com.google.auto</groupId>
<artifactId>auto-common</artifactId>
</dependency>
<!-- Zxcvbn -->
<dependency>
@@ -16,22 +16,20 @@ import java.util.function.Consumer;
import javax.inject.Named;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.CommonsModule;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.jni.JniModule;
import org.cryptomator.keychain.KeychainModule;
import org.cryptomator.ui.controllers.ViewControllerModule;
import org.cryptomator.ui.model.VaultComponent;
import org.fxmisc.easybind.EasyBind;
import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class, JniModule.class}, subcomponents = {VaultComponent.class})
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
public class UiModule {
@Provides
@@ -9,8 +9,7 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildErrorDialog;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -28,25 +27,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AutoUnlocker;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.cryptomator.ui.util.EawtApplicationWrapper;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.fxmisc.easybind.monadic.MonadicBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Binding;
@@ -81,6 +61,25 @@ import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.model.AutoUnlocker;
import org.cryptomator.ui.model.UpgradeStrategies;
import org.cryptomator.ui.model.UpgradeStrategy;
import org.cryptomator.ui.model.Vault;
import org.cryptomator.ui.model.VaultFactory;
import org.cryptomator.ui.model.VaultList;
import org.cryptomator.ui.util.DialogBuilderUtil;
import org.fxmisc.easybind.EasyBind;
import org.fxmisc.easybind.Subscription;
import org.fxmisc.easybind.monadic.MonadicBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildErrorDialog;
@Singleton
public class MainController implements ViewController {
@@ -129,10 +128,8 @@ public class MainController implements ViewController {
EasyBind.subscribe(areAllVaultsLocked, Platform::setImplicitExit);
autoUnlocker.unlockAllSilently();
EawtApplicationWrapper.getApplication().ifPresent(app -> {
app.setPreferencesHandler(() -> {
Platform.runLater(this::toggleShowSettings);
});
Desktop.getDesktop().setPreferencesHandler(e -> {
Platform.runLater(this::toggleShowSettings);
});
}
@@ -38,6 +38,11 @@ public class VaultList extends TransformationList<Vault, VaultSettings> {
return index;
}
@Override
public int getViewIndex(int index) {
return index;
}
@Override
public Vault get(int index) {
VaultSettings s = source.get(index);
@@ -1,127 +0,0 @@
/*******************************************************************************
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.ui.util;
import java.io.File;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.SupplierThrowingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Reflection-based wrapper for com.apple.eawt.Application.
*/
public class EawtApplicationWrapper {
private static final Logger LOG = LoggerFactory.getLogger(EawtApplicationWrapper.class);
private final Class<?> applicationClass;
private final Object application;
private EawtApplicationWrapper() throws ReflectiveOperationException {
this.applicationClass = Class.forName("com.apple.eawt.Application");
this.application = applicationClass.getMethod("getApplication").invoke(null);
}
/**
* @return A wrapper for com.apple.ewat.Application if the current OS is macOS and the class is available in this JVM.
*/
public static Optional<EawtApplicationWrapper> getApplication() {
if (!SystemUtils.IS_OS_MAC_OSX) {
return Optional.empty();
}
try {
return Optional.of(new EawtApplicationWrapper());
} catch (ReflectiveOperationException e) {
return Optional.empty();
}
}
private void setOpenFileHandler(InvocationHandler handler) throws ReflectiveOperationException {
Class<?> handlerClass = Class.forName("com.apple.eawt.OpenFilesHandler");
Method setter = applicationClass.getMethod("setOpenFileHandler", handlerClass);
Object proxy = Proxy.newProxyInstance(applicationClass.getClassLoader(), new Class<?>[] {handlerClass}, handler);
setter.invoke(application, proxy);
}
public void setOpenFileHandler(Consumer<List<File>> handler) {
try {
Class<?> openFilesEventClass = Class.forName("com.apple.eawt.AppEvent$OpenFilesEvent");
Method getFiles = openFilesEventClass.getMethod("getFiles");
setOpenFileHandler(methodSpecificInvocationHandler("openFiles", args -> {
Object openFilesEvent = args[0];
assert openFilesEventClass.isInstance(openFilesEvent);
@SuppressWarnings("unchecked")
List<File> files = (List<File>) uncheckedReflectiveOperation(() -> getFiles.invoke(openFilesEvent));
handler.accept(files);
return null;
}));
} catch (ReflectiveOperationException e) {
LOG.error("Exception setting openFileHandler.", e);
}
}
private void setPreferencesHandler(InvocationHandler handler) throws ReflectiveOperationException {
Class<?> handlerClass = Class.forName("com.apple.eawt.PreferencesHandler");
Method setter = applicationClass.getMethod("setPreferencesHandler", handlerClass);
Object proxy = Proxy.newProxyInstance(applicationClass.getClassLoader(), new Class<?>[] {handlerClass}, handler);
setter.invoke(application, proxy);
}
public void setPreferencesHandler(Runnable handler) {
try {
setPreferencesHandler(methodSpecificInvocationHandler("handlePreferences", args -> {
handler.run();
return null;
}));
} catch (ReflectiveOperationException e) {
LOG.error("Exception setting preferencesHandler.", e);
}
}
private static InvocationHandler methodSpecificInvocationHandler(String methodName, Function<Object[], Object> handler) {
return new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals(methodName)) {
return handler.apply(args);
} else {
throw new UnsupportedOperationException("Unexpected invocation " + method.getName() + ", expected " + methodName);
}
}
};
}
/**
* Wraps {@link ReflectiveOperationException}s as {@link UncheckedReflectiveOperationException}.
*
* @param operation Invokation throwing an ReflectiveOperationException
* @return Result returned by <code>operation</code>
* @throws UncheckedReflectiveOperationException in case <code>operation</code> throws an ReflectiveOperationException.
*/
private static <T> T uncheckedReflectiveOperation(SupplierThrowingException<T, ReflectiveOperationException> operation) throws UncheckedReflectiveOperationException {
try {
return operation.get();
} catch (ReflectiveOperationException e) {
throw new UncheckedReflectiveOperationException(e);
}
}
private static class UncheckedReflectiveOperationException extends RuntimeException {
public UncheckedReflectiveOperationException(ReflectiveOperationException cause) {
super(cause);
}
}
}