|
@@ -6,49 +6,104 @@
|
|
|
package org.cryptomator.launcher;
|
|
|
|
|
|
import javafx.application.Application;
|
|
|
+import javafx.application.Platform;
|
|
|
import javafx.stage.Stage;
|
|
|
import org.apache.commons.lang3.SystemUtils;
|
|
|
+import org.cryptomator.logging.DebugMode;
|
|
|
+import org.cryptomator.logging.LoggerConfiguration;
|
|
|
import org.cryptomator.ui.controllers.MainController;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
+import javax.inject.Inject;
|
|
|
+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 {
|
|
|
|
|
|
- private static final Logger LOG;
|
|
|
- private static final CryptomatorComponent CRYPTOMATOR_COMPONENT;
|
|
|
+ // DaggerCryptomatorComponent gets generated by Dagger.
|
|
|
+ // Run Maven and include target/generated-sources/annotations in your IDE.
|
|
|
+ private static final CryptomatorComponent CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.create();
|
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
|
|
|
|
|
|
- static {
|
|
|
- // DaggerCryptomatorComponent gets generated by Dagger.
|
|
|
- // Run Maven and include target/generated-sources/annotations in your IDE.
|
|
|
- CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.create();
|
|
|
- CRYPTOMATOR_COMPONENT.initLogging().run();
|
|
|
- LOG = LoggerFactory.getLogger(Cryptomator.class);
|
|
|
+ private final LoggerConfiguration logConfig;
|
|
|
+ private final DebugMode debugMode;
|
|
|
+ private final IpcFactory ipcFactory;
|
|
|
+ private final Optional<String> applicationVersion;
|
|
|
+
|
|
|
+ @Inject
|
|
|
+ Cryptomator(LoggerConfiguration logConfig, DebugMode debugMode, IpcFactory ipcFactory, @Named("applicationVersion") Optional<String> applicationVersion) {
|
|
|
+ this.logConfig = logConfig;
|
|
|
+ this.debugMode = debugMode;
|
|
|
+ this.ipcFactory = ipcFactory;
|
|
|
+ this.applicationVersion = applicationVersion;
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
- LOG.info("Starting Cryptomator {} on {} {} ({})", CRYPTOMATOR_COMPONENT.applicationVersion().orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
|
|
+ int exitCode = CRYPTOMATOR_COMPONENT.application().run(args);
|
|
|
+ System.exit(exitCode); // end remaining non-daemon threads.
|
|
|
+ }
|
|
|
|
|
|
- try (IpcFactory.IpcEndpoint endpoint = CRYPTOMATOR_COMPONENT.ipcFactory().create()) {
|
|
|
+ /**
|
|
|
+ * 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.
|
|
|
+ */
|
|
|
+ private int run(String[] args) {
|
|
|
+ logConfig.init();
|
|
|
+ LOG.info("Starting Cryptomator {} on {} {} ({})", applicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
|
|
|
+
|
|
|
+ if (sendArgsToRunningInstance(args)) {
|
|
|
+ LOG.info("Found running application instance. Shutting down...");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ runGuiApplication();
|
|
|
+ LOG.info("Shutting down...");
|
|
|
+ return 0;
|
|
|
+ } catch (Throwable e) {
|
|
|
+ LOG.error("Terminating due to error", e);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Attempts to create an IPC connection to a running Cryptomator instance and sends it the given args.
|
|
|
+ * If no external process could be reached, the args will be handled by the loopback IPC endpoint.
|
|
|
+ *
|
|
|
+ * @param args Arguments to send to the instance (if possible)
|
|
|
+ * @return <code>true</code> if a different process could be reached, <code>false</code> otherwise.
|
|
|
+ */
|
|
|
+ private boolean sendArgsToRunningInstance(String[] args) {
|
|
|
+ try (IpcFactory.IpcEndpoint endpoint = ipcFactory.create()) {
|
|
|
endpoint.getRemote().handleLaunchArgs(args); // if we are the server, getRemote() returns self.
|
|
|
- if (endpoint.isConnectedToRemote()) {
|
|
|
- LOG.info("Found running application instance. Shutting down.");
|
|
|
- } else {
|
|
|
- CRYPTOMATOR_COMPONENT.debugMode().initialize();
|
|
|
- CleanShutdownPerformer.registerShutdownHook();
|
|
|
- Application.launch(MainApp.class, args);
|
|
|
- }
|
|
|
+ return endpoint.isConnectedToRemote();
|
|
|
} catch (IOException e) {
|
|
|
LOG.error("Failed to initiate inter-process communication.", e);
|
|
|
- System.exit(2);
|
|
|
- } catch (Throwable e) {
|
|
|
- LOG.error("Error during startup", e);
|
|
|
- System.exit(1);
|
|
|
+ return false;
|
|
|
}
|
|
|
- System.exit(0); // end remaining non-daemon threads.
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Launches the JavaFX application and waits until shutdown is requested.
|
|
|
+ */
|
|
|
+ private void runGuiApplication() {
|
|
|
+ debugMode.initialize();
|
|
|
+ CleanShutdownPerformer.registerShutdownHook();
|
|
|
+ Application.launch(MainApp.class);
|
|
|
+// Platform.startup(() -> {
|
|
|
+// assert Platform.isFxApplicationThread();
|
|
|
+// FxApplication app = CRYPTOMATOR_COMPONENT.fxApplicationComponent().application();
|
|
|
+// app.start();
|
|
|
+// });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
// 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 {
|
|
|
|