This commit is contained in:
Sebastian Stenzel
2017-05-28 00:08:08 +02:00
parent f4265e1d73
commit 8c55946cf0
2 changed files with 44 additions and 25 deletions

View File

@@ -13,7 +13,6 @@ import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.util.concurrent.BlockingQueue;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.util.EawtApplicationWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,13 +24,11 @@ class FileOpenRequestHandler {
public FileOpenRequestHandler(BlockingQueue<Path> fileOpenRequests) {
this.fileOpenRequests = fileOpenRequests;
if (SystemUtils.IS_OS_MAC_OSX) {
EawtApplicationWrapper.getApplication().ifPresent(app -> {
app.setOpenFileHandler(files -> {
files.stream().map(File::toPath).forEach(fileOpenRequests::add);
});
EawtApplicationWrapper.getApplication().ifPresent(app -> {
app.setOpenFileHandler(files -> {
files.stream().map(File::toPath).forEach(fileOpenRequests::add);
});
}
});
}
public void handleLaunchArgs(String[] args) {

View File

@@ -12,7 +12,10 @@ 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;
@@ -31,7 +34,13 @@ public class EawtApplicationWrapper {
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) {
@@ -50,15 +59,12 @@ public class EawtApplicationWrapper {
try {
Class<?> openFilesEventClass = Class.forName("com.apple.eawt.AppEvent$OpenFilesEvent");
Method getFiles = openFilesEventClass.getMethod("getFiles");
setOpenFileHandler(newMethodSpecificInvocationHandler("openFiles", args -> {
try {
Object openFilesEvent = args[0];
@SuppressWarnings("unchecked")
List<File> files = (List<File>) getFiles.invoke(openFilesEvent);
handler.accept(files);
} catch (ReflectiveOperationException e) {
LOG.error("Error invoking openFileHandler.", e);
}
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) {
@@ -75,7 +81,7 @@ public class EawtApplicationWrapper {
public void setPreferencesHandler(Runnable handler) {
try {
setPreferencesHandler(newMethodSpecificInvocationHandler("handlePreferences", args -> {
setPreferencesHandler(methodSpecificInvocationHandler("handlePreferences", args -> {
handler.run();
return null;
}));
@@ -84,22 +90,38 @@ public class EawtApplicationWrapper {
}
}
@FunctionalInterface
private static interface MethodSpecificInvocationHandler {
Object invoke(Object[] args);
}
private static InvocationHandler newMethodSpecificInvocationHandler(String methodName, MethodSpecificInvocationHandler handler) {
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.invoke(args);
return handler.apply(args);
} else {
return null;
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);
}
}
}