diff --git a/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java b/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java deleted file mode 100644 index 7bca69457..000000000 --- a/main/commons/src/main/java/org/cryptomator/common/LazyInitializer.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Skymatic UG (haftungsbeschränkt). - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the accompanying LICENSE file. - *******************************************************************************/ -package org.cryptomator.common; - -import com.google.common.base.Throwables; - -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; -import java.util.function.UnaryOperator; - -public final class LazyInitializer { - - private LazyInitializer() { - } - - /** - * Same as {@link #initializeLazily(AtomicReference, SupplierThrowingException, Class)} except that no checked exception may be thrown by the factory function. - * - * @param Type of the value - * @param reference A reference to a maybe not yet initialized value. - * @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive. - * @return The initialized value - */ - public static T initializeLazily(AtomicReference reference, Supplier factory) { - SupplierThrowingException factoryThrowingRuntimeExceptions = () -> factory.get(); - return initializeLazily(reference, factoryThrowingRuntimeExceptions, RuntimeException.class); - } - - /** - * Threadsafe lazy initialization pattern as proposed on http://stackoverflow.com/a/30247202/4014509 - * - * @param Type of the value - * @param Type of the any expected exception that may occur during initialization - * @param reference A reference to a maybe not yet initialized value. - * @param factory A factory providing a value for the reference, if it doesn't exist yet. The factory may be invoked multiple times, but only one result will survive. - * @param exceptionType Expected exception type. - * @return The initialized value - * @throws E Exception thrown by the factory function. - */ - public static T initializeLazily(AtomicReference reference, SupplierThrowingException factory, Class exceptionType) throws E { - final T existing = reference.get(); - if (existing != null) { - return existing; - } else { - try { - return reference.updateAndGet(invokeFactoryIfNull(factory)); - } catch (InitializationException e) { - Throwables.throwIfUnchecked(e.getCause()); - Throwables.throwIfInstanceOf(e.getCause(), exceptionType); - throw e; - } - } - } - - private static UnaryOperator invokeFactoryIfNull(SupplierThrowingException factory) throws InitializationException { - return currentValue -> { - if (currentValue == null) { - try { - return factory.get(); - } catch (Exception e) { - throw new InitializationException(e); - } - } else { - return currentValue; - } - }; - } - - private static class InitializationException extends RuntimeException { - - public InitializationException(Throwable cause) { - super(cause); - } - - } -} diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java index 390e40f5a..85bc436a2 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/SettingsProvider.java @@ -8,13 +8,13 @@ *******************************************************************************/ package org.cryptomator.common.settings; +import com.google.common.base.Suppliers; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import org.cryptomator.common.Environment; -import org.cryptomator.common.LazyInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +48,7 @@ public class SettingsProvider implements Supplier { private static final long SAVE_DELAY_MS = 1000; private final AtomicReference> scheduledSaveCmd = new AtomicReference<>(); - private final AtomicReference settings = new AtomicReference<>(); + private final Supplier settings = Suppliers.memoize(this::load); private final SettingsJsonAdapter settingsJsonAdapter = new SettingsJsonAdapter(); private final Environment env; private final ScheduledExecutorService scheduler; @@ -66,7 +66,7 @@ public class SettingsProvider implements Supplier { @Override public Settings get() { - return LazyInitializer.initializeLazily(settings, this::load); + return settings.get(); } private Settings load() { diff --git a/main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java b/main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java index f2ab973f6..730f0fb6d 100644 --- a/main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java +++ b/main/commons/src/main/java/org/cryptomator/common/vaults/Vault.java @@ -10,7 +10,6 @@ package org.cryptomator.common.vaults; import com.google.common.base.Strings; import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.common.LazyInitializer; import org.cryptomator.common.mountpoint.InvalidMountPointException; import org.cryptomator.common.settings.VaultSettings; import org.cryptomator.common.vaults.Volume.VolumeException; @@ -100,11 +99,7 @@ public class Vault { // Commands // ********************************************************************************/ - private CryptoFileSystem getCryptoFileSystem(CharSequence passphrase) throws NoSuchFileException, IOException, InvalidPassphraseException, CryptoException { - return LazyInitializer.initializeLazily(cryptoFileSystem, () -> unlockCryptoFileSystem(passphrase), IOException.class); - } - - private CryptoFileSystem unlockCryptoFileSystem(CharSequence passphrase) throws NoSuchFileException, IOException, InvalidPassphraseException, CryptoException { + private CryptoFileSystem createCryptoFileSystem(CharSequence passphrase) throws NoSuchFileException, IOException, InvalidPassphraseException, CryptoException { Set flags = EnumSet.noneOf(FileSystemFlags.class); if (vaultSettings.usesReadOnlyMode().get()) { flags.add(FileSystemFlags.READONLY); @@ -127,9 +122,14 @@ public class Vault { } public synchronized void unlock(CharSequence passphrase) throws CryptoException, IOException, VolumeException, InvalidMountPointException { - CryptoFileSystem fs = getCryptoFileSystem(passphrase); - volume = volumeProvider.get(); - volume.mount(fs, getEffectiveMountFlags()); + if (cryptoFileSystem.get() == null) { + CryptoFileSystem fs = createCryptoFileSystem(passphrase); + cryptoFileSystem.set(fs); + volume = volumeProvider.get(); + volume.mount(fs, getEffectiveMountFlags()); + } else { + throw new IllegalStateException("Already unlocked."); + } } public synchronized void lock(boolean forced) throws VolumeException {