diff --git a/main/crypto-api/pom.xml b/main/crypto-api/pom.xml
index a903fed95..5e2ff08ad 100644
--- a/main/crypto-api/pom.xml
+++ b/main/crypto-api/pom.xml
@@ -18,6 +18,7 @@
Cryptomator cryptographic module API
+
commons-io
commons-io
diff --git a/main/pom.xml b/main/pom.xml
index 5ce5d04e0..190d77ca2 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -103,6 +103,13 @@
commons-codec
${commons-codec.version}
+
+
+
+ com.google.inject
+ guice
+ 3.0
+
diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index fbcb9671b..033920f33 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -19,9 +19,8 @@
Cryptomator
- org.cryptomator.ui.Main
+ org.cryptomator.ui.Cryptomator
${java.home}/../lib/ant-javafx.jar
- 8.20.8
@@ -50,23 +49,10 @@
commons-lang3
-
-
+
com.google.inject
guice
- 3.0
diff --git a/main/ui/src/main/java/org/cryptomator/ui/Main.java b/main/ui/src/main/java/org/cryptomator/ui/Cryptomator.java
similarity index 99%
rename from main/ui/src/main/java/org/cryptomator/ui/Main.java
rename to main/ui/src/main/java/org/cryptomator/ui/Cryptomator.java
index fca076b5a..27b3dbf68 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/Main.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/Cryptomator.java
@@ -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> OPEN_FILE_HANDLER = new CompletableFuture<>();
diff --git a/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java b/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java
index b4d62bfa5..df204e2b6 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/MainApplication.java
@@ -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));
}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/MainController.java b/main/ui/src/main/java/org/cryptomator/ui/MainController.java
index a1dd920e2..130a66be0 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/MainController.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/MainController.java
@@ -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 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 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 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();
diff --git a/main/ui/src/main/java/org/cryptomator/ui/MainModule.java b/main/ui/src/main/java/org/cryptomator/ui/MainModule.java
index 06f294136..14520604d 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/MainModule.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/MainModule.java
@@ -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, 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
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
index c688b6b0a..98867d0ee 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/Vault.java
@@ -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 unlocked = new SimpleObjectProperty(this, "unlocked", Boolean.FALSE);
private final Path path;
private String mountName;
private DeferredClosable webDavServlet = DeferredClosable.empty();
private DeferredClosable 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());
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultDeserializer.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultDeserializer.java
deleted file mode 100644
index 890a08310..000000000
--- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultDeserializer.java
+++ /dev/null
@@ -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 {
-
- @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;
- }
-
-}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java
new file mode 100644
index 000000000..7cac1a904
--- /dev/null
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/VaultObjectMapperProvider.java
@@ -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 {
+
+ private final Provider cryptorProvider;
+
+ @Inject
+ public VaultObjectMapperProvider(final Provider 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 {
+
+ @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 {
+
+ @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;
+ }
+
+ }
+
+}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/VaultSerializer.java b/main/ui/src/main/java/org/cryptomator/ui/model/VaultSerializer.java
deleted file mode 100644
index c77ceb367..000000000
--- a/main/ui/src/main/java/org/cryptomator/ui/model/VaultSerializer.java
+++ /dev/null
@@ -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 {
-
- @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();
- }
-
-}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java
index 30365ec04..cb4445b3b 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/settings/Settings.java
@@ -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 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 */
diff --git a/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java b/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java
new file mode 100644
index 000000000..38988b13a
--- /dev/null
+++ b/main/ui/src/main/java/org/cryptomator/ui/settings/SettingsProvider.java
@@ -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 {
+
+ 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);
+ }
+ }
+
+}
diff --git a/main/ui/src/main/java/org/cryptomator/ui/util/SingleInstanceManager.java b/main/ui/src/main/java/org/cryptomator/ui/util/SingleInstanceManager.java
index 4b687b7ce..a14b9f242 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/util/SingleInstanceManager.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/util/SingleInstanceManager.java
@@ -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 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();