mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 20:21:27 +00:00
moved from guice to dagger
This commit is contained in:
11
NOTICE.md
11
NOTICE.md
@@ -7,7 +7,6 @@ Cryptomator is licensed under the MIT license. The details can be found in the a
|
||||
|
||||
Cryptomator uses third party softwares that may be licensed under different licenses.
|
||||
|
||||
|
||||
### Jackson
|
||||
Jackson is a high-performance, Free/Open Source JSON processing library.
|
||||
It was originally written by Tatu Saloranta (tatu.saloranta@iki.fi), and has
|
||||
@@ -24,7 +23,6 @@ FasterXML.com (http://fasterxml.com).
|
||||
in some artifacts (usually source distributions); but is always available
|
||||
from the source code management (SCM) system project uses.
|
||||
|
||||
|
||||
### Jetty
|
||||
Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
|
||||
|
||||
@@ -39,7 +37,6 @@ Permission to use, copy, modify and distribute UnixCrypt
|
||||
for non-commercial or commercial purposes and without fee is
|
||||
granted provided that the copyright notice appears in all copies.
|
||||
|
||||
|
||||
### Jackrabbit WebDAV Library
|
||||
Copyright 2004-2014 The Apache Software Foundation
|
||||
|
||||
@@ -83,6 +80,12 @@ Copyright (c) 2013, ControlsFX
|
||||
|
||||
Licensed under the accompanying BSD license file.
|
||||
|
||||
### Dagger 2
|
||||
Copyright 2014 Google, Inc.
|
||||
Copyright 2012 Square, Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0
|
||||
|
||||
### Apache Log4j
|
||||
Copyright 1999-2012 Apache Software Foundation
|
||||
|
||||
@@ -93,4 +96,4 @@ ResolverUtil.java Copyright 2005-2006 Tim Fennell
|
||||
### JUnit
|
||||
Copyright (c) 2000-2006, www.hamcrest.org
|
||||
|
||||
Licensed under the accompanying BSD license file.
|
||||
Licensed under the accompanying BSD license file.
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- org.apache.httpcomponents:httpclient is newer, but jackrabbit uses this version. We don't have a reason to upgrade -->
|
||||
<!-- org.apache.httpcomponents:httpclient is newer, but jackrabbit uses this version. We don't have a reason to upgrade -->
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>${commons-httpclient.version}</version>
|
||||
@@ -127,9 +127,9 @@
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON -->
|
||||
|
||||
@@ -55,8 +55,35 @@
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.inject</groupId>
|
||||
<artifactId>javax.inject</artifactId>
|
||||
<version>1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.dagger</groupId>
|
||||
<artifactId>dagger-compiler</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<!-- workaround for http://jira.codehaus.org/browse/MCOMPILER-202 -->
|
||||
<forceJavacCompilerUse>true</forceJavacCompilerUse>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.cryptomator.ui;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.controllers.MainController;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
|
||||
import dagger.Component;
|
||||
|
||||
@Singleton
|
||||
@Component(modules = CryptomatorModule.class)
|
||||
interface CryptomatorComponent {
|
||||
ExecutorService executorService();
|
||||
|
||||
DeferredCloser deferredCloser();
|
||||
|
||||
MainController mainController();
|
||||
}
|
||||
120
main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java
Normal file
120
main/ui/src/main/java/org/cryptomator/ui/CryptomatorModule.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package org.cryptomator.ui;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.crypto.SamplingCryptorDecorator;
|
||||
import org.cryptomator.crypto.aes256.Aes256Cryptor;
|
||||
import org.cryptomator.ui.model.VaultFactory;
|
||||
import org.cryptomator.ui.model.VaultObjectMapperProvider;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.cryptomator.ui.settings.SettingsProvider;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.DeferredCloser.Closer;
|
||||
import org.cryptomator.ui.util.SemVerComparator;
|
||||
import org.cryptomator.ui.util.mount.WebDavMounter;
|
||||
import org.cryptomator.ui.util.mount.WebDavMounterProvider;
|
||||
import org.cryptomator.webdav.WebDavServer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import javafx.application.Application;
|
||||
|
||||
@Module
|
||||
class CryptomatorModule {
|
||||
|
||||
private final Application application;
|
||||
private final DeferredCloser deferredCloser;
|
||||
|
||||
public CryptomatorModule(Application application) {
|
||||
this.application = application;
|
||||
this.deferredCloser = new DeferredCloser();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Application provideApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
DeferredCloser provideDeferredCloser() {
|
||||
return deferredCloser;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("SemVer")
|
||||
Comparator<String> provideSemVerComparator() {
|
||||
return new SemVerComparator();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
VaultObjectMapperProvider provideVaultObjectMapperProvider(VaultFactory vaultFactory) {
|
||||
return new VaultObjectMapperProvider(vaultFactory);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("VaultJsonMapper")
|
||||
ObjectMapper provideVaultObjectMapper(VaultObjectMapperProvider vaultObjectMapperProvider) {
|
||||
return vaultObjectMapperProvider.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
SettingsProvider provideSettingsProvider(DeferredCloser closer, @Named("VaultJsonMapper") Provider<ObjectMapper> objectMapper) {
|
||||
return new SettingsProvider(closer, objectMapper.get());
|
||||
}
|
||||
|
||||
@Provides
|
||||
Settings provideSettings(SettingsProvider settingsProvider) {
|
||||
return settingsProvider.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ExecutorService provideExecutorService() {
|
||||
return closeLater(Executors.newCachedThreadPool(), ExecutorService::shutdown);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
VaultFactory provideVaultFactory(WebDavServer server, Provider<Cryptor> cryptorProvider, WebDavMounter mounter, DeferredCloser closer) {
|
||||
return new VaultFactory(server, cryptorProvider, mounter, closer);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
WebDavMounter provideWebDavMounterProvider(WebDavServer server, ExecutorService executorService) {
|
||||
return new WebDavMounterProvider(server, executorService).get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
WebDavServer provideWebDavServer() {
|
||||
final WebDavServer webDavServer = new WebDavServer();
|
||||
webDavServer.start();
|
||||
return closeLater(webDavServer, WebDavServer::stop);
|
||||
}
|
||||
|
||||
@Provides
|
||||
Cryptor provideCryptor() {
|
||||
return SamplingCryptorDecorator.decorate(new Aes256Cryptor());
|
||||
}
|
||||
|
||||
private <T> T closeLater(T object, Closer<T> closer) {
|
||||
return deferredCloser.closeLater(object, closer).get().get();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,15 +15,7 @@ import java.nio.file.Path;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.MainModule.ControllerFactory;
|
||||
import org.cryptomator.ui.controllers.MainController;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.ActiveWindowStyleSupport;
|
||||
@@ -34,8 +26,10 @@ import org.cryptomator.ui.util.TrayIconUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class MainApplication extends Application {
|
||||
|
||||
@@ -44,28 +38,15 @@ public class MainApplication extends Application {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
|
||||
|
||||
private final ExecutorService executorService;
|
||||
private final ControllerFactory controllerFactory;
|
||||
private final DeferredCloser closer;
|
||||
private final MainController mainCtrl;
|
||||
|
||||
public MainApplication() {
|
||||
this(getInjector());
|
||||
}
|
||||
|
||||
private static Injector getInjector() {
|
||||
return Guice.createInjector(new MainModule());
|
||||
}
|
||||
|
||||
public MainApplication(Injector injector) {
|
||||
this(injector.getInstance(ExecutorService.class), injector.getInstance(ControllerFactory.class), injector.getInstance(DeferredCloser.class), injector.getInstance(MainApplicationReference.class));
|
||||
}
|
||||
|
||||
public MainApplication(ExecutorService executorService, ControllerFactory controllerFactory, DeferredCloser closer, MainApplicationReference appRef) {
|
||||
super();
|
||||
this.executorService = executorService;
|
||||
this.controllerFactory = controllerFactory;
|
||||
this.closer = closer;
|
||||
final CryptomatorComponent comp = DaggerCryptomatorComponent.builder().cryptomatorModule(new CryptomatorModule(this)).build();
|
||||
this.executorService = comp.executorService();
|
||||
this.closer = comp.deferredCloser();
|
||||
this.mainCtrl = comp.mainController();
|
||||
Cryptomator.addShutdownTask(closer::close);
|
||||
appRef.set(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,34 +64,29 @@ public class MainApplication extends Application {
|
||||
});
|
||||
|
||||
chooseNativeStylesheet();
|
||||
|
||||
mainCtrl.initStage(primaryStage);
|
||||
|
||||
final ResourceBundle rb = ResourceBundle.getBundle("localization");
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"), rb);
|
||||
loader.setControllerFactory(controllerFactory);
|
||||
final Parent root = loader.load();
|
||||
final MainController ctrl = loader.getController();
|
||||
ctrl.setStage(primaryStage);
|
||||
final Scene scene = new Scene(root);
|
||||
primaryStage.setTitle(rb.getString("app.name"));
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.sizeToScene();
|
||||
primaryStage.setResizable(false);
|
||||
primaryStage.show();
|
||||
|
||||
ActiveWindowStyleSupport.startObservingFocus(primaryStage);
|
||||
TrayIconUtil.init(primaryStage, rb, () -> {
|
||||
quit();
|
||||
});
|
||||
|
||||
for (String arg : getParameters().getUnnamed()) {
|
||||
handleCommandLineArg(ctrl, arg);
|
||||
handleCommandLineArg(mainCtrl, arg);
|
||||
}
|
||||
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(ctrl, file.getAbsolutePath()));
|
||||
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(mainCtrl, file.getAbsolutePath()));
|
||||
}
|
||||
|
||||
LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, executorService), LocalInstance::close).get().get();
|
||||
|
||||
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(ctrl, arg));
|
||||
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(mainCtrl, arg));
|
||||
}
|
||||
|
||||
void handleCommandLineArg(final MainController ctrl, String arg) {
|
||||
@@ -162,25 +138,4 @@ public class MainApplication extends Application {
|
||||
closer.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed to inject MainApplication. Problem: Application needs to be set asap after injector creation.
|
||||
*/
|
||||
static class MainApplicationReference {
|
||||
|
||||
private Application application;
|
||||
|
||||
private void set(Application application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
public Application get() {
|
||||
if (application == null) {
|
||||
throw new IllegalStateException("not yet ready.");
|
||||
} else {
|
||||
return application;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 cryptomator.org
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Tillmann Gaida - initial implementation
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.crypto.SamplingCryptorDecorator;
|
||||
import org.cryptomator.crypto.aes256.Aes256Cryptor;
|
||||
import org.cryptomator.ui.MainApplication.MainApplicationReference;
|
||||
import org.cryptomator.ui.model.VaultFactory;
|
||||
import org.cryptomator.ui.model.VaultObjectMapperProvider;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.cryptomator.ui.settings.SettingsProvider;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.DeferredCloser.Closer;
|
||||
import org.cryptomator.ui.util.SemVerComparator;
|
||||
import org.cryptomator.ui.util.mount.WebDavMounter;
|
||||
import org.cryptomator.ui.util.mount.WebDavMounterProvider;
|
||||
import org.cryptomator.webdav.WebDavServer;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provider;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
public class MainModule extends AbstractModule {
|
||||
|
||||
private final DeferredCloser deferredCloser = new DeferredCloser();
|
||||
|
||||
public static interface ControllerFactory extends Callback<Class<?>, Object> {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DeferredCloser.class).toInstance(deferredCloser);
|
||||
bind(ObjectMapper.class).annotatedWith(Names.named("VaultJsonMapper")).toProvider(VaultObjectMapperProvider.class);
|
||||
bind(Settings.class).toProvider(SettingsProvider.class);
|
||||
bind(WebDavMounter.class).toProvider(WebDavMounterProvider.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ControllerFactory getControllerFactory(Injector injector) {
|
||||
return cls -> injector.getInstance(cls);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
MainApplicationReference getApplicationBinding() {
|
||||
return new MainApplicationReference();
|
||||
}
|
||||
|
||||
@Provides
|
||||
Application getApplication(MainApplicationReference ref) {
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("SemVer")
|
||||
@Singleton
|
||||
Comparator<String> getSemVerComparator() {
|
||||
return new SemVerComparator();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ExecutorService getExec() {
|
||||
return closeLater(Executors.newCachedThreadPool(), ExecutorService::shutdown);
|
||||
}
|
||||
|
||||
@Provides
|
||||
Cryptor getCryptor() {
|
||||
return SamplingCryptorDecorator.decorate(new Aes256Cryptor());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
VaultFactory getVaultFactory(WebDavServer server, Provider<Cryptor> cryptorProvider, WebDavMounter mounter, DeferredCloser closer) {
|
||||
return new VaultFactory(server, cryptorProvider, mounter, closer);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
WebDavServer getServer() {
|
||||
final WebDavServer webDavServer = new WebDavServer();
|
||||
webDavServer.start();
|
||||
return closeLater(webDavServer, WebDavServer::stop);
|
||||
}
|
||||
|
||||
<T> T closeLater(T object, Closer<T> closer) {
|
||||
return deferredCloser.closeLater(object, closer).get().get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* Controller presenting a single view.
|
||||
*/
|
||||
abstract class AbstractFXMLViewController implements Initializable {
|
||||
|
||||
private Parent fxmlRoot;
|
||||
|
||||
/**
|
||||
* URL from #initialize(URL, ResourceBundle)
|
||||
*/
|
||||
protected URL rootUrl;
|
||||
|
||||
/**
|
||||
* ResourceBundle from #initialize(URL, ResourceBundle)
|
||||
*/
|
||||
protected ResourceBundle resourceBundle;
|
||||
|
||||
/**
|
||||
* Gets the URL to the FXML file describing the view presented by this controller.<br/>
|
||||
*
|
||||
* A default implementation would look like this:<br/>
|
||||
* <code>
|
||||
* return getClass().getResource("/myView.fxml");
|
||||
* </code>
|
||||
*
|
||||
* @return FXML resource URL
|
||||
*/
|
||||
protected abstract URL getFxmlResourceUrl();
|
||||
|
||||
/**
|
||||
* @return Localization bundle for the FXML labels or <code>null</code>.
|
||||
*/
|
||||
protected abstract ResourceBundle getFxmlResourceBundle();
|
||||
|
||||
@Override
|
||||
public final void initialize(URL location, ResourceBundle resources) {
|
||||
this.rootUrl = location;
|
||||
this.resourceBundle = resources;
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
protected void initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a FXML loader used in {@link #loadFxml()}. This method can be overwritten for further loader customization.
|
||||
*
|
||||
* @return Configured loader ready to load.
|
||||
*/
|
||||
protected FXMLLoader createFxmlLoader() {
|
||||
final URL fxmlUrl = getFxmlResourceUrl();
|
||||
final ResourceBundle rb = getFxmlResourceBundle();
|
||||
final FXMLLoader loader = new FXMLLoader(fxmlUrl, rb);
|
||||
loader.setController(this);
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the view presented by this controller from the FXML file return by {@link #getFxmlResourceUrl()}. This method can only be invoked once.
|
||||
*
|
||||
* @return Parent view element.
|
||||
*/
|
||||
protected final synchronized Parent loadFxml() {
|
||||
if (fxmlRoot == null) {
|
||||
final FXMLLoader loader = createFxmlLoader();
|
||||
try {
|
||||
fxmlRoot = loader.load();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Could not load FXML file from location: " + loader.getLocation(), e);
|
||||
}
|
||||
}
|
||||
return fxmlRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scene with the root node from the FXML file and applies it to the given stage.
|
||||
*/
|
||||
public void initStage(Stage stage) {
|
||||
final Parent root = loadFxml();
|
||||
stage.setScene(new Scene(root));
|
||||
stage.sizeToScene();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Creates a new stage and calls {@link #initStage(Stage)}.
|
||||
*/
|
||||
public Stage createStage() {
|
||||
final Stage stage = new Stage();
|
||||
initStage(stage);
|
||||
return stage;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,15 +10,8 @@ import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.text.Text;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.crypto.exceptions.UnsupportedKeyLengthException;
|
||||
import org.cryptomator.crypto.exceptions.UnsupportedVaultException;
|
||||
@@ -28,13 +21,20 @@ import org.cryptomator.ui.model.Vault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class ChangePasswordController implements Initializable {
|
||||
@Singleton
|
||||
public class ChangePasswordController extends AbstractFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ChangePasswordController.class);
|
||||
|
||||
private ResourceBundle rb;
|
||||
private ChangePasswordListener listener;
|
||||
private Vault vault;
|
||||
|
||||
@@ -65,9 +65,17 @@ public class ChangePasswordController implements Initializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/change_password.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
oldPasswordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
newPasswordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
retypePasswordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
@@ -109,19 +117,19 @@ public class ChangePasswordController implements Initializable {
|
||||
vault.getCryptor().decryptMasterKey(masterKeyInputStream, oldPassword);
|
||||
Files.copy(masterKeyPath, masterKeyBackupPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException ex) {
|
||||
messageText.setText(rb.getString("changePassword.errorMessage.decryptionFailed"));
|
||||
messageText.setText(resourceBundle.getString("changePassword.errorMessage.decryptionFailed"));
|
||||
LOG.error("Decryption failed for technical reasons.", ex);
|
||||
newPasswordField.swipe();
|
||||
retypePasswordField.swipe();
|
||||
return;
|
||||
} catch (WrongPasswordException e) {
|
||||
messageText.setText(rb.getString("changePassword.errorMessage.wrongPassword"));
|
||||
messageText.setText(resourceBundle.getString("changePassword.errorMessage.wrongPassword"));
|
||||
newPasswordField.swipe();
|
||||
retypePasswordField.swipe();
|
||||
Platform.runLater(oldPasswordField::requestFocus);
|
||||
return;
|
||||
} catch (UnsupportedKeyLengthException ex) {
|
||||
messageText.setText(rb.getString("changePassword.errorMessage.unsupportedKeyLengthInstallJCE"));
|
||||
messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedKeyLengthInstallJCE"));
|
||||
LOG.warn("Unsupported Key-Length. Please install Oracle Java Cryptography Extension (JCE).", ex);
|
||||
newPasswordField.swipe();
|
||||
retypePasswordField.swipe();
|
||||
@@ -129,9 +137,9 @@ public class ChangePasswordController implements Initializable {
|
||||
} catch (UnsupportedVaultException e) {
|
||||
downloadsPageLink.setVisible(true);
|
||||
if (e.isVaultOlderThanSoftware()) {
|
||||
messageText.setText(rb.getString("changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
|
||||
messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
|
||||
} else if (e.isSoftwareOlderThanVault()) {
|
||||
messageText.setText(rb.getString("changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
|
||||
messageText.setText(resourceBundle.getString("changePassword.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
|
||||
}
|
||||
newPasswordField.swipe();
|
||||
retypePasswordField.swipe();
|
||||
@@ -146,7 +154,7 @@ public class ChangePasswordController implements Initializable {
|
||||
final CharSequence newPassword = newPasswordField.getCharacters();
|
||||
try (final OutputStream masterKeyOutputStream = Files.newOutputStream(masterKeyPath, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.SYNC)) {
|
||||
vault.getCryptor().encryptMasterKey(masterKeyOutputStream, newPassword);
|
||||
messageText.setText(rb.getString("changePassword.infoMessage.success"));
|
||||
messageText.setText(resourceBundle.getString("changePassword.infoMessage.success"));
|
||||
Platform.runLater(this::didChangePassword);
|
||||
// At this point the backup is still using the old password.
|
||||
// It will be changed as soon as the user unlocks the vault the next time.
|
||||
|
||||
@@ -19,23 +19,25 @@ import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class InitializeController implements Initializable {
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
|
||||
@Singleton
|
||||
public class InitializeController extends AbstractFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(InitializeController.class);
|
||||
|
||||
private ResourceBundle localization;
|
||||
private Vault vault;
|
||||
private InitializationListener listener;
|
||||
|
||||
@@ -51,9 +53,22 @@ public class InitializeController implements Initializable {
|
||||
@FXML
|
||||
private Label messageLabel;
|
||||
|
||||
@Inject
|
||||
public InitializeController() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.localization = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/initialize.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
passwordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
retypePasswordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
}
|
||||
@@ -88,9 +103,9 @@ public class InitializeController implements Initializable {
|
||||
listener.didInitialize(this);
|
||||
}
|
||||
} catch (FileAlreadyExistsException ex) {
|
||||
messageLabel.setText(localization.getString("initialize.messageLabel.alreadyInitialized"));
|
||||
messageLabel.setText(resourceBundle.getString("initialize.messageLabel.alreadyInitialized"));
|
||||
} catch (InvalidPathException ex) {
|
||||
messageLabel.setText(localization.getString("initialize.messageLabel.invalidPath"));
|
||||
messageLabel.setText(resourceBundle.getString("initialize.messageLabel.invalidPath"));
|
||||
} catch (IOException ex) {
|
||||
LOG.error("I/O Exception", ex);
|
||||
} finally {
|
||||
|
||||
@@ -4,6 +4,10 @@ import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@@ -18,18 +22,13 @@ import javafx.collections.ListChangeListener.Change;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.control.cell.CheckBoxListCell;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.StringConverter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
|
||||
public class MacWarningsController implements Initializable {
|
||||
public class MacWarningsController extends AbstractFXMLViewController {
|
||||
|
||||
@FXML
|
||||
private ListView<Warning> warningsList;
|
||||
@@ -43,7 +42,6 @@ public class MacWarningsController implements Initializable {
|
||||
private final ChangeListener<Boolean> stageVisibilityChangeListener = this::windowVisibilityDidChange;
|
||||
private Stage stage;
|
||||
private Vault vault;
|
||||
private ResourceBundle rb;
|
||||
|
||||
@Inject
|
||||
public MacWarningsController(Application application) {
|
||||
@@ -51,8 +49,17 @@ public class MacWarningsController implements Initializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/mac_warnings.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
warnings.addListener(this::warningsDidInvalidate);
|
||||
warningsList.setItems(warnings);
|
||||
warningsList.setCellFactory(CheckBoxListCell.forListView(Warning::selectedProperty, new StringConverter<Warning>() {
|
||||
@@ -70,6 +77,13 @@ public class MacWarningsController implements Initializable {
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initStage(Stage stage) {
|
||||
super.initStage(stage);
|
||||
this.stage = stage;
|
||||
stage.showingProperty().addListener(new WeakChangeListener<>(stageVisibilityChangeListener));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void didClickWhitelistButton(ActionEvent event) {
|
||||
warnings.filtered(w -> w.isSelected()).stream().forEach(w -> {
|
||||
@@ -103,7 +117,7 @@ public class MacWarningsController implements Initializable {
|
||||
|
||||
private void windowVisibilityDidChange(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
|
||||
if (Boolean.TRUE.equals(newValue)) {
|
||||
stage.setTitle(String.format(rb.getString("macWarnings.windowTitle"), vault.getName()));
|
||||
stage.setTitle(String.format(resourceBundle.getString("macWarnings.windowTitle"), vault.getName()));
|
||||
warnings.addAll(vault.getNamesOfResourcesWithInvalidMac().stream().map(Warning::new).collect(Collectors.toList()));
|
||||
vault.getNamesOfResourcesWithInvalidMac().addListener(this.unauthenticatedResourcesChangeListener);
|
||||
} else {
|
||||
@@ -116,11 +130,6 @@ public class MacWarningsController implements Initializable {
|
||||
whitelistButton.setDisable(warnings.filtered(w -> w.isSelected()).isEmpty());
|
||||
}
|
||||
|
||||
public void setStage(Stage stage) {
|
||||
this.stage = stage;
|
||||
stage.showingProperty().addListener(new WeakChangeListener<>(stageVisibilityChangeListener));
|
||||
}
|
||||
|
||||
public void setVault(Vault vault) {
|
||||
this.vault = vault;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,28 @@ import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.controllers.ChangePasswordController.ChangePasswordListener;
|
||||
import org.cryptomator.ui.controllers.InitializeController.InitializationListener;
|
||||
import org.cryptomator.ui.controllers.UnlockController.UnlockListener;
|
||||
import org.cryptomator.ui.controllers.UnlockedController.LockListener;
|
||||
import org.cryptomator.ui.controls.DirectoryListCell;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.VaultFactory;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dagger.Lazy;
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.geometry.Side;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
@@ -38,21 +52,8 @@ import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
import org.cryptomator.ui.MainModule.ControllerFactory;
|
||||
import org.cryptomator.ui.controllers.ChangePasswordController.ChangePasswordListener;
|
||||
import org.cryptomator.ui.controllers.InitializeController.InitializationListener;
|
||||
import org.cryptomator.ui.controllers.UnlockController.UnlockListener;
|
||||
import org.cryptomator.ui.controllers.UnlockedController.LockListener;
|
||||
import org.cryptomator.ui.controls.DirectoryListCell;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.VaultFactory;
|
||||
import org.cryptomator.ui.settings.Settings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class MainController implements Initializable, InitializationListener, UnlockListener, LockListener, ChangePasswordListener {
|
||||
@Singleton
|
||||
public class MainController extends AbstractFXMLViewController implements InitializationListener, UnlockListener, LockListener, ChangePasswordListener {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
@@ -76,28 +77,50 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
@FXML
|
||||
private Pane contentPane;
|
||||
|
||||
private final ControllerFactory controllerFactory;
|
||||
private final Settings settings;
|
||||
private final VaultFactory vaultFactoy;
|
||||
|
||||
private ResourceBundle rb;
|
||||
private final Lazy<WelcomeController> welcomeController;
|
||||
private final Lazy<InitializeController> initializeController;
|
||||
private final Lazy<UnlockController> unlockController;
|
||||
private final Provider<UnlockedController> unlockedController;
|
||||
private final Lazy<ChangePasswordController> changePasswordController;
|
||||
|
||||
@Inject
|
||||
public MainController(ControllerFactory controllerFactory, Settings settings, VaultFactory vaultFactoy) {
|
||||
public MainController(Settings settings, VaultFactory vaultFactoy, Lazy<WelcomeController> welcomeController, Lazy<InitializeController> initializeController, Lazy<UnlockController> unlockController,
|
||||
Provider<UnlockedController> unlockedController, Lazy<ChangePasswordController> changePasswordController) {
|
||||
super();
|
||||
this.controllerFactory = controllerFactory;
|
||||
this.settings = settings;
|
||||
this.vaultFactoy = vaultFactoy;
|
||||
this.welcomeController = welcomeController;
|
||||
this.initializeController = initializeController;
|
||||
this.unlockController = unlockController;
|
||||
this.unlockedController = unlockedController;
|
||||
this.changePasswordController = changePasswordController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/main.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
final ObservableList<Vault> items = FXCollections.observableList(settings.getDirectories());
|
||||
vaultList.setItems(items);
|
||||
vaultList.setCellFactory(this::createDirecoryListCell);
|
||||
vaultList.getSelectionModel().getSelectedItems().addListener(this::selectedVaultDidChange);
|
||||
this.showWelcomeView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initStage(Stage stage) {
|
||||
super.initStage(stage);
|
||||
this.stage = stage;
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -191,14 +214,14 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
private void selectedVaultDidChange(ListChangeListener.Change<? extends Vault> change) {
|
||||
final Vault selectedVault = vaultList.getSelectionModel().getSelectedItem();
|
||||
if (selectedVault == null) {
|
||||
stage.setTitle(rb.getString("app.name"));
|
||||
stage.setTitle(resourceBundle.getString("app.name"));
|
||||
showWelcomeView();
|
||||
} else if (!Files.isDirectory(selectedVault.getPath())) {
|
||||
Platform.runLater(() -> {
|
||||
vaultList.getItems().remove(selectedVault);
|
||||
vaultList.getSelectionModel().clearSelection();
|
||||
});
|
||||
stage.setTitle(rb.getString("app.name"));
|
||||
stage.setTitle(resourceBundle.getString("app.name"));
|
||||
showWelcomeView();
|
||||
} else {
|
||||
stage.setTitle(selectedVault.getName());
|
||||
@@ -237,25 +260,17 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T showView(String fxml) {
|
||||
try {
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml), rb);
|
||||
loader.setControllerFactory(controllerFactory);
|
||||
final Parent root = loader.load();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
return loader.getController();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to load fxml file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void showWelcomeView() {
|
||||
this.showView("/fxml/welcome.fxml");
|
||||
final Parent root = welcomeController.get().loadFxml();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
}
|
||||
|
||||
private void showInitializeView(Vault vault) {
|
||||
final InitializeController ctrl = showView("/fxml/initialize.fxml");
|
||||
final InitializeController ctrl = initializeController.get();
|
||||
final Parent root = ctrl.loadFxml();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
ctrl.setVault(vault);
|
||||
ctrl.setListener(this);
|
||||
}
|
||||
@@ -266,7 +281,10 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
}
|
||||
|
||||
private void showUnlockView(Vault vault) {
|
||||
final UnlockController ctrl = showView("/fxml/unlock.fxml");
|
||||
final UnlockController ctrl = unlockController.get();
|
||||
final Parent root = ctrl.loadFxml();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
ctrl.setVault(vault);
|
||||
ctrl.setListener(this);
|
||||
}
|
||||
@@ -278,7 +296,10 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
}
|
||||
|
||||
private void showUnlockedView(Vault vault) {
|
||||
final UnlockedController ctrl = showView("/fxml/unlocked.fxml");
|
||||
final UnlockedController ctrl = unlockedController.get();
|
||||
final Parent root = ctrl.loadFxml();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
ctrl.setVault(vault);
|
||||
ctrl.setListener(this);
|
||||
}
|
||||
@@ -292,7 +313,10 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
}
|
||||
|
||||
private void showChangePasswordView(Vault vault) {
|
||||
final ChangePasswordController ctrl = showView("/fxml/change_password.fxml");
|
||||
final ChangePasswordController ctrl = changePasswordController.get();
|
||||
final Parent root = ctrl.loadFxml();
|
||||
contentPane.getChildren().clear();
|
||||
contentPane.getChildren().add(root);
|
||||
ctrl.setVault(vault);
|
||||
ctrl.setListener(this);
|
||||
}
|
||||
|
||||
@@ -19,19 +19,7 @@ import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.security.auth.DestroyFailedException;
|
||||
|
||||
import org.apache.commons.lang3.CharUtils;
|
||||
@@ -44,13 +32,22 @@ import org.cryptomator.ui.util.FXThreads;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class UnlockController implements Initializable {
|
||||
public class UnlockController extends AbstractFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UnlockController.class);
|
||||
|
||||
private ResourceBundle rb;
|
||||
private UnlockListener listener;
|
||||
private Vault vault;
|
||||
|
||||
@@ -77,15 +74,22 @@ public class UnlockController implements Initializable {
|
||||
|
||||
@Inject
|
||||
public UnlockController(Application app, ExecutorService exec) {
|
||||
super();
|
||||
this.app = app;
|
||||
this.exec = exec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/unlock.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
passwordField.textProperty().addListener(this::passwordFieldsDidChange);
|
||||
mountName.addEventFilter(KeyEvent.KEY_TYPED, this::filterAlphanumericKeyEvents);
|
||||
mountName.textProperty().addListener(this::mountNameDidChange);
|
||||
@@ -124,7 +128,7 @@ public class UnlockController implements Initializable {
|
||||
try (final InputStream masterKeyInputStream = Files.newInputStream(masterKeyPath, StandardOpenOption.READ)) {
|
||||
vault.getCryptor().decryptMasterKey(masterKeyInputStream, password);
|
||||
if (!vault.startServer()) {
|
||||
messageText.setText(rb.getString("unlock.messageLabel.startServerFailed"));
|
||||
messageText.setText(resourceBundle.getString("unlock.messageLabel.startServerFailed"));
|
||||
vault.getCryptor().destroy();
|
||||
return;
|
||||
}
|
||||
@@ -136,26 +140,26 @@ public class UnlockController implements Initializable {
|
||||
} catch (IOException ex) {
|
||||
setControlsDisabled(false);
|
||||
progressIndicator.setVisible(false);
|
||||
messageText.setText(rb.getString("unlock.errorMessage.decryptionFailed"));
|
||||
messageText.setText(resourceBundle.getString("unlock.errorMessage.decryptionFailed"));
|
||||
LOG.error("Decryption failed for technical reasons.", ex);
|
||||
} catch (WrongPasswordException e) {
|
||||
setControlsDisabled(false);
|
||||
progressIndicator.setVisible(false);
|
||||
messageText.setText(rb.getString("unlock.errorMessage.wrongPassword"));
|
||||
messageText.setText(resourceBundle.getString("unlock.errorMessage.wrongPassword"));
|
||||
Platform.runLater(passwordField::requestFocus);
|
||||
} catch (UnsupportedKeyLengthException ex) {
|
||||
setControlsDisabled(false);
|
||||
progressIndicator.setVisible(false);
|
||||
messageText.setText(rb.getString("unlock.errorMessage.unsupportedKeyLengthInstallJCE"));
|
||||
messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedKeyLengthInstallJCE"));
|
||||
LOG.warn("Unsupported Key-Length. Please install Oracle Java Cryptography Extension (JCE).", ex);
|
||||
} catch (UnsupportedVaultException e) {
|
||||
setControlsDisabled(false);
|
||||
progressIndicator.setVisible(false);
|
||||
downloadsPageLink.setVisible(true);
|
||||
if (e.isVaultOlderThanSoftware()) {
|
||||
messageText.setText(rb.getString("unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
|
||||
messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.vaultOlderThanSoftware") + " ");
|
||||
} else if (e.isSoftwareOlderThanVault()) {
|
||||
messageText.setText(rb.getString("unlock.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
|
||||
messageText.setText(resourceBundle.getString("unlock.errorMessage.unsupportedVersion.softwareOlderThanVault") + " ");
|
||||
}
|
||||
} catch (DestroyFailedException e) {
|
||||
setControlsDisabled(false);
|
||||
|
||||
@@ -8,10 +8,17 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.cryptomator.crypto.CryptorIOSampling;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.ActiveWindowStyleSupport;
|
||||
import org.cryptomator.ui.util.mount.CommandFailedException;
|
||||
|
||||
import javafx.animation.Animation;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
@@ -20,10 +27,6 @@ import javafx.collections.ListChangeListener;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
@@ -32,21 +35,10 @@ import javafx.scene.control.Label;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import org.cryptomator.crypto.CryptorIOSampling;
|
||||
import org.cryptomator.ui.MainModule.ControllerFactory;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.ActiveWindowStyleSupport;
|
||||
import org.cryptomator.ui.util.mount.CommandFailedException;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class UnlockedController implements Initializable {
|
||||
public class UnlockedController extends AbstractFXMLViewController {
|
||||
|
||||
private static final int IO_SAMPLING_STEPS = 100;
|
||||
private static final double IO_SAMPLING_INTERVAL = 0.25;
|
||||
private final ControllerFactory controllerFactory;
|
||||
private final Stage macWarningWindow = new Stage();
|
||||
private MacWarningsController macWarningCtrl;
|
||||
private LockListener listener;
|
||||
private Vault vault;
|
||||
private Timeline ioAnimation;
|
||||
@@ -60,32 +52,28 @@ public class UnlockedController implements Initializable {
|
||||
@FXML
|
||||
private NumberAxis xAxis;
|
||||
|
||||
private ResourceBundle rb;
|
||||
private final Stage macWarningsWindow = new Stage();
|
||||
private final MacWarningsController macWarningsController;
|
||||
|
||||
@Inject
|
||||
public UnlockedController(ControllerFactory controllerFactory) {
|
||||
this.controllerFactory = controllerFactory;
|
||||
public UnlockedController(Provider<MacWarningsController> macWarningsControllerProvider) {
|
||||
this.macWarningsController = macWarningsControllerProvider.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/unlocked.fxml");
|
||||
}
|
||||
|
||||
try {
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/mac_warnings.fxml"), rb);
|
||||
loader.setControllerFactory(controllerFactory);
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
final Parent root = loader.load();
|
||||
macWarningWindow.setScene(new Scene(root));
|
||||
macWarningWindow.sizeToScene();
|
||||
macWarningWindow.setResizable(false);
|
||||
ActiveWindowStyleSupport.startObservingFocus(macWarningWindow);
|
||||
|
||||
macWarningCtrl = loader.getController();
|
||||
macWarningCtrl.setStage(macWarningWindow);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to load fxml file.", e);
|
||||
}
|
||||
@Override
|
||||
public void initialize() {
|
||||
macWarningsController.initStage(macWarningsWindow);
|
||||
ActiveWindowStyleSupport.startObservingFocus(macWarningsWindow);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -93,7 +81,7 @@ public class UnlockedController implements Initializable {
|
||||
try {
|
||||
vault.unmount();
|
||||
} catch (CommandFailedException e) {
|
||||
messageLabel.setText(rb.getString("unlocked.label.unmountFailed"));
|
||||
messageLabel.setText(resourceBundle.getString("unlocked.label.unmountFailed"));
|
||||
return;
|
||||
}
|
||||
vault.stopServer();
|
||||
@@ -110,11 +98,11 @@ public class UnlockedController implements Initializable {
|
||||
private void macWarningsDidChange(ListChangeListener.Change<? extends String> change) {
|
||||
if (change.getList().size() > 0) {
|
||||
Platform.runLater(() -> {
|
||||
macWarningWindow.show();
|
||||
macWarningsWindow.show();
|
||||
});
|
||||
} else {
|
||||
Platform.runLater(() -> {
|
||||
macWarningWindow.hide();
|
||||
macWarningsWindow.hide();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -138,6 +126,13 @@ public class UnlockedController implements Initializable {
|
||||
ioAnimation.play();
|
||||
}
|
||||
|
||||
private void stopIoSampling() {
|
||||
if (ioAnimation != null) {
|
||||
ioGraph.getData().clear();
|
||||
ioAnimation.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private class IoSamplingAnimationHandler implements EventHandler<ActionEvent> {
|
||||
|
||||
private static final double BYTES_TO_MEGABYTES_FACTOR = 1.0 / IO_SAMPLING_INTERVAL / 1024.0 / 1024.0;
|
||||
@@ -181,7 +176,7 @@ public class UnlockedController implements Initializable {
|
||||
|
||||
public void setVault(Vault vault) {
|
||||
this.vault = vault;
|
||||
macWarningCtrl.setVault(vault);
|
||||
macWarningsController.setVault(vault);
|
||||
|
||||
// listen to MAC warnings as long as this vault is unlocked:
|
||||
final ListChangeListener<String> macWarningsListener = this::macWarningsDidChange;
|
||||
@@ -193,6 +188,7 @@ public class UnlockedController implements Initializable {
|
||||
});
|
||||
|
||||
// sample crypto-throughput:
|
||||
stopIoSampling();
|
||||
if (vault.getCryptor() instanceof CryptorIOSampling) {
|
||||
startIoSampling((CryptorIOSampling) vault.getCryptor());
|
||||
} else {
|
||||
|
||||
@@ -16,17 +16,9 @@ import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.httpclient.HttpClient;
|
||||
import org.apache.commons.httpclient.HttpMethod;
|
||||
@@ -40,7 +32,16 @@ import org.slf4j.LoggerFactory;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class WelcomeController implements Initializable {
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Hyperlink;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
@Singleton
|
||||
public class WelcomeController extends AbstractFXMLViewController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WelcomeController.class);
|
||||
|
||||
@@ -53,7 +54,6 @@ public class WelcomeController implements Initializable {
|
||||
private final Application app;
|
||||
private final Comparator<String> semVerComparator;
|
||||
private final ExecutorService executor;
|
||||
private ResourceBundle rb;
|
||||
|
||||
@Inject
|
||||
public WelcomeController(Application app, @Named("SemVer") Comparator<String> semVerComparator, ExecutorService executor) {
|
||||
@@ -63,8 +63,17 @@ public class WelcomeController implements Initializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
this.rb = rb;
|
||||
protected URL getFxmlResourceUrl() {
|
||||
return getClass().getResource("/fxml/welcome.fxml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceBundle getFxmlResourceBundle() {
|
||||
return ResourceBundle.getBundle("localization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
this.botImageView.setImage(new Image(WelcomeController.class.getResource("/bot_welcome.png").toString()));
|
||||
executor.execute(this::checkForUpdates);
|
||||
}
|
||||
@@ -103,7 +112,7 @@ public class WelcomeController implements Initializable {
|
||||
final String currentVersion = WelcomeController.class.getPackage().getImplementationVersion();
|
||||
LOG.debug("Current version: {}, lastest version: {}", currentVersion, latestVersion);
|
||||
if (currentVersion != null && semVerComparator.compare(currentVersion, latestVersion) < 0) {
|
||||
final String msg = String.format(rb.getString("welcome.newVersionMessage"), latestVersion, currentVersion);
|
||||
final String msg = String.format(resourceBundle.getString("welcome.newVersionMessage"), latestVersion, currentVersion);
|
||||
Platform.runLater(() -> {
|
||||
this.updateLink.setText(msg);
|
||||
this.updateLink.setVisible(true);
|
||||
|
||||
@@ -2,14 +2,14 @@ package org.cryptomator.ui.model;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.mount.WebDavMounter;
|
||||
import org.cryptomator.webdav.WebDavServer;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class VaultFactory {
|
||||
|
||||
private final WebDavServer server;
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
@@ -16,7 +17,6 @@ import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class VaultObjectMapperProvider implements Provider<ObjectMapper> {
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.cryptomator.ui.settings;
|
||||
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import dagger.Module;
|
||||
|
||||
@Module
|
||||
public class SettingsModule {
|
||||
|
||||
@Singleton
|
||||
Provider<Settings> provideSettingsProvider(Provider<ObjectMapper> objectMapper) {
|
||||
return new SettingsProvider(new DeferredCloser(), objectMapper.get());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import java.nio.file.StandardOpenOption;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
@@ -18,7 +19,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class SettingsProvider implements Provider<Settings> {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class SettingsProvider implements Provider<Settings> {
|
||||
this.deferredCloser = deferredCloser;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
|
||||
private Path getSettingsPath() throws IOException {
|
||||
String settingsPathProperty = System.getProperty("settingsPath");
|
||||
if (settingsPathProperty == null) {
|
||||
|
||||
@@ -20,6 +20,8 @@ import org.cryptomator.ui.controllers.MainController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Tries to bring open-close symmetry in contexts where the resource outlives
|
||||
@@ -57,8 +59,10 @@ public class DeferredCloser implements AutoCloseable {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
@VisibleForTesting
|
||||
final Map<Long, ManagedResource<?>> cleanups = new ConcurrentSkipListMap<>();
|
||||
|
||||
@VisibleForTesting
|
||||
final AtomicLong counter = new AtomicLong();
|
||||
|
||||
public class ManagedResource<T> implements DeferredClosable<T> {
|
||||
@@ -73,6 +77,7 @@ public class DeferredCloser implements AutoCloseable {
|
||||
this.closer = closer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
final T oldObject = object.getAndSet(null);
|
||||
if (oldObject != null) {
|
||||
@@ -86,6 +91,7 @@ public class DeferredCloser implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> get() throws IllegalStateException {
|
||||
return Optional.ofNullable(object.get());
|
||||
}
|
||||
@@ -94,6 +100,7 @@ public class DeferredCloser implements AutoCloseable {
|
||||
/**
|
||||
* Closes all added objects which have not been closed before and releases references.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
for (Iterator<ManagedResource<?>> iterator = cleanups.values().iterator(); iterator.hasNext();) {
|
||||
final ManagedResource<?> closableProvider = iterator.next();
|
||||
|
||||
@@ -12,13 +12,12 @@ package org.cryptomator.ui.util.mount;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.cryptomator.webdav.WebDavServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class WebDavMounterProvider implements Provider<WebDavMounter> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WebDavMounterProvider.class);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<?import javafx.scene.text.Text?>
|
||||
|
||||
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" fx:controller="org.cryptomator.ui.controllers.ChangePasswordController" xmlns:fx="http://javafx.com/fxml">
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" fx:controller="org.cryptomator.ui.controllers.InitializeController" xmlns:fx="http://javafx.com/fxml">
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
|
||||
<VBox styleClass="root" alignment="CENTER" prefHeight="225.0" prefWidth="525.0" spacing="12.0" fx:controller="org.cryptomator.ui.controllers.MacWarningsController" xmlns:fx="http://javafx.com/fxml">
|
||||
<VBox styleClass="root" alignment="CENTER" prefHeight="225.0" prefWidth="525.0" spacing="12.0" xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<padding><Insets top="12.0" right="12.0" bottom="12.0" left="12.0"/></padding>
|
||||
|
||||
|
||||
@@ -18,12 +18,11 @@
|
||||
<?import javafx.scene.control.MenuItem?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
|
||||
<HBox fx:id="rootPane" prefHeight="440.0" prefWidth="640.0" fx:controller="org.cryptomator.ui.controllers.MainController" xmlns:fx="http://javafx.com/fxml">
|
||||
<HBox fx:id="rootPane" prefHeight="440.0" prefWidth="640.0" xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<padding><Insets top="20" right="20" bottom="20" left="20.0"/></padding>
|
||||
|
||||
<fx:define>
|
||||
<fx:include fx:id="welcomeView" source="welcome.fxml" />
|
||||
<ContextMenu fx:id="vaultListCellContextMenu">
|
||||
<items>
|
||||
<MenuItem text="%main.directoryList.contextMenu.remove" onAction="#didClickRemoveSelectedEntry" />
|
||||
@@ -49,11 +48,7 @@
|
||||
</ToolBar>
|
||||
</children>
|
||||
</VBox>
|
||||
<Pane fx:id="contentPane">
|
||||
<children>
|
||||
<fx:reference source="welcomeView" />
|
||||
</children>
|
||||
</Pane>
|
||||
<Pane fx:id="contentPane"/>
|
||||
</children>
|
||||
|
||||
</HBox>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<?import javafx.scene.control.Hyperlink?>
|
||||
<?import javafx.scene.text.Text?>
|
||||
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" fx:controller="org.cryptomator.ui.controllers.UnlockController" xmlns:fx="http://javafx.com/fxml">
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" fx:controller="org.cryptomator.ui.controllers.UnlockedController" xmlns:fx="http://javafx.com/fxml">
|
||||
<GridPane vgap="12.0" hgap="12.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
|
||||
<padding>
|
||||
<Insets top="24.0" right="24.0" bottom="24.0" left="24.0" />
|
||||
</padding>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.control.Hyperlink?>
|
||||
|
||||
<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:controller="org.cryptomator.ui.controllers.WelcomeController">
|
||||
<AnchorPane xmlns:fx="http://javafx.com/fxml">
|
||||
|
||||
<children>
|
||||
<Label AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="20.0" prefWidth="400.0" alignment="CENTER" style="-fx-font-size: 1.5em;" text="%welcome.welcomeLabel"/>
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package org.cryptomator.ui.test;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
import org.junit.runners.model.InitializationError;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Taken from http://fabiostrozzi.eu/2011/03/27/junit-tests-easy-guice/
|
||||
*/
|
||||
public class GuiceJUnitRunner extends BlockJUnit4ClassRunner {
|
||||
private final Injector injector;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
public @interface GuiceModules {
|
||||
Class<?>[] value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createTest() throws Exception {
|
||||
Object obj = super.createTest();
|
||||
injector.injectMembers(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public GuiceJUnitRunner(Class<?> klass) throws InitializationError {
|
||||
super(klass);
|
||||
Class<?>[] classes = getModulesFor(klass);
|
||||
injector = createInjectorFor(classes);
|
||||
}
|
||||
|
||||
private Injector createInjectorFor(Class<?>[] classes) throws InitializationError {
|
||||
Module[] modules = new Module[classes.length];
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
try {
|
||||
modules[i] = (Module) (classes[i]).newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new InitializationError(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new InitializationError(e);
|
||||
}
|
||||
}
|
||||
return Guice.createInjector(modules);
|
||||
}
|
||||
|
||||
private Class<?>[] getModulesFor(Class<?> klass) throws InitializationError {
|
||||
GuiceModules annotation = klass.getAnnotation(GuiceModules.class);
|
||||
if (annotation == null)
|
||||
throw new InitializationError("Missing @GuiceModules annotation for unit test '" + klass.getName() + "'");
|
||||
return annotation.value();
|
||||
}
|
||||
}
|
||||
@@ -2,23 +2,12 @@ package org.cryptomator.ui.util;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.cryptomator.ui.MainModule;
|
||||
import org.cryptomator.ui.test.GuiceJUnitRunner;
|
||||
import org.cryptomator.ui.test.GuiceJUnitRunner.GuiceModules;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(GuiceJUnitRunner.class)
|
||||
@GuiceModules(MainModule.class)
|
||||
public class SemVerComparatorTest {
|
||||
|
||||
@Inject
|
||||
@Named("SemVer")
|
||||
private Comparator<String> semVerComparator;
|
||||
private final Comparator<String> semVerComparator = new SemVerComparator();
|
||||
|
||||
// equal versions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user