Introduced new scope @FxApplicationScoped below @Singleton.

This allows us to initialize Dagger before we start the JavaFX application, which will in turn allow us to access Environment from within the IPC classes.

Affects #663
This commit is contained in:
Sebastian Stenzel
2019-02-19 00:11:58 +01:00
parent d7dda7d249
commit 79306ea498
34 changed files with 372 additions and 405 deletions

View File

@@ -1,6 +1,5 @@
package org.cryptomator.common;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import org.slf4j.Logger;
@@ -30,7 +29,6 @@ public class Environment {
LOG.debug("cryptomator.settingsPath: {}", System.getProperty("cryptomator.settingsPath"));
LOG.debug("cryptomator.ipcPortPath: {}", System.getProperty("cryptomator.ipcPortPath"));
LOG.debug("cryptomator.keychainPath: {}", System.getProperty("cryptomator.ipcPortPath"));
}
public Stream<Path> getSettingsPath() {

View File

@@ -0,0 +1,13 @@
package org.cryptomator.common;
import javax.inject.Scope;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface FxApplicationScoped {
}

View File

@@ -5,11 +5,10 @@
*******************************************************************************/
package org.cryptomator.keychain;
import java.util.Optional;
import dagger.Component;
import javax.inject.Singleton;
import dagger.Component;
import java.util.Optional;
@Singleton
@Component(modules = KeychainModule.class)

View File

@@ -1,20 +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 java.util.Optional;
public class ApplicationVersion {
public static String orElse(String other) {
return get().orElse(other);
}
public static Optional<String> get() {
return Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion());
}
}

View File

@@ -5,42 +5,83 @@
*******************************************************************************/
package org.cryptomator.launcher;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import javafx.application.Application;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.ui.controllers.MainController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Application;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Cryptomator {
private static final Logger LOG = LoggerFactory.getLogger(Cryptomator.class);
static final BlockingQueue<Path> FILE_OPEN_REQUESTS = new ArrayBlockingQueue<>(10);
private static final CryptomatorComponent CRYPTOMATOR_COMPONENT = DaggerCryptomatorComponent.create();
private static final Path DEFAULT_IPC_PATH = Paths.get(".ipcPort.tmp");
// We need a separate FX Application class.
// If org.cryptomator.launcher.Cryptomator simply extended Application, the module system magically kicks in and throws exceptions
public static class MainApp extends Application {
private Stage primaryStage;
@Override
public void start(Stage primaryStage) {
LOG.info("JavaFX application started.");
this.primaryStage = primaryStage;
primaryStage.setMinWidth(652.0);
primaryStage.setMinHeight(440.0);
FxApplicationComponent fxApplicationComponent = CRYPTOMATOR_COMPONENT.fxApplicationComponent() //
.fxApplication(this) //
.mainWindow(primaryStage) //
.build();
fxApplicationComponent.debugMode().initialize();
MainController mainCtrl = fxApplicationComponent.fxmlLoader().load("/fxml/main.fxml");
mainCtrl.initStage(primaryStage);
primaryStage.show();
}
@Override
public void stop() {
assert primaryStage != null;
primaryStage.hide();
LOG.info("JavaFX application stopped.");
}
}
public static void main(String[] args) {
LOG.info("Starting Cryptomator {} on {} {} ({})", ApplicationVersion.orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
LOG.info("Starting Cryptomator {} on {} {} ({})", CRYPTOMATOR_COMPONENT.applicationVersion().orElse("SNAPSHOT"), SystemUtils.OS_NAME, SystemUtils.OS_VERSION, SystemUtils.OS_ARCH);
FileOpenRequestHandler fileOpenRequestHandler = new FileOpenRequestHandler(FILE_OPEN_REQUESTS);
try (InterProcessCommunicator communicator = InterProcessCommunicator.start(new IpcProtocolImpl(fileOpenRequestHandler))) {
FileOpenRequestHandler fileOpenRequestHandler = CRYPTOMATOR_COMPONENT.fileOpenRequestHanlder();
Path ipcPortPath = CRYPTOMATOR_COMPONENT.environment().getIpcPortPath().findFirst().orElse(DEFAULT_IPC_PATH);
try (InterProcessCommunicator communicator = InterProcessCommunicator.start(ipcPortPath, new IpcProtocolImpl(fileOpenRequestHandler))) {
if (communicator.isServer()) {
fileOpenRequestHandler.handleLaunchArgs(args);
CleanShutdownPerformer.registerShutdownHook();
Application.launch(MainApplication.class, args);
Application.launch(MainApp.class, args);
} else {
communicator.handleLaunchArgs(args);
LOG.info("Found running application instance. Shutting down.");
}
System.exit(0); // end remaining non-daemon threads.
} 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);
}
System.exit(0); // end remaining non-daemon threads.
}
private static class IpcProtocolImpl implements InterProcessCommunicationProtocol {

View File

@@ -0,0 +1,26 @@
package org.cryptomator.launcher;
import dagger.Component;
import org.cryptomator.common.CommonsModule;
import org.cryptomator.common.Environment;
import javax.inject.Named;
import javax.inject.Singleton;
import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
@Singleton
@Component(modules = {CryptomatorModule.class, CommonsModule.class})
public interface CryptomatorComponent {
Environment environment();
FileOpenRequestHandler fileOpenRequestHanlder();
@Named("applicationVersion")
Optional<String> applicationVersion();
FxApplicationComponent.Builder fxApplicationComponent();
}

View File

@@ -0,0 +1,30 @@
package org.cryptomator.launcher;
import dagger.Module;
import dagger.Provides;
import javax.inject.Named;
import javax.inject.Singleton;
import java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@Module
class CryptomatorModule {
@Provides
@Singleton
@Named("fileOpenRequests")
BlockingQueue<Path> provideFileOpenRequests() {
return new ArrayBlockingQueue<>(10);
}
@Provides
@Singleton
@Named("applicationVersion")
Optional<String> provideApplicationVersion() {
return Optional.ofNullable(Cryptomator.class.getPackage().getImplementationVersion());
}
}

View File

@@ -7,6 +7,7 @@
package org.cryptomator.launcher;
import java.awt.Desktop;
import java.awt.desktop.OpenFilesEvent;
import java.io.File;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
@@ -17,22 +18,30 @@ import java.util.concurrent.BlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@Singleton
class FileOpenRequestHandler {
private static final Logger LOG = LoggerFactory.getLogger(FileOpenRequestHandler.class);
private final BlockingQueue<Path> fileOpenRequests;
public FileOpenRequestHandler(BlockingQueue<Path> fileOpenRequests) {
@Inject
public FileOpenRequestHandler(@Named("fileOpenRequests") BlockingQueue<Path> fileOpenRequests) {
this.fileOpenRequests = fileOpenRequests;
try {
Desktop.getDesktop().setOpenFileHandler(e -> {
e.getFiles().stream().map(File::toPath).forEach(fileOpenRequests::add);
});
Desktop.getDesktop().setOpenFileHandler(this::openFiles);
} catch (UnsupportedOperationException e) {
LOG.info("Unable to setOpenFileHandler, probably not supported on this OS.");
}
}
private void openFiles(final OpenFilesEvent evt) {
evt.getFiles().stream().map(File::toPath).forEach(fileOpenRequests::add);
}
public void handleLaunchArgs(String[] args) {
handleLaunchArgs(FileSystems.getDefault(), args);
}

View File

@@ -5,19 +5,35 @@
*******************************************************************************/
package org.cryptomator.launcher;
import javax.inject.Singleton;
import dagger.BindsInstance;
import dagger.Subcomponent;
import javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.logging.DebugMode;
import org.cryptomator.ui.controllers.ViewControllerLoader;
import dagger.Component;
import javax.inject.Named;
@Singleton
@Component(modules = LauncherModule.class)
interface LauncherComponent {
@FxApplicationScoped
@Subcomponent(modules = FxApplicationModule.class)
interface FxApplicationComponent {
ViewControllerLoader fxmlLoader();
DebugMode debugMode();
@Subcomponent.Builder
interface Builder {
@BindsInstance
Builder fxApplication(Application application);
@BindsInstance
Builder mainWindow(@Named("mainWindow") Stage mainWindow);
FxApplicationComponent build();
}
}

View File

@@ -0,0 +1,26 @@
/*******************************************************************************
* 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.Module;
import dagger.Provides;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.UiModule;
import javax.inject.Named;
import java.util.function.Consumer;
@Module(includes = {UiModule.class})
class FxApplicationModule {
@Provides
@FxApplicationScoped
@Named("shutdownTaskScheduler")
Consumer<Runnable> provideShutdownTaskScheduler() {
return CleanShutdownPerformer::scheduleShutdownTask;
}
}

View File

@@ -48,16 +48,12 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
public abstract boolean isServer();
/**
* @param portFilePath Path to a file containing the IPC port
* @param endpoint The server-side communication endpoint.
* @return Either a client or a server communicator.
* @throws IOException In case of communication errors.
*/
public static InterProcessCommunicator start(InterProcessCommunicationProtocol endpoint) throws IOException {
return start(getIpcPortPath(), endpoint);
}
// visible for testing
static InterProcessCommunicator start(Path portFilePath, InterProcessCommunicationProtocol endpoint) throws IOException {
public static InterProcessCommunicator start(Path portFilePath, InterProcessCommunicationProtocol endpoint) throws IOException {
System.setProperty("java.rmi.server.hostname", "localhost");
try {
// try to connect to existing server:
@@ -76,24 +72,6 @@ abstract class InterProcessCommunicator implements InterProcessCommunicationProt
return server;
}
private static Path getIpcPortPath() {
final String settingsPathProperty = System.getProperty("cryptomator.ipcPortPath");
if (settingsPathProperty == null) {
LOG.warn("System property cryptomator.ipcPortPath not set.");
return Paths.get(".ipcPort.tmp");
} else {
return Paths.get(replaceHomeDir(settingsPathProperty));
}
}
private static String replaceHomeDir(String path) {
if (path.startsWith("~/")) {
return SystemUtils.USER_HOME + path.substring(1);
} else {
return path;
}
}
public static class ClientCommunicator extends InterProcessCommunicator {
private final IpcProtocolRemote remote;

View File

@@ -1,68 +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 java.nio.file.Path;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.function.Consumer;
import javax.inject.Named;
import javax.inject.Singleton;
import org.cryptomator.ui.UiModule;
import dagger.Module;
import dagger.Provides;
import javafx.application.Application;
import javafx.stage.Stage;
@Module(includes = {UiModule.class})
class LauncherModule {
private final Application application;
private final Stage mainWindow;
public LauncherModule(Application application, Stage mainWindow) {
this.application = application;
this.mainWindow = mainWindow;
}
@Provides
@Singleton
Application provideApplication() {
return application;
}
@Provides
@Singleton
@Named("applicationVersion")
Optional<String> provideApplicationVersion() {
return ApplicationVersion.get();
}
@Provides
@Singleton
@Named("mainWindow")
Stage provideMainWindow() {
return mainWindow;
}
@Provides
@Singleton
@Named("fileOpenRequests")
BlockingQueue<Path> provideFileOpenRequests() {
return Cryptomator.FILE_OPEN_REQUESTS;
}
@Provides
@Singleton
@Named("shutdownTaskScheduler")
Consumer<Runnable> provideShutdownTaskScheduler() {
return CleanShutdownPerformer::scheduleShutdownTask;
}
}

View File

@@ -1,45 +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 javafx.application.Application;
import javafx.stage.Stage;
import org.cryptomator.ui.controllers.MainController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MainApplication extends Application {
private static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
private Stage primaryStage;
@Override
public void start(Stage primaryStage) {
LOG.info("JavaFX application started.");
this.primaryStage = primaryStage;
primaryStage.setMinWidth(652.0);
primaryStage.setMinHeight(440.0);
LauncherModule launcherModule = new LauncherModule(this, primaryStage);
LauncherComponent launcherComponent = DaggerLauncherComponent.builder() //
.launcherModule(launcherModule) //
.build();
launcherComponent.debugMode().initialize();
MainController mainCtrl = launcherComponent.fxmlLoader().load("/fxml/main.fxml");
mainCtrl.initStage(primaryStage);
primaryStage.show();
}
@Override
public void stop() {
assert primaryStage != null;
primaryStage.hide();
LOG.info("JavaFX application stopped.");
}
}

View File

@@ -5,22 +5,20 @@
*******************************************************************************/
package org.cryptomator.logging;
import static java.util.Arrays.asList;
import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Singleton;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import javax.inject.Inject;
import java.util.Collection;
@Singleton
import static java.util.Arrays.asList;
@FxApplicationScoped
public class DebugMode {
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(DebugMode.class);

View File

@@ -9,6 +9,24 @@
*******************************************************************************/
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;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.SwingUtilities;
import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
@@ -24,27 +42,7 @@ import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.SwingUtilities;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.jni.JniException;
import org.cryptomator.jni.MacApplicationUiState;
import org.cryptomator.jni.MacFunctions;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javafx.stage.Stage;
@Singleton
@FxApplicationScoped
public class ExitUtil {
private static final Logger LOG = LoggerFactory.getLogger(ExitUtil.class);

View File

@@ -8,21 +8,11 @@
*******************************************************************************/
package org.cryptomator.ui;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
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.FxApplicationScoped;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.SettingsProvider;
import org.cryptomator.frontend.webdav.WebDavServer;
@@ -31,19 +21,27 @@ import org.cryptomator.ui.controllers.ViewControllerModule;
import org.cryptomator.ui.model.VaultComponent;
import org.fxmisc.easybind.EasyBind;
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
import javax.inject.Named;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@Module(includes = {ViewControllerModule.class, KeychainModule.class}, subcomponents = {VaultComponent.class})
public class UiModule {
private static final int NUM_SCHEDULER_THREADS = 4;
@Provides
@Singleton
@FxApplicationScoped
Settings provideSettings(SettingsProvider settingsProvider) {
return settingsProvider.get();
}
@Provides
@Singleton
@FxApplicationScoped
ScheduledExecutorService provideScheduledExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
final AtomicInteger threadNumber = new AtomicInteger(1);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(NUM_SCHEDULER_THREADS, r -> {
@@ -57,7 +55,7 @@ public class UiModule {
}
@Provides
@Singleton
@FxApplicationScoped
ExecutorService provideExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
final AtomicInteger threadNumber = new AtomicInteger(1);
ExecutorService executorService = Executors.newCachedThreadPool(r -> {
@@ -71,7 +69,7 @@ public class UiModule {
}
@Provides
@Singleton
@FxApplicationScoped
Binding<InetSocketAddress> provideServerSocketAddressBinding(Settings settings) {
return EasyBind.map(settings.port(), (Number port) -> {
String host = SystemUtils.IS_OS_WINDOWS ? "127.0.0.1" : "localhost";
@@ -80,7 +78,7 @@ public class UiModule {
}
@Provides
@Singleton
@FxApplicationScoped
WebDavServer provideWebDavServer(Binding<InetSocketAddress> serverSocketAddressBinding) {
WebDavServer server = WebDavServer.create();
// no need to unsubscribe eventually, because server is a singleton

View File

@@ -9,24 +9,6 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Binding;
@@ -62,6 +44,7 @@ import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.ExitUtil;
import org.cryptomator.ui.controls.DirectoryListCell;
@@ -79,9 +62,25 @@ import org.fxmisc.easybind.monadic.MonadicBinding;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.stream.Stream;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildErrorDialog;
@Singleton
@FxApplicationScoped
public class MainController implements ViewController {
private static final Logger LOG = LoggerFactory.getLogger(MainController.class);

View File

@@ -5,14 +5,14 @@
*******************************************************************************/
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.layout.VBox;
import org.cryptomator.common.FxApplicationScoped;
@Singleton
import javax.inject.Inject;
@FxApplicationScoped
public class NotFoundController implements ViewController {
@Inject

View File

@@ -25,6 +25,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.common.settings.Settings;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.ui.l10n.Localization;
@@ -32,10 +33,9 @@ import org.cryptomator.ui.model.Volume;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Optional;
@Singleton
@FxApplicationScoped
public class SettingsController implements ViewController {
private static final CharMatcher DIGITS_MATCHER = CharMatcher.inRange('0', '9');

View File

@@ -5,20 +5,18 @@
*******************************************************************************/
package org.cryptomator.ui.controllers;
import javafx.fxml.FXMLLoader;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.ui.l10n.Localization;
import javax.inject.Inject;
import javax.inject.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.cryptomator.ui.l10n.Localization;
import javafx.fxml.FXMLLoader;
@Singleton
@FxApplicationScoped
public class ViewControllerLoader {
private final Map<Class<? extends ViewController>, Provider<ViewController>> controllerProviders;

View File

@@ -8,22 +8,6 @@
******************************************************************************/
package org.cryptomator.ui.controllers;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@@ -39,15 +23,31 @@ 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.common.settings.Settings;
import org.cryptomator.ui.l10n.Localization;
import org.cryptomator.ui.util.Tasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static org.cryptomator.ui.util.DialogBuilderUtil.buildYesNoDialog;
@Singleton
@FxApplicationScoped
public class WelcomeController implements ViewController {
private static final Logger LOG = LoggerFactory.getLogger(WelcomeController.class);

View File

@@ -5,6 +5,13 @@
*******************************************************************************/
package org.cryptomator.ui.l10n;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -19,16 +26,7 @@ import java.util.Objects;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
@Singleton
@FxApplicationScoped
public class Localization extends ResourceBundle {
private static final Logger LOG = LoggerFactory.getLogger(Localization.class);

View File

@@ -5,6 +5,13 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.keychain.KeychainAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.Arrays;
@@ -14,15 +21,7 @@ import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.cryptolib.api.CryptoException;
import org.cryptomator.keychain.KeychainAccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
@FxApplicationScoped
public class AutoUnlocker {
private static final Logger LOG = LoggerFactory.getLogger(AutoUnlocker.class);

View File

@@ -5,15 +5,15 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
@FxApplicationScoped
public class UpgradeStrategies {
private final Collection<UpgradeStrategy> strategies;

View File

@@ -5,23 +5,21 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import javax.inject.Inject;
import javax.inject.Singleton;
import javafx.application.Platform;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javafx.application.Platform;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@Singleton
@FxApplicationScoped
class UpgradeVersion3DropBundleExtension extends UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3DropBundleExtension.class);

View File

@@ -5,8 +5,17 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.common.MessageDigestSupplier;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
@@ -19,22 +28,13 @@ import java.util.EnumSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.io.BaseEncoding;
import org.apache.commons.lang3.StringUtils;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.common.MessageDigestSupplier;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
* Contains the collective knowledge of all creatures who were alive during the development of vault format 3.
* This class uses no external classes from the crypto or shortening layer by purpose, so we don't need legacy code inside these.
*/
@Singleton
@FxApplicationScoped
class UpgradeVersion3to4 extends UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion3to4.class);

View File

@@ -5,6 +5,15 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.api.FileHeader;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
@@ -18,21 +27,11 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.EnumSet;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.cryptolib.Cryptors;
import org.cryptomator.cryptolib.api.Cryptor;
import org.cryptomator.cryptolib.api.FileHeader;
import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Contains the collective knowledge of all creatures who were alive during the development of vault format 3.
* This class uses no external classes from the crypto or shortening layer by purpose, so we don't need legacy code inside these.
*/
@Singleton
@FxApplicationScoped
class UpgradeVersion4to5 extends UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion4to5.class);

View File

@@ -5,11 +5,7 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.cryptofs.migration.Migrators;
import org.cryptomator.cryptofs.migration.api.NoApplicableMigratorException;
import org.cryptomator.cryptolib.Cryptors;
@@ -19,7 +15,10 @@ import org.cryptomator.ui.l10n.Localization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
import javax.inject.Inject;
import java.io.IOException;
@FxApplicationScoped
class UpgradeVersion5toX extends UpgradeStrategy {
private static final Logger LOG = LoggerFactory.getLogger(UpgradeVersion5toX.class);

View File

@@ -5,6 +5,8 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import dagger.BindsInstance;
import org.cryptomator.common.settings.VaultSettings;
import org.cryptomator.ui.model.VaultModule.PerVault;
import dagger.Subcomponent;
@@ -17,7 +19,9 @@ public interface VaultComponent {
@Subcomponent.Builder
interface Builder {
Builder vaultModule(VaultModule module);
@BindsInstance
Builder vaultSettings(VaultSettings vaultSettings);
VaultComponent build();
}

View File

@@ -8,15 +8,14 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.cryptomator.common.FxApplicationScoped;
import org.cryptomator.common.settings.VaultSettings;
import javax.inject.Inject;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.common.settings.VaultSettings;
@Singleton
@FxApplicationScoped
public class VaultFactory {
private final VaultComponent.Builder vaultComponentBuilder;
@@ -32,8 +31,7 @@ public class VaultFactory {
}
private Vault create(VaultSettings vaultSettings) {
VaultModule module = new VaultModule(vaultSettings);
VaultComponent comp = vaultComponentBuilder.vaultModule(module).build();
VaultComponent comp = vaultComponentBuilder.vaultSettings(vaultSettings).build();
return comp.vault();
}

View File

@@ -5,22 +5,19 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import java.util.List;
import java.util.stream.IntStream;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
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.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
@Singleton
import javax.inject.Inject;
import java.util.List;
import java.util.stream.IntStream;
@FxApplicationScoped
public class VaultList extends TransformationList<Vault, VaultSettings> {
private final VaultFactory vaultFactory;

View File

@@ -5,37 +5,22 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import dagger.Module;
import dagger.Provides;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VolumeImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Scope;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
import javax.inject.Scope;
import org.cryptomator.common.settings.VolumeImpl;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.common.settings.VaultSettings;
import dagger.Module;
import dagger.Provides;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Module
public class VaultModule {
private static final Logger LOG = LoggerFactory.getLogger(VaultModule.class);
private final VaultSettings vaultSettings;
public VaultModule(VaultSettings vaultSettings) {
this.vaultSettings = Objects.requireNonNull(vaultSettings);
}
@Provides
@PerVault
public VaultSettings provideVaultSettings() {
return vaultSettings;
}
@Scope
@Documented

View File

@@ -5,6 +5,11 @@
*******************************************************************************/
package org.cryptomator.ui.model;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.FxApplicationScoped;
import javax.inject.Inject;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Set;
@@ -13,13 +18,7 @@ import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.SystemUtils;
@Singleton
@FxApplicationScoped
public final class WindowsDriveLetters {
private static final Set<Character> D_TO_Z;

View File

@@ -8,24 +8,21 @@
*******************************************************************************/
package org.cryptomator.ui.util;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.cryptomator.ui.l10n.Localization;
import com.google.common.base.Strings;
import com.nulabinc.zxcvbn.Zxcvbn;
import javafx.geometry.Insets;
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.l10n.Localization;
@Singleton
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@FxApplicationScoped
public class PasswordStrengthUtil {
private static final int PW_TRUNC_LEN = 100; // truncate very long passwords, since zxcvbn memory and runtime depends vastly on the length