This commit is contained in:
Sebastian Stenzel
2019-07-10 15:14:23 +02:00
parent 7fedcafa9e
commit f880db4902
27 changed files with 142 additions and 108 deletions

View File

@@ -11,30 +11,38 @@ import java.util.concurrent.ConcurrentMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
class CleanShutdownPerformer extends Thread {
private static final Logger LOG = LoggerFactory.getLogger(CleanShutdownPerformer.class);
static final ConcurrentMap<Runnable, Boolean> SHUTDOWN_TASKS = new ConcurrentHashMap<>();
private final ConcurrentMap<Runnable, Boolean> tasks = new ConcurrentHashMap<>();
@Inject
CleanShutdownPerformer() {
super(null, null, "ShutdownTasks", 0);
}
@Override
public void run() {
LOG.debug("Running graceful shutdown tasks...");
SHUTDOWN_TASKS.keySet().forEach(r -> {
tasks.keySet().forEach(r -> {
try {
r.run();
} catch (RuntimeException e) {
LOG.error("Exception while shutting down.", e);
}
});
SHUTDOWN_TASKS.clear();
LOG.info("Goodbye.");
tasks.clear();
}
static void scheduleShutdownTask(Runnable task) {
SHUTDOWN_TASKS.put(task, Boolean.TRUE);
void scheduleShutdownTask(Runnable task) {
tasks.put(task, Boolean.TRUE);
}
static void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new CleanShutdownPerformer());
void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(this);
}
}

View File

@@ -5,12 +5,11 @@
*******************************************************************************/
package org.cryptomator.launcher;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.application.Platform;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.logging.LoggerConfiguration;
import org.cryptomator.ui.controllers.MainController;
import org.cryptomator.ui.FxApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -19,6 +18,7 @@ import javax.inject.Named;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
@Singleton
public class Cryptomator {
@@ -32,13 +32,17 @@ public class Cryptomator {
private final DebugMode debugMode;
private final IpcFactory ipcFactory;
private final Optional<String> applicationVersion;
private final CountDownLatch shutdownLatch;
private final CleanShutdownPerformer shutdownPerformer;
@Inject
Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, IpcFactory ipcFactory, @Named("applicationVersion") Optional<String> applicationVersion) {
Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, IpcFactory ipcFactory, @Named("applicationVersion") Optional<String> applicationVersion, @Named("shutdownLatch") CountDownLatch shutdownLatch, CleanShutdownPerformer shutdownPerformer) {
this.logConfig = logConfig;
this.debugMode = debugMode;
this.ipcFactory = ipcFactory;
this.applicationVersion = applicationVersion;
this.shutdownLatch = shutdownLatch;
this.shutdownPerformer = shutdownPerformer;
}
public static void main(String[] args) {
@@ -48,6 +52,7 @@ public class Cryptomator {
/**
* Main entry point of the application launcher.
*
* @param args The arguments passed to this program via {@link #main(String[])}.
* @return Nonzero exit code in case of an error.
*/
@@ -77,45 +82,26 @@ public class Cryptomator {
/**
* Launches the JavaFX application and waits until shutdown is requested.
*
* @return Nonzero exit code in case of an error.
* @implNote This method blocks until {@link #shutdownLatch} reached zero.
*/
private int runGuiApplication() {
try {
CleanShutdownPerformer.registerShutdownHook();
Application.launch(MainApp.class);
LOG.info("Shutting down...");
shutdownPerformer.registerShutdownHook();
Platform.startup(() -> {
assert Platform.isFxApplicationThread();
FxApplication app = CRYPTOMATOR_COMPONENT.fxApplicationComponent().application();
app.start();
});
shutdownLatch.await();
LOG.info("UI shut down");
return 0;
} catch (Throwable e) {
LOG.error("Terminating due to error", e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return 1;
}
}
// We need a separate FX Application class, until we can use the module system. See https://stackoverflow.com/q/54756176/4014509
public static class MainApp extends Application {
@Override
public void start(Stage primaryStage) {
LOG.info("JavaFX application started.");
primaryStage.setMinWidth(652.0);
primaryStage.setMinHeight(440.0);
FxApplicationComponent fxApplicationComponent = CRYPTOMATOR_COMPONENT.fxApplicationComponent() //
.fxApplication(this) //
.mainWindow(primaryStage) //
.build();
MainController mainCtrl = fxApplicationComponent.fxmlLoader().load("/fxml/main.fxml");
mainCtrl.initStage(primaryStage);
primaryStage.show();
}
@Override
public void stop() {
LOG.info("JavaFX application stopped.");
}
}
}

View File

@@ -3,6 +3,7 @@ package org.cryptomator.launcher;
import dagger.Component;
import org.cryptomator.common.CommonsModule;
import org.cryptomator.logging.LoggerModule;
import org.cryptomator.ui.FxApplicationComponent;
import javax.inject.Singleton;
@@ -12,6 +13,6 @@ public interface CryptomatorComponent {
Cryptomator application();
FxApplicationComponent.Builder fxApplicationComponent();
FxApplicationComponent fxApplicationComponent();
}

View File

@@ -4,6 +4,7 @@ import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.ui.model.AppLaunchEvent;
import javax.inject.Named;
@@ -12,10 +13,25 @@ import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
@Module
class CryptomatorModule {
@Provides
@Singleton
@Named("shutdownTaskScheduler")
Consumer<Runnable> provideShutdownTaskScheduler(CleanShutdownPerformer shutdownPerformer) {
return shutdownPerformer::scheduleShutdownTask;
}
@Provides
@Singleton
@Named("shutdownLatch")
static CountDownLatch provideShutdownLatch() {
return new CountDownLatch(1);
}
@Provides
@Singleton
static Settings provideSettings(SettingsProvider settingsProvider) {

View File

@@ -1,36 +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.launcher;
import dagger.BindsInstance;
import dagger.Subcomponent;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.controllers.ViewControllerLoader;
import javax.inject.Named;
@FxApplicationScoped
@Subcomponent(modules = FxApplicationModule.class)
interface FxApplicationComponent {
ViewControllerLoader fxmlLoader();
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder fxApplication(Application application);
@BindsInstance
Builder mainWindow(@Named("mainWindow") Stage mainWindow);
FxApplicationComponent build();
}
}

View File

@@ -12,7 +12,6 @@ package org.cryptomator.ui;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.jni.JniException;
import org.cryptomator.jni.MacApplicationUiState;

View File

@@ -0,0 +1,39 @@
package org.cryptomator.ui;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.ui.controllers.MainController;
import org.cryptomator.ui.controllers.ViewControllerLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
@FxApplicationScoped
public class FxApplication extends Application {
private static final Logger LOG = LoggerFactory.getLogger(FxApplication.class);
private final Stage primaryStage;
private final ViewControllerLoader fxmlLoader;
@Inject
FxApplication(@Named("mainWindow") Stage primaryStage, ViewControllerLoader fxmlLoader) {
this.primaryStage = primaryStage;
this.fxmlLoader = fxmlLoader;
}
public void start() {
LOG.info("Starting GUI...");
start(primaryStage);
}
@Override
public void start(Stage primaryStage) {
MainController mainCtrl = fxmlLoader.load("/fxml/main.fxml");
mainCtrl.initStage(primaryStage);
primaryStage.show();
}
}

View File

@@ -0,0 +1,16 @@
/*******************************************************************************
* 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;
import dagger.Subcomponent;
@FxApplicationScoped
@Subcomponent(modules = FxApplicationModule.class)
public interface FxApplicationComponent {
FxApplication application();
}

View File

@@ -3,24 +3,31 @@
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the accompanying LICENSE file.
*******************************************************************************/
package org.cryptomator.launcher;
package org.cryptomator.ui;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.UiModule;
import javafx.application.Application;
import javafx.stage.Stage;
import javax.inject.Named;
import java.util.function.Consumer;
@Module(includes = {UiModule.class})
class FxApplicationModule {
abstract class FxApplicationModule {
@Provides
@FxApplicationScoped
@Named("shutdownTaskScheduler")
Consumer<Runnable> provideShutdownTaskScheduler() {
return CleanShutdownPerformer::scheduleShutdownTask;
@Named("mainWindow")
static Stage providePrimaryStage() {
Stage stage = new Stage();
stage.setMinWidth(652.0);
stage.setMinHeight(440.0);
return stage;
}
@Binds
@FxApplicationScoped
abstract Application provideApplication(FxApplication application);
}

View File

@@ -1,4 +1,4 @@
package org.cryptomator.common;
package org.cryptomator.ui;
import javax.inject.Scope;
import java.lang.annotation.Documented;

View File

@@ -12,7 +12,6 @@ import dagger.Module;
import dagger.Provides;
import javafx.beans.binding.Binding;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.frontend.webdav.WebDavServer;
import org.cryptomator.keychain.KeychainModule;

View File

@@ -44,7 +44,7 @@ import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;

View File

@@ -8,7 +8,7 @@ package org.cryptomator.ui.controllers;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.layout.VBox;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import javax.inject.Inject;

View File

@@ -12,7 +12,6 @@ import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.Parent;
@@ -25,7 +24,7 @@ import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import javafx.util.StringConverter;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.ui.l10n.Localization;

View File

@@ -6,7 +6,7 @@
package org.cryptomator.ui.controllers;
import javafx.fxml.FXMLLoader;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.ui.l10n.Localization;
import javax.inject.Inject;

View File

@@ -23,7 +23,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.layout.VBox;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.util.Tasks;

View File

@@ -7,7 +7,7 @@ package org.cryptomator.ui.l10n;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -5,7 +5,7 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.keychain.KeychainAccess;
import org.slf4j.Logger;

View File

@@ -8,7 +8,7 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.common.settings.VaultSettings;
import javax.inject.Inject;

View File

@@ -9,7 +9,7 @@ import com.google.common.collect.Lists;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.TransformationList;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;

View File

@@ -6,7 +6,7 @@
package org.cryptomator.ui.model;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -5,7 +5,7 @@
*******************************************************************************/
package org.cryptomator.ui.model.upgrade;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.ui.model.Vault;
import javax.inject.Inject;

View File

@@ -7,7 +7,7 @@ package org.cryptomator.ui.model.upgrade;
import javafx.application.Platform;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.ui.l10n.Localization;

View File

@@ -7,7 +7,7 @@ package org.cryptomator.ui.model.upgrade;
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.common.MessageDigestSupplier;

View File

@@ -5,7 +5,7 @@
*******************************************************************************/
package org.cryptomator.ui.model.upgrade;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.api.FileHeader;

View File

@@ -5,7 +5,7 @@
*******************************************************************************/
package org.cryptomator.ui.model.upgrade;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.cryptofs.migration.Migrators;
import org.cryptomator.cryptofs.migration.api.NoApplicableMigratorException;
import org.cryptomator.cryptolib.Cryptors;

View File

@@ -15,7 +15,7 @@ import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.FxApplicationScoped;
import org.cryptomator.ui.l10n.Localization;
import javax.inject.Inject;