mirror of
https://github.com/cryptomator/cryptomator.git
synced 2024-11-23 12:09:45 +00:00
Injecting Cryptor using Guice
This commit is contained in:
parent
b68cf71494
commit
8ba89a3bf5
@ -18,6 +18,7 @@
|
||||
<name>Cryptomator cryptographic module API</name>
|
||||
|
||||
<dependencies>
|
||||
<!-- commons -->
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
|
@ -103,6 +103,13 @@
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>${commons-codec.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON -->
|
||||
<dependency>
|
||||
|
@ -19,9 +19,8 @@
|
||||
|
||||
<properties>
|
||||
<javafx.application.name>Cryptomator</javafx.application.name>
|
||||
<exec.mainClass>org.cryptomator.ui.Main</exec.mainClass>
|
||||
<exec.mainClass>org.cryptomator.ui.Cryptomator</exec.mainClass>
|
||||
<javafx.tools.ant.jar>${java.home}/../lib/ant-javafx.jar</javafx.tools.ant.jar>
|
||||
<controlsfx.version>8.20.8</controlsfx.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -50,23 +49,10 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- UI
|
||||
<dependency>
|
||||
<groupId>org.controlsfx</groupId>
|
||||
<artifactId>controlsfx</artifactId>
|
||||
<version>${controlsfx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.axet</groupId>
|
||||
<artifactId>desktop</artifactId>
|
||||
<version>2.2.3</version>
|
||||
</dependency> -->
|
||||
|
||||
<!-- DI -->
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
@ -28,7 +28,7 @@ import org.eclipse.jetty.util.ConcurrentHashSet;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Main {
|
||||
public class Cryptomator {
|
||||
public static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
|
||||
|
||||
public static final CompletableFuture<Consumer<File>> OPEN_FILE_HANDLER = new CompletableFuture<>();
|
@ -18,13 +18,14 @@ import java.util.concurrent.ExecutorService;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.JavaFXBuilderFactory;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.MainModule.ControllerFactory;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.util.ActiveWindowStyleSupport;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.SingleInstanceManager;
|
||||
@ -32,6 +33,7 @@ import org.cryptomator.ui.util.SingleInstanceManager.LocalInstance;
|
||||
import org.cryptomator.ui.util.TrayIconUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
@ -42,11 +44,8 @@ public class MainApplication extends Application {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MainApplication.class);
|
||||
|
||||
private final CleanShutdownPerformer cleanShutdownPerformer = new CleanShutdownPerformer();
|
||||
|
||||
private final ExecutorService executorService;
|
||||
|
||||
private final ControllerFactory controllerFactory;
|
||||
|
||||
private final DeferredCloser closer;
|
||||
|
||||
public MainApplication() {
|
||||
@ -62,9 +61,7 @@ public class MainApplication extends Application {
|
||||
}
|
||||
|
||||
public MainApplication(Injector injector) {
|
||||
this(injector.getInstance(ExecutorService.class),
|
||||
injector.getInstance(ControllerFactory.class),
|
||||
injector.getInstance(DeferredCloser.class));
|
||||
this(injector.getInstance(ExecutorService.class), injector.getInstance(ControllerFactory.class), injector.getInstance(DeferredCloser.class));
|
||||
}
|
||||
|
||||
public MainApplication(ExecutorService executorService, ControllerFactory controllerFactory, DeferredCloser closer) {
|
||||
@ -91,7 +88,7 @@ public class MainApplication extends Application {
|
||||
|
||||
chooseNativeStylesheet();
|
||||
final ResourceBundle rb = ResourceBundle.getBundle("localization");
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"), rb);
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/main.fxml"), rb, new JavaFXBuilderFactory(MainApplication.class.getClassLoader()));
|
||||
loader.setControllerFactory(controllerFactory);
|
||||
final Parent root = loader.load();
|
||||
final MainController ctrl = loader.getController();
|
||||
@ -112,11 +109,10 @@ public class MainApplication extends Application {
|
||||
}
|
||||
|
||||
if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
Main.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(ctrl, file.getAbsolutePath()));
|
||||
Cryptomator.OPEN_FILE_HANDLER.complete(file -> handleCommandLineArg(ctrl, file.getAbsolutePath()));
|
||||
}
|
||||
|
||||
LocalInstance cryptomatorGuiInstance = closer.closeLater(
|
||||
SingleInstanceManager.startLocalInstance(APPLICATION_KEY, executorService), LocalInstance::close).get().get();
|
||||
LocalInstance cryptomatorGuiInstance = closer.closeLater(SingleInstanceManager.startLocalInstance(APPLICATION_KEY, executorService), LocalInstance::close).get().get();
|
||||
|
||||
cryptomatorGuiInstance.registerListener(arg -> handleCommandLineArg(ctrl, arg));
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.fxml.JavaFXBuilderFactory;
|
||||
import javafx.geometry.Side;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.ContextMenu;
|
||||
@ -37,7 +38,9 @@ import javafx.scene.layout.Pane;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
import javafx.util.BuilderFactory;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.ui.InitializeController.InitializationListener;
|
||||
import org.cryptomator.ui.MainModule.ControllerFactory;
|
||||
import org.cryptomator.ui.UnlockController.UnlockListener;
|
||||
@ -49,6 +52,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class MainController implements Initializable, InitializationListener, UnlockListener, LockListener {
|
||||
|
||||
@ -74,17 +78,19 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
@FXML
|
||||
private Pane contentPane;
|
||||
|
||||
private final ControllerFactory controllerFactory;
|
||||
private final Settings settings;
|
||||
private final Provider<Cryptor> cryptorProvider;
|
||||
private final BuilderFactory builderFactory = new JavaFXBuilderFactory(MainController.class.getClassLoader());
|
||||
|
||||
private ResourceBundle rb;
|
||||
|
||||
private final ControllerFactory controllerFactory;
|
||||
|
||||
private final Settings settings;
|
||||
|
||||
@Inject
|
||||
public MainController(ControllerFactory controllerFactory, Settings settings) {
|
||||
public MainController(ControllerFactory controllerFactory, Settings settings, Provider<Cryptor> cryptorProvider) {
|
||||
super();
|
||||
this.controllerFactory = controllerFactory;
|
||||
this.settings = settings;
|
||||
this.cryptorProvider = cryptorProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -164,7 +170,7 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
return;
|
||||
}
|
||||
|
||||
final Vault vault = new Vault(vaultPath);
|
||||
final Vault vault = new Vault(vaultPath, cryptorProvider.get());
|
||||
if (!directoryList.getItems().contains(vault)) {
|
||||
directoryList.getItems().add(vault);
|
||||
}
|
||||
@ -222,7 +228,7 @@ public class MainController implements Initializable, InitializationListener, Un
|
||||
|
||||
private <T> T showView(String fxml) {
|
||||
try {
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml), rb);
|
||||
final FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml), rb, builderFactory);
|
||||
loader.setControllerFactory(controllerFactory);
|
||||
final Parent root = loader.load();
|
||||
contentPane.getChildren().clear();
|
||||
|
@ -11,21 +11,29 @@ package org.cryptomator.ui;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javafx.util.Callback;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.crypto.SamplingDecorator;
|
||||
import org.cryptomator.crypto.aes256.Aes256Cryptor;
|
||||
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.webdav.WebDavServer;
|
||||
|
||||
import javafx.util.Callback;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
public class MainModule extends AbstractModule {
|
||||
DeferredCloser deferredCloser = new DeferredCloser();
|
||||
|
||||
private final DeferredCloser deferredCloser = new DeferredCloser();
|
||||
|
||||
public static interface ControllerFactory extends Callback<Class<?>, Object> {
|
||||
|
||||
@ -34,6 +42,8 @@ public class MainModule extends AbstractModule {
|
||||
@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);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ -49,9 +59,8 @@ public class MainModule extends AbstractModule {
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Settings getSettings() {
|
||||
return closeLater(Settings.load(), Settings::save);
|
||||
Cryptor getCryptor() {
|
||||
return SamplingDecorator.decorate(new Aes256Cryptor());
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
@ -13,8 +13,6 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
import org.cryptomator.crypto.SamplingDecorator;
|
||||
import org.cryptomator.crypto.aes256.Aes256Cryptor;
|
||||
import org.cryptomator.ui.util.DeferredClosable;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.cryptomator.ui.util.MasterKeyFilter;
|
||||
@ -26,11 +24,6 @@ import org.cryptomator.webdav.WebDavServer.ServletLifeCycleAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
@JsonSerialize(using = VaultSerializer.class)
|
||||
@JsonDeserialize(using = VaultDeserializer.class)
|
||||
public class Vault implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 3754487289683599469L;
|
||||
@ -38,18 +31,19 @@ public class Vault implements Serializable {
|
||||
|
||||
public static final String VAULT_FILE_EXTENSION = ".cryptomator";
|
||||
|
||||
private final Cryptor cryptor = SamplingDecorator.decorate(new Aes256Cryptor());
|
||||
private final Cryptor cryptor;
|
||||
private final ObjectProperty<Boolean> unlocked = new SimpleObjectProperty<Boolean>(this, "unlocked", Boolean.FALSE);
|
||||
private final Path path;
|
||||
private String mountName;
|
||||
private DeferredClosable<ServletLifeCycleAdapter> webDavServlet = DeferredClosable.empty();
|
||||
private DeferredClosable<WebDavMount> webDavMount = DeferredClosable.empty();
|
||||
|
||||
public Vault(final Path vaultDirectoryPath) {
|
||||
public Vault(final Path vaultDirectoryPath, final Cryptor cryptor) {
|
||||
if (!Files.isDirectory(vaultDirectoryPath) || !vaultDirectoryPath.getFileName().toString().endsWith(VAULT_FILE_EXTENSION)) {
|
||||
throw new IllegalArgumentException("Not a valid vault directory: " + vaultDirectoryPath);
|
||||
}
|
||||
this.path = vaultDirectoryPath;
|
||||
this.cryptor = cryptor;
|
||||
|
||||
try {
|
||||
setMountName(getName());
|
||||
|
@ -1,27 +0,0 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
public class VaultDeserializer extends JsonDeserializer<Vault> {
|
||||
|
||||
@Override
|
||||
public Vault deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
final JsonNode node = jp.readValueAsTree();
|
||||
final String pathStr = node.get("path").asText();
|
||||
final Path path = FileSystems.getDefault().getPath(pathStr);
|
||||
final Vault dir = new Vault(path);
|
||||
if (node.has("mountName")) {
|
||||
dir.setMountName(node.get("mountName").asText());
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.crypto.Cryptor;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
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> {
|
||||
|
||||
private final Provider<Cryptor> cryptorProvider;
|
||||
|
||||
@Inject
|
||||
public VaultObjectMapperProvider(final Provider<Cryptor> cryptorProvider) {
|
||||
this.cryptorProvider = cryptorProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectMapper get() {
|
||||
final ObjectMapper om = new ObjectMapper();
|
||||
final SimpleModule module = new SimpleModule("VaultJsonMapper");
|
||||
module.addSerializer(Vault.class, new VaultSerializer());
|
||||
module.addDeserializer(Vault.class, new VaultDeserializer());
|
||||
om.registerModule(module);
|
||||
return om;
|
||||
}
|
||||
|
||||
private class VaultSerializer extends JsonSerializer<Vault> {
|
||||
|
||||
@Override
|
||||
public void serialize(Vault value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeStartObject();
|
||||
jgen.writeStringField("path", value.getPath().toString());
|
||||
jgen.writeStringField("mountName", value.getMountName().toString());
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class VaultDeserializer extends JsonDeserializer<Vault> {
|
||||
|
||||
@Override
|
||||
public Vault deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
final JsonNode node = jp.readValueAsTree();
|
||||
final String pathStr = node.get("path").asText();
|
||||
final Path path = FileSystems.getDefault().getPath(pathStr);
|
||||
final Vault dir = new Vault(path, cryptorProvider.get());
|
||||
if (node.has("mountName")) {
|
||||
dir.setMountName(node.get("mountName").asText());
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
public class VaultSerializer extends JsonSerializer<Vault> {
|
||||
|
||||
@Override
|
||||
public void serialize(Vault value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
|
||||
jgen.writeStartObject();
|
||||
jgen.writeStringField("path", value.getPath().toString());
|
||||
jgen.writeStringField("mountName", value.getMountName().toString());
|
||||
jgen.writeEndObject();
|
||||
}
|
||||
|
||||
}
|
@ -8,82 +8,26 @@
|
||||
******************************************************************************/
|
||||
package org.cryptomator.ui.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
@JsonPropertyOrder(value = {"directories"})
|
||||
public class Settings implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7609959894417878744L;
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
|
||||
private static final Path SETTINGS_DIR;
|
||||
private static final String SETTINGS_FILE = "settings.json";
|
||||
private static final ObjectMapper JSON_OM = new ObjectMapper();
|
||||
|
||||
static {
|
||||
final String appdata = System.getenv("APPDATA");
|
||||
final FileSystem fs = FileSystems.getDefault();
|
||||
|
||||
if (SystemUtils.IS_OS_WINDOWS && appdata != null) {
|
||||
SETTINGS_DIR = fs.getPath(appdata, "Cryptomator");
|
||||
} else if (SystemUtils.IS_OS_WINDOWS && appdata == null) {
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, ".Cryptomator");
|
||||
} else if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, "Library/Application Support/Cryptomator");
|
||||
} else {
|
||||
// (os.contains("solaris") || os.contains("sunos") || os.contains("linux") || os.contains("unix"))
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, ".Cryptomator");
|
||||
}
|
||||
}
|
||||
|
||||
private List<Vault> directories;
|
||||
|
||||
private Settings() {
|
||||
// private constructor
|
||||
}
|
||||
/**
|
||||
* Package-private constructor; use {@link SettingsProvider}.
|
||||
*/
|
||||
Settings() {
|
||||
|
||||
public static synchronized Settings load() {
|
||||
try {
|
||||
Files.createDirectories(SETTINGS_DIR);
|
||||
final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
|
||||
final InputStream in = Files.newInputStream(settingsFile, StandardOpenOption.READ);
|
||||
return JSON_OM.readValue(in, Settings.class);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to load settings, creating new one.");
|
||||
return Settings.defaultSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void save() {
|
||||
try {
|
||||
Files.createDirectories(SETTINGS_DIR);
|
||||
final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
|
||||
final OutputStream out = Files.newOutputStream(settingsFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
|
||||
JSON_OM.writeValue(out, this);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to save settings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Settings defaultSettings() {
|
||||
return new Settings();
|
||||
}
|
||||
|
||||
/* Getter/Setter */
|
||||
|
@ -0,0 +1,84 @@
|
||||
package org.cryptomator.ui.settings;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
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> {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(Settings.class);
|
||||
private static final Path SETTINGS_DIR;
|
||||
private static final String SETTINGS_FILE = "settings.json";
|
||||
|
||||
static {
|
||||
final String appdata = System.getenv("APPDATA");
|
||||
final FileSystem fs = FileSystems.getDefault();
|
||||
|
||||
if (SystemUtils.IS_OS_WINDOWS && appdata != null) {
|
||||
SETTINGS_DIR = fs.getPath(appdata, "Cryptomator");
|
||||
} else if (SystemUtils.IS_OS_WINDOWS && appdata == null) {
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, ".Cryptomator");
|
||||
} else if (SystemUtils.IS_OS_MAC_OSX) {
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, "Library/Application Support/Cryptomator");
|
||||
} else {
|
||||
// (os.contains("solaris") || os.contains("sunos") || os.contains("linux") || os.contains("unix"))
|
||||
SETTINGS_DIR = fs.getPath(SystemUtils.USER_HOME, ".Cryptomator");
|
||||
}
|
||||
}
|
||||
|
||||
private final DeferredCloser deferredCloser;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Inject
|
||||
public SettingsProvider(DeferredCloser deferredCloser, @Named("VaultJsonMapper") ObjectMapper objectMapper) {
|
||||
this.deferredCloser = deferredCloser;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Settings get() {
|
||||
Settings settings = null;
|
||||
try {
|
||||
Files.createDirectories(SETTINGS_DIR);
|
||||
final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
|
||||
final InputStream in = Files.newInputStream(settingsFile, StandardOpenOption.READ);
|
||||
settings = objectMapper.readValue(in, Settings.class);
|
||||
} catch (IOException e) {
|
||||
LOG.warn("Failed to load settings, creating new one.");
|
||||
settings = new Settings();
|
||||
}
|
||||
deferredCloser.closeLater(settings, this::save);
|
||||
return settings;
|
||||
}
|
||||
|
||||
private void save(Settings settings) {
|
||||
if (settings == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Files.createDirectories(SETTINGS_DIR);
|
||||
final Path settingsFile = SETTINGS_DIR.resolve(SETTINGS_FILE);
|
||||
final OutputStream out = Files.newOutputStream(settingsFile, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE);
|
||||
objectMapper.writeValue(out, settings);
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to save settings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -30,7 +30,7 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.prefs.Preferences;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.cryptomator.ui.Main;
|
||||
import org.cryptomator.ui.Cryptomator;
|
||||
import org.cryptomator.ui.util.ListenerRegistry.ListenerRegistration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -193,7 +193,7 @@ public class SingleInstanceManager {
|
||||
IOUtils.closeQuietly(selector);
|
||||
IOUtils.closeQuietly(channel);
|
||||
if (getSavedPort(applicationKey).orElse(-1).equals(port)) {
|
||||
Preferences.userNodeForPackage(Main.class).remove(applicationKey);
|
||||
Preferences.userNodeForPackage(Cryptomator.class).remove(applicationKey);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ public class SingleInstanceManager {
|
||||
|
||||
/**
|
||||
* Checks if there is a valid port at
|
||||
* {@link Preferences#userNodeForPackage(Class)} for {@link Main} under the
|
||||
* {@link Preferences#userNodeForPackage(Class)} for {@link Cryptomator} under the
|
||||
* given applicationKey, tries to connect to the port at the loopback
|
||||
* address and checks if the port identifies with the applicationKey.
|
||||
*
|
||||
@ -284,7 +284,7 @@ public class SingleInstanceManager {
|
||||
}
|
||||
|
||||
static Optional<Integer> getSavedPort(String applicationKey) {
|
||||
int port = Preferences.userNodeForPackage(Main.class).getInt(applicationKey, -1);
|
||||
int port = Preferences.userNodeForPackage(Cryptomator.class).getInt(applicationKey, -1);
|
||||
|
||||
if (port == -1) {
|
||||
LOG.info("no running instance found");
|
||||
@ -296,7 +296,7 @@ public class SingleInstanceManager {
|
||||
|
||||
/**
|
||||
* Creates a server socket on a free port and saves the port in
|
||||
* {@link Preferences#userNodeForPackage(Class)} for {@link Main} under the
|
||||
* {@link Preferences#userNodeForPackage(Class)} for {@link Cryptomator} under the
|
||||
* given applicationKey.
|
||||
*
|
||||
* @param applicationKey
|
||||
@ -312,7 +312,7 @@ public class SingleInstanceManager {
|
||||
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
|
||||
final int port = ((InetSocketAddress) channel.getLocalAddress()).getPort();
|
||||
Preferences.userNodeForPackage(Main.class).putInt(applicationKey, port);
|
||||
Preferences.userNodeForPackage(Cryptomator.class).putInt(applicationKey, port);
|
||||
LOG.info("InstanceManager bound to port {}", port);
|
||||
|
||||
Selector selector = Selector.open();
|
||||
|
Loading…
Reference in New Issue
Block a user