mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 02:01:27 +00:00
fixes #499
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class Optionals {
|
||||
|
||||
@@ -14,4 +15,16 @@ public final class Optionals {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function that is equivalent to the input function but immediately gets the value of the returned optional when invoked.
|
||||
*
|
||||
* @param <T> the type of the input to the function
|
||||
* @param <R> the type of the result of the function
|
||||
* @param optionalFunction An input function {@code Function<Foo, Optional<Bar>>}
|
||||
* @return A {@code Function<Foo, Bar>}, that may throw an NoSuchElementException, if the original function returns an empty optional.
|
||||
*/
|
||||
public static <T, R> Function<T, R> unwrap(Function<T, Optional<R>> optionalFunction) {
|
||||
return t -> optionalFunction.apply(t).get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,15 +62,7 @@ public class ExitUtil {
|
||||
this.macFunctions = macFunctions;
|
||||
}
|
||||
|
||||
public void initExitHandler() {
|
||||
initExitHandler(ExitUtil::platformExitOnMainThread);
|
||||
}
|
||||
|
||||
private static void platformExitOnMainThread() {
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
|
||||
private void initExitHandler(Runnable exitCommand) {
|
||||
public void initExitHandler(Runnable exitCommand) {
|
||||
if (SystemUtils.IS_OS_LINUX) {
|
||||
initMinimizeExitHandler(exitCommand);
|
||||
} else {
|
||||
|
||||
@@ -189,10 +189,15 @@ public class MainController implements ViewController {
|
||||
stage.getIcons().add(new Image(getClass().getResourceAsStream("/window_icon.png")));
|
||||
Application.setUserAgentStylesheet(getClass().getResource("/css/win_theme.css").toString());
|
||||
}
|
||||
exitUtil.initExitHandler();
|
||||
exitUtil.initExitHandler(this::gracefulShutdown);
|
||||
listenToFileOpenRequests(stage);
|
||||
}
|
||||
|
||||
private void gracefulShutdown() {
|
||||
vaults.filtered(Vault::isUnlocked).forEach(Vault::prepareForShutdown);
|
||||
Platform.runLater(Platform::exit);
|
||||
}
|
||||
|
||||
private void loadFont(String resourcePath) {
|
||||
try (InputStream in = getClass().getResourceAsStream(resourcePath)) {
|
||||
Font.loadFont(in, 12.0);
|
||||
|
||||
@@ -18,13 +18,14 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.ConsumerThrowingException;
|
||||
import org.cryptomator.common.LazyInitializer;
|
||||
import org.cryptomator.common.Optionals;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.cryptofs.CryptoFileSystem;
|
||||
@@ -36,6 +37,7 @@ import org.cryptomator.frontend.webdav.WebDavServer;
|
||||
import org.cryptomator.frontend.webdav.mount.MountParams;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.Mount;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.UnmountOperation;
|
||||
import org.cryptomator.frontend.webdav.servlet.WebDavServletController;
|
||||
import org.cryptomator.ui.model.VaultModule.PerVault;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
@@ -143,17 +145,17 @@ public class Vault {
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void unmount() throws Exception {
|
||||
unmount(mount -> mount.unmount());
|
||||
public synchronized void unmount() throws CommandFailedException {
|
||||
unmount(Function.identity());
|
||||
}
|
||||
|
||||
public synchronized void unmountForced() throws Exception {
|
||||
unmount(mount -> mount.forced().get().unmount());
|
||||
public synchronized void unmountForced() throws CommandFailedException {
|
||||
unmount(Optionals.unwrap(Mount::forced));
|
||||
}
|
||||
|
||||
private synchronized void unmount(ConsumerThrowingException<Mount, CommandFailedException> command) throws CommandFailedException {
|
||||
private synchronized void unmount(Function<Mount, ? extends UnmountOperation> unmountOperationChooser) throws CommandFailedException {
|
||||
if (mount != null) {
|
||||
command.accept(mount);
|
||||
unmountOperationChooser.apply(mount).unmount();
|
||||
}
|
||||
Platform.runLater(() -> {
|
||||
mounted.set(false);
|
||||
@@ -177,6 +179,30 @@ public class Vault {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ejects any mounted drives and locks this vault. no-op if this vault is currently locked.
|
||||
*/
|
||||
public void prepareForShutdown() {
|
||||
try {
|
||||
unmount();
|
||||
} catch (CommandFailedException e) {
|
||||
if (supportsForcedUnmount()) {
|
||||
try {
|
||||
unmountForced();
|
||||
} catch (CommandFailedException e1) {
|
||||
LOG.warn("Failed to force unmount vault.");
|
||||
}
|
||||
} else {
|
||||
LOG.warn("Failed to gracefully unmount vault.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
lock();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to lock vault.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reveal() throws CommandFailedException {
|
||||
if (mount != null) {
|
||||
mount.reveal();
|
||||
|
||||
Reference in New Issue
Block a user