mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-17 10:11:27 +00:00
cleanup
This commit is contained in:
@@ -8,13 +8,6 @@ public final class Optionals {
|
||||
private Optionals() {
|
||||
}
|
||||
|
||||
public static <T, E extends Exception> void ifPresent(Optional<T> optional, ConsumerThrowingException<T, E> consumer) throws E {
|
||||
final T t = optional.orElse(null);
|
||||
if (t != null) {
|
||||
consumer.accept(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function that is equivalent to the input function but immediately gets the value of the returned optional when invoked.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -37,7 +37,7 @@ import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.jni.JniException;
|
||||
import org.cryptomator.jni.MacApplicationUiState;
|
||||
import org.cryptomator.jni.MacFunctions;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -24,10 +24,7 @@ import org.cryptomator.jni.JniModule;
|
||||
import org.cryptomator.keychain.KeychainModule;
|
||||
import org.cryptomator.ui.controllers.ViewControllerModule;
|
||||
import org.cryptomator.ui.model.VaultComponent;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
@@ -36,22 +33,6 @@ import javafx.beans.binding.Binding;
|
||||
@Module(includes = {ViewControllerModule.class, CommonsModule.class, KeychainModule.class, JniModule.class}, subcomponents = {VaultComponent.class})
|
||||
public class UiModule {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(UiModule.class);
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
DeferredCloser provideDeferredCloser(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
|
||||
DeferredCloser closer = new DeferredCloser();
|
||||
shutdownTaskScheduler.accept(() -> {
|
||||
try {
|
||||
closer.close();
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error during shutdown.", e);
|
||||
}
|
||||
});
|
||||
return closer;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
Settings provideSettings(SettingsProvider settingsProvider) {
|
||||
@@ -60,8 +41,10 @@ public class UiModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ExecutorService provideExecutorService(DeferredCloser closer) {
|
||||
return closer.closeLater(Executors.newCachedThreadPool(), ExecutorService::shutdown).get().orElseThrow(IllegalStateException::new);
|
||||
ExecutorService provideExecutorService(@Named("shutdownTaskScheduler") Consumer<Runnable> shutdownTaskScheduler) {
|
||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
shutdownTaskScheduler.accept(executorService::shutdown);
|
||||
return executorService;
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -20,8 +20,8 @@ import javax.inject.Singleton;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.PasswordStrengthUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -19,8 +19,8 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.PasswordStrengthUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -29,13 +29,13 @@ import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.ui.ExitUtil;
|
||||
import org.cryptomator.ui.controls.DirectoryListCell;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.AutoUnlocker;
|
||||
import org.cryptomator.ui.model.UpgradeStrategies;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.VaultFactory;
|
||||
import org.cryptomator.ui.model.VaultList;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -16,7 +16,7 @@ import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -24,9 +24,9 @@ import org.cryptomator.frontend.webdav.ServerLifecycleException;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.CommandFailedException;
|
||||
import org.cryptomator.keychain.KeychainAccess;
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.model.WindowsDriveLetters;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -14,8 +14,8 @@ import java.util.Optional;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.cryptomator.ui.util.DialogBuilderUtil;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
@@ -11,11 +11,11 @@ import java.util.Optional;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.cryptomator.ui.controls.SecPasswordField;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.model.UpgradeStrategies;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy;
|
||||
import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
|
||||
import org.cryptomator.ui.model.Vault;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -9,7 +14,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.controllers;
|
||||
|
||||
import dagger.Module;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -30,7 +30,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.cryptomator.ui.util.AsyncTaskService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 Sebastian Stenzel
|
||||
* Copyright (c) 2014, 2017 Sebastian Stenzel
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.settings;
|
||||
package org.cryptomator.ui.l10n;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -1,3 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.model;
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.cryptomator.cryptolib.api.CryptorProvider;
|
||||
import org.cryptomator.cryptolib.api.InvalidPassphraseException;
|
||||
import org.cryptomator.cryptolib.api.KeyFile;
|
||||
import org.cryptomator.cryptolib.api.UnsupportedVaultFormatException;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import javax.inject.Singleton;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.cryptolib.Cryptors;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.cryptolib.Cryptors;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.cryptolib.common.MessageDigestSupplier;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import javax.inject.Singleton;
|
||||
import org.cryptomator.cryptolib.Cryptors;
|
||||
import org.cryptomator.cryptolib.api.Cryptor;
|
||||
import org.cryptomator.cryptolib.api.FileHeader;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -40,7 +40,6 @@ import org.cryptomator.frontend.webdav.mount.Mounter.Mount;
|
||||
import org.cryptomator.frontend.webdav.mount.Mounter.UnmountOperation;
|
||||
import org.cryptomator.frontend.webdav.servlet.WebDavServletController;
|
||||
import org.cryptomator.ui.model.VaultModule.PerVault;
|
||||
import org.cryptomator.ui.util.DeferredCloser;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -60,7 +59,6 @@ public class Vault {
|
||||
private final Settings settings;
|
||||
private final VaultSettings vaultSettings;
|
||||
private final WebDavServer server;
|
||||
private final DeferredCloser closer;
|
||||
private final BooleanProperty unlocked = new SimpleBooleanProperty();
|
||||
private final BooleanProperty mounted = new SimpleBooleanProperty();
|
||||
private final AtomicReference<CryptoFileSystem> cryptoFileSystem = new AtomicReference<>();
|
||||
@@ -69,11 +67,10 @@ public class Vault {
|
||||
private Mount mount;
|
||||
|
||||
@Inject
|
||||
Vault(Settings settings, VaultSettings vaultSettings, WebDavServer server, DeferredCloser closer) {
|
||||
Vault(Settings settings, VaultSettings vaultSettings, WebDavServer server) {
|
||||
this.settings = settings;
|
||||
this.vaultSettings = vaultSettings;
|
||||
this.server = server;
|
||||
this.closer = closer;
|
||||
}
|
||||
|
||||
// ******************************************************************************
|
||||
@@ -89,9 +86,7 @@ public class Vault {
|
||||
.withPassphrase(passphrase) //
|
||||
.withMasterkeyFilename(MASTERKEY_FILENAME) //
|
||||
.build();
|
||||
CryptoFileSystem fs = CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
||||
closer.closeLater(fs);
|
||||
return fs;
|
||||
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
||||
}
|
||||
|
||||
public void create(CharSequence passphrase) throws IOException {
|
||||
@@ -103,7 +98,7 @@ public class Vault {
|
||||
}
|
||||
}
|
||||
if (!isValidVaultDirectory()) {
|
||||
getCryptoFileSystem(passphrase); // implicitly creates a non-existing vault
|
||||
createCryptoFileSystem(passphrase).close(); // implicitly creates a non-existing vault
|
||||
} else {
|
||||
throw new FileAlreadyExistsException(getPath().toString());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
|
||||
@@ -49,7 +49,7 @@ public class AsyncTaskService {
|
||||
|
||||
private ConsumerThrowingException<ResultType, ?> successHandler = value -> {
|
||||
};
|
||||
private List<ErrorHandler<Throwable>> errorHandlers = new ArrayList<>();
|
||||
private final List<ErrorHandler<Throwable>> errorHandlers = new ArrayList<>();
|
||||
private RunnableThrowingException<?> finallyHandler = () -> {
|
||||
};
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 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.util;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Wrapper around an object, which should be closed later - explicitly or by a
|
||||
* {@link DeferredCloser}. The wrapped object can be accessed as long as the
|
||||
* resource has not been closed.
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*
|
||||
* @param <T>
|
||||
* any type
|
||||
*/
|
||||
public interface DeferredClosable<T> extends AutoCloseable {
|
||||
/**
|
||||
* Returns the wrapped Object.
|
||||
*
|
||||
* @return empty if the object has been closed.
|
||||
*/
|
||||
public Optional<T> get();
|
||||
|
||||
/**
|
||||
* @return an empty object.
|
||||
*/
|
||||
public static <T> DeferredClosable<T> empty() {
|
||||
return DeferredCloser.empty();
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2016 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.util;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.cryptomator.common.ConsumerThrowingException;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Tries to bring open-close symmetry in contexts where the resource outlives
|
||||
* the current scope by introducing a manager, which closes the resources if
|
||||
* they haven't been closed before.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If you have a {@link DeferredCloser} instance present, call
|
||||
* {@link #closeLater(Object, ConsumerThrowingException)} immediately after you have opened the
|
||||
* resource and return a resource handle. If {@link #close()} is called, the
|
||||
* resource will be closed. Calling {@link DeferredClosable#close()} on the resource
|
||||
* handle will also close the resource and prevent a second closing by
|
||||
* {@link #close()}.
|
||||
* </p>
|
||||
*
|
||||
* @author Tillmann Gaida
|
||||
*/
|
||||
public class DeferredCloser implements AutoCloseable {
|
||||
|
||||
@VisibleForTesting
|
||||
final Map<Long, ManagedResource<?>> cleanups = new ConcurrentSkipListMap<>();
|
||||
|
||||
@VisibleForTesting
|
||||
final AtomicLong counter = new AtomicLong();
|
||||
|
||||
private class ManagedResource<T> implements DeferredClosable<T> {
|
||||
|
||||
private final long number = counter.incrementAndGet();
|
||||
private final T object;
|
||||
private final ConsumerThrowingException<T, Exception> closer;
|
||||
private boolean closed = false;
|
||||
|
||||
public ManagedResource(T object, ConsumerThrowingException<T, Exception> closer) {
|
||||
super();
|
||||
this.object = Objects.requireNonNull(object);
|
||||
this.closer = Objects.requireNonNull(closer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() throws Exception {
|
||||
closer.accept(object);
|
||||
cleanups.remove(number);
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<T> get() throws IllegalStateException {
|
||||
if (closed) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all added objects which have not been closed before and releases references.
|
||||
*/
|
||||
@Override
|
||||
public void close() throws ExecutionException {
|
||||
ExecutionException exception = null;
|
||||
for (Iterator<ManagedResource<?>> iterator = cleanups.values().iterator(); iterator.hasNext();) {
|
||||
final ManagedResource<?> closableProvider = iterator.next();
|
||||
try {
|
||||
closableProvider.close();
|
||||
iterator.remove();
|
||||
} catch (Exception e) {
|
||||
if (exception == null) {
|
||||
exception = new ExecutionException(e);
|
||||
} else {
|
||||
exception.addSuppressed(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
public <T> DeferredClosable<T> closeLater(T object, ConsumerThrowingException<T, Exception> closer) {
|
||||
Objects.requireNonNull(object);
|
||||
Objects.requireNonNull(closer);
|
||||
final ManagedResource<T> resource = new ManagedResource<T>(object, closer);
|
||||
cleanups.put(resource.number, resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
public <T extends AutoCloseable> DeferredClosable<T> closeLater(T object) {
|
||||
Objects.requireNonNull(object);
|
||||
final ManagedResource<T> resource = new ManagedResource<T>(object, AutoCloseable::close);
|
||||
cleanups.put(resource.number, resource);
|
||||
return resource;
|
||||
}
|
||||
|
||||
private static final EmptyResource<?> EMPTY_RESOURCE = new EmptyResource<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> DeferredClosable<T> empty() {
|
||||
return (DeferredClosable<T>) EMPTY_RESOURCE;
|
||||
}
|
||||
|
||||
static class EmptyResource<T> implements DeferredClosable<T> {
|
||||
@Override
|
||||
public Optional<T> get() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
@@ -15,7 +15,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cryptomator.ui.settings.Localization;
|
||||
import org.cryptomator.ui.l10n.Localization;
|
||||
|
||||
import com.nulabinc.zxcvbn.Zxcvbn;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE.txt.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.settings;
|
||||
package org.cryptomator.ui.l10n;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -1,56 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Sebastian Stenzel and others.
|
||||
* This file is licensed under the terms of the MIT license.
|
||||
* See the LICENSE.txt file for more info.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.ui.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class DeferredCloserTest {
|
||||
@Test
|
||||
public void testBasicFunctionality() throws Exception {
|
||||
DeferredCloser closer = new DeferredCloser();
|
||||
|
||||
final Closeable obj = mock(Closeable.class);
|
||||
|
||||
final DeferredClosable<Closeable> resource = closer.closeLater(obj);
|
||||
|
||||
assertTrue(resource.get().isPresent());
|
||||
assertTrue(resource.get().get() == obj);
|
||||
|
||||
closer.close();
|
||||
|
||||
assertFalse(resource.get().isPresent());
|
||||
verify(obj).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoremoval() throws Exception {
|
||||
DeferredCloser closer = new DeferredCloser();
|
||||
|
||||
final DeferredClosable<Closeable> resource = closer.closeLater(mock(Closeable.class));
|
||||
final DeferredClosable<Closeable> resource2 = closer.closeLater(mock(Closeable.class));
|
||||
|
||||
resource.close();
|
||||
|
||||
assertFalse(resource.get().isPresent());
|
||||
assertEquals(1, closer.cleanups.size());
|
||||
|
||||
assertTrue(resource2.get().isPresent());
|
||||
|
||||
closer.close();
|
||||
|
||||
assertFalse(resource2.get().isPresent());
|
||||
|
||||
assertEquals(0, closer.cleanups.size());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user